} /* end reassemble_tcp */ /* here we search through all the frag we have collected to see if * one fits */ bool check_fragments(int index) { tcp_frag prev = null; tcp_frag current; current = frags[index]; while (current != null) { if (current.seq == seq[index]) { /* this fragment fits the stream */ if (current.data != null) { write_packet_data(index, current.data); } seq[index] += current.len; if (prev != null) { prev.next = current.next; } else { frags[index] = current.next; } current.data = null; current = null; return(true); } prev = current; current = current.next; } return(false); }
/// <summary> /// Search through all the frag we have collected to see if one fits /// </summary> /// <param name="net_src"></param> /// <param name="net_dst"></param> /// <param name="srcport"></param> /// <param name="dstport"></param> /// <param name="index"></param> /// <param name="timestamp"></param> /// <param name="acknowledged"></param> /// <returns></returns> private bool CheckFragments(long net_src, long net_dst, uint srcport, uint dstport, int index, PosixTimeval timestamp, uint acknowledged) { try { tcp_frag prev = null; tcp_frag current; ulong lowest_seq; current = _frags[index]; if (current != null) { lowest_seq = current.seq; while (current != null) { if ((lowest_seq > current.seq)) { lowest_seq = current.seq; } if (current.seq < _seq[index]) { ulong newseq; /* this sequence number seems dated, but * check the end to make sure it has no more * info than we have already seen */ newseq = current.seq + current.len; if (newseq > _seq[index]) { ulong new_pos; /* this one has more than we have seen. let's get the * payload that we have not seen. This happens when * part of this frame has been retransmitted */ new_pos = _seq[index] - current.seq; if (current.data_len > new_pos) { //sc->dlen = current.data_len - new_pos; byte[] tmpData = new byte[current.data_len - new_pos]; Buffer.BlockCopy(current.data, (int)new_pos, tmpData, 0, (int)(current.data_len - new_pos)); SavePacketData(net_src, net_dst, srcport, dstport, index, tmpData, timestamp); } _seq[index] += (current.len - new_pos); } /* Remove the fragment from the list as the "new" part of it * has been processed or its data has been seen already in * another packet. */ if (prev != null) { prev.next = current.next; } else { _frags[index] = current.next; } return(true); } if (current.seq == _seq[index]) { /* this fragment fits the stream */ if (current.data != null) { SavePacketData(net_src, net_dst, srcport, dstport, index, current.data, timestamp); } _seq[index] += current.len; if (prev != null) { prev.next = current.next; } else { _frags[index] = current.next; } current.data = null; current = null; return(true); } prev = current; current = current.next; } if (acknowledged > lowest_seq) { /* There are frames missing in the capture file that were seen * by the receiving host. Add dummy stream chunk with the data * "[xxx bytes missing in capture file]". */ //dummy_str = g_strdup_printf("[%d bytes missing in capture file]", // (int)(lowest_seq - seq[idx])); //sc->dlen = (guint32)strlen(dummy_str); byte[] dummyData = new byte[(lowest_seq - _seq[index])]; SavePacketData(net_src, net_dst, srcport, dstport, index, dummyData, timestamp); _seq[index] = lowest_seq; return(true); } } return(false); } catch (Exception ex) { //this.Log().Error(ex.ToString()); return(false); } }
/// <summary> /// Reconstructs the tcp session /// </summary> /// <param name="sequence">Sequence number of the tcp packet</param> /// <param name="length">The size of the original packet data</param> /// <param name="data">The captured data</param> /// <param name="data_length">The length of the captured data</param> /// <param name="synflag"></param> /// <param name="net_src">The source ip address</param> /// <param name="net_dst">The destination ip address</param> /// <param name="srcport">The source port</param> /// <param name="dstport">The destination port</param> /// <param name="timestamp">Packet timestamp</param> private void ReassembleTcp(ulong sequence, uint acknowledgement, ulong length, byte[] data, ulong data_length, bool synflag, long net_src, long net_dst, uint srcport, uint dstport, PosixTimeval timestamp) { try { long srcx, dstx; int src_index, j; bool first = false; ulong newseq; tcp_frag tmp_frag; src_index = -1; /* Now check if the packet is for this connection. */ srcx = net_src; dstx = net_dst; /* Check to see if we have seen this source IP and port before. * (Yes, we have to check both source IP and port; the connection * might be between two different ports on the same machine.) */ for (j = 0; j < 2; j++) { if (_srcAddr[j] == srcx && _srcPort[j] == srcport) { src_index = j; //break; } } /* we didn't find it if src_index == -1 */ if (src_index < 0) { /* assign it to a src_index and get going */ for (j = 0; j < 2; j++) { if (_srcPort[j] == 0) { _srcAddr[j] = srcx; _srcPort[j] = srcport; src_index = j; first = true; break; } } } if (src_index < 0) { throw new Exception("Too many addresses!"); } /* Before adding data for this flow to the data_out_file, check whether * this frame acks fragments that were already seen. This happens when * frames are not in the capture file, but were actually seen by the * receiving host (Fixes bug 592). */ if (_frags[1 - src_index] != null) { while (CheckFragments(net_src, net_dst, srcport, dstport, 1 - src_index, timestamp, acknowledgement)) { ; } } /* now that we have filed away the srcs, lets get the sequence number stuff figured out */ if (first) { /* this is the first time we have seen this src's sequence number */ _seq[src_index] = sequence + length; if (synflag) { _seq[src_index]++; } SavePacketData(net_src, net_dst, srcport, dstport, src_index, data, timestamp); return; } /* if we are here, we have already seen this src, let's * try and figure out if this packet is in the right place */ if (sequence < _seq[src_index]) { /* this sequence number seems dated, but * check the end to make sure it has no more * info than we have already seen */ newseq = sequence + length; if (newseq > _seq[src_index]) { ulong new_len; /* this one has more than we have seen. let's get the * payload that we have not seen. */ new_len = _seq[src_index] - sequence; if (data_length <= new_len) { data = null; data_length = 0; } else { data_length -= new_len; byte[] tmpData = new byte[data_length]; Buffer.BlockCopy(data, (int)new_len, tmpData, 0, (int)data_length); //for (ulong i = 0; i < data_length; i++) //{ // tmpData[i] = data[i + new_len]; //} data = tmpData; } sequence = _seq[src_index]; length = newseq - _seq[src_index]; /* this will now appear to be right on time :) */ } } if (sequence == _seq[src_index]) { /* right on time */ _seq[src_index] += length; if (synflag) { _seq[src_index]++; } if (data != null) { SavePacketData(net_src, net_dst, srcport, dstport, src_index, data, timestamp); } /* done with the packet, see if it caused a fragment to fit */ while (CheckFragments(net_src, net_dst, srcport, dstport, src_index, timestamp, acknowledgement)) { ; } } else { /* out of order packet */ if (data_length > 0 && sequence > _seq[src_index]) { tmp_frag = new tcp_frag(); tmp_frag.data = data; tmp_frag.seq = sequence; tmp_frag.len = length; tmp_frag.data_len = data_length; if (_frags[src_index] != null) { tmp_frag.next = _frags[src_index]; } else { tmp_frag.next = null; } _frags[src_index] = tmp_frag; } } } catch (Exception ex) { //this.Log().Error(ex.ToString()); } }
/// <summary> /// Reconstructs the tcp session /// </summary> /// <param name="sequence">Sequence number of the tcp packet</param> /// <param name="length">The size of the original packet data</param> /// <param name="data">The captured data</param> /// <param name="data_length">The length of the captured data</param> /// <param name="synflag"></param> /// <param name="net_src">The source ip address</param> /// <param name="net_dst">The destination ip address</param> /// <param name="srcport">The source port</param> /// <param name="dstport">The destination port</param> /// <param name="timestamp">Packet timestamp</param> private void ReassembleTcp(ulong sequence, uint acknowledgement, ulong length, byte[] data, ulong data_length, bool synflag, long net_src, long net_dst, uint srcport, uint dstport, PosixTimeval timestamp) { try { long srcx, dstx; int src_index, j; bool first = false; ulong newseq; tcp_frag tmp_frag; src_index = -1; /* Now check if the packet is for this connection. */ srcx = net_src; dstx = net_dst; /* Check to see if we have seen this source IP and port before. (Yes, we have to check both source IP and port; the connection might be between two different ports on the same machine.) */ for (j = 0; j < 2; j++) { if (_srcAddr[j] == srcx && _srcPort[j] == srcport) { src_index = j; //break; } } /* we didn't find it if src_index == -1 */ if (src_index < 0) { /* assign it to a src_index and get going */ for (j = 0; j < 2; j++) { if (_srcPort[j] == 0) { _srcAddr[j] = srcx; _srcPort[j] = srcport; src_index = j; first = true; break; } } } if (src_index < 0) { throw new Exception("Too many addresses!"); } /* Before adding data for this flow to the data_out_file, check whether * this frame acks fragments that were already seen. This happens when * frames are not in the capture file, but were actually seen by the * receiving host (Fixes bug 592). */ if (_frags[1 - src_index] != null) { while (CheckFragments(net_src, net_dst, srcport, dstport, 1 - src_index, timestamp, acknowledgement)) ; } /* now that we have filed away the srcs, lets get the sequence number stuff figured out */ if (first) { /* this is the first time we have seen this src's sequence number */ _seq[src_index] = sequence + length; if (synflag) { _seq[src_index]++; } SavePacketData(net_src, net_dst, srcport, dstport, src_index, data, timestamp); return; } /* if we are here, we have already seen this src, let's try and figure out if this packet is in the right place */ if (sequence < _seq[src_index]) { /* this sequence number seems dated, but check the end to make sure it has no more info than we have already seen */ newseq = sequence + length; if (newseq > _seq[src_index]) { ulong new_len; /* this one has more than we have seen. let's get the payload that we have not seen. */ new_len = _seq[src_index] - sequence; if (data_length <= new_len) { data = null; data_length = 0; } else { data_length -= new_len; byte[] tmpData = new byte[data_length]; Buffer.BlockCopy(data, (int)new_len, tmpData, 0, (int)data_length); //for (ulong i = 0; i < data_length; i++) //{ // tmpData[i] = data[i + new_len]; //} data = tmpData; } sequence = _seq[src_index]; length = newseq - _seq[src_index]; /* this will now appear to be right on time :) */ } } if (sequence == _seq[src_index]) { /* right on time */ _seq[src_index] += length; if (synflag) { _seq[src_index]++; } if (data != null) { SavePacketData(net_src, net_dst, srcport, dstport, src_index, data, timestamp); } /* done with the packet, see if it caused a fragment to fit */ while (CheckFragments(net_src, net_dst, srcport, dstport, src_index, timestamp, acknowledgement)) ; } else { /* out of order packet */ if (data_length > 0 && sequence > _seq[src_index]) { tmp_frag = new tcp_frag(); tmp_frag.data = data; tmp_frag.seq = sequence; tmp_frag.len = length; tmp_frag.data_len = data_length; if (_frags[src_index] != null) { tmp_frag.next = _frags[src_index]; } else { tmp_frag.next = null; } _frags[src_index] = tmp_frag; } } } catch (Exception ex) { //this.Log().Error(ex.ToString()); } }
private void reassemble_tcp(ulong sequence, ulong length, byte[] data, ulong data_length, bool synflag, long net_src, long net_dst, uint srcport, uint dstport) { long srcx, dstx; int src_index, j; bool first = false; ulong newseq; tcp_frag tmp_frag; src_index = -1; /* Now check if the packet is for this connection. */ srcx = net_src; dstx = net_dst; /* Check to see if we have seen this source IP and port before. * (Yes, we have to check both source IP and port; the connection * might be between two different ports on the same machine.) */ for (j = 0; j < 2; j++) { if (src_addr[j] == srcx && src_port[j] == srcport) { src_index = j; } } /* we didn't find it if src_index == -1 */ if (src_index < 0) { /* assign it to a src_index and get going */ for (j = 0; j < 2; j++) { if (src_port[j] == 0) { src_addr[j] = srcx; src_port[j] = srcport; src_index = j; first = true; break; } } } if (src_index < 0) { throw new Exception("ERROR in reassemble_tcp: Too many addresses!"); } if (data_length < length) { incomplete_tcp_stream = true; } /* now that we have filed away the srcs, lets get the sequence number stuff * figured out */ if (first) { /* this is the first time we have seen this src's sequence number */ seq[src_index] = sequence + length; if (synflag) { seq[src_index]++; } /* write out the packet data */ write_packet_data(src_index, data); return; } /* if we are here, we have already seen this src, let's * try and figure out if this packet is in the right place */ if (sequence < seq[src_index]) { /* this sequence number seems dated, but * check the end to make sure it has no more * info than we have already seen */ newseq = sequence + length; if (newseq > seq[src_index]) { ulong new_len; /* this one has more than we have seen. let's get the * payload that we have not seen. */ new_len = seq[src_index] - sequence; if (data_length <= new_len) { data = null; data_length = 0; incomplete_tcp_stream = true; } else { data_length -= new_len; byte[] tmpData = new byte[data_length]; for (ulong i = 0; i < data_length; i++) { tmpData[i] = data[i + new_len]; } data = tmpData; } sequence = seq[src_index]; length = newseq - seq[src_index]; /* this will now appear to be right on time :) */ } } if (sequence == seq[src_index]) { /* right on time */ seq[src_index] += length; if (synflag) { seq[src_index]++; } if (data != null) { write_packet_data(src_index, data); } /* done with the packet, see if it caused a fragment to fit */ while (check_fragments(src_index)) { ; } } else { /* out of order packet */ if (data_length > 0 && sequence > seq[src_index]) { tmp_frag = new tcp_frag(); tmp_frag.data = data; tmp_frag.seq = sequence; tmp_frag.len = length; tmp_frag.data_len = data_length; if (frags[src_index] != null) { tmp_frag.next = frags[src_index]; } else { tmp_frag.next = null; } frags[src_index] = tmp_frag; } } } /* end reassemble_tcp */