gboolean empty_tcp_stream;
gboolean incomplete_tcp_stream;
+static guint32 tcp_stream_to_follow;
static guint8 ip_address[2][MAX_IPADDR_LEN];
static guint port[2];
static guint bytes_written[2];
buf = g_strdup_printf("tcp.stream eq %d", conv->index);
len = 4;
is_ipv6 = FALSE;
+ tcp_stream_to_follow = conv->index;
}
else if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4
&& pi->ipproto == IP_PROTO_UDP ) {
buf = g_strdup_printf("tcp.stream eq %d", conv->index);
len = 16;
is_ipv6 = TRUE;
+ tcp_stream_to_follow = conv->index;
}
else if( pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6
&& pi->ipproto == IP_PROTO_UDP ) {
static guint src_port[2] = { 0, 0 };
void
-reassemble_tcp( gulong sequence, gulong acknowledgement, gulong length,
- const char* data, gulong data_length, int synflag,
- address *net_src, address *net_dst,
+reassemble_tcp( guint32 tcp_stream, gulong sequence, gulong acknowledgement,
+ gulong length, const char* data, gulong data_length,
+ int synflag, address *net_src, address *net_dst,
guint srcport, guint dstport) {
guint8 srcx[MAX_IPADDR_LEN], dstx[MAX_IPADDR_LEN];
int src_index, j, first = 0, len;
src_index = -1;
/* First, check if this packet should be processed. */
+ if ( tcp_stream != tcp_stream_to_follow )
+ return;
if ((net_src->type != AT_IPv4 && net_src->type != AT_IPv6) ||
(net_dst->type != AT_IPv4 && net_dst->type != AT_IPv6))
else
len = 16;
- /* Now check if the packet is for this connection. */
memcpy(srcx, net_src->data, len);
memcpy(dstx, net_dst->data, len);
- if (
- ! (
- memcmp(srcx, ip_address[0], len) == 0 &&
- memcmp(dstx, ip_address[1], len) == 0 &&
- srcport == port[0] &&
- dstport == port[1]
- ) &&
- ! (
- memcmp(srcx, ip_address[1], len) == 0 &&
- memcmp(dstx, ip_address[0], len) == 0 &&
- srcport == port[1] &&
- dstport == port[0]
- )
- )
- return;
/* 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
}
else {
/* out of order packet */
- if(data_length > 0 && sequence > seq[src_index] ) {
+ if(data_length > 0 && ((glong)(sequence - seq[src_index]) > 0) ) {
tmp_frag = (tcp_frag *)g_malloc( sizeof( tcp_frag ) );
tmp_frag->data = (gchar *)g_malloc( data_length );
tmp_frag->seq = sequence;
/* here we search through all the frag we have collected to see if
one fits */
static int
-check_fragments( int index, tcp_stream_chunk *sc, gulong acknowledged ) {
+check_fragments( int idx, tcp_stream_chunk *sc, gulong acknowledged ) {
tcp_frag *prev = NULL;
tcp_frag *current;
gulong lowest_seq;
gchar *dummy_str;
- current = frags[index];
+ current = frags[idx];
if( current ) {
lowest_seq = current->seq;
while( current ) {
lowest_seq = current->seq;
}
- if( current->seq < seq[index] ) {
+ if( current->seq < seq[idx] ) {
gulong 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] ) {
+ if( newseq > seq[idx] ) {
gulong 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;
+ new_pos = seq[idx] - current->seq;
if ( current->data_len > new_pos ) {
sc->dlen = current->data_len - new_pos;
- write_packet_data( index, sc, current->data + new_pos );
+ write_packet_data( idx, sc, current->data + new_pos );
}
- seq[index] += (current->len - new_pos);
- if( prev ) {
- prev->next = current->next;
- } else {
- frags[index] = current->next;
- }
- g_free( current->data );
- g_free( current );
- return 1;
+ seq[idx] += (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 ) {
+ prev->next = current->next;
+ } else {
+ frags[idx] = current->next;
}
+ g_free( current->data );
+ g_free( current );
+ return 1;
}
- if( current->seq == seq[index] ) {
+ if( current->seq == seq[idx] ) {
/* this fragment fits the stream */
if( current->data ) {
sc->dlen = current->data_len;
- write_packet_data( index, sc, current->data );
+ write_packet_data( idx, sc, current->data );
}
- seq[index] += current->len;
+ seq[idx] += current->len;
if( prev ) {
prev->next = current->next;
} else {
- frags[index] = current->next;
+ frags[idx] = current->next;
}
g_free( current->data );
g_free( current );
* "[xxx bytes missing in capture file]".
*/
dummy_str = g_strdup_printf("[%d bytes missing in capture file]",
- (int)(lowest_seq - seq[index]) );
- sc->dlen = strlen(dummy_str);
- write_packet_data( index, sc, dummy_str );
+ (int)(lowest_seq - seq[idx]) );
+ sc->dlen = (guint32) strlen(dummy_str);
+ write_packet_data( idx, sc, dummy_str );
g_free(dummy_str);
- seq[index] = lowest_seq;
+ seq[idx] = lowest_seq;
return 1;
}
}
}
static void
-write_packet_data( int index, tcp_stream_chunk *sc, const char *data )
+write_packet_data( int idx, tcp_stream_chunk *sc, const char *data )
{
- DISSECTOR_ASSERT(1 * sizeof(tcp_stream_chunk) == fwrite( sc, 1, sizeof(tcp_stream_chunk), data_out_file ));
- DISSECTOR_ASSERT(1 * sc->dlen == fwrite( data, 1, sc->dlen, data_out_file ));
- bytes_written[index] += sc->dlen;
+ size_t ret;
+
+ ret = fwrite( sc, 1, sizeof(tcp_stream_chunk), data_out_file );
+ DISSECTOR_ASSERT(sizeof(tcp_stream_chunk) == ret);
+
+ ret = fwrite( data, 1, sc->dlen, data_out_file );
+ DISSECTOR_ASSERT(sc->dlen == ret);
+
+ bytes_written[idx] += sc->dlen;
empty_tcp_stream = FALSE;
}