2 * Routines for packet disassembly
4 * $Id: packet.c,v 1.58 1999/12/02 01:33:55 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
30 #ifdef HAVE_SYS_TYPES_H
31 # include <sys/types.h>
34 #ifdef HAVE_SYS_SOCKET_H
35 #include <sys/socket.h>
50 #ifdef NEED_SNPRINTF_H
51 # include "snprintf.h"
54 #ifdef HAVE_NETINET_IN_H
55 # include <netinet/in.h>
58 #include <arpa/inet.h>
60 #ifdef NEED_INET_V6DEFS_H
61 # include "inet_v6defs.h"
68 extern capture_file cf;
70 static int proto_frame = -1;
71 static int hf_frame_arrival_time = -1;
72 static int hf_frame_time_delta = -1;
73 static int hf_frame_number = -1;
74 static int hf_frame_packet_len = -1;
75 static int hf_frame_capture_len = -1;
77 static gint ett_frame = -1;
79 /* Wrapper for the most common case of asking
80 * for a string using a colon as the hex-digit separator.
83 ether_to_str(const guint8 *ad)
85 return ether_to_str_punct(ad, ':');
88 /* Places char punct in the string as the hex-digit separator.
89 * If punct is '\0', no punctuation is applied (and thus
90 * the resulting string is 5 bytes shorter)
93 ether_to_str_punct(const guint8 *ad, char punct) {
94 static gchar str[3][18];
99 static const gchar hex_digits[16] = "0123456789abcdef";
101 if (cur == &str[0][0]) {
103 } else if (cur == &str[1][0]) {
113 *--p = hex_digits[octet&0xF];
115 *--p = hex_digits[octet&0xF];
126 ip_to_str(const guint8 *ad) {
127 static gchar str[3][16];
134 if (cur == &str[0][0]) {
136 } else if (cur == &str[1][0]) {
146 *--p = (octet%10) + '0';
150 if (digit != 0 || octet != 0)
163 ip6_to_str(struct e_in6_addr *ad) {
164 #ifndef INET6_ADDRSTRLEN
165 #define INET6_ADDRSTRLEN 46
167 static gchar buf[INET6_ADDRSTRLEN];
169 inet_ntop(AF_INET6, (u_char*)ad, (gchar*)buf, sizeof(buf));
174 #define PLURALIZE(n) (((n) > 1) ? "s" : "")
175 #define COMMA(do_it) ((do_it) ? ", " : "")
178 time_secs_to_str(guint32 time)
180 static gchar str[3][8+1+4+2+2+5+2+2+7+2+2+7+1];
181 static gchar *cur, *p;
182 int hours, mins, secs;
185 if (cur == &str[0][0]) {
187 } else if (cur == &str[1][0]) {
202 sprintf(p, "%u day%s", time, PLURALIZE(time));
208 sprintf(p, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
214 sprintf(p, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
220 sprintf(p, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
224 /* Max string length for displaying byte string. */
225 #define MAX_BYTE_STR_LEN 20
227 /* Turn an array of bytes into a string showing the bytes in hex. */
228 #define N_BYTES_TO_STR_STRINGS 6
230 bytes_to_str(const guint8 *bd, int bd_len) {
231 static gchar str[N_BYTES_TO_STR_STRINGS][MAX_BYTE_STR_LEN+3+1];
236 static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
237 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
240 if (cur_idx >= N_BYTES_TO_STR_STRINGS)
242 cur = &str[cur_idx][0];
244 len = MAX_BYTE_STR_LEN;
245 while (bd_len > 0 && len > 0) {
246 *p++ = hex[(*bd) >> 4];
247 *p++ = hex[(*bd) & 0xF];
253 /* Note that we're not showing the full string. */
262 static const char *mon_names[12] = {
278 abs_time_to_str(struct timeval *abs_time)
282 static char str[3][3+1+2+2+4+1+2+1+2+1+2+1+4+1 + 5 /* extra */];
284 if (cur == &str[0][0]) {
286 } else if (cur == &str[1][0]) {
292 tmp = localtime(&abs_time->tv_sec);
293 sprintf(cur, "%s %2d, %d %02d:%02d:%02d.%04ld",
294 mon_names[tmp->tm_mon],
300 (long)abs_time->tv_usec/100);
306 rel_time_to_str(struct timeval *rel_time)
309 static char str[3][10+1+6+1];
311 if (cur == &str[0][0]) {
313 } else if (cur == &str[1][0]) {
319 sprintf(cur, "%ld.%06ld", (long)rel_time->tv_sec,
320 (long)rel_time->tv_usec);
326 * Given a pointer into a data buffer, and to the end of the buffer,
327 * find the end of the (putative) line at that position in the data
329 * Return a pointer to the EOL character(s) in "*eol".
332 find_line_end(const u_char *data, const u_char *dataend, const u_char **eol)
334 const u_char *lineend;
336 lineend = memchr(data, '\n', dataend - data);
337 if (lineend == NULL) {
339 * No LF - line is probably continued in next TCP segment.
345 * Is the LF at the beginning of the line?
347 if (lineend > data) {
349 * No - is it preceded by a carriage return?
350 * (Perhaps it's supposed to be, but that's not guaranteed....)
352 if (*(lineend - 1) == '\r') {
354 * Yes. The EOL starts with the CR.
359 * No. The EOL starts with the LF.
364 * I seem to remember that we once saw lines ending with LF-CR
365 * in an HTTP request or response, so check if it's *followed*
366 * by a carriage return.
368 if (lineend < (dataend - 1) && *(lineend + 1) == '\r') {
370 * It's <non-LF><LF><CR>; say it ends with the CR.
378 * Point to the character after the last character.
385 #define MAX_COLUMNS_LINE_DETAIL 62
388 * Get the length of the next token in a line, and the beginning of the
389 * next token after that (if any).
390 * Return 0 if there is no next token.
393 get_token_len(const u_char *linep, const u_char *lineend,
394 const u_char **next_token)
396 const u_char *tokenp;
402 * Search for a blank, a CR or an LF, or the end of the buffer.
404 while (linep < lineend && *linep != ' ' && *linep != '\r' && *linep != '\n')
406 token_len = linep - tokenp;
409 * Skip trailing blanks.
411 while (linep < lineend && *linep == ' ')
420 * Given a string, generate a string from it that shows non-printable
421 * characters as C-style escapes, and return a pointer to it.
424 format_text(const u_char *string, int len)
426 static gchar fmtbuf[MAX_COLUMNS_LINE_DETAIL + 3 + 4 + 1];
429 const u_char *stringend = string + len;
434 fmtbufp = &fmtbuf[0];
435 while (string < stringend) {
436 if (column >= MAX_COLUMNS_LINE_DETAIL) {
438 * Put "..." and quit.
440 strcpy(fmtbufp, " ...");
495 *fmtbufp++ = i + '0';
498 *fmtbufp++ = i + '0';
501 *fmtbufp++ = i + '0';
512 /* Tries to match val against each element in the value_string array vs.
513 Returns the associated string ptr on a match.
514 Formats val with fmt, and returns the resulting string, on failure. */
516 val_to_str(guint32 val, const value_string *vs, const char *fmt) {
518 static gchar str[3][64];
521 ret = match_strval(val, vs);
524 if (cur == &str[0][0]) {
526 } else if (cur == &str[1][0]) {
531 snprintf(cur, 64, fmt, val);
535 /* Tries to match val against each element in the value_string array vs.
536 Returns the associated string ptr on a match, or NULL on failure. */
538 match_strval(guint32 val, const value_string *vs) {
541 while (vs[i].strptr) {
542 if (vs[i].value == val)
543 return(vs[i].strptr);
550 /* Generate, into "buf", a string showing the bits of a bitfield.
551 Return a pointer to the character after that string. */
553 decode_bitfield_value(char *buf, guint32 val, guint32 mask, int width)
561 bit = 1 << (width - 1);
564 /* This bit is part of the field. Show its value. */
570 /* This bit is not part of the field. */
585 /* Generate a string describing a Boolean bitfield (a one-bit field that
586 says something is either true of false). */
588 decode_boolean_bitfield(guint32 val, guint32 mask, int width,
589 const char *truedesc, const char *falsedesc)
591 static char buf[1025];
594 p = decode_bitfield_value(buf, val, mask, width);
598 strcpy(p, falsedesc);
602 /* Generate a string describing an enumerated bitfield (an N-bit field
603 with various specific values having particular names). */
605 decode_enumerated_bitfield(guint32 val, guint32 mask, int width,
606 const value_string *tab, const char *fmt)
608 static char buf[1025];
611 p = decode_bitfield_value(buf, val, mask, width);
612 sprintf(p, fmt, val_to_str(val & mask, tab, "Unknown"));
616 /* Generate a string describing a numeric bitfield (an N-bit field whose
617 value is just a number). */
619 decode_numeric_bitfield(guint32 val, guint32 mask, int width,
622 static char buf[1025];
626 /* Compute the number of bits we have to shift the bitfield right
627 to extract its value. */
628 while ((mask & (1<<shift)) == 0)
631 p = decode_bitfield_value(buf, val, mask, width);
632 sprintf(p, fmt, (val & mask) >> shift);
636 /* Checks to see if a particular packet information element is needed for
639 check_col(frame_data *fd, gint el) {
643 for (i = 0; i < fd->cinfo->num_cols; i++) {
644 if (fd->cinfo->fmt_matx[i][el])
651 /* Adds a vararg list to a packet info string. */
653 col_add_fstr(frame_data *fd, gint el, gchar *format, ...) {
658 va_start(ap, format);
659 for (i = 0; i < fd->cinfo->num_cols; i++) {
660 if (fd->cinfo->fmt_matx[i][el]) {
662 max_len = COL_MAX_INFO_LEN;
664 max_len = COL_MAX_LEN;
665 vsnprintf(fd->cinfo->col_data[i], max_len, format, ap);
671 col_add_str(frame_data *fd, gint el, const gchar* str) {
675 for (i = 0; i < fd->cinfo->num_cols; i++) {
676 if (fd->cinfo->fmt_matx[i][el]) {
678 max_len = COL_MAX_INFO_LEN;
680 max_len = COL_MAX_LEN;
681 strncpy(fd->cinfo->col_data[i], str, max_len);
682 fd->cinfo->col_data[i][max_len - 1] = 0;
687 /* Appends a vararg list to a packet info string. */
689 col_append_fstr(frame_data *fd, gint el, gchar *format, ...) {
694 va_start(ap, format);
695 for (i = 0; i < fd->cinfo->num_cols; i++) {
696 if (fd->cinfo->fmt_matx[i][el]) {
697 len = strlen(fd->cinfo->col_data[i]);
699 max_len = COL_MAX_INFO_LEN;
701 max_len = COL_MAX_LEN;
702 vsnprintf(&fd->cinfo->col_data[i][len], max_len - len, format, ap);
708 col_append_str(frame_data *fd, gint el, gchar* str) {
712 for (i = 0; i < fd->cinfo->num_cols; i++) {
713 if (fd->cinfo->fmt_matx[i][el]) {
714 len = strlen(fd->cinfo->col_data[i]);
716 max_len = COL_MAX_LEN;
718 max_len = COL_MAX_INFO_LEN;
719 strncat(fd->cinfo->col_data[i], str, max_len - len);
720 fd->cinfo->col_data[i][max_len - 1] = 0;
725 void blank_packetinfo(void)
727 pi.dl_src.type = AT_NONE;
728 pi.dl_dst.type = AT_NONE;
729 pi.net_src.type = AT_NONE;
730 pi.net_dst.type = AT_NONE;
731 pi.src.type = AT_NONE;
732 pi.dst.type = AT_NONE;
739 /* Allow protocols to register "init" routines, which are called before
740 we make a pass through a capture file and dissect all its packets
741 (e.g., when we read in a new capture file, or run a "filter packets"
742 or "colorize packets" pass over the current capture file). */
743 static GSList *init_routines;
746 register_init_routine(void (*func)(void))
748 init_routines = g_slist_append(init_routines, func);
751 /* Call all the registered "init" routines. */
753 call_init_routine(gpointer routine, gpointer dummy)
755 void (*func)(void) = routine;
761 init_all_protocols(void)
763 g_slist_foreach(init_routines, &call_init_routine, NULL);
766 /* this routine checks the frame type from the cf structure */
768 dissect_packet(const u_char *pd, frame_data *fd, proto_tree *tree)
774 /* Put in frame header information. */
776 ti = proto_tree_add_item_format(tree, proto_frame, 0, fd->cap_len,
777 NULL, "Frame (%d on wire, %d captured)", fd->pkt_len, fd->cap_len);
779 fh_tree = proto_item_add_subtree(ti, ett_frame);
781 tv.tv_sec = fd->abs_secs;
782 tv.tv_usec = fd->abs_usecs;
784 proto_tree_add_item(fh_tree, hf_frame_arrival_time,
787 tv.tv_sec = fd->del_secs;
788 tv.tv_usec = fd->del_usecs;
790 proto_tree_add_item(fh_tree, hf_frame_time_delta,
793 proto_tree_add_item(fh_tree, hf_frame_number,
796 proto_tree_add_item_format(fh_tree, hf_frame_packet_len,
797 0, 0, fd->pkt_len, "Packet Length: %d byte%s", fd->pkt_len,
798 plurality(fd->pkt_len, "", "s"));
800 proto_tree_add_item_format(fh_tree, hf_frame_capture_len,
801 0, 0, fd->cap_len, "Capture Length: %d byte%s", fd->cap_len,
802 plurality(fd->cap_len, "", "s"));
807 /* Set the initial payload to the packet length, and the initial
808 captured payload to the capture length (other protocols may
809 reduce them if their headers say they're less). */
810 pi.len = fd->pkt_len;
811 pi.captured_len = fd->cap_len;
814 case WTAP_ENCAP_ETHERNET :
815 dissect_eth(pd, 0, fd, tree);
817 case WTAP_ENCAP_FDDI :
818 dissect_fddi(pd, fd, tree, FALSE);
820 case WTAP_ENCAP_FDDI_BITSWAPPED :
821 dissect_fddi(pd, fd, tree, TRUE);
824 dissect_tr(pd, 0, fd, tree);
826 case WTAP_ENCAP_NULL :
827 dissect_null(pd, fd, tree);
829 case WTAP_ENCAP_PPP :
830 dissect_ppp(pd, fd, tree);
832 case WTAP_ENCAP_LAPB :
833 dissect_lapb(pd, fd, tree);
835 case WTAP_ENCAP_RAW_IP :
836 dissect_raw(pd, fd, tree);
838 case WTAP_ENCAP_LINUX_ATM_CLIP :
839 dissect_clip(pd, fd, tree);
841 case WTAP_ENCAP_ATM_SNIFFER :
842 dissect_atm(pd, fd, tree);
844 case WTAP_ENCAP_ASCEND :
845 dissect_ascend(pd, fd, tree);
847 case WTAP_ENCAP_LAPD :
848 dissect_lapd(pd, fd, tree);
854 proto_register_frame(void)
856 static hf_register_info hf[] = {
857 { &hf_frame_arrival_time,
858 { "Arrival Time", "frame.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
861 { &hf_frame_time_delta,
862 { "Time delta from previous packet", "frame.time_delta", FT_RELATIVE_TIME, BASE_NONE, NULL,
867 { "Frame Number", "frame.number", FT_UINT32, BASE_DEC, NULL, 0x0,
870 { &hf_frame_packet_len,
871 { "Total Frame Length", "frame.pkt_len", FT_UINT32, BASE_DEC, NULL, 0x0,
874 { &hf_frame_capture_len,
875 { "Capture Frame Length", "frame.cap_len", FT_UINT32, BASE_DEC, NULL, 0x0,
878 static gint *ett[] = {
882 proto_frame = proto_register_protocol("Frame", "frame");
883 proto_register_field_array(proto_frame, hf, array_length(hf));
884 proto_register_subtree_array(ett, array_length(ett));