} /* 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> /// 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> 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; } } }
/// <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> 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 */