aboutsummaryrefslogtreecommitdiffstats
path: root/packet-bootp.c
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2002-09-28 04:12:38 +0000
committerGerald Combs <gerald@wireshark.org>2002-09-28 04:12:38 +0000
commit7928808681d5cd5d42b75bfe0bf2200d11c892e1 (patch)
treedcef9e3efba3414af306e1ea76b0039332ce3cc4 /packet-bootp.c
parentc2bb2c8d5250d51cfafad59ba00be262bc07aa28 (diff)
Decode DHCP option 52 (Option Overload). Decode the options embedded
in the sname and file options as needed. Thanks to Tedd Frechette for the sample capture. svn path=/trunk/; revision=6345
Diffstat (limited to 'packet-bootp.c')
-rw-r--r--packet-bootp.c87
1 files changed, 78 insertions, 9 deletions
diff --git a/packet-bootp.c b/packet-bootp.c
index 22ef4ef0b7..3c3edf55a5 100644
--- a/packet-bootp.c
+++ b/packet-bootp.c
@@ -2,7 +2,7 @@
* Routines for BOOTP/DHCP packet disassembly
* Gilbert Ramirez <gram@alumni.rice.edu>
*
- * $Id: packet-bootp.c,v 1.70 2002/08/28 21:00:08 jmayer Exp $
+ * $Id: packet-bootp.c,v 1.71 2002/09/28 04:12:38 gerald Exp $
*
* The information used comes from:
* RFC 951: Bootstrap Protocol
@@ -134,6 +134,18 @@ get_dhcp_type(guint8 byte)
/* DHCP Authentication Replay Detection Methods */
#define AUTHEN_RDM_MONOTONIC_COUNTER 0x00
+/* DHCP Option Overload (option code 52) */
+#define OPT_OVERLOAD_FILE 1
+#define OPT_OVERLOAD_SNAME 2
+#define OPT_OVERLOAD_BOTH 3
+
+/* Server name and boot file offsets and lengths */
+#define SERVER_NAME_OFFSET 44
+#define SERVER_NAME_LEN 64
+#define FILE_NAME_OFFSET 108
+#define FILE_NAME_LEN 128
+#define VENDOR_INFO_OFFSET 236
+
/* Returns the number of bytes consumed by this option. */
static int
bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
@@ -147,11 +159,13 @@ bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
guchar byte;
int i,optp, consumed;
gulong time_secs;
- proto_tree *v_tree;
+ proto_tree *v_tree, *o52tree;
proto_item *vti;
guint8 protocol;
guint8 algorithm;
guint8 rdm;
+ int o52voff, o52eoff;
+ gboolean o52at_end;
static const value_string nbnt_vals[] = {
{0x1, "B-node" },
@@ -173,6 +187,12 @@ bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
{AUTHEN_RDM_MONOTONIC_COUNTER, "Monotonically-increasing counter" },
{0, NULL } };
+ static const value_string opt_overload_vals[] = {
+ { OPT_OVERLOAD_FILE, "Boot file name holds options", },
+ { OPT_OVERLOAD_SNAME, "Server host name holds options", },
+ { OPT_OVERLOAD_BOTH, "Boot file and server host names hold options" },
+ { 0, NULL } };
+
static struct opt_info opt[] = {
/* 0 */ { "Padding", none },
/* 1 */ { "Subnet Mask", ipv4 },
@@ -562,6 +582,51 @@ bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
"Unknown (0x%02x)"));
break;
+ case 52: /* Option Overload */
+ byte = tvb_get_guint8(tvb, voff+2);
+ vti = proto_tree_add_text(bp_tree, tvb, voff, consumed,
+ "Option %d: %s = %s", code, text,
+ val_to_str(byte, opt_overload_vals,
+ "Unknown (0x%02x)"));
+
+ /* Just in case we find an option 52 in sname or file */
+ if (voff > VENDOR_INFO_OFFSET && byte >= 1 && byte <= 3) {
+ o52tree = proto_item_add_subtree(vti, ett_bootp_option);
+ if (byte == 1 || byte == 3) { /* 'file' */
+ vti = proto_tree_add_text (o52tree, tvb,
+ FILE_NAME_OFFSET, FILE_NAME_LEN,
+ "Boot file name option overload");
+ v_tree = proto_item_add_subtree(vti, ett_bootp_option);
+ o52voff = FILE_NAME_OFFSET;
+ o52eoff = FILE_NAME_OFFSET + FILE_NAME_LEN;
+ o52at_end = FALSE;
+ while (o52voff < o52eoff && !o52at_end) {
+ o52voff += bootp_option(tvb, v_tree, o52voff,
+ o52eoff, FALSE, &o52at_end,
+ dhcp_type_p, vendor_class_id_p);
+ }
+ }
+ if (byte == 2 || byte == 3) { /* 'sname' */
+ vti = proto_tree_add_text (o52tree, tvb,
+ SERVER_NAME_OFFSET, SERVER_NAME_LEN,
+ "Server host name option overload");
+ v_tree = proto_item_add_subtree(vti, ett_bootp_option);
+ o52voff = SERVER_NAME_OFFSET;
+ o52eoff = SERVER_NAME_OFFSET + SERVER_NAME_LEN;
+ o52at_end = FALSE;
+ while (o52voff < o52eoff && !o52at_end) {
+ o52voff += bootp_option(tvb, v_tree, o52voff,
+ o52eoff, FALSE, &o52at_end,
+ dhcp_type_p, vendor_class_id_p);
+ }
+ }
+ }
+
+/* protocol = tvb_get_guint8(tvb, voff+2);
+ proto_tree_add_text(v_tree, tvb, voff+2, 1, "Protocol: %s (%u)",
+ val_to_str(protocol, authen_protocol_vals, "Unknown"),
+ protocol); */
+ break;
case 53: /* DHCP Message Type */
proto_tree_add_text(bp_tree, tvb, voff, 3, "Option %d: %s = DHCP %s",
code, text, get_dhcp_type(tvb_get_guint8(tvb, voff+2)));
@@ -1196,29 +1261,33 @@ dissect_bootp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* The server host name is optional */
if (tvb_get_guint8(tvb, 44) != '\0') {
proto_tree_add_item(bp_tree, hf_bootp_server, tvb,
- 44, 64, FALSE);
+ SERVER_NAME_OFFSET,
+ SERVER_NAME_LEN, FALSE);
}
else {
proto_tree_add_string_format(bp_tree, hf_bootp_server, tvb,
- 44, 64,
- tvb_get_ptr(tvb, 44, 1),
+ SERVER_NAME_OFFSET,
+ SERVER_NAME_LEN,
+ tvb_get_ptr(tvb, SERVER_NAME_OFFSET, 1),
"Server host name not given");
}
/* Boot file */
if (tvb_get_guint8(tvb, 108) != '\0') {
proto_tree_add_item(bp_tree, hf_bootp_file, tvb,
- 108, 128, FALSE);
+ FILE_NAME_OFFSET,
+ FILE_NAME_LEN, FALSE);
}
else {
proto_tree_add_string_format(bp_tree, hf_bootp_file, tvb,
- 108, 128,
- tvb_get_ptr(tvb, 108, 1),
+ FILE_NAME_OFFSET,
+ FILE_NAME_LEN,
+ tvb_get_ptr(tvb, FILE_NAME_OFFSET, 1),
"Boot file name not given");
}
}
- voff = 236;
+ voff = VENDOR_INFO_OFFSET;
/* rfc2132 says it SHOULD exist, not that it MUST exist */
if (tvb_bytes_exist(tvb, voff, 4)) {