Witness: enum witness_interface_state
[metze/wireshark/wip.git] / epan / follow.c
1 /* follow.c
2  *
3  * $Id$
4  *
5  * Copyright 1998 Mike Hall <mlh@io.com>
6  *
7  * Wireshark - Network traffic analyzer
8  * By Gerald Combs <gerald@wireshark.org>
9  * Copyright 1998 Gerald Combs
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  *
25  */
26
27 #include "config.h"
28
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35
36 #include <glib.h>
37 #include <epan/packet.h>
38 #include <epan/to_str.h>
39 #include <epan/emem.h>
40 #include <epan/dissectors/packet-tcp.h>
41 #include "follow.h"
42 #include <epan/conversation.h>
43
44 #define MAX_IPADDR_LEN  16
45
46 typedef struct _tcp_frag {
47   guint32             seq;
48   guint32             len;
49   guint32             data_len;
50   gchar              *data;
51   struct _tcp_frag   *next;
52 } tcp_frag;
53
54 WS_DLL_PUBLIC_DEF
55 FILE* data_out_file = NULL;
56
57 gboolean empty_tcp_stream;
58 gboolean incomplete_tcp_stream;
59
60 static guint32 tcp_stream_to_follow = 0;
61 static guint8  ip_address[2][MAX_IPADDR_LEN];
62 static guint   port[2];
63 static guint   bytes_written[2];
64 static gboolean is_ipv6 = FALSE;
65
66 static int check_fragments( int, tcp_stream_chunk *, guint32 );
67 static void write_packet_data( int, tcp_stream_chunk *, const char * );
68
69 void
70 follow_stats(follow_stats_t* stats)
71 {
72         int i;
73
74         for (i = 0; i < 2 ; i++) {
75                 memcpy(stats->ip_address[i], ip_address[i], MAX_IPADDR_LEN);
76                 stats->port[i] = port[i];
77                 stats->bytes_written[i] = bytes_written[i];
78                 stats->is_ipv6 = is_ipv6;
79         }
80 }
81
82 /* This will build a display filter text that will only
83    pass the packets related to the stream. There is a
84    chance that two streams could intersect, but not a
85    very good one */
86 gchar*
87 build_follow_conv_filter( packet_info *pi ) {
88   char* buf;
89   int len;
90   conversation_t *conv=NULL;
91   struct tcp_analysis *tcpd;
92   wmem_list_frame_t* protos;
93   int proto_id;
94   const char* proto_name;
95   gboolean is_tcp = FALSE, is_udp = FALSE;
96
97   protos = wmem_list_head(pi->layers);
98
99   /* walk the list of a available protocols in the packet to
100       figure out if any of them affect context sensitivity */
101   while (protos != NULL)
102   {
103     proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
104     proto_name = proto_get_protocol_filter_name(proto_id);
105
106     if (!strcmp(proto_name, "tcp")) {
107         is_tcp = TRUE;
108     } else if (!strcmp(proto_name, "udp")) {
109         is_udp = TRUE;
110     }
111             
112     protos = wmem_list_frame_next(protos);
113   }
114
115   if( ((pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4) ||
116        (pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6))
117         && is_tcp && (conv=find_conversation(pi->fd->num, &pi->src, &pi->dst, pi->ptype,
118               pi->srcport, pi->destport, 0)) != NULL ) {
119     /* TCP over IPv4 */
120     tcpd=get_tcp_conversation_data(conv, pi);
121     if (tcpd) {
122       buf = g_strdup_printf("tcp.stream eq %d", tcpd->stream);
123       tcp_stream_to_follow = tcpd->stream;
124       if (pi->net_src.type == AT_IPv4) {
125         len = 4;
126         is_ipv6 = FALSE;
127       } else {
128         len = 16;
129         is_ipv6 = TRUE;
130       }
131     } else {
132       return NULL;
133     }
134   }
135   else if( pi->net_src.type == AT_IPv4 && pi->net_dst.type == AT_IPv4
136            && is_udp ) {
137   /* UDP over IPv4 */
138     buf = g_strdup_printf(
139              "(ip.addr eq %s and ip.addr eq %s) and (udp.port eq %d and udp.port eq %d)",
140              ip_to_str((const guint8 *)pi->net_src.data),
141              ip_to_str((const guint8 *)pi->net_dst.data),
142              pi->srcport, pi->destport );
143     len = 4;
144     is_ipv6 = FALSE;
145   }
146   else if( pi->net_src.type == AT_IPv6 && pi->net_dst.type == AT_IPv6
147         && is_udp ) {
148     /* UDP over IPv6 */
149     buf = g_strdup_printf(
150              "(ipv6.addr eq %s and ipv6.addr eq %s) and (udp.port eq %d and udp.port eq %d)",
151              ip6_to_str((const struct e_in6_addr *)pi->net_src.data),
152              ip6_to_str((const struct e_in6_addr *)pi->net_dst.data),
153              pi->srcport, pi->destport );
154     len = 16;
155     is_ipv6 = TRUE;
156   }
157   else {
158     return NULL;
159   }
160   memcpy(ip_address[0], pi->net_src.data, len);
161   memcpy(ip_address[1], pi->net_dst.data, len);
162   port[0] = pi->srcport;
163   port[1] = pi->destport;
164   return buf;
165 }
166
167 static gboolean         find_tcp_addr;
168 static address          tcp_addr[2];
169 static gboolean         find_tcp_index;
170
171 gchar*
172 build_follow_index_filter(void) {
173   gchar *buf;
174
175   find_tcp_addr = TRUE;
176   buf = g_strdup_printf("tcp.stream eq %d", tcp_stream_to_follow);
177   return buf;
178 }
179
180 /* select a tcp stream to follow via it's address/port pairs */
181 gboolean
182 follow_tcp_addr(const address *addr0, guint port0,
183                 const address *addr1, guint port1)
184 {
185   if (addr0 == NULL || addr1 == NULL || addr0->type != addr1->type ||
186       port0 > G_MAXUINT16 || port1 > G_MAXUINT16 )  {
187     return FALSE;
188   }
189
190   if (find_tcp_index || find_tcp_addr) {
191     return FALSE;
192   }
193
194   switch (addr0->type) {
195   default:
196     return FALSE;
197   case AT_IPv4:
198   case AT_IPv6:
199     is_ipv6 = addr0->type == AT_IPv6;
200     break;
201   }
202
203   find_tcp_index = TRUE;
204
205   memcpy(ip_address[0], addr0->data, addr0->len);
206   SET_ADDRESS(&tcp_addr[0], addr0->type, addr0->len, ip_address[0]);
207   port[0] = port0;
208
209   memcpy(ip_address[1], addr1->data, addr1->len);
210   SET_ADDRESS(&tcp_addr[1], addr1->type, addr1->len, ip_address[1]);
211   port[1] = port1;
212
213   return TRUE;
214 }
215
216 /* select a tcp stream to follow via its index */
217 gboolean
218 follow_tcp_index(guint32 indx)
219 {
220   if (find_tcp_index || find_tcp_addr) {
221     return FALSE;
222   }
223
224   if (indx > get_tcp_stream_count()) {
225     return FALSE;
226   }
227
228   find_tcp_addr = TRUE;
229   tcp_stream_to_follow = indx;
230   memset(ip_address, 0, sizeof ip_address);
231   port[0] = port[1] = 0;
232
233   return TRUE;
234 }
235
236 guint32
237 get_follow_tcp_index(void) {
238   return tcp_stream_to_follow;
239 }
240
241 /* here we are going to try and reconstruct the data portion of a TCP
242    session. We will try and handle duplicates, TCP fragments, and out
243    of order packets in a smart way. */
244
245 static tcp_frag *frags[2] = { 0, 0 };
246 static guint32 seq[2];
247 static guint8 src_addr[2][MAX_IPADDR_LEN];
248 static guint src_port[2] = { 0, 0 };
249
250 void
251 reassemble_tcp( guint32 tcp_stream, guint32 sequence, guint32 acknowledgement,
252                 guint32 length, const char* data, guint32 data_length, 
253                 int synflag, address *net_src, address *net_dst, 
254                 guint srcport, guint dstport, guint32 packet_num) {
255   guint8 srcx[MAX_IPADDR_LEN], dstx[MAX_IPADDR_LEN];
256   int src_index, j, first = 0, len;
257   guint32 newseq;
258   tcp_frag *tmp_frag;
259   tcp_stream_chunk sc;
260
261   src_index = -1;
262
263   /* First, check if this packet should be processed. */
264   if (find_tcp_index) {
265     if ((port[0] == srcport && port[1] == dstport &&
266          ADDRESSES_EQUAL(&tcp_addr[0], net_src) &&
267          ADDRESSES_EQUAL(&tcp_addr[1], net_dst))
268         ||
269         (port[1] == srcport && port[0] == dstport &&
270          ADDRESSES_EQUAL(&tcp_addr[1], net_src) &&
271          ADDRESSES_EQUAL(&tcp_addr[0], net_dst))) {
272       find_tcp_index = FALSE;
273       tcp_stream_to_follow = tcp_stream;
274     }
275     else {
276       return;
277     }
278   }
279   else if ( tcp_stream != tcp_stream_to_follow )
280     return;
281
282   if ((net_src->type != AT_IPv4 && net_src->type != AT_IPv6) ||
283       (net_dst->type != AT_IPv4 && net_dst->type != AT_IPv6))
284     return;
285
286   if (net_src->type == AT_IPv4)
287     len = 4;
288   else
289     len = 16;
290
291   memcpy(srcx, net_src->data, len);
292   memcpy(dstx, net_dst->data, len);
293
294   /* follow_tcp_index() needs to learn address/port pairs */
295   if (find_tcp_addr) {
296     find_tcp_addr = FALSE;
297     memcpy(ip_address[0], net_src->data, net_src->len);
298     port[0] = srcport;
299     memcpy(ip_address[1], net_dst->data, net_dst->len);
300     port[1] = dstport;
301     if (net_src->type == AT_IPv6 && net_dst->type == AT_IPv6) {
302       is_ipv6 = TRUE;
303     } else {
304       is_ipv6 = FALSE;
305     }
306   }
307
308   /* Check to see if we have seen this source IP and port before.
309      (Yes, we have to check both source IP and port; the connection
310      might be between two different ports on the same machine.) */
311   for( j=0; j<2; j++ ) {
312     if (memcmp(src_addr[j], srcx, len) == 0 && src_port[j] == srcport ) {
313       src_index = j;
314     }
315   }
316   /* we didn't find it if src_index == -1 */
317   if( src_index < 0 ) {
318     /* assign it to a src_index and get going */
319     for( j=0; j<2; j++ ) {
320       if( src_port[j] == 0 ) {
321         memcpy(src_addr[j], srcx, len);
322         src_port[j] = srcport;
323         src_index = j;
324         first = 1;
325         break;
326       }
327     }
328   }
329   if( src_index < 0 ) {
330     fprintf( stderr, "ERROR in reassemble_tcp: Too many addresses!\n");
331     return;
332   }
333
334   if( data_length < length ) {
335     incomplete_tcp_stream = TRUE;
336   }
337
338   /* Before adding data for this flow to the data_out_file, check whether
339    * this frame acks fragments that were already seen. This happens when
340    * frames are not in the capture file, but were actually seen by the 
341    * receiving host (Fixes bug 592).
342    */
343   if( frags[1-src_index] ) {
344     memcpy(sc.src_addr, dstx, len);
345     sc.src_port = dstport;
346     sc.dlen     = 0;        /* Will be filled in in check_fragments */
347     while ( check_fragments( 1-src_index, &sc, acknowledgement ) )
348       ;
349   }
350
351   /* Initialize our stream chunk.  This data gets written to disk. */
352   memcpy(sc.src_addr, srcx, len);
353   sc.src_port   = srcport;
354   sc.dlen       = data_length;
355   sc.packet_num = packet_num;
356
357   /* now that we have filed away the srcs, lets get the sequence number stuff
358      figured out */
359   if( first ) {
360     /* this is the first time we have seen this src's sequence number */
361     seq[src_index] = sequence + length;
362     if( synflag ) {
363       seq[src_index]++;
364     }
365     /* write out the packet data */
366     write_packet_data( src_index, &sc, data );
367     return;
368   }
369   /* if we are here, we have already seen this src, let's
370      try and figure out if this packet is in the right place */
371   if( sequence < seq[src_index] ) {
372     /* this sequence number seems dated, but
373        check the end to make sure it has no more
374        info than we have already seen */
375     newseq = sequence + length;
376     if( newseq > seq[src_index] ) {
377       guint32 new_len;
378
379       /* this one has more than we have seen. let's get the
380          payload that we have not seen. */
381
382       new_len = seq[src_index] - sequence;
383
384       if ( data_length <= new_len ) {
385         data = NULL;
386         data_length = 0;
387         incomplete_tcp_stream = TRUE;
388       } else {
389         data += new_len;
390         data_length -= new_len;
391       }
392       sc.dlen = data_length;
393       sequence = seq[src_index];
394       length = newseq - seq[src_index];
395
396       /* this will now appear to be right on time :) */
397     }
398   }
399   if ( sequence == seq[src_index] ) {
400     /* right on time */
401     seq[src_index] += length;
402     if( synflag ) seq[src_index]++;
403     if( data ) {
404       write_packet_data( src_index, &sc, data );
405     }
406     /* done with the packet, see if it caused a fragment to fit */
407     while( check_fragments( src_index, &sc, 0 ) )
408       ;
409   }
410   else {
411     /* out of order packet */
412     if(data_length > 0 && GT_SEQ(sequence, seq[src_index]) ) {
413       tmp_frag = (tcp_frag *)g_malloc( sizeof( tcp_frag ) );
414       tmp_frag->data = (gchar *)g_malloc( data_length );
415       tmp_frag->seq = sequence;
416       tmp_frag->len = length;
417       tmp_frag->data_len = data_length;
418       memcpy( tmp_frag->data, data, data_length );
419       if( frags[src_index] ) {
420         tmp_frag->next = frags[src_index];
421       } else {
422         tmp_frag->next = NULL;
423       }
424       frags[src_index] = tmp_frag;
425     }
426   }
427 } /* end reassemble_tcp */
428
429 /* here we search through all the frag we have collected to see if
430    one fits */
431 static int
432 check_fragments( int idx, tcp_stream_chunk *sc, guint32 acknowledged ) {
433   tcp_frag *prev = NULL;
434   tcp_frag *current;
435   guint32 lowest_seq;
436   gchar *dummy_str;
437
438   current = frags[idx];
439   if( current ) {
440     lowest_seq = current->seq;
441     while( current ) {
442       if( GT_SEQ(lowest_seq, current->seq) ) {
443         lowest_seq = current->seq;
444       }
445
446       if( current->seq < seq[idx] ) {
447         guint32 newseq;
448         /* this sequence number seems dated, but
449            check the end to make sure it has no more
450            info than we have already seen */
451         newseq = current->seq + current->len;
452         if( newseq > seq[idx] ) {
453           guint32 new_pos;
454
455           /* this one has more than we have seen. let's get the
456              payload that we have not seen. This happens when 
457              part of this frame has been retransmitted */
458
459           new_pos = seq[idx] - current->seq;
460
461           if ( current->data_len > new_pos ) {
462             sc->dlen = current->data_len - new_pos;
463             write_packet_data( idx, sc, current->data + new_pos );
464           }
465
466           seq[idx] += (current->len - new_pos);
467         } 
468
469         /* Remove the fragment from the list as the "new" part of it
470          * has been processed or its data has been seen already in 
471          * another packet. */
472         if( prev ) {
473           prev->next = current->next;
474         } else {
475           frags[idx] = current->next;
476         }
477         g_free( current->data );
478         g_free( current );
479         return 1;
480       }
481
482       if( current->seq == seq[idx] ) {
483         /* this fragment fits the stream */
484         if( current->data ) {
485           sc->dlen = current->data_len;
486           write_packet_data( idx, sc, current->data );
487         }
488         seq[idx] += current->len;
489         if( prev ) {
490           prev->next = current->next;
491         } else {
492           frags[idx] = current->next;
493         }
494         g_free( current->data );
495         g_free( current );
496         return 1;
497       }
498       prev = current;
499       current = current->next;
500     }
501     if( GT_SEQ(acknowledged, lowest_seq) ) {
502       /* There are frames missing in the capture file that were seen
503        * by the receiving host. Add dummy stream chunk with the data
504        * "[xxx bytes missing in capture file]".
505        */
506       dummy_str = g_strdup_printf("[%d bytes missing in capture file]",
507                         (int)(lowest_seq - seq[idx]) );
508       sc->dlen = (guint32) strlen(dummy_str);
509       write_packet_data( idx, sc, dummy_str );
510       g_free(dummy_str);
511       seq[idx] = lowest_seq;
512       return 1;
513     }
514   } 
515   return 0;
516 }
517
518 /* this should always be called before we start to reassemble a stream */
519 void
520 reset_tcp_reassembly(void)
521 {
522   tcp_frag *current, *next;
523   int i;
524
525   empty_tcp_stream = TRUE;
526   incomplete_tcp_stream = FALSE;
527   find_tcp_addr = FALSE;
528   find_tcp_index = FALSE;
529   for( i=0; i<2; i++ ) {
530     seq[i] = 0;
531     memset(src_addr[i], '\0', MAX_IPADDR_LEN);
532     src_port[i] = 0;
533     memset(ip_address[i], '\0', MAX_IPADDR_LEN);
534     port[i] = 0;
535     bytes_written[i] = 0;
536     current = frags[i];
537     while( current ) {
538       next = current->next;
539       g_free( current->data );
540       g_free( current );
541       current = next;
542     }
543     frags[i] = NULL;
544   }
545 }
546
547 static void
548 write_packet_data( int idx, tcp_stream_chunk *sc, const char *data )
549 {
550   size_t ret;
551
552   ret = fwrite( sc, 1, sizeof(tcp_stream_chunk), data_out_file );
553   DISSECTOR_ASSERT(sizeof(tcp_stream_chunk) == ret);
554   
555   ret = fwrite( data, 1, sc->dlen, data_out_file );
556   DISSECTOR_ASSERT(sc->dlen == ret);
557
558   bytes_written[idx] += sc->dlen;
559   empty_tcp_stream = FALSE;
560 }