2 * Routines for packet disassembly
4 * $Id: packet.c,v 1.10 1998/11/12 00:06:40 gram 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>
41 #ifdef NEED_SNPRINTF_H
42 # include "snprintf.h"
45 #ifdef HAVE_NETINET_IN_H
46 # include <netinet/in.h>
54 extern GtkWidget *byte_view;
55 extern GdkFont *m_r_font, *m_b_font;
56 extern capture_file cf;
59 ether_to_str(guint8 *ad) {
60 static gchar str[3][18];
63 if (cur == &str[0][0]) {
65 } else if (cur == &str[1][0]) {
70 sprintf(cur, "%02x:%02x:%02x:%02x:%02x:%02x", ad[0], ad[1], ad[2],
76 ip_to_str(guint8 *ad) {
77 static gchar str[3][16];
80 if (cur == &str[0][0]) {
82 } else if (cur == &str[1][0]) {
87 sprintf(cur, "%d.%d.%d.%d", ad[0], ad[1], ad[2], ad[3]);
92 packet_hex_print(GtkText *bv, guchar *pd, gint len, gint bstart, gint blen) {
93 gint i = 0, j, k, cur;
94 gchar line[128], hexchars[] = "0123456789abcdef";
95 GdkFont *cur_font, *new_font;
98 /* Print the line number */
99 sprintf(line, "%04x ", i);
100 gtk_text_insert(bv, m_r_font, NULL, NULL, line, -1);
101 /* Do we start in bold? */
102 cur_font = (i >= bstart && i < (bstart + blen)) ? m_b_font : m_r_font;
104 k = i + BYTE_VIEW_WIDTH;
106 /* Print the hex bit */
109 line[cur++] = hexchars[(pd[i] & 0xf0) >> 4];
110 line[cur++] = hexchars[pd[i] & 0x0f];
112 line[cur++] = ' '; line[cur++] = ' ';
116 /* Did we cross a bold/plain boundary? */
117 new_font = (i >= bstart && i < (bstart + blen)) ? m_b_font : m_r_font;
118 if (cur_font != new_font) {
119 gtk_text_insert(bv, cur_font, NULL, NULL, line, cur);
125 gtk_text_insert(bv, cur_font, NULL, NULL, line, cur);
128 /* Print the ASCII bit */
129 cur_font = (i >= bstart && i < (bstart + blen)) ? m_b_font : m_r_font;
132 line[cur++] = (isgraph(pd[i])) ? pd[i] : '.';
137 /* Did we cross a bold/plain boundary? */
138 new_font = (i >= bstart && i < (bstart + blen)) ? m_b_font : m_r_font;
139 if (cur_font != new_font) {
140 gtk_text_insert(bv, cur_font, NULL, NULL, line, cur);
147 gtk_text_insert(bv, cur_font, NULL, NULL, line, -1);
152 add_item_to_tree(GtkWidget *tree, gint start, gint len,
153 gchar *format, ...) {
156 gchar label_str[256];
158 /* This limits us to a max packet size of 65535 bytes. */
159 /* Are there any systems out there with < 32-bit pointers? */
160 /* To do: use gtk_object_set_data instead, now that I know it exists. */
161 va_start(ap, format);
162 vsnprintf(label_str, 256, format, ap);
163 ti = gtk_tree_item_new_with_label(label_str);
164 gtk_object_set_data(GTK_OBJECT(ti), E_TREEINFO_START_KEY, (gpointer) start);
165 gtk_object_set_data(GTK_OBJECT(ti), E_TREEINFO_LEN_KEY, (gpointer) len);
166 gtk_tree_append(GTK_TREE(tree), ti);
173 add_subtree(GtkWidget *ti, GtkWidget *subtree, gint idx) {
174 static gint tree_type[NUM_TREE_TYPES];
176 gtk_tree_item_set_subtree(GTK_TREE_ITEM(ti), subtree);
178 gtk_tree_item_expand(GTK_TREE_ITEM(ti));
179 gtk_signal_connect(GTK_OBJECT(ti), "expand", (GtkSignalFunc) expand_tree,
180 (gpointer) &tree_type[idx]);
181 gtk_signal_connect(GTK_OBJECT(ti), "collapse", (GtkSignalFunc) collapse_tree,
182 (gpointer) &tree_type[idx]);
186 expand_tree(GtkWidget *w, gpointer data) {
187 gint *val = (gint *) data;
192 collapse_tree(GtkWidget *w, gpointer data) {
193 gint *val = (gint *) data;
197 /* Tries to match val against each element in the value_string array vs.
198 Returns the associated string ptr on a match.
199 Formats val with fmt, and returns the resulting string, on failure. */
201 val_to_str(guint32 val, const value_string *vs, const char *fmt) {
203 static gchar str[3][64];
206 ret = match_strval(val, vs);
209 if (cur == &str[0][0]) {
211 } else if (cur == &str[1][0]) {
216 snprintf(cur, 64, fmt, val);
220 /* Tries to match val against each element in the value_string array vs.
221 Returns the associated string ptr on a match, or NULL on failure. */
223 match_strval(guint32 val, const value_string *vs) {
226 while (vs[i].strptr) {
227 if (vs[i].value == val)
228 return(vs[i].strptr);
235 static const char *mon_names[12] = {
250 /* this routine checks the frame type from the cf structure */
252 dissect_packet(const u_char *pd, guint32 ts_secs, guint32 ts_usecs,
253 frame_data *fd, GtkTree *tree)
255 GtkWidget *fh_tree, *ti;
259 /* Put in frame header information. */
260 if (fd->win_info[COL_NUM]) {
261 if (timestamp_type == ABSOLUTE) {
263 tmp = localtime(&then);
264 sprintf(fd->win_info[COL_TIME], "%02d:%02d:%02d.%04ld",
268 (long)fd->usecs/100);
270 sprintf(fd->win_info[COL_TIME], "%d.%06d", ts_secs, ts_usecs);
274 ti = add_item_to_tree(GTK_WIDGET(tree), 0, fd->cap_len,
275 "Frame (%d on wire, %d captured)",
276 fd->pkt_len, fd->cap_len);
278 fh_tree = gtk_tree_new();
279 add_subtree(ti, fh_tree, ETT_FRAME);
281 tmp = localtime(&then);
282 add_item_to_tree(fh_tree, 0, 0,
283 "Frame arrived on %s %2d, %d %02d:%02d:%02d.%04ld",
284 mon_names[tmp->tm_mon],
290 (long)fd->usecs/100);
292 add_item_to_tree(fh_tree, 0, 0, "Total frame length: %d bytes",
294 add_item_to_tree(fh_tree, 0, 0, "Capture frame length: %d bytes",
300 case WTAP_ENCAP_ETHERNET :
301 dissect_eth(pd, fd, tree);
303 case WTAP_ENCAP_FDDI :
304 dissect_fddi(pd, fd, tree);
307 dissect_tr(pd, fd, tree);
309 case WTAP_ENCAP_NONE :
310 dissect_null(pd, fd, tree);
312 case WTAP_ENCAP_PPP :
313 dissect_ppp(pd, fd, tree);
315 case WTAP_ENCAP_RAW_IP :
316 dissect_raw(pd, fd, tree);
322 dissect_eth(pd, fd, tree);
325 dissect_fddi(pd, fd, tree);
328 dissect_tr(pd, fd, tree);
331 dissect_null(pd, fd, tree);
334 dissect_ppp(pd, fd, tree);
337 dissect_raw(pd, fd, tree);