Make the "Preferences" dialog box use the new utilities to make the Esc
[obnox/wireshark/wip.git] / packet.c
1 /* packet.c
2  * Routines for packet disassembly
3  *
4  * $Id: packet.c,v 1.79 2000/05/05 09:32:07 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
32 #endif
33
34 #ifdef HAVE_SYS_SOCKET_H
35 #include <sys/socket.h>
36 #endif
37
38 #ifdef HAVE_WINSOCK_H
39 #include <winsock.h>
40 #endif
41
42 #include <glib.h>
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <stdarg.h>
47 #include <string.h>
48 #include <ctype.h>
49 #include <time.h>
50
51 #ifdef NEED_SNPRINTF_H
52 # include "snprintf.h"
53 #endif
54
55 #ifdef HAVE_NETINET_IN_H
56 # include <netinet/in.h>
57 #endif
58
59 #ifdef HAVE_ARPA_INET_H
60 #include <arpa/inet.h>
61 #endif
62
63 #ifdef NEED_INET_V6DEFS_H
64 # include "inet_v6defs.h"
65 #endif
66
67 #include "packet.h"
68 #include "print.h"
69 #include "timestamp.h"
70 #include "file.h"
71
72 #include "packet-ascend.h"
73 #include "packet-atalk.h"
74 #include "packet-atm.h"
75 #include "packet-clip.h"
76 #include "packet-eth.h"
77 #include "packet-fddi.h"
78 #include "packet-ipv6.h"
79 #include "packet-lapb.h"
80 #include "packet-lapd.h"
81 #include "packet-null.h"
82 #include "packet-ppp.h"
83 #include "packet-raw.h"
84 #include "packet-sna.h"
85 #include "packet-tr.h"
86 #include "packet-v120.h"
87 #include "packet-vines.h"
88
89 #ifndef __RESOLV_H__
90 #include "resolv.h"
91 #endif
92
93 #include "plugins.h"
94
95 extern capture_file  cf;
96
97 static int proto_frame = -1;
98 static int hf_frame_arrival_time = -1;
99 static int hf_frame_time_delta = -1;
100 static int hf_frame_number = -1;
101 static int hf_frame_packet_len = -1;
102 static int hf_frame_capture_len = -1;
103
104 static gint ett_frame = -1;
105
106 GMemChunk *frame_proto_data_area = NULL;
107
108 /* 
109  * Free up any space allocated for frame proto data areas and then 
110  * allocate a new area.
111  *
112  * We can free the area, as the structures it contains are pointed to by
113  * frames, that will be freed as well.
114  */
115 static void
116 packet_init_protocol(void)
117 {
118
119   if (frame_proto_data_area)
120     g_mem_chunk_destroy(frame_proto_data_area);
121
122   frame_proto_data_area = g_mem_chunk_new("frame_proto_data_area",
123                                           sizeof(frame_proto_data),
124                                           20 * sizeof(frame_proto_data), /* FIXME*/
125                                           G_ALLOC_ONLY);
126
127 }
128
129 /* Wrapper for the most common case of asking
130  * for a string using a colon as the hex-digit separator.
131  */
132 gchar *
133 ether_to_str(const guint8 *ad)
134 {
135         return ether_to_str_punct(ad, ':');
136 }
137
138 /* Places char punct in the string as the hex-digit separator.
139  * If punct is '\0', no punctuation is applied (and thus
140  * the resulting string is 5 bytes shorter)
141  */
142 gchar *
143 ether_to_str_punct(const guint8 *ad, char punct) {
144   static gchar  str[3][18];
145   static gchar *cur;
146   gchar        *p;
147   int          i;
148   guint32      octet;
149   static const gchar hex_digits[16] = "0123456789abcdef";
150
151   if (cur == &str[0][0]) {
152     cur = &str[1][0];
153   } else if (cur == &str[1][0]) {  
154     cur = &str[2][0];
155   } else {  
156     cur = &str[0][0];
157   }
158   p = &cur[18];
159   *--p = '\0';
160   i = 5;
161   for (;;) {
162     octet = ad[i];
163     *--p = hex_digits[octet&0xF];
164     octet >>= 4;
165     *--p = hex_digits[octet&0xF];
166     if (i == 0)
167       break;
168     if (punct)
169       *--p = punct;
170     i--;
171   }
172   return p;
173 }
174
175 gchar *
176 ip_to_str(const guint8 *ad) {
177   static gchar  str[3][16];
178   static gchar *cur;
179   gchar        *p;
180   int           i;
181   guint32       octet;
182   guint32       digit;
183
184   if (cur == &str[0][0]) {
185     cur = &str[1][0];
186   } else if (cur == &str[1][0]) {  
187     cur = &str[2][0];
188   } else {  
189     cur = &str[0][0];
190   }
191   p = &cur[16];
192   *--p = '\0';
193   i = 3;
194   for (;;) {
195     octet = ad[i];
196     *--p = (octet%10) + '0';
197     octet /= 10;
198     digit = octet%10;
199     octet /= 10;
200     if (digit != 0 || octet != 0)
201       *--p = digit + '0';
202     if (octet != 0)
203       *--p = octet + '0';
204     if (i == 0)
205       break;
206     *--p = '.';
207     i--;
208   }
209   return p;
210 }
211
212 gchar *
213 ip6_to_str(struct e_in6_addr *ad) {
214 #ifndef INET6_ADDRSTRLEN
215 #define INET6_ADDRSTRLEN 46
216 #endif
217   static gchar buf[INET6_ADDRSTRLEN];
218
219   inet_ntop(AF_INET6, (u_char*)ad, (gchar*)buf, sizeof(buf));
220   return buf;
221 }
222
223
224 #define PLURALIZE(n)    (((n) > 1) ? "s" : "")
225 #define COMMA(do_it)    ((do_it) ? ", " : "")
226
227 gchar *
228 time_secs_to_str(guint32 time)
229 {
230   static gchar  str[3][8+1+4+2+2+5+2+2+7+2+2+7+1];
231   static gchar *cur, *p;
232   int hours, mins, secs;
233   int do_comma;
234
235   if (cur == &str[0][0]) {
236     cur = &str[1][0];
237   } else if (cur == &str[1][0]) {  
238     cur = &str[2][0];
239   } else {  
240     cur = &str[0][0];
241   }
242
243   if (time == 0) {
244     sprintf(cur, "0 time");
245     return cur;
246   }
247
248   secs = time % 60;
249   time /= 60;
250   mins = time % 60;
251   time /= 60;
252   hours = time % 24;
253   time /= 24;
254
255   p = cur;
256   if (time != 0) {
257     sprintf(p, "%u day%s", time, PLURALIZE(time));
258     p += strlen(p);
259     do_comma = 1;
260   } else
261     do_comma = 0;
262   if (hours != 0) {
263     sprintf(p, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
264     p += strlen(p);
265     do_comma = 1;
266   } else
267     do_comma = 0;
268   if (mins != 0) {
269     sprintf(p, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
270     p += strlen(p);
271     do_comma = 1;
272   } else
273     do_comma = 0;
274   if (secs != 0)
275     sprintf(p, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
276   return cur;
277 }
278
279 /* Max string length for displaying byte string.  */
280 #define MAX_BYTE_STR_LEN        32
281
282 /* Turn an array of bytes into a string showing the bytes in hex. */
283 #define N_BYTES_TO_STR_STRINGS  6
284 gchar *
285 bytes_to_str(const guint8 *bd, int bd_len) {
286   static gchar  str[N_BYTES_TO_STR_STRINGS][MAX_BYTE_STR_LEN+3+1];
287   static int    cur_idx;
288   gchar        *cur;
289   gchar        *p;
290   int           len;
291   static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
292                                 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
293
294   cur_idx++;
295   if (cur_idx >= N_BYTES_TO_STR_STRINGS)
296     cur_idx = 0;
297   cur = &str[cur_idx][0];
298   p = cur;
299   len = MAX_BYTE_STR_LEN;
300   while (bd_len > 0 && len > 0) {
301     *p++ = hex[(*bd) >> 4];
302     *p++ = hex[(*bd) & 0xF];
303     len -= 2;
304     bd++;
305     bd_len--;
306   }
307   if (bd_len != 0) {
308     /* Note that we're not showing the full string.  */
309     *p++ = '.';
310     *p++ = '.';
311     *p++ = '.';
312   }
313   *p = '\0';
314   return cur;
315 }
316
317 static const char *mon_names[12] = {
318         "Jan",
319         "Feb",
320         "Mar",
321         "Apr",
322         "May",
323         "Jun",
324         "Jul",
325         "Aug",
326         "Sep",
327         "Oct",
328         "Nov",
329         "Dec"
330 };
331
332 gchar *
333 abs_time_to_str(struct timeval *abs_time)
334 {
335         struct tm *tmp;
336         static gchar *cur;
337         static char str[3][3+1+2+2+4+1+2+1+2+1+2+1+4+1 + 5 /* extra */];
338
339         if (cur == &str[0][0]) {
340                 cur = &str[1][0];
341         } else if (cur == &str[1][0]) {
342                 cur = &str[2][0];
343         } else {
344                 cur = &str[0][0];
345         }
346
347         tmp = localtime(&abs_time->tv_sec);
348         sprintf(cur, "%s %2d, %d %02d:%02d:%02d.%04ld",
349             mon_names[tmp->tm_mon],
350             tmp->tm_mday,
351             tmp->tm_year + 1900,
352             tmp->tm_hour,
353             tmp->tm_min,
354             tmp->tm_sec,
355             (long)abs_time->tv_usec/100);
356
357         return cur;
358 }
359
360 gchar *
361 rel_time_to_str(struct timeval *rel_time)
362 {
363         static gchar *cur;
364         static char str[3][10+1+6+1];
365
366         if (cur == &str[0][0]) {
367                 cur = &str[1][0];
368         } else if (cur == &str[1][0]) {
369                 cur = &str[2][0];
370         } else {
371                 cur = &str[0][0];
372         }
373
374         sprintf(cur, "%ld.%06ld", (long)rel_time->tv_sec,
375                 (long)rel_time->tv_usec);
376
377         return cur;
378 }
379
380 /*
381  * Given a pointer into a data buffer, and to the end of the buffer,
382  * find the end of the (putative) line at that position in the data
383  * buffer.
384  * Return a pointer to the EOL character(s) in "*eol".
385  */
386 const u_char *
387 find_line_end(const u_char *data, const u_char *dataend, const u_char **eol)
388 {
389   const u_char *lineend;
390
391   lineend = memchr(data, '\n', dataend - data);
392   if (lineend == NULL) {
393     /*
394      * No LF - line is probably continued in next TCP segment.
395      */
396     lineend = dataend;
397     *eol = dataend;
398   } else {
399     /*
400      * Is the LF at the beginning of the line?
401      */
402     if (lineend > data) {
403       /*
404        * No - is it preceded by a carriage return?
405        * (Perhaps it's supposed to be, but that's not guaranteed....)
406        */
407       if (*(lineend - 1) == '\r') {
408         /*
409          * Yes.  The EOL starts with the CR.
410          */
411         *eol = lineend - 1;
412       } else {
413         /*
414          * No.  The EOL starts with the LF.
415          */
416         *eol = lineend;
417
418         /*
419          * I seem to remember that we once saw lines ending with LF-CR
420          * in an HTTP request or response, so check if it's *followed*
421          * by a carriage return.
422          */
423         if (lineend < (dataend - 1) && *(lineend + 1) == '\r') {
424           /*
425            * It's <non-LF><LF><CR>; say it ends with the CR.
426            */
427           lineend++;
428         }
429       }
430     }
431
432     /*
433      * Point to the character after the last character.
434      */
435     lineend++;
436   }
437   return lineend;
438 }
439
440 #define MAX_COLUMNS_LINE_DETAIL 62
441
442 /*
443  * Get the length of the next token in a line, and the beginning of the
444  * next token after that (if any).
445  * Return 0 if there is no next token.
446  */
447 int
448 get_token_len(const u_char *linep, const u_char *lineend,
449               const u_char **next_token)
450 {
451   const u_char *tokenp;
452   int token_len;
453
454   tokenp = linep;
455   
456   /*
457    * Search for a blank, a CR or an LF, or the end of the buffer.
458    */
459   while (linep < lineend && *linep != ' ' && *linep != '\r' && *linep != '\n')
460       linep++;
461   token_len = linep - tokenp;
462
463   /*
464    * Skip trailing blanks.
465    */
466   while (linep < lineend && *linep == ' ')
467     linep++;
468
469   *next_token = linep;
470
471   return token_len;
472 }
473
474 /*
475  * Given a string, generate a string from it that shows non-printable
476  * characters as C-style escapes, and return a pointer to it.
477  */
478 gchar *
479 format_text(const u_char *string, int len)
480 {
481   static gchar fmtbuf[MAX_COLUMNS_LINE_DETAIL + 3 + 4 + 1];
482   gchar *fmtbufp;
483   int column;
484   const u_char *stringend = string + len;
485   u_char c;
486   int i;
487
488   column = 0;
489   fmtbufp = &fmtbuf[0];
490   while (string < stringend) {
491     if (column >= MAX_COLUMNS_LINE_DETAIL) {
492       /*
493        * Put "..." and quit.
494        */
495       strcpy(fmtbufp, " ...");
496       fmtbufp += 4;
497       break;
498     }
499     c = *string++;
500     if (isprint(c)) {
501       *fmtbufp++ = c;
502       column++;
503     } else {
504       *fmtbufp++ =  '\\';
505       column++;
506       switch (c) {
507
508       case '\\':
509         *fmtbufp++ = '\\';
510         column++;
511         break;
512
513       case '\a':
514         *fmtbufp++ = 'a';
515         column++;
516         break;
517
518       case '\b':
519         *fmtbufp++ = 'b';
520         column++;
521         break;
522
523       case '\f':
524         *fmtbufp++ = 'f';
525         column++;
526         break;
527
528       case '\n':
529         *fmtbufp++ = 'n';
530         column++;
531         break;
532
533       case '\r':
534         *fmtbufp++ = 'r';
535         column++;
536         break;
537
538       case '\t':
539         *fmtbufp++ = 't';
540         column++;
541         break;
542
543       case '\v':
544         *fmtbufp++ = 'v';
545         column++;
546         break;
547
548       default:
549         i = (c>>6)&03;
550         *fmtbufp++ = i + '0';
551         column++;
552         i = (c>>3)&07;
553         *fmtbufp++ = i + '0';
554         column++;
555         i = (c>>0)&07;
556         *fmtbufp++ = i + '0';
557         column++;
558         break;
559       }
560     }
561   }
562   *fmtbufp = '\0';
563   return fmtbuf;
564 }
565
566
567 /* Tries to match val against each element in the value_string array vs.
568    Returns the associated string ptr on a match.
569    Formats val with fmt, and returns the resulting string, on failure. */
570 gchar*
571 val_to_str(guint32 val, const value_string *vs, const char *fmt) {
572   gchar *ret;
573   static gchar  str[3][64];
574   static gchar *cur;
575
576   ret = match_strval(val, vs);
577   if (ret != NULL)
578     return ret;
579   if (cur == &str[0][0]) {
580     cur = &str[1][0];
581   } else if (cur == &str[1][0]) {  
582     cur = &str[2][0];
583   } else {  
584     cur = &str[0][0];
585   }
586   snprintf(cur, 64, fmt, val);
587   return cur;
588 }
589
590 /* Tries to match val against each element in the value_string array vs.
591    Returns the associated string ptr on a match, or NULL on failure. */
592 gchar*
593 match_strval(guint32 val, const value_string *vs) {
594   gint i = 0;
595   
596   while (vs[i].strptr) {
597     if (vs[i].value == val)
598       return(vs[i].strptr);
599     i++;
600   }
601
602   return(NULL);
603 }
604
605 /* Generate, into "buf", a string showing the bits of a bitfield.
606    Return a pointer to the character after that string. */
607 char *
608 decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width)
609 {
610   int i;
611   guint32 bit;
612   char *p;
613
614   i = 0;
615   p = buf;
616   bit = 1 << (width - 1);
617   for (;;) {
618     if (mask & bit) {
619       /* This bit is part of the field.  Show its value. */
620       if (val & bit)
621         *p++ = '1';
622       else
623         *p++ = '0';
624     } else {
625       /* This bit is not part of the field. */
626       *p++ = '.';
627     }
628     bit >>= 1;
629     i++;
630     if (i >= width)
631       break;
632     if (i % 4 == 0)
633       *p++ = ' ';
634   }
635   strcpy(p, " = ");
636   p += 3;
637   return p;
638 }
639
640 /* Generate a string describing a Boolean bitfield (a one-bit field that
641    says something is either true of false). */
642 const char *
643 decode_boolean_bitfield(guint32 val, guint32 mask, int width,
644     const char *truedesc, const char *falsedesc)
645 {
646   static char buf[1025];
647   char *p;
648
649   p = decode_bitfield_value(buf, val, mask, width);
650   if (val & mask)
651     strcpy(p, truedesc);
652   else
653     strcpy(p, falsedesc);
654   return buf;
655 }
656
657 /* Generate a string describing an enumerated bitfield (an N-bit field
658    with various specific values having particular names). */
659 const char *
660 decode_enumerated_bitfield(guint32 val, guint32 mask, int width,
661     const value_string *tab, const char *fmt)
662 {
663   static char buf[1025];
664   char *p;
665
666   p = decode_bitfield_value(buf, val, mask, width);
667   sprintf(p, fmt, val_to_str(val & mask, tab, "Unknown"));
668   return buf;
669 }
670
671 /* Generate a string describing a numeric bitfield (an N-bit field whose
672    value is just a number). */
673 const char *
674 decode_numeric_bitfield(guint32 val, guint32 mask, int width,
675     const char *fmt)
676 {
677   static char buf[1025];
678   char *p;
679   int shift = 0;
680
681   /* Compute the number of bits we have to shift the bitfield right
682      to extract its value. */
683   while ((mask & (1<<shift)) == 0)
684     shift++;
685
686   p = decode_bitfield_value(buf, val, mask, width);
687   sprintf(p, fmt, (val & mask) >> shift);
688   return buf;
689 }
690
691 /* Checks to see if a particular packet information element is needed for
692    the packet list */
693 gint
694 check_col(frame_data *fd, gint el) {
695   int i;
696
697   if (fd->cinfo) {
698     for (i = 0; i < fd->cinfo->num_cols; i++) {
699       if (fd->cinfo->fmt_matx[i][el])
700         return TRUE;
701     }
702   }
703   return FALSE;
704 }
705
706 /* Adds a vararg list to a packet info string. */
707 void
708 col_add_fstr(frame_data *fd, gint el, gchar *format, ...) {
709   va_list ap;
710   int     i;
711   size_t  max_len;
712   
713   va_start(ap, format);
714   for (i = 0; i < fd->cinfo->num_cols; i++) {
715     if (fd->cinfo->fmt_matx[i][el]) {
716       if (el == COL_INFO)
717         max_len = COL_MAX_INFO_LEN;
718       else
719         max_len = COL_MAX_LEN;
720       vsnprintf(fd->cinfo->col_data[i], max_len, format, ap);
721     }
722   }
723 }
724
725 void
726 col_add_str(frame_data *fd, gint el, const gchar* str) {
727   int    i;
728   size_t max_len;
729
730   for (i = 0; i < fd->cinfo->num_cols; i++) {
731     if (fd->cinfo->fmt_matx[i][el]) {
732       if (el == COL_INFO)
733         max_len = COL_MAX_INFO_LEN;
734       else
735         max_len = COL_MAX_LEN;
736       strncpy(fd->cinfo->col_data[i], str, max_len);
737       fd->cinfo->col_data[i][max_len - 1] = 0;
738     }
739   }
740 }
741
742 /* Appends a vararg list to a packet info string. */
743 void
744 col_append_fstr(frame_data *fd, gint el, gchar *format, ...) {
745   va_list ap;
746   int     i;
747   size_t  len, max_len;
748   
749   va_start(ap, format);
750   for (i = 0; i < fd->cinfo->num_cols; i++) {
751     if (fd->cinfo->fmt_matx[i][el]) {
752       len = strlen(fd->cinfo->col_data[i]);
753       if (el == COL_INFO)
754         max_len = COL_MAX_INFO_LEN;
755       else
756         max_len = COL_MAX_LEN;
757       vsnprintf(&fd->cinfo->col_data[i][len], max_len - len, format, ap);
758     }
759   }
760 }
761
762 void
763 col_append_str(frame_data *fd, gint el, gchar* str) {
764   int    i;
765   size_t len, max_len;
766
767   for (i = 0; i < fd->cinfo->num_cols; i++) {
768     if (fd->cinfo->fmt_matx[i][el]) {
769       len = strlen(fd->cinfo->col_data[i]);
770       if (el == COL_INFO)
771         max_len = COL_MAX_LEN;
772       else
773         max_len = COL_MAX_INFO_LEN;
774       strncat(fd->cinfo->col_data[i], str, max_len - len);
775       fd->cinfo->col_data[i][max_len - 1] = 0;
776     }
777   }
778 }
779
780 /* To do: Add check_col checks to the col_add* routines */
781
782 static void
783 col_set_abs_time(frame_data *fd, int col)
784 {
785   struct tm *tmp;
786   time_t then;
787
788   then = fd->abs_secs;
789   tmp = localtime(&then);
790   snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%02d:%02d:%02d.%04ld",
791     tmp->tm_hour,
792     tmp->tm_min,
793     tmp->tm_sec,
794     (long)fd->abs_usecs/100);
795 }
796
797 static void
798 col_set_rel_time(frame_data *fd, int col)
799 {
800   snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%d.%06d", fd->rel_secs,
801     fd->rel_usecs);
802 }
803
804 static void
805 col_set_delta_time(frame_data *fd, int col)
806 {
807   snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%d.%06d", fd->del_secs,
808     fd->del_usecs);
809 }
810
811 /* Add "command-line-specified" time.
812    XXX - this is called from "file.c" when the user changes the time
813    format they want for "command-line-specified" time; it's a bit ugly
814    that we have to export it, but if we go to a CList-like widget that
815    invokes callbacks to get the text for the columns rather than
816    requiring us to stuff the text into the widget from outside, we
817    might be able to clean this up. */
818 void
819 col_set_cls_time(frame_data *fd, int col)
820 {
821   switch (timestamp_type) {
822     case ABSOLUTE:
823       col_set_abs_time(fd, col);
824       break;
825
826     case RELATIVE:
827       col_set_rel_time(fd, col);
828       break;
829
830     case DELTA:
831       col_set_delta_time(fd, col);
832       break;
833   }
834 }
835
836 static void
837 col_set_addr(frame_data *fd, int col, address *addr, gboolean is_res)
838 {
839   u_int ipv4_addr;
840   struct e_in6_addr ipv6_addr;
841   struct atalk_ddp_addr ddp_addr;
842   struct sna_fid_type_4_addr sna_fid_type_4_addr;
843
844   switch (addr->type) {
845
846   case AT_ETHER:
847     if (is_res)
848       strncpy(fd->cinfo->col_data[col], get_ether_name(addr->data), COL_MAX_LEN);
849     else
850       strncpy(fd->cinfo->col_data[col], ether_to_str(addr->data), COL_MAX_LEN);
851     break;
852
853   case AT_IPv4:
854     memcpy(&ipv4_addr, addr->data, sizeof ipv4_addr);
855     if (is_res)
856       strncpy(fd->cinfo->col_data[col], get_hostname(ipv4_addr), COL_MAX_LEN);
857     else
858       strncpy(fd->cinfo->col_data[col], ip_to_str(addr->data), COL_MAX_LEN);
859     break;
860
861   case AT_IPv6:
862     memcpy(&ipv6_addr.s6_addr, addr->data, sizeof ipv6_addr.s6_addr);
863     if (is_res)
864       strncpy(fd->cinfo->col_data[col], get_hostname6(&ipv6_addr), COL_MAX_LEN);
865     else
866       strncpy(fd->cinfo->col_data[col], ip6_to_str(&ipv6_addr), COL_MAX_LEN);
867     break;
868
869   case AT_IPX:
870     strncpy(fd->cinfo->col_data[col],
871       ipx_addr_to_str(pntohl(&addr->data[0]), &addr->data[4]), COL_MAX_LEN);
872     break;
873
874   case AT_SNA:
875     switch (addr->len) {
876
877     case 1:
878       snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%04X", addr->data[0]);
879       break;
880
881     case 2:
882       snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%04X",
883         pntohs(&addr->data[0]));
884       break;
885
886     case SNA_FID_TYPE_4_ADDR_LEN:
887       memcpy(&sna_fid_type_4_addr, addr->data, SNA_FID_TYPE_4_ADDR_LEN);
888       strncpy(fd->cinfo->col_data[col],
889         sna_fid_type_4_addr_to_str(&sna_fid_type_4_addr), COL_MAX_LEN);
890       break;
891     }
892     break;
893
894   case AT_ATALK:
895     memcpy(&ddp_addr, addr->data, sizeof ddp_addr);
896     strncpy(fd->cinfo->col_data[col], atalk_addr_to_str(&ddp_addr),
897       COL_MAX_LEN);
898     break;
899
900   case AT_VINES:
901     strncpy(fd->cinfo->col_data[col], vines_addr_to_str(&addr->data[0]),
902       COL_MAX_LEN);
903     break;
904
905   default:
906     break;
907   }
908   fd->cinfo->col_data[col][COL_MAX_LEN - 1] = '\0';
909 }
910
911 static void
912 col_set_port(frame_data *fd, int col, port_type ptype, guint32 port,
913                 gboolean is_res)
914 {
915   switch (ptype) {
916
917   case PT_TCP:
918     if (is_res)
919       strncpy(fd->cinfo->col_data[col], get_tcp_port(port), COL_MAX_LEN);
920     else
921       snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%u", port);
922     break;
923
924   case PT_UDP:
925     if (is_res)
926       strncpy(fd->cinfo->col_data[col], get_udp_port(port), COL_MAX_LEN);
927     else
928       snprintf(fd->cinfo->col_data[col], COL_MAX_LEN, "%u", port);
929     break;
930
931   default:
932     break;
933   }
934   fd->cinfo->col_data[col][COL_MAX_LEN - 1] = '\0';
935 }
936
937 void
938 fill_in_columns(frame_data *fd)
939 {
940   int i;
941
942   for (i = 0; i < fd->cinfo->num_cols; i++) {
943     switch (fd->cinfo->col_fmt[i]) {
944
945     case COL_NUMBER:
946       snprintf(fd->cinfo->col_data[i], COL_MAX_LEN, "%u", fd->num);
947       break;
948
949     case COL_CLS_TIME:
950       col_set_cls_time(fd, i);
951       break;
952
953     case COL_ABS_TIME:
954       col_set_abs_time(fd, i);
955       break;
956
957     case COL_REL_TIME:
958       col_set_rel_time(fd, i);
959       break;
960
961     case COL_DELTA_TIME:
962       col_set_delta_time(fd, i);
963       break;
964
965     case COL_DEF_SRC:
966     case COL_RES_SRC:   /* COL_DEF_SRC is currently just like COL_RES_SRC */
967       col_set_addr(fd, i, &pi.src, TRUE);
968       break;
969
970     case COL_UNRES_SRC:
971       col_set_addr(fd, i, &pi.src, FALSE);
972       break;
973
974     case COL_DEF_DL_SRC:
975     case COL_RES_DL_SRC:
976       col_set_addr(fd, i, &pi.dl_src, TRUE);
977       break;
978
979     case COL_UNRES_DL_SRC:
980       col_set_addr(fd, i, &pi.dl_src, FALSE);
981       break;
982
983     case COL_DEF_NET_SRC:
984     case COL_RES_NET_SRC:
985       col_set_addr(fd, i, &pi.net_src, TRUE);
986       break;
987
988     case COL_UNRES_NET_SRC:
989       col_set_addr(fd, i, &pi.net_src, FALSE);
990       break;
991
992     case COL_DEF_DST:
993     case COL_RES_DST:   /* COL_DEF_DST is currently just like COL_RES_DST */
994       col_set_addr(fd, i, &pi.dst, TRUE);
995       break;
996
997     case COL_UNRES_DST:
998       col_set_addr(fd, i, &pi.dst, FALSE);
999       break;
1000
1001     case COL_DEF_DL_DST:
1002     case COL_RES_DL_DST:
1003       col_set_addr(fd, i, &pi.dl_dst, TRUE);
1004       break;
1005
1006     case COL_UNRES_DL_DST:
1007       col_set_addr(fd, i, &pi.dl_dst, FALSE);
1008       break;
1009
1010     case COL_DEF_NET_DST:
1011     case COL_RES_NET_DST:
1012       col_set_addr(fd, i, &pi.net_dst, TRUE);
1013       break;
1014
1015     case COL_UNRES_NET_DST:
1016       col_set_addr(fd, i, &pi.net_dst, FALSE);
1017       break;
1018
1019     case COL_DEF_SRC_PORT:
1020     case COL_RES_SRC_PORT:      /* COL_DEF_SRC_PORT is currently just like COL_RES_SRC_PORT */
1021       col_set_port(fd, i, pi.ptype, pi.srcport, TRUE);
1022       break;
1023
1024     case COL_UNRES_SRC_PORT:
1025       col_set_port(fd, i, pi.ptype, pi.srcport, FALSE);
1026       break;
1027
1028     case COL_DEF_DST_PORT:
1029     case COL_RES_DST_PORT:      /* COL_DEF_DST_PORT is currently just like COL_RES_DST_PORT */
1030       col_set_port(fd, i, pi.ptype, pi.destport, TRUE);
1031       break;
1032
1033     case COL_UNRES_DST_PORT:
1034       col_set_port(fd, i, pi.ptype, pi.destport, FALSE);
1035       break;
1036
1037     case COL_PROTOCOL:  /* currently done by dissectors */
1038     case COL_INFO:      /* currently done by dissectors */
1039       break;
1040
1041     case COL_PACKET_LENGTH:
1042       snprintf(fd->cinfo->col_data[i], COL_MAX_LEN, "%d", fd->pkt_len);
1043       break;
1044
1045     case NUM_COL_FMTS:  /* keep compiler happy - shouldn't get here */
1046       break;
1047     }
1048   }
1049 }
1050         
1051 void blank_packetinfo(void)
1052 {
1053   pi.dl_src.type = AT_NONE;
1054   pi.dl_dst.type = AT_NONE;
1055   pi.net_src.type = AT_NONE;
1056   pi.net_dst.type = AT_NONE;
1057   pi.src.type = AT_NONE;
1058   pi.dst.type = AT_NONE;
1059   pi.ipproto  = 0;
1060   pi.ptype = PT_NONE;
1061   pi.srcport  = 0;
1062   pi.destport = 0;
1063 }
1064
1065 /* Do all one-time initialization. */
1066 void
1067 dissect_init(void)
1068 {
1069         proto_init();
1070         dfilter_init();
1071 #ifdef HAVE_PLUGINS
1072         init_plugins();
1073 #endif
1074 }
1075
1076 void
1077 dissect_cleanup(void)
1078 {
1079         proto_cleanup();
1080         dfilter_cleanup();
1081 }
1082
1083 /* Allow protocols to register "init" routines, which are called before
1084    we make a pass through a capture file and dissect all its packets
1085    (e.g., when we read in a new capture file, or run a "filter packets"
1086    or "colorize packets" pass over the current capture file). */
1087 static GSList *init_routines;
1088
1089 void
1090 register_init_routine(void (*func)(void))
1091 {
1092         init_routines = g_slist_append(init_routines, func);
1093 }
1094
1095 /* Call all the registered "init" routines. */
1096 static void
1097 call_init_routine(gpointer routine, gpointer dummy)
1098 {
1099         void (*func)(void) = routine;
1100
1101         (*func)();
1102 }
1103
1104 void
1105 init_all_protocols(void)
1106 {
1107         g_slist_foreach(init_routines, &call_init_routine, NULL);
1108 }
1109
1110 /* this routine checks the frame type from the cf structure */
1111 void
1112 dissect_packet(const u_char *pd, frame_data *fd, proto_tree *tree)
1113 {
1114         proto_tree *fh_tree;
1115         proto_item *ti;
1116         struct timeval tv;
1117
1118         /* Put in frame header information. */
1119         if (tree) {
1120           ti = proto_tree_add_protocol_format(tree, proto_frame, 0, fd->cap_len,
1121             "Frame %u (%u on wire, %u captured)", fd->num,
1122             fd->pkt_len, fd->cap_len);
1123
1124           fh_tree = proto_item_add_subtree(ti, ett_frame);
1125
1126           tv.tv_sec = fd->abs_secs;
1127           tv.tv_usec = fd->abs_usecs;
1128
1129           proto_tree_add_item(fh_tree, hf_frame_arrival_time,
1130                 0, 0, &tv);
1131
1132           tv.tv_sec = fd->del_secs;
1133           tv.tv_usec = fd->del_usecs;
1134
1135           proto_tree_add_item(fh_tree, hf_frame_time_delta,
1136                 0, 0, &tv);
1137
1138           proto_tree_add_item(fh_tree, hf_frame_number,
1139                 0, 0, fd->num);
1140
1141           proto_tree_add_uint_format(fh_tree, hf_frame_packet_len,
1142                 0, 0, fd->pkt_len, "Packet Length: %d byte%s", fd->pkt_len,
1143                 plurality(fd->pkt_len, "", "s"));
1144                 
1145           proto_tree_add_uint_format(fh_tree, hf_frame_capture_len,
1146                 0, 0, fd->cap_len, "Capture Length: %d byte%s", fd->cap_len,
1147                 plurality(fd->cap_len, "", "s"));
1148         }
1149
1150         blank_packetinfo();
1151
1152         /* Set the initial payload to the packet length, and the initial
1153            captured payload to the capture length (other protocols may
1154            reduce them if their headers say they're less). */
1155         pi.len = fd->pkt_len;
1156         pi.captured_len = fd->cap_len;
1157
1158         switch (fd->lnk_t) {
1159                 case WTAP_ENCAP_ETHERNET :
1160                         dissect_eth(pd, 0, fd, tree);
1161                         break;
1162                 case WTAP_ENCAP_FDDI :
1163                         dissect_fddi(pd, fd, tree, FALSE);
1164                         break;
1165                 case WTAP_ENCAP_FDDI_BITSWAPPED :
1166                         dissect_fddi(pd, fd, tree, TRUE);
1167                         break;
1168                 case WTAP_ENCAP_TR :
1169                         dissect_tr(pd, 0, fd, tree);
1170                         break;
1171                 case WTAP_ENCAP_NULL :
1172                         dissect_null(pd, fd, tree);
1173                         break;
1174                 case WTAP_ENCAP_PPP :
1175                         dissect_ppp(pd, 0, fd, tree);
1176                         break;
1177                 case WTAP_ENCAP_LAPB :
1178                         dissect_lapb(pd, fd, tree);
1179                         break;
1180                 case WTAP_ENCAP_RAW_IP :
1181                         dissect_raw(pd, fd, tree);
1182                         break;
1183                 case WTAP_ENCAP_LINUX_ATM_CLIP :
1184                         dissect_clip(pd, fd, tree);
1185                         break;
1186                 case WTAP_ENCAP_ATM_SNIFFER :
1187                         dissect_atm(pd, fd, tree);
1188                         break;
1189                 case WTAP_ENCAP_ASCEND :
1190                         dissect_ascend(pd, fd, tree);
1191                         break;
1192                 case WTAP_ENCAP_LAPD :
1193                         dissect_lapd(pd, fd, tree);
1194                         break;
1195                 case WTAP_ENCAP_V120 :
1196                         dissect_v120(pd, fd, tree);
1197                         break;
1198         }
1199
1200         fd->flags.visited = 1;
1201 }
1202
1203 gint p_compare(gconstpointer a, gconstpointer b)
1204 {
1205
1206   if (((frame_proto_data *)a) -> proto > ((frame_proto_data *)b) -> proto)
1207     return 1;
1208   else if (((frame_proto_data *)a) -> proto == ((frame_proto_data *)b) -> proto)
1209     return 0;
1210   else
1211     return -1;
1212
1213 }
1214
1215 void
1216 p_add_proto_data(frame_data *fd, int proto, void *proto_data)
1217 {
1218   frame_proto_data *p1 = g_mem_chunk_alloc(frame_proto_data_area);
1219  
1220   g_assert(p1 != NULL);
1221
1222   p1 -> proto = proto;
1223   p1 -> proto_data = proto_data;
1224
1225   /* Add it to the GSLIST */
1226
1227   fd -> pfd = g_slist_insert_sorted(fd -> pfd,
1228                                     (gpointer *)p1,
1229                                     p_compare);
1230
1231 }
1232
1233 void *
1234 p_get_proto_data(frame_data *fd, int proto)
1235 {
1236   frame_proto_data temp;
1237   GSList *item;
1238
1239   temp.proto = proto;
1240   temp.proto_data = NULL;
1241
1242   item = g_slist_find_custom(fd->pfd, (gpointer *)&temp, p_compare);
1243
1244   if (item) return (void *)item->data;
1245
1246   return NULL;
1247
1248 }
1249
1250 void
1251 p_rem_proto_data(frame_data *fd, int proto)
1252 {
1253
1254
1255 }
1256
1257 void
1258 proto_register_frame(void)
1259 {
1260         static hf_register_info hf[] = {
1261                 { &hf_frame_arrival_time,
1262                 { "Arrival Time",               "frame.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
1263                         ""}},
1264
1265                 { &hf_frame_time_delta,
1266                 { "Time delta from previous packet",    "frame.time_delta", FT_RELATIVE_TIME, BASE_NONE, NULL,
1267                         0x0,
1268                         "" }},
1269
1270                 { &hf_frame_number,
1271                 { "Frame Number",               "frame.number", FT_UINT32, BASE_DEC, NULL, 0x0,
1272                         "" }},
1273
1274                 { &hf_frame_packet_len,
1275                 { "Total Frame Length",         "frame.pkt_len", FT_UINT32, BASE_DEC, NULL, 0x0,
1276                         "" }},
1277
1278                 { &hf_frame_capture_len,
1279                 { "Capture Frame Length",       "frame.cap_len", FT_UINT32, BASE_DEC, NULL, 0x0,
1280                         "" }},
1281         };
1282         static gint *ett[] = {
1283                 &ett_frame,
1284         };
1285
1286         proto_frame = proto_register_protocol("Frame", "frame");
1287         proto_register_field_array(proto_frame, hf, array_length(hf));
1288         proto_register_subtree_array(ett, array_length(ett));
1289
1290         register_init_routine(&packet_init_protocol);
1291
1292 }
1293
1294 /*********************** code added for sub-dissector lookup *********************/
1295
1296 static GHashTable *dissector_tables = NULL;
1297
1298 /* Finds a dissector table by field name. */
1299 static dissector_table_t
1300 find_dissector_table(const char *name)
1301 {
1302         g_assert(dissector_tables);
1303         return g_hash_table_lookup( dissector_tables, name );
1304 }
1305
1306 /* lookup a dissector based upon pattern. */
1307 dissector_t
1308 dissector_lookup( dissector_table_t table, guint32 pattern)
1309 {
1310         return g_hash_table_lookup( table, GUINT_TO_POINTER( pattern));
1311 }
1312
1313
1314 /* add an entry, lookup the dissector table for the specified field name,  */
1315 /* if a valid table found, add the subdissector */
1316 void
1317 dissector_add(const char *name, guint32 pattern, dissector_t dissector)
1318 {
1319         dissector_table_t sub_dissectors = find_dissector_table( name);
1320
1321 /* sanity check */
1322         g_assert( sub_dissectors);
1323
1324 /* do the table insertion */
1325         g_hash_table_insert( sub_dissectors, GUINT_TO_POINTER( pattern),
1326          (gpointer)dissector);
1327 }
1328
1329 /* delete the entry for this dissector at this pattern */
1330
1331 /* NOTE: this doesn't use the dissector call variable. It is included to */
1332 /*      be consistant with the dissector_add and more importantly to be used */
1333 /*      if the technique of adding a temporary dissector is implemented.  */
1334 /*      If temporary dissectors are deleted, then the original dissector must */
1335 /*      be available. */
1336 void
1337 dissector_delete(const char *name, guint32 pattern, dissector_t dissector)
1338 {
1339         dissector_table_t sub_dissectors = find_dissector_table( name);
1340
1341 /* sanity check */
1342         g_assert( sub_dissectors);
1343
1344 /* remove the hash table entry */
1345         g_hash_table_remove( sub_dissectors, GUINT_TO_POINTER( pattern));
1346 }
1347
1348 /* Look for a given port in a given dissector table and, if found, call
1349    the dissector with the arguments supplied, and return TRUE, otherwise
1350    return FALSE. */
1351 gboolean
1352 dissector_try_port(dissector_table_t sub_dissectors, guint32 port,
1353     const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1354 {
1355         dissector_t subdissector;
1356
1357         subdissector = dissector_lookup(sub_dissectors, port);
1358         if (subdissector != NULL) {
1359                 pi.match_port = port;
1360                 (subdissector)(pd, offset, fd, tree);
1361                 return TRUE;
1362         } else
1363                 return FALSE;
1364 }
1365
1366 dissector_table_t
1367 register_dissector_table(const char *name)
1368 {
1369         dissector_table_t       sub_dissectors;
1370
1371         /* Create our hash-of-hashes if it doesn't already exist */
1372         if (!dissector_tables) {
1373                 dissector_tables = g_hash_table_new( g_str_hash, g_str_equal );
1374                 g_assert(dissector_tables);
1375         }
1376
1377         /* Make sure the registration is unique */
1378         g_assert(!g_hash_table_lookup( dissector_tables, name ));
1379
1380         /* Create and register the dissector table for this name; returns */
1381         /* a pointer to the dissector table. */
1382         sub_dissectors = g_hash_table_new( g_direct_hash, g_direct_equal );
1383         g_hash_table_insert( dissector_tables, (gpointer)name, (gpointer) sub_dissectors );
1384         return sub_dissectors;
1385 }
1386
1387 static GHashTable *heur_dissector_lists = NULL;
1388
1389 /* Finds a heuristic dissector table by field name. */
1390 static heur_dissector_list_t *
1391 find_heur_dissector_list(const char *name)
1392 {
1393         g_assert(heur_dissector_lists != NULL);
1394         return g_hash_table_lookup(heur_dissector_lists, name);
1395 }
1396
1397 void
1398 heur_dissector_add(const char *name, heur_dissector_t dissector)
1399 {
1400         heur_dissector_list_t *sub_dissectors = find_heur_dissector_list(name);
1401
1402         /* sanity check */
1403         g_assert(sub_dissectors != NULL);
1404
1405         /* do the table insertion */
1406         *sub_dissectors = g_slist_append(*sub_dissectors, (gpointer)dissector);
1407 }
1408
1409 gboolean
1410 dissector_try_heuristic(heur_dissector_list_t sub_dissectors,
1411     const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
1412 {
1413         heur_dissector_t subdissector;
1414         GSList *entry;
1415
1416         for (entry = sub_dissectors; entry != NULL; entry = g_slist_next(entry)) {
1417                 subdissector = (heur_dissector_t)entry->data;
1418                 if ((subdissector)(pd, offset, fd, tree))
1419                         return TRUE;
1420         }
1421         return FALSE;
1422 }
1423
1424 void
1425 register_heur_dissector_list(const char *name, heur_dissector_list_t *sub_dissectors)
1426 {
1427         /* Create our hash-of-hashes if it doesn't already exist */
1428         if (heur_dissector_lists == NULL) {
1429                 heur_dissector_lists = g_hash_table_new(g_str_hash, g_str_equal);
1430                 g_assert(heur_dissector_lists != NULL);
1431         }
1432
1433         /* Make sure the registration is unique */
1434         g_assert(g_hash_table_lookup(heur_dissector_lists, name) == NULL);
1435
1436         *sub_dissectors = NULL; /* initially empty */
1437         g_hash_table_insert(heur_dissector_lists, (gpointer)name,
1438             (gpointer) sub_dissectors);
1439 }