Added guy's time and DHCP patch.
authorGilbert Ramirez <gram@alumni.rice.edu>
Thu, 28 Jan 1999 21:29:36 +0000 (21:29 -0000)
committerGilbert Ramirez <gram@alumni.rice.edu>
Thu, 28 Jan 1999 21:29:36 +0000 (21:29 -0000)
svn path=/trunk/; revision=177

packet-arp.c
packet-bootp.c
packet-dns.c
packet.c
packet.h
snprintf.c

index 9906f607d3ed18324dc4beb2e77565d5c2a2588d..41e337e786ec3693b33d7034a8206ea0651700fe 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-arp.c
  * Routines for ARP packet disassembly
  *
- * $Id: packet-arp.c,v 1.10 1998/11/17 04:28:49 gerald Exp $
+ * $Id: packet-arp.c,v 1.11 1999/01/28 21:29:34 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -117,10 +117,12 @@ arpaddr_to_str(guint8 *ad, int ad_len) {
   return cur;
 }
 
-static gchar *
+gchar *
 arphrdaddr_to_str(guint8 *ad, int ad_len, guint16 type) {
-  if (type == ARPHRD_ETHER && ad_len == 6) {
-    /* Ethernet address.  */
+  if ((type == ARPHRD_ETHER || type == ARPHRD_EETHER || type == ARPHRD_IEEE802)
+                               && ad_len == 6) {
+    /* Ethernet address (or Experimental 3Mb Ethernet, or IEEE 802.x
+       address, which are the same type of address). */
     return ether_to_str(ad);
   }
   return arpaddr_to_str(ad, ad_len);
@@ -135,30 +137,8 @@ arpproaddr_to_str(guint8 *ad, int ad_len, guint16 type) {
   return arpaddr_to_str(ad, ad_len);
 }
 
-/* Offsets of fields within an ARP packet. */
-#define        AR_HRD          0
-#define        AR_PRO          2
-#define        AR_HLN          4
-#define        AR_PLN          5
-#define        AR_OP           6
-
-void
-dissect_arp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
-  guint16     ar_hrd;
-  guint16     ar_pro;
-  guint8      ar_hln;
-  guint8      ar_pln;
-  guint16     ar_op;
-  GtkWidget   *arp_tree, *ti;
-  gchar       *op_str;
-  int         sha_offset, spa_offset, tha_offset, tpa_offset;
-  gchar       *sha_str, *spa_str, *tha_str, *tpa_str;
-  static const value_string op_vals[] = {
-    {ARPOP_REQUEST,  "ARP request" },
-    {ARPOP_REPLY,    "ARP reply"   },
-    {ARPOP_RREQUEST, "RARP request"},
-    {ARPOP_RREPLY,   "RARP reply"  },
-    {0,              NULL          } };
+gchar *
+arphrdtype_to_str(guint16 hwtype, const char *fmt) {
   static const value_string hrd_vals[] = {
     {ARPHRD_NETROM,   "NET/ROM pseudo"       },
     {ARPHRD_ETHER,    "Ethernet"             },
@@ -190,6 +170,34 @@ dissect_arp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
     {ARPHRD_EUI_64,   "EUI-64"               },
     {0,                NULL                  } };
 
+    return val_to_str(hwtype, hrd_vals, fmt);
+}
+
+/* Offsets of fields within an ARP packet. */
+#define        AR_HRD          0
+#define        AR_PRO          2
+#define        AR_HLN          4
+#define        AR_PLN          5
+#define        AR_OP           6
+
+void
+dissect_arp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
+  guint16     ar_hrd;
+  guint16     ar_pro;
+  guint8      ar_hln;
+  guint8      ar_pln;
+  guint16     ar_op;
+  GtkWidget   *arp_tree, *ti;
+  gchar       *op_str;
+  int         sha_offset, spa_offset, tha_offset, tpa_offset;
+  gchar       *sha_str, *spa_str, *tha_str, *tpa_str;
+  static const value_string op_vals[] = {
+    {ARPOP_REQUEST,  "ARP request" },
+    {ARPOP_REPLY,    "ARP reply"   },
+    {ARPOP_RREQUEST, "RARP request"},
+    {ARPOP_RREPLY,   "RARP reply"  },
+    {0,              NULL          } };
+
   /* To do: Check for {cap len,pkt len} < struct len */
   ar_hrd = pntohs(&pd[offset + AR_HRD]);
   ar_pro = pntohs(&pd[offset + AR_PRO]);
@@ -246,7 +254,7 @@ dissect_arp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree) {
     arp_tree = gtk_tree_new();
     add_subtree(ti, arp_tree, ETT_ARP);
     add_item_to_tree(arp_tree, offset + AR_HRD, 2,
-      "Hardware type: %s", val_to_str(ar_hrd, hrd_vals, "Unknown (0x%04x)"));
+      "Hardware type: %s", arphrdtype_to_str(ar_hrd, "Unknown (0x%04x)"));
     add_item_to_tree(arp_tree, offset + AR_PRO, 2,
       "Protocol type: %s", ethertype_to_str(ar_pro, "Unknown (0x%04x)"));
     add_item_to_tree(arp_tree, offset + AR_HLN, 1,
index f9430f36b45e2d7cfcdf3ae104bc4a3e007ce322..ca38fa16cb0e35908d5137f7346d97657189e9c4 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for BOOTP/DHCP packet disassembly
  * Gilbert Ramirez <gram@verdict.uthscsa.edu>
  *
- * $Id: packet-bootp.c,v 1.14 1998/11/20 17:47:33 gram Exp $
+ * $Id: packet-bootp.c,v 1.15 1999/01/28 21:29:35 gram Exp $
  *
  * The information used comes from:
  * RFC 2132: DHCP Options and BOOTP Vendor Extensions
@@ -51,6 +51,7 @@
 #include "etypes.h"
 
 enum field_type { none, ipv4, string, toggle, yes_no, special, opaque,
+       time_in_secs,
        val_u_byte, val_u_short, val_u_long,
        val_s_long };
 
@@ -62,7 +63,7 @@ struct opt_info {
 #define NUM_OPT_INFOS 77
 
 /* returns the number of bytes consumed by this option */
-int
+static int
 bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
 {
        char                    *text;
@@ -70,10 +71,11 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
        u_char                  code = pd[voff];
        int                             vlen = pd[voff+1];
        u_char                  byte;
-       int                             i, consumed = 1; /* if code is unknown, consume 1 byte */
+       int                             i, consumed = vlen + 2;
+       u_long                  time_secs;
        GtkWidget               *vti, *v_tree;
 
-       char    *opt53_text[] = {
+       static const char       *opt53_text[] = {
                "Unknown Message Type",
                "Discover",
                "Offer",
@@ -84,6 +86,12 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
                "Release",
                "Inform"
        };
+       static const value_string nbnt_vals[] = {
+           {0x1,   "B-node" },
+           {0x2,   "P-node" },
+           {0x4,   "M-node" },
+           {0x8,   "H-node" },
+           {0,     NULL     } };
 
        static struct opt_info opt[] = {
                /*   0 */ { "Padding",                                                          none },
@@ -110,7 +118,7 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
                /*  21 */ { "Policy Filter",                                            special },
                /*  22 */ { "Maximum Datagram Reassembly Size",         val_u_short },
                /*  23 */ { "Default IP Time-to-Live",                          val_u_byte },
-               /*  24 */ { "Path MTU Aging Timeout",                           val_u_long },
+               /*  24 */ { "Path MTU Aging Timeout",                           time_in_secs },
                /*  25 */ { "Path MTU Plateau Table",                           val_u_short },
                /*  26 */ { "Interface MTU",                                            val_u_short },
                /*  27 */ { "All Subnets are Local",                            yes_no },
@@ -121,10 +129,10 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
                /*  32 */ { "Router Solicitation Address",                      ipv4 },
                /*  33 */ { "Static Route",                                                     special },
                /*  34 */ { "Trailer Encapsulation",                            toggle },
-               /*  35 */ { "ARP Cache Timeout",                                        val_u_long },
+               /*  35 */ { "ARP Cache Timeout",                                        time_in_secs },
                /*  36 */ { "Ethernet Encapsulation",                           toggle },
                /*  37 */ { "TCP Default TTL",                                          val_u_byte },
-               /*  38 */ { "TCP Keepalive Interval",                           val_u_long },
+               /*  38 */ { "TCP Keepalive Interval",                           time_in_secs },
                /*  39 */ { "TCP Keepalive Garbage",                            toggle },
                /*  40 */ { "Network Information Service Domain",       string },
                /*  41 */ { "Network Information Service Servers",      ipv4 },
@@ -137,15 +145,15 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
                /*  48 */ { "X Window System Font Server",                      ipv4 },
                /*  49 */ { "X Window System Display Manager",          ipv4 },
                /*  50 */ { "Requested IP Address",                                     ipv4 },
-               /*  51 */ { "IP Address Lease Time",                            val_u_long },
+               /*  51 */ { "IP Address Lease Time",                            time_in_secs },
                /*  52 */ { "Option Overload",                                          special },
                /*  53 */ { "DHCP Message Type",                                        special },
                /*  54 */ { "Server Identifier",                                        ipv4 },
                /*  55 */ { "Parameter Request List",                           special },
                /*  56 */ { "Message",                                                          string },
                /*  57 */ { "Maximum DHCP Message Size",                        val_u_short },
-               /*  58 */ { "Renewal Time Value",                                       val_u_long },
-               /*  59 */ { "Rebinding Time Value",                                     val_u_long },
+               /*  58 */ { "Renewal Time Value",                                       time_in_secs },
+               /*  59 */ { "Rebinding Time Value",                                     time_in_secs },
                /*  60 */ { "Vendor class identifier",                          opaque },
                /*  61 */ { "Client identifier",                                        special },
                /*  64 */ { "Network Information Service+ Domain",      string },
@@ -196,7 +204,7 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
                                v_tree = gtk_tree_new();
                                add_subtree(vti, v_tree, ETT_BOOTP_OPTION);
                                for (i = voff + 2; i < voff + consumed; i += 8) {
-                                       add_item_to_tree(v_tree, i, 4, "IP Address/Mask: %s/%s",
+                                       add_item_to_tree(v_tree, i, 8, "IP Address/Mask: %s/%s",
                                                ip_to_str((guint8*)&pd[i]),
                                                ip_to_str((guint8*)&pd[i+4]));
                                }
@@ -220,7 +228,7 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
                                v_tree = gtk_tree_new();
                                add_subtree(vti, v_tree, ETT_BOOTP_OPTION);
                                for (i = voff + 2; i < voff + consumed; i += 8) {
-                                       add_item_to_tree(v_tree, i, 4,
+                                       add_item_to_tree(v_tree, i, 8,
                                                "Destination IP Address/Router: %s/%s",
                                                ip_to_str((guint8*)&pd[i]),
                                                ip_to_str((guint8*)&pd[i+4]));
@@ -228,6 +236,21 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
                        }
                        break;
 
+               /* Vendor-Specific Info */
+               case 43:
+                       add_item_to_tree(bp_tree, voff, consumed,
+                                       "Option %d: %s", code, text);
+                       break;
+
+               /* NetBIOS-over-TCP/IP Node Type */
+               case 46:
+                       byte = pd[voff+2];
+                       add_item_to_tree(bp_tree, voff, consumed,
+                                       "Option %d: %s = %s", code, text,
+                                       val_to_str(byte, nbnt_vals,
+                                           "Unknown (0x%02x)"));
+                       break;
+                               
                /* DHCP Message Type */
                case 53:
                        byte = pd[voff+2];
@@ -265,16 +288,19 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
                        /* We *MAY* use hwtype/hwaddr. If we have 7 bytes, I'll
                                guess that the first is the hwtype, and the last 6 are
                                the hw addr */
-                       if (pd[voff+1] == 7) {
+                       if (vlen == 7) {
                                vti = add_item_to_tree(GTK_WIDGET(bp_tree), voff,
                                        consumed, "Option %d: %s", code, text);
                                v_tree = gtk_tree_new();
                                add_subtree(vti, v_tree, ETT_BOOTP_OPTION);
                                add_item_to_tree(v_tree, voff+2, 1,
-                                       "Hardware type: 0x%02x", pd[voff+2]);
+                                       "Hardware type: %s",
+                                       arphrdtype_to_str(pd[voff+2],
+                                               "Unknown (0x%02x)"));
                                add_item_to_tree(v_tree, voff+3, 6,
                                        "Client hardware address: %s",
-                                       ether_to_str((guint8*)&pd[voff+3]));
+                                       arphrdaddr_to_str((guint8*)&pd[voff+3],
+                                               6, pd[voff+2]));
                        }
                        /* otherwise, it's opaque data */
                        else {
@@ -295,7 +321,6 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
        }
 
        /* Normal cases */
-       consumed = vlen + 2;
        if (code < NUM_OPT_INFOS) {
                text = opt[code].text;
                ftype = opt[code].ftype;
@@ -398,6 +423,15 @@ bootp_option(const u_char *pd, GtkWidget *bp_tree, int voff, int eoff)
                                }
                                break;
 
+                       case time_in_secs:
+                               time_secs = pntohl(&pd[voff+2]);
+                               add_item_to_tree(bp_tree, voff, consumed,
+                                       "Option %d: %s = %s", code, text,
+                                       ((time_secs == 0xffffffff) ?
+                                           "infinity" :
+                                           time_secs_to_str(time_secs)));
+                               break;
+
                        default:
                                add_item_to_tree(bp_tree, voff, consumed,
                                                "Option %d: %s (%d bytes)", code, text, vlen);
@@ -421,14 +455,13 @@ dissect_bootp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
                col_add_str(fd, COL_PROTOCOL, "BOOTP");
 
        if (check_col(fd, COL_INFO)) {
-               /* if hwaddr is 6 bytes, assume MAC */
-               if (pd[offset] == 1 && pd[offset+2] == 6) {
+               if (pd[offset] == 1) {
                        col_add_fstr(fd, COL_INFO, "Boot Request from %s",
-                               ether_to_str((guint8*)&pd[offset+28]));
+                               arphrdaddr_to_str((guint8*)&pd[offset+28],
+                                       pd[offset+2], pd[offset+1]));
                }
                else {
-                       col_add_str(fd, COL_INFO, pd[offset] == 1 ? "Boot Request" :
-                               "Boot Reply");
+                       col_add_str(fd, COL_INFO, "Boot Reply");
                }
        }
 
@@ -441,7 +474,8 @@ dissect_bootp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
                add_item_to_tree(bp_tree, offset, 1, pd[offset] == 1 ?
                        "Boot Request" : "Boot Reply");
                add_item_to_tree(bp_tree, offset + 1, 1,
-                       "Hardware type: 0x%02x", pd[offset+1]);
+                       "Hardware type: %s",
+                       arphrdtype_to_str(pd[offset+1], "Unknown (0x%02x)"));
                add_item_to_tree(bp_tree, offset + 2, 1,
                        "Hardware address length: %d", pd[offset+2]);
                add_item_to_tree(bp_tree, offset + 3, 1,
@@ -461,20 +495,10 @@ dissect_bootp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
                add_item_to_tree(bp_tree, offset + 24, 4,
                        "Relay agent IP address: %s", ip_to_str((guint8*)&pd[offset+24]));
 
-               /* If HW address is 6 bytes, assume MAC. */
-               if (pd[offset+2] == 6) {
-                       add_item_to_tree(bp_tree, offset + 28, 6,
-                               "Client hardware address: %s",
-                               ether_to_str((guint8*)&pd[offset+28]));
-               }
-               else {
-                       add_item_to_tree(bp_tree, offset + 28, 16,
-                               "Client hardware address: %02x:%02x%02x:%02x:%02x:%02x:%02x:%02x%02x:%02x%02x:%02x:%02x:%02x:%02x:%02x",
-                               pd[offset+28], pd[offset+29], pd[offset+30], pd[offset+31],
-                               pd[offset+32], pd[offset+33], pd[offset+34], pd[offset+35],
-                               pd[offset+36], pd[offset+37], pd[offset+38], pd[offset+39],
-                               pd[offset+40], pd[offset+41], pd[offset+42], pd[offset+43]);
-               }
+               add_item_to_tree(bp_tree, offset + 28, pd[offset+2],
+                       "Client hardware address: %s",
+                       arphrdaddr_to_str((guint8*)&pd[offset+28],
+                               pd[offset+2], pd[offset+1]));
 
                /* The server host name is optional */
                if (pd[offset+44]) {
@@ -496,10 +520,9 @@ dissect_bootp(const u_char *pd, int offset, frame_data *fd, GtkTree *tree)
                                "Boot file name not given");
                }
 
-               if (pntohl(&pd[offset+236]) ==  0x63538263) {
+               if (pntohl(&pd[offset+236]) == 0x63825363) {
                        add_item_to_tree(bp_tree, offset + 236, 4,
-                               "Magic cookie: %s (generic)",
-                                       ip_to_str((guint8*)&pd[offset+236]));
+                               "Magic cookie: (OK)");
                }
                else {
                        add_item_to_tree(bp_tree, offset + 236, 4,
index 9e14fdab3f08ec564932878434c70597844b0820..c1a3170febed81b159cd9b3e8c4492edf79a0a69 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-dns.c
  * Routines for DNS packet disassembly
  *
- * $Id: packet-dns.c,v 1.14 1999/01/05 09:01:42 guy Exp $
+ * $Id: packet-dns.c,v 1.15 1999/01/28 21:29:35 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -341,7 +341,8 @@ add_rr_to_tree(GtkWidget *trr, int rr_type, int offset, const char *name,
   offset += 2;
   add_item_to_tree(rr_tree, offset, 2, "Class: %s", class_name);
   offset += 2;
-  add_item_to_tree(rr_tree, offset, 4, "Time to live: %u", ttl);
+  add_item_to_tree(rr_tree, offset, 4, "Time to live: %s",
+                                               time_secs_to_str(ttl));
   offset += 4;
   add_item_to_tree(rr_tree, offset, 2, "Data length: %u", data_len);
   return rr_tree;
index c8dc74889152216026cf65e98eee97286ac9add7..efe9c29a578a3c0e56fddd2eb27a24b48796be9c 100644 (file)
--- a/packet.c
+++ b/packet.c
@@ -1,7 +1,7 @@
 /* packet.c
  * Routines for packet disassembly
  *
- * $Id: packet.c,v 1.18 1999/01/07 16:15:35 gram Exp $
+ * $Id: packet.c,v 1.19 1999/01/28 21:29:36 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -89,6 +89,56 @@ ip_to_str(const guint8 *ad) {
   return cur;
 }
 
+#define        PLURALIZE(n)    (((n) > 1) ? "s" : "")
+#define        COMMA(do_it)    ((do_it) ? ", " : "")
+
+gchar *
+time_secs_to_str(guint32 time)
+{
+  static gchar  str[3][8+1+4+2+2+5+2+2+7+2+2+7+1];
+  static gchar *cur, *p;
+  int hours, mins, secs;
+  int do_comma;
+
+  if (cur == &str[0][0]) {
+    cur = &str[1][0];
+  } else if (cur == &str[1][0]) {  
+    cur = &str[2][0];
+  } else {  
+    cur = &str[0][0];
+  }
+
+  secs = time % 60;
+  time /= 60;
+  mins = time % 60;
+  time /= 60;
+  hours = time % 24;
+  time /= 24;
+
+  p = cur;
+  if (time != 0) {
+    sprintf(p, "%u day%s", time, PLURALIZE(time));
+    p += strlen(p);
+    do_comma = 1;
+  } else
+    do_comma = 0;
+  if (hours != 0) {
+    sprintf(p, "%s%u hour%s", COMMA(do_comma), hours, PLURALIZE(hours));
+    p += strlen(p);
+    do_comma = 1;
+  } else
+    do_comma = 0;
+  if (mins != 0) {
+    sprintf(p, "%s%u minute%s", COMMA(do_comma), mins, PLURALIZE(mins));
+    p += strlen(p);
+    do_comma = 1;
+  } else
+    do_comma = 0;
+  if (secs != 0)
+    sprintf(p, "%s%u second%s", COMMA(do_comma), secs, PLURALIZE(secs));
+  return cur;
+}
+
 void
 packet_hex_print(GtkText *bv, guchar *pd, gint len, gint bstart, gint blen) {
   gint     i = 0, j, k, cur;
index ed67f6b4b4fbf2a3a051d1d671315d2deabe79fd..226d0878b756f3dc4cd7251f86ca1b293d5934cb 100644 (file)
--- a/packet.h
+++ b/packet.h
@@ -1,7 +1,7 @@
 /* packet.h
  * Definitions for packet disassembly structures and routines
  *
- * $Id: packet.h,v 1.33 1999/01/05 08:48:40 guy Exp $
+ * $Id: packet.h,v 1.34 1999/01/28 21:29:36 gram Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -498,6 +498,7 @@ void       dissect_ip_tcp_options(GtkWidget *, const u_char *, int, guint,
 /* Utility routines used by packet*.c */
 gchar*     ether_to_str(const guint8 *);
 gchar*     ip_to_str(const guint8 *);
+gchar*     time_secs_to_str(guint32);
 void       packet_hex_print(GtkText *, guint8 *, gint, gint, gint);
 #define E_TREEINFO_START_KEY "tree_info_start"
 #define E_TREEINFO_LEN_KEY   "tree_info_len"
@@ -585,4 +586,8 @@ void ethertype(guint16 etype, int offset,
                const u_char *pd, frame_data *fd, GtkTree *tree,
                GtkWidget *fh_tree);
 
+/* These functions are in packet-arp.c */
+gchar *arphrdaddr_to_str(guint8 *ad, int ad_len, guint16 type);
+gchar *arphrdtype_to_str(guint16 hwtype, const char *fmt);
+
 #endif /* packet.h */
index 8224051888cdf08600acbff3370b9ba9243d3a30..8aee168768f659b7022715b9f8351f5dad601db3 100644 (file)
@@ -574,9 +574,9 @@ va_list args;
           case 'o':  /* octal */
             STAR_ARGS(&data);
             if (data.a_long == FOUND)
-              d = va_arg(args, long);
+              d = va_arg(args, unsigned long);
             else
-              d = va_arg(args, int);
+              d = va_arg(args, unsigned int);
             octal(&data, d);
             state = 0;
             break;
@@ -584,9 +584,9 @@ va_list args;
           case 'X':  /* hexadecimal */
             STAR_ARGS(&data);
             if (data.a_long == FOUND)
-              d = va_arg(args, long);
+              d = va_arg(args, unsigned long);
             else
-              d = va_arg(args, int);
+              d = va_arg(args, unsigned int);
             hexa(&data, d);
             state = 0;
             break;