Ethereal-dev: [Ethereal-dev] bootp fixes

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Joerg Mayer <jmayer@xxxxxxxxx>
Date: Wed, 19 Jun 2002 18:53:13 +0200
see changelog
--
Joerg Mayer                                          <jmayer@xxxxxxxxx>
I found out that "pro" means "instead of" (as in proconsul). Now I know
what proactive means.
Changelog: <jmayer@xxxxxxxxx>
	packet-bootp.c:
	      - dissect the flags field properly (some tool
		sent a wrong bc-flag (0x0100 instead of 0x8000) and
		the only way to see this was in the hexdump.
	      - The existence of the bootp.vendor field is optional.
		Iff it's there and the magic is not the dhcp one,
		this field is exactly 64 byes long.
	epan/proto.c:
		Fix a typo in a comment.

Index: ethereal/packet-bootp.c
===================================================================
RCS file: /cvsroot/ethereal/packet-bootp.c,v
retrieving revision 1.64
diff -u -r1.64 packet-bootp.c
--- packet-bootp.c	2002/05/28 20:08:09	1.64
+++ packet-bootp.c	2002/06/19 16:44:46
@@ -57,6 +57,8 @@
 static int hf_bootp_id = -1;
 static int hf_bootp_secs = -1;
 static int hf_bootp_flag = -1;
+static int hf_bootp_flag_broadcast = -1;
+static int hf_bootp_flag_reserved = -1;
 static int hf_bootp_ip_client = -1;
 static int hf_bootp_ip_your = -1;
 static int hf_bootp_ip_server = -1;
@@ -65,14 +67,19 @@
 static int hf_bootp_server = -1;
 static int hf_bootp_file = -1;
 static int hf_bootp_cookie = -1;
+static int hf_bootp_vendor = -1;
 static int hf_bootp_dhcp = -1;
 
 static guint ett_bootp = -1;
+static guint ett_bootp_flag = -1;
 static guint ett_bootp_option = -1;
 
 #define UDP_PORT_BOOTPS  67
 #define UDP_PORT_BOOTPC  68
 
+#define BOOTP_BC	0x8000
+#define BOOTP_MBZ	0x7FFF
+
 enum field_type { none, ipv4, string, toggle, yes_no, special, opaque,
 	time_in_secs,
 	val_u_byte, val_u_short, val_u_le_short, val_u_long,
@@ -83,6 +90,11 @@
 	enum field_type ftype;
 };
 
+static const true_false_string flag_set_broadcast = {
+  "Broadcast",
+  "Unicast"
+};
+
 #define NUM_OPT_INFOS 211
 #define NUM_O63_SUBOPTS 11
 
@@ -1085,6 +1097,8 @@
 dissect_bootp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 {
 	proto_tree	*bp_tree = NULL;
+	proto_tree	*flag_tree = NULL;
+	proto_tree	*ftree = NULL;
 	proto_item	*ti;
 	guint8		op;
 	guint8		htype, hlen;
@@ -1094,6 +1108,7 @@
 	gboolean	at_end;
 	const char	*dhcp_type = NULL;
 	const guint8	*vendor_class_id = NULL;
+	guint16		flag;
 
 	if (check_col(pinfo->cinfo, COL_PROTOCOL))
 		col_set_str(pinfo->cinfo, COL_PROTOCOL, "BOOTP");
@@ -1127,6 +1142,9 @@
 		}
 	}
 
+	voff = 236;
+	eoff = tvb_reported_length(tvb);
+
 	if (tree) {
 		ti = proto_tree_add_item(tree, proto_bootp, tvb, 0, -1, FALSE);
 		bp_tree = proto_item_add_subtree(ti, ett_bootp);
@@ -1148,9 +1166,14 @@
 				    4, 4, FALSE);
 		proto_tree_add_item(bp_tree, hf_bootp_secs, tvb,
 				    8, 2, FALSE);
