Add a new Wiretap encapsulation type WTAP_ENCAP_FDDI_BITSWAPPED, meaning
[obnox/wireshark/wip.git] / packet.c
1 /* packet.c
2  * Routines for packet disassembly
3  *
4  * $Id: packet.c,v 1.40 1999/08/24 03:19:23 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 <stdarg.h>
46 #include <string.h>
47 #include <ctype.h>
48 #include <time.h>
49
50 #ifdef NEED_SNPRINTF_H
51 # include "snprintf.h"
52 #endif
53
54 #ifdef HAVE_NETINET_IN_H
55 # include <netinet/in.h>
56 #endif
57
58 #include "packet.h"
59 #include "file.h"
60
61 extern capture_file  cf;
62
63 int proto_frame = -1;
64 int hf_frame_arrival_time = -1;
65 int hf_frame_packet_len = -1;
66 int hf_frame_capture_len = -1;
67
68 gchar *
69 ether_to_str(const guint8 *ad) {
70   static gchar  str[3][18];
71   static gchar *cur;
72   gchar        *p;
73   int          i;
74   guint32      octet;
75   static const gchar hex_digits[16] = "0123456789abcdef";
76
77   if (cur == &str[0][0]) {
78     cur = &str[1][0];
79   } else if (cur == &str[1][0]) {  
80     cur = &str[2][0];
81   } else {  
82     cur = &str[0][0];
83   }
84   p = &cur[18];
85   *--p = '\0';
86   i = 5;
87   for (;;) {
88     octet = ad[i];
89     *--p = hex_digits[octet&0xF];
90     octet >>= 4;
91     *--p = hex_digits[octet&0xF];
92     if (i == 0)
93       break;
94     *--p = ':';
95     i--;
96   }
97   return p;
98 }
99
100 gchar *
101 ip_to_str(const guint8 *ad) {
102   static gchar  str[3][16];
103   static gchar *cur;
104   gchar        *p;
105   int           i;
106   guint32       octet;
107   guint32       digit;
108
109   if (cur == &str[0][0]) {
110     cur = &str[1][0];
111   } else if (cur == &str[1][0]) {  
112     cur = &str[2][0];
113   } else {  
114     cur = &str[0][0];
115   }
116   p = &cur[16];
117   *--p = '\0';
118   i = 3;
119   for (;;) {
120     octet = ad[i];
121     *--p = (octet%10) + '0';
122     octet /= 10;
123     digit = octet%10;
124     octet /= 10;
125     if (digit != 0 || octet != 0)
126       *--p = digit + '0';
127     if (octet != 0)
128       *--p = octet + '0';
129     if (i == 0)
130       break;
131     *--p = '.';
132     i--;
133   }
134   return p;
135 }
136
137 #define PLURALIZE(n)    (((n) > 1) ? "s" : "")
138 #define COMMA(do_it)    ((do_it) ? ", " : "")
139
140 gchar *
141 time_secs_to_str(guint32 time)
142 {
143   static gchar  str[3][8+1+4+2+2+5+2+2+7+2+2+7+1];
144   static gchar *cur, *p;
145   int hours, mins, secs;
146   int do_comma;
147
148   if (cur == &str[0][0]) {
149     cur = &str[1][0];
150   } else if (cur == &str[1][0]) {  
151     cur = &str[2][0];
152   } else {  
153     cur = &str[0][0];
154   }
155
156   secs = time % 60;
157   time /= 60;
158   mins = time % 60;
159   time /= 60;
160   hours = time % 24;
161   time /= 24;
162
163   p = cur;
164   if (time != 0) {
165     sprintf(p, "%u day%s", time, PLURALIZE(time));
166     p += strlen(p);
167     do_comma = 1;
168   } else
169     do_comma = 0;
170   if (hours != 0) {
171     sprintf(p, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
172     p += strlen(p);
173     do_comma = 1;
174   } else
175     do_comma = 0;
176   if (mins != 0) {
177     sprintf(p, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
178     p += strlen(p);
179     do_comma = 1;
180   } else
181     do_comma = 0;
182   if (secs != 0)
183     sprintf(p, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
184   return cur;
185 }
186
187 /* Max string length for displaying byte string.  */
188 #define MAX_BYTE_STR_LEN        16
189
190 /* Turn an array of bytes into a string showing the bytes in hex. */
191 gchar *
192 bytes_to_str(const guint8 *bd, int bd_len) {
193   static gchar  str[3][MAX_BYTE_STR_LEN+3+1];
194   static gchar *cur;
195   gchar        *p;
196   int           len;
197   static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
198                                 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
199
200   if (cur == &str[0][0]) {
201     cur = &str[1][0];
202   } else if (cur == &str[1][0]) {  
203     cur = &str[2][0];
204   } else {  
205     cur = &str[0][0];
206   }
207   p = cur;
208   len = MAX_BYTE_STR_LEN;
209   while (bd_len > 0 && len > 0) {
210     *p++ = hex[(*bd) >> 4];
211     *p++ = hex[(*bd) & 0xF];
212     len -= 2;
213     bd++;
214     bd_len--;
215   }
216   if (bd_len != 0) {
217     /* Note that we're not showing the full string.  */
218     *p++ = '.';
219     *p++ = '.';
220     *p++ = '.';
221   }
222   *p = '\0';
223   return cur;
224 }
225
226 static const char *mon_names[12] = {
227         "Jan",
228         "Feb",
229         "Mar",
230         "Apr",
231         "May",
232         "Jun",
233         "Jul",
234         "Aug",
235         "Sep",
236         "Oct",
237         "Nov",
238         "Dec"
239 };
240
241 gchar *
242 abs_time_to_str(struct timeval *abs_time)
243 {
244         struct tm *tmp;
245         static gchar *cur;
246         static char str[3][3+1+2+2+4+1+2+1+2+1+2+1+4+1 + 5 /* extra */];
247
248         if (cur == &str[0][0]) {
249                 cur = &str[1][0];
250         } else if (cur == &str[1][0]) {
251                 cur = &str[2][0];
252         } else {
253                 cur = &str[0][0];
254         }
255
256         tmp = localtime(&abs_time->tv_sec);
257         sprintf(cur, "%s %2d, %d %02d:%02d:%02d.%04ld",
258             mon_names[tmp->tm_mon],
259             tmp->tm_mday,
260             tmp->tm_year + 1900,
261             tmp->tm_hour,
262             tmp->tm_min,
263             tmp->tm_sec,
264             (long)abs_time->tv_usec/100);
265
266         return cur;
267 }
268
269
270 /*
271  * Given a pointer into a data buffer, and to the end of the buffer,
272  * find the end of the (putative) line at that position in the data
273  * buffer.
274  * Return a pointer to the EOL character(s) in "*eol".
275  */
276 const u_char *
277 find_line_end(const u_char *data, const u_char *dataend, const u_char **eol)
278 {
279   const u_char *lineend;
280
281   lineend = memchr(data, '\n', dataend - data);
282   if (lineend == NULL) {
283     /*
284      * No LF - line is probably continued in next TCP segment.
285      */
286     lineend = dataend;
287     *eol = dataend;
288   } else {
289     /*
290      * Is the LF at the beginning of the line?
291      */
292     if (lineend > data) {
293       /*
294        * No - is it preceded by a carriage return?
295        * (Perhaps it's supposed to be, but that's not guaranteed....)
296        */
297       if (*(lineend - 1) == '\r') {
298         /*
299          * Yes.  The EOL starts with the CR.
300          */
301         *eol = lineend - 1;
302       } else {
303         /*
304          * No.  The EOL starts with the LF.
305          */
306         *eol = lineend;
307
308         /*
309          * I seem to remember that we once saw lines ending with LF-CR
310          * in an HTTP request or response, so check if it's *followed*
311          * by a carriage return.
312          */
313         if (lineend < (dataend - 1) && *(lineend + 1) == '\r') {
314           /*
315            * It's <non-LF><LF><CR>; say it ends with the CR.
316            */
317           lineend++;
318         }
319       }
320     }
321
322     /*
323      * Point to the character after the last character.
324      */
325     lineend++;
326   }
327   return lineend;
328 }
329
330 #define MAX_COLUMNS_LINE_DETAIL 62
331
332 /*
333  * Get the length of the next token in a line, and the beginning of the
334  * next token after that (if any).
335  * Return 0 if there is no next token.
336  */
337 int
338 get_token_len(const u_char *linep, const u_char *lineend,
339               const u_char **next_token)
340 {
341   const u_char *tokenp;
342   int token_len;
343
344   tokenp = linep;
345   
346   /*
347    * Search for a blank, a CR or an LF, or the end of the buffer.
348    */
349   while (linep < lineend && *linep != ' ' && *linep != '\r' && *linep != '\n')
350       linep++;
351   token_len = linep - tokenp;
352
353   /*
354    * Skip trailing blanks.
355    */
356   while (linep < lineend && *linep == ' ')
357     linep++;
358
359   *next_token = linep;
360
361   return token_len;
362 }
363
364 /*
365  * Given a string, generate a string from it that shows non-printable
366  * characters as C-style escapes, and return a pointer to it.
367  */
368 gchar *
369 format_text(const u_char *string, int len)
370 {
371   static gchar fmtbuf[MAX_COLUMNS_LINE_DETAIL + 3 + 4 + 1];
372   gchar *fmtbufp;
373   int column;
374   const u_char *stringend = string + len;
375   u_char c;
376   int i;
377
378   column = 0;
379   fmtbufp = &fmtbuf[0];
380   while (string < stringend) {
381     if (column >= MAX_COLUMNS_LINE_DETAIL) {
382       /*
383        * Put "..." and quit.
384        */
385       strcpy(fmtbufp, " ...");
386       break;
387     }
388     c = *string++;
389     if (isprint(c)) {
390       *fmtbufp++ = c;
391       column++;
392     } else {
393       *fmtbufp++ =  '\\';
394       column++;
395       switch (c) {
396
397       case '\\':
398         *fmtbufp++ = '\\';
399         column++;
400         break;
401
402       case '\a':
403         *fmtbufp++ = 'a';
404         column++;
405         break;
406
407       case '\b':
408         *fmtbufp++ = 'b';
409         column++;
410         break;
411
412       case '\f':
413         *fmtbufp++ = 'f';
414         column++;
415         break;
416
417       case '\n':
418         *fmtbufp++ = 'n';
419         column++;
420         break;
421
422       case '\r':
423         *fmtbufp++ = 'r';
424         column++;
425         break;
426
427       case '\t':
428         *fmtbufp++ = 't';
429         column++;
430         break;
431
432       case '\v':
433         *fmtbufp++ = 'v';
434         column++;
435         break;
436
437       default:
438         i = (c>>6)&03;
439         *fmtbufp++ = i + '0';
440         column++;
441         i = (c>>3)&07;
442         *fmtbufp++ = i + '0';
443         column++;
444         i = (c>>0)&07;
445         *fmtbufp++ = i + '0';
446         column++;
447         break;
448       }
449     }
450   }
451   *fmtbufp = '\0';
452   return fmtbuf;
453 }
454
455
456 /* Tries to match val against each element in the value_string array vs.
457    Returns the associated string ptr on a match.
458    Formats val with fmt, and returns the resulting string, on failure. */
459 gchar*
460 val_to_str(guint32 val, const value_string *vs, const char *fmt) {
461   gchar *ret;
462   static gchar  str[3][64];
463   static gchar *cur;
464
465   ret = match_strval(val, vs);
466   if (ret != NULL)
467     return ret;
468   if (cur == &str[0][0]) {
469     cur = &str[1][0];
470   } else if (cur == &str[1][0]) {  
471     cur = &str[2][0];
472   } else {  
473     cur = &str[0][0];
474   }
475   snprintf(cur, 64, fmt, val);
476   return cur;
477 }
478
479 /* Tries to match val against each element in the value_string array vs.
480    Returns the associated string ptr on a match, or NULL on failure. */
481 gchar*
482 match_strval(guint32 val, const value_string *vs) {
483   gint i = 0;
484   
485   while (vs[i].strptr) {
486     if (vs[i].value == val)
487       return(vs[i].strptr);
488     i++;
489   }
490
491   return(NULL);
492 }
493
494 /* Generate, into "buf", a string showing the bits of a bitfield.
495    Return a pointer to the character after that string. */
496 static char *
497 decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width)
498 {
499   int i;
500   guint32 bit;
501   char *p;
502
503   i = 0;
504   p = buf;
505   bit = 1 << (width - 1);
506   for (;;) {
507     if (mask & bit) {
508       /* This bit is part of the field.  Show its value. */
509       if (val & bit)
510         *p++ = '1';
511       else
512         *p++ = '0';
513     } else {
514       /* This bit is not part of the field. */
515       *p++ = '.';
516     }
517     bit >>= 1;
518     i++;
519     if (i >= width)
520       break;
521     if (i % 4 == 0)
522       *p++ = ' ';
523   }
524   strcpy(p, " = ");
525   p += 3;
526   return p;
527 }
528
529 /* Generate a string describing a Boolean bitfield (a one-bit field that
530    says something is either true of false). */
531 const char *
532 decode_boolean_bitfield(guint32 val, guint32 mask, int width,
533     const char *truedesc, const char *falsedesc)
534 {
535   static char buf[1025];
536   char *p;
537
538   p = decode_bitfield_value(buf, val, mask, width);
539   if (val & mask)
540     strcpy(p, truedesc);
541   else
542     strcpy(p, falsedesc);
543   return buf;
544 }
545
546 /* Generate a string describing an enumerated bitfield (an N-bit field
547    with various specific values having particular names). */
548 const char *
549 decode_enumerated_bitfield(guint32 val, guint32 mask, int width,
550     const value_string *tab, const char *fmt)
551 {
552   static char buf[1025];
553   char *p;
554
555   p = decode_bitfield_value(buf, val, mask, width);
556   sprintf(p, fmt, val_to_str(val & mask, tab, "Unknown"));
557   return buf;
558 }
559
560 /* Generate a string describing a numeric bitfield (an N-bit field whose
561    value is just a number). */
562 const char *
563 decode_numeric_bitfield(guint32 val, guint32 mask, int width,
564     const char *fmt)
565 {
566   static char buf[1025];
567   char *p;
568   int shift = 0;
569
570   /* Compute the number of bits we have to shift the bitfield right
571      to extract its value. */
572   while ((mask & (1<<shift)) == 0)
573     shift++;
574
575   p = decode_bitfield_value(buf, val, mask, width);
576   sprintf(p, fmt, (val & mask) >> shift);
577   return buf;
578 }
579
580 /* Checks to see if a particular packet information element is needed for
581    the packet list */
582 gint
583 check_col(frame_data *fd, gint el) {
584   int i;
585
586   if (fd->cinfo) {
587     for (i = 0; i < fd->cinfo->num_cols; i++) {
588       if (fd->cinfo->fmt_matx[i][el])
589         return TRUE;
590     }
591   }
592   return FALSE;
593 }
594
595 /* Adds a vararg list to a packet info string. */
596 void
597 col_add_fstr(frame_data *fd, gint el, gchar *format, ...) {
598   va_list    ap;
599   int        i;
600   
601   va_start(ap, format);
602   for (i = 0; i < fd->cinfo->num_cols; i++) {
603     if (fd->cinfo->fmt_matx[i][el])
604       vsnprintf(fd->cinfo->col_data[i], COL_MAX_LEN, format, ap);
605   }
606 }
607
608 void
609 col_add_str(frame_data *fd, gint el, const gchar* str) {
610   int i;
611   
612   for (i = 0; i < fd->cinfo->num_cols; i++) {
613     if (fd->cinfo->fmt_matx[i][el]) {
614       strncpy(fd->cinfo->col_data[i], str, COL_MAX_LEN);
615       fd->cinfo->col_data[i][COL_MAX_LEN - 1] = 0;
616     }
617   }
618 }
619
620 /* this routine checks the frame type from the cf structure */
621 void
622 dissect_packet(const u_char *pd, frame_data *fd, proto_tree *tree)
623 {
624         proto_tree *fh_tree;
625         proto_item *ti;
626         struct timeval tv;
627
628         /* Put in frame header information. */
629         if (tree) {
630           ti = proto_tree_add_item_format(tree, proto_frame, 0, fd->cap_len,
631             NULL, "Frame (%d on wire, %d captured)", fd->pkt_len, fd->cap_len);
632
633           fh_tree = proto_item_add_subtree(ti, ETT_FRAME);
634
635           tv.tv_sec = fd->abs_secs;
636           tv.tv_usec = fd->abs_usecs;
637
638           proto_tree_add_item(fh_tree, hf_frame_arrival_time,
639                 0, 0, &tv);
640
641           proto_tree_add_item_format(fh_tree, hf_frame_packet_len,
642                 0, 0, fd->pkt_len, "Packet Length: %d byte%s", fd->pkt_len,
643                 plurality(fd->pkt_len, "", "s"));
644                 
645           proto_tree_add_item_format(fh_tree, hf_frame_capture_len,
646                 0, 0, fd->cap_len, "Capture Length: %d byte%s", fd->cap_len,
647                 plurality(fd->cap_len, "", "s"));
648         }
649
650         /* Set the initial payload to the packet length, and the initial
651            captured payload to the capture length (other protocols may
652            reduce them if their headers say they're less). */
653         pi.len = fd->pkt_len;
654         pi.captured_len = fd->cap_len;
655
656         switch (fd->lnk_t) {
657                 case WTAP_ENCAP_ETHERNET :
658                         dissect_eth(pd, 0, fd, tree);
659                         break;
660                 case WTAP_ENCAP_FDDI :
661                         dissect_fddi(pd, fd, tree, FALSE);
662                         break;
663                 case WTAP_ENCAP_FDDI_BITSWAPPED :
664                         dissect_fddi(pd, fd, tree, TRUE);
665                         break;
666                 case WTAP_ENCAP_TR :
667                         dissect_tr(pd, 0, fd, tree);
668                         break;
669                 case WTAP_ENCAP_NULL :
670                         dissect_null(pd, fd, tree);
671                         break;
672                 case WTAP_ENCAP_PPP :
673                         dissect_ppp(pd, fd, tree);
674                         break;
675                 case WTAP_ENCAP_LAPB :
676                         dissect_lapb(pd, fd, tree);
677                         break;
678                 case WTAP_ENCAP_RAW_IP :
679                         dissect_raw(pd, fd, tree);
680                         break;
681                 case WTAP_ENCAP_LINUX_ATM_CLIP :
682                         dissect_clip(pd, fd, tree);
683                         break;
684                 case WTAP_ENCAP_ATM_SNIFFER :
685                         dissect_atm(pd, fd, tree);
686                         break;
687         }
688 }
689
690 void
691 proto_register_frame(void)
692 {
693         static hf_register_info hf[] = {
694                 { &hf_frame_arrival_time,
695                 { "Arrival Time",               "frame.time", FT_ABSOLUTE_TIME, NULL }},
696
697                 { &hf_frame_packet_len,
698                 { "Total Frame Length",         "frame.pkt_len", FT_UINT32, NULL }},
699
700                 { &hf_frame_capture_len,
701                 { "Capture Frame Length",       "frame.cap_len", FT_UINT32, NULL }}
702         };
703
704         proto_frame = proto_register_protocol("Frame", "frame");
705         proto_register_field_array(proto_frame, hf, array_length(hf));
706 }