-		proto_tree_add_uint(bp_tree, hf_bootp_flag, tvb,
-				    10, 2, tvb_get_ntohs(tvb, 10) & 0x8000);
-
+		flag = tvb_get_ntohs(tvb, 10);
+		ftree = proto_tree_add_uint(bp_tree, hf_bootp_flag, tvb,
+				    10, 2, flag);
+    		flag_tree = proto_item_add_subtree(ftree, ett_bootp_flag);
+		proto_tree_add_boolean(flag_tree, hf_bootp_flag_broadcast, tvb,
+				    10, 2, (flag & BOOTP_BC) >> 15);
+		proto_tree_add_uint(flag_tree, hf_bootp_flag_reserved, tvb,
+				    10, 2, flag & BOOTP_MBZ);
 		proto_tree_add_item(bp_tree, hf_bootp_ip_client, tvb, 
 				    12, 4, FALSE);
 		proto_tree_add_item(bp_tree, hf_bootp_ip_your, tvb, 
@@ -1199,21 +1222,23 @@
 						   "Boot file name not given");
 		}
 
-		tvb_memcpy(tvb, (void *)&ip_addr, 236, sizeof(ip_addr));
-		if (tvb_get_ntohl(tvb, 236) == 0x63825363) {
-			proto_tree_add_ipv4_format(bp_tree, hf_bootp_cookie, tvb,
+		/* rfc2123 says it SHOULD exist */
+		if (tvb_bytes_exist(tvb, 236, 4)) {
+			tvb_memcpy(tvb, (void *)&ip_addr, 236, sizeof(ip_addr));
+			if (tvb_get_ntohl(tvb, 236) == 0x63825363) {
+				proto_tree_add_ipv4_format(bp_tree, hf_bootp_cookie, tvb,
 					    236, 4, ip_addr,
 					    "Magic cookie: (OK)");
-		}
-		else {
-			proto_tree_add_ipv4(bp_tree, hf_bootp_cookie, tvb,
-					    236, 4, ip_addr);
+				voff += 4;
+			}
+			else {
+				proto_tree_add_text(bp_tree,  tvb,
+						236, 64, "Bootp vendor specific options");
+				voff += 64;
+			}
 		}
 	}
 
-	voff = 240;
-	eoff = tvb_reported_length(tvb);
-
 	/*
 	 * In the first pass, we just look for the DHCP message type
 	 * and Vendor class identifier options.
@@ -1307,10 +1332,20 @@
       	"", HFILL }},
 
     { &hf_bootp_flag,
-      { "Broadcast flag",	       	"bootp.flag",    FT_UINT16,
+      { "Bootp flags flag",	       	"bootp.flag",    FT_UINT16,
         BASE_HEX,			NULL,		 0x0,
       	"", HFILL }},
 
+    { &hf_bootp_flag_broadcast,
+      { "Broadcast flag",	       	"bootp.flag.bc",    FT_BOOLEAN,
+        1,			TFS(&flag_set_broadcast),      BOOTP_BC >> 15,
+      	"", HFILL }},
+
+    { &hf_bootp_flag_reserved,
+      { "Reserved flags",	       	"bootp.flag.reserved",    FT_UINT16,
+        BASE_HEX,			NULL,		0x0,
+      	"", HFILL }},
+
     { &hf_bootp_ip_client,
       { "Client IP address",	       	"bootp.ip.client",FT_IPv4,
         BASE_NONE,			NULL,		  0x0,
@@ -1350,9 +1385,15 @@
       { "Magic cookie",			"bootp.cookie",	 FT_IPv4,
          BASE_NONE,			NULL,		 0x0,
       	"", HFILL }},
+
+    { &hf_bootp_vendor,
+      { "Bootp Vendoroptions",		"bootp.vendor", FT_BYTES,
+        BASE_NONE,			NULL,		 0x0,
+      	"", HFILL }},
   };
   static gint *ett[] = {
     &ett_bootp,
+    &ett_bootp_flag,
     &ett_bootp_option,
   };
   
Index: ethereal/epan/proto.c
===================================================================
RCS file: /cvsroot/ethereal/epan/proto.c,v
retrieving revision 1.69
diff -u -r1.69 proto.c
--- proto.c	2002/05/14 10:15:10	1.69
+++ proto.c	2002/06/19 16:44:48
@@ -2175,7 +2175,7 @@
 	default:
 		break;
 	}
-	/* if this is a bitfield, compure bitshift */
+	/* if this is a bitfield, compute bitshift */
 	if (hfinfo->bitmask) {
 		while ((hfinfo->bitmask & (1 << hfinfo->bitshift)) == 0)
 			hfinfo->bitshift++;