aboutsummaryrefslogtreecommitdiffstats
path: root/packet-bootp.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2004-05-07 08:02:23 +0000
committerGuy Harris <guy@alum.mit.edu>2004-05-07 08:02:23 +0000
commit7cb69aab559c84802fd1dd7c511dd4f49eafbdb8 (patch)
treeffaea34e5682d39e95857254a5dec7e0215986f6 /packet-bootp.c
parent461fd185f033d73687f4fcef7a545ba3b007afe3 (diff)
downloadwireshark-7cb69aab559c84802fd1dd7c511dd4f49eafbdb8.tar.gz
wireshark-7cb69aab559c84802fd1dd7c511dd4f49eafbdb8.tar.bz2
wireshark-7cb69aab559c84802fd1dd7c511dd4f49eafbdb8.zip
From Thomas Anders:
- support vendor-specific DHCP option 43 interpretation per CableLabs standards (for compliant cable devices, identified by option 60) - support DHCP option 122 with all suboptions (RFC 3495: CableLabs Client Configuration; RFC 3594: PacketCable Security Ticket Control) - update DHCP options list: add options 117-122 (see http://www.iana.org/assignments/bootp-dhcp-parameters) - minor enhancements for DHCP options 2, 82 - minor code cleanup svn path=/trunk/; revision=10809
Diffstat (limited to 'packet-bootp.c')
-rw-r--r--packet-bootp.c285
1 files changed, 262 insertions, 23 deletions
diff --git a/packet-bootp.c b/packet-bootp.c
index a00853ba44..b6294d3310 100644
--- a/packet-bootp.c
+++ b/packet-bootp.c
@@ -1,8 +1,9 @@
/* packet-bootp.c
* Routines for BOOTP/DHCP packet disassembly
- * Gilbert Ramirez <gram@alumni.rice.edu>
+ * Copyright 1998, Gilbert Ramirez <gram@alumni.rice.edu>
+ * Copyright 2004, Thomas Anders <thomas.anders [AT] blue-cable.de>
*
- * $Id: packet-bootp.c,v 1.77 2003/12/03 20:01:20 guy Exp $
+ * $Id: packet-bootp.c,v 1.78 2004/05/07 08:02:22 guy Exp $
*
* The information used comes from:
* RFC 951: Bootstrap Protocol
@@ -15,6 +16,8 @@
* RFC 3046: DHCP Relay Agent Information Option
* RFC 3118: Authentication for DHCP Messages
* RFC 3203: DHCP reconfigure extension
+ * RFC 3495: DHCP Option (122) for CableLabs Client Configuration
+ * RFC 3594: PacketCable Security Ticket Control Sub-Option (122.9)
* BOOTP and DHCP Parameters
* http://www.iana.org/assignments/bootp-dhcp-parameters
*
@@ -46,6 +49,7 @@
#include <epan/int-64bit.h>
#include <epan/packet.h>
#include "packet-arp.h"
+#include "packet-dns.h" /* for get_dns_name() */
#include "prefs.h"
#include "tap.h"
@@ -84,10 +88,12 @@ gboolean novell_string = FALSE;
#define BOOTP_BC 0x8000
#define BOOTP_MBZ 0x7FFF
+#define PLURALIZE(n) (((n) > 1) ? "s" : "")
+
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,
- val_s_long };
+ val_s_long, fqdn, ipv4_or_fqdn };
struct opt_info {
char *text;
@@ -99,11 +105,13 @@ static const true_false_string flag_set_broadcast = {
"Unicast"
};
-#define NUM_OPT_INFOS 211
-#define NUM_O63_SUBOPTS 11
static int dissect_vendor_pxeclient_suboption(proto_tree *v_tree, tvbuff_t *tvb,
int optp);
+static int dissect_vendor_cablelabs_suboption(proto_tree *v_tree, tvbuff_t *tvb,
+ int optp);
+static int dissect_cablelabs_clientconfig_suboption(proto_tree *v_tree, tvbuff_t *tvb,
+ int optp);
static int dissect_netware_ip_suboption(proto_tree *v_tree, tvbuff_t *tvb,
int optp);
static int bootp_dhcp_decode_agent_info(proto_tree *v_tree, tvbuff_t *tvb,
@@ -216,7 +224,7 @@ bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
static struct opt_info opt[] = {
/* 0 */ { "Padding", none },
/* 1 */ { "Subnet Mask", ipv4 },
- /* 2 */ { "Time Offset", val_s_long },
+ /* 2 */ { "Time Offset", time_in_secs },
/* 3 */ { "Router", ipv4 },
/* 4 */ { "Time Server", ipv4 },
/* 5 */ { "Name Server", ipv4 },
@@ -331,12 +339,12 @@ bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
/* 114 */ { "URL", opaque },
/* 115 */ { "DHCP Failover Protocol", opaque },
/* 116 */ { "DHCP Auto-Configuration", opaque },
- /* 117 */ { "Unassigned", opaque },
- /* 118 */ { "Unassigned", opaque },
- /* 119 */ { "Unassigned", opaque },
- /* 120 */ { "Unassigned", opaque },
- /* 121 */ { "Unassigned", opaque },
- /* 122 */ { "Unassigned", opaque },
+ /* 117 */ { "Name Service Search", opaque },
+ /* 118 */ { "Subnet Selection Option", opaque },
+ /* 119 */ { "Domain Search", opaque },
+ /* 120 */ { "SIP Servers", opaque },
+ /* 121 */ { "Classless Static Route", opaque },
+ /* 122 */ { "CableLabs Client Configuration", special },
/* 123 */ { "Unassigned", opaque },
/* 124 */ { "Unassigned", opaque },
/* 125 */ { "Unassigned", opaque },
@@ -588,6 +596,20 @@ bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
optp = dissect_vendor_pxeclient_suboption(v_tree,
tvb, optp);
}
+ } else if (*vendor_class_id_p != NULL &&
+ ((strncmp(*vendor_class_id_p, "pktc", strlen("pktc")) == 0) ||
+ (strncmp(*vendor_class_id_p, "docsis", strlen("docsis")) == 0) ||
+ (strncmp(*vendor_class_id_p, "CableHome", strlen("CableHome")) == 0))) {
+ /* CableLabs standard - see www.cablelabs.com/projects */
+ vti = proto_tree_add_text(bp_tree, tvb, voff,
+ consumed, "Option %d: %s (CableLabs)", code, text);
+ v_tree = proto_item_add_subtree(vti, ett_bootp_option);
+
+ optp = voff+2;
+ while (optp < voff+consumed) {
+ optp = dissect_vendor_cablelabs_suboption(v_tree,
+ tvb, optp);
+ }
} else {
proto_tree_add_text(bp_tree, tvb, voff, consumed,
"Option %d: %s (%d bytes)", code, text, vlen);
@@ -658,7 +680,7 @@ bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
v_tree = proto_item_add_subtree(vti, ett_bootp_option);
for (i = 0; i < vlen; i++) {
byte = tvb_get_guint8(tvb, voff+2+i);
- if (byte < NUM_OPT_INFOS) {
+ if (byte < array_length(opt)) {
proto_tree_add_text(v_tree, tvb, voff+2+i, 1, "%d = %s",
byte, opt[byte].text);
} else {
@@ -781,6 +803,16 @@ bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
}
break;
+ case 122: /* CableLabs Client Configuration */
+ vti = proto_tree_add_text(bp_tree, tvb, voff,
+ vlen + 2, "Option %d: %s", code, text);
+ v_tree = proto_item_add_subtree(vti, ett_bootp_option);
+ optp = voff+2;
+ while (optp < voff+consumed) {
+ optp = dissect_cablelabs_clientconfig_suboption(v_tree, tvb, optp);
+ }
+ break;
+
case 90: /* DHCP Authentication */
case 210: /* Was this used for authentication at one time? */
vti = proto_tree_add_text(bp_tree, tvb, voff,
@@ -864,7 +896,7 @@ bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
}
/* Normal cases */
- if (code < NUM_OPT_INFOS) {
+ if (code < array_length(opt)) {
text = opt[code].text;
ftype = opt[code].ftype;
@@ -994,15 +1026,18 @@ bootp_dhcp_decode_agent_info(proto_tree *v_tree, tvbuff_t *tvb, int optp)
switch (subopt) {
case 1:
proto_tree_add_text(v_tree, tvb, optp, subopt_len + 2,
- "Agent Circuit ID (%d bytes)", subopt_len);
+ "Agent Circuit ID: %s",
+ tvb_bytes_to_str(tvb, optp+2, subopt_len));
break;
case 2:
proto_tree_add_text(v_tree, tvb, optp, subopt_len + 2,
- "Agent Remote ID (%d bytes)", subopt_len);
+ "Agent Remote ID: %s",
+ tvb_bytes_to_str(tvb, optp+2, subopt_len));
break;
default:
proto_tree_add_text(v_tree, tvb, optp, subopt_len + 2,
- "Unknown agent option: %d", subopt);
+ "Invalid agent suboption %d (%d bytes)",
+ subopt, subopt_len);
break;
}
optp += (subopt_len + 2);
@@ -1046,7 +1081,6 @@ dissect_vendor_pxeclient_suboption(proto_tree *v_tree, tvbuff_t *tvb, int optp)
/* 71 {"PXE boot item", special} */
/* 255 {"PXE end options", special} */
};
-#define NUM_O43PXECLIENT_SUBOPTS (12)
subopt = tvb_get_guint8(tvb, optp);
@@ -1067,11 +1101,11 @@ dissect_vendor_pxeclient_suboption(proto_tree *v_tree, tvbuff_t *tvb, int optp)
proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
"Suboption %d: %s (%d byte%s)" ,
subopt, "PXE boot item",
- subopt_len, (subopt_len != 1)?"s":"");
- } else if ( (subopt < 1 ) || (subopt > NUM_O43PXECLIENT_SUBOPTS) ) {
+ subopt_len, PLURALIZE(subopt_len));
+ } else if ((subopt < 1 ) || (subopt > array_length(o43pxeclient_opt))) {
proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
"Unknown suboption %d (%d byte%s)", subopt, subopt_len,
- (subopt_len != 1)?"s":"");
+ PLURALIZE(subopt_len));
} else {
switch (o43pxeclient_opt[subopt].ft) {
@@ -1085,7 +1119,7 @@ dissect_vendor_pxeclient_suboption(proto_tree *v_tree, tvbuff_t *tvb, int optp)
proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
"Suboption %d: %s (%d byte%s)" ,
subopt, o43pxeclient_opt[subopt].text,
- subopt_len, (subopt_len != 1)?"s":"");
+ subopt_len, PLURALIZE(subopt_len));
break;
case val_u_le_short:
@@ -1129,6 +1163,104 @@ dissect_vendor_pxeclient_suboption(proto_tree *v_tree, tvbuff_t *tvb, int optp)
}
static int
+dissect_vendor_cablelabs_suboption(proto_tree *v_tree, tvbuff_t *tvb, int optp)
+{
+ guint8 subopt;
+ guint8 subopt_len;
+
+ struct o43cablelabs_opt_info {
+ char *text;
+ enum field_type ft;
+ };
+
+ static struct o43cablelabs_opt_info o43cablelabs_opt[]= {
+ /* 0 */ {"nop", special}, /* dummy */
+ /* 1 */ {"Suboption Request List", string},
+ /* 2 */ {"Device Type", string},
+ /* 3 */ {"eSAFE Types", string},
+ /* 4 */ {"Serial Number", string},
+ /* 5 */ {"Hardware Version", string},
+ /* 6 */ {"Software Version", string},
+ /* 7 */ {"Boot ROM version", string},
+ /* 8 */ {"Organizational Unique Identifier", string},
+ /* 9 */ {"Model Number", string},
+ /* 10 */ {"Vendor Name", string},
+ /* *** 11-30: CableHome *** */
+ /* 11 */ {"PS WAN-Man", special},
+ /* 12 */ {"CM/PS System Description", string},
+ /* 13 */ {"CM/PS Firmware Revision", string},
+ /* 14 */ {"Firewall Policy File Version", string},
+ /* 15 */ {"Unassigned (CableHome)", special},
+ /* 16 */ {"Unassigned (CableHome)", special},
+ /* 17 */ {"Unassigned (CableHome)", special},
+ /* 18 */ {"Unassigned (CableHome)", special},
+ /* 19 */ {"Unassigned (CableHome)", special},
+ /* 20 */ {"Unassigned (CableHome)", special},
+ /* 21 */ {"Unassigned (CableHome)", special},
+ /* 22 */ {"Unassigned (CableHome)", special},
+ /* 23 */ {"Unassigned (CableHome)", special},
+ /* 24 */ {"Unassigned (CableHome)", special},
+ /* 25 */ {"Unassigned (CableHome)", special},
+ /* 26 */ {"Unassigned (CableHome)", special},
+ /* 27 */ {"Unassigned (CableHome)", special},
+ /* 28 */ {"Unassigned (CableHome)", special},
+ /* 29 */ {"Unassigned (CableHome)", special},
+ /* 30 */ {"Unassigned (CableHome)", special},
+ /* *** 31-50: PacketCable *** */
+ /* 31 */ {"MTA MAC Address", string},
+ /* 32 */ {"Correlation ID", string},
+ /* 33-50 {"Unassigned (PacketCable)", special}, */
+ /* *** 51-127: CableLabs *** */
+ /* 51-127 {"Unassigned (CableLabs)", special}, */
+ /* *** 128-254: Vendors *** */
+ /* 128-254 {"Unassigned (Vendors)", special}, */
+ /* 255 {"end options", special} */
+ };
+
+ subopt = tvb_get_guint8(tvb, optp);
+
+ if (subopt == 0 ) {
+ proto_tree_add_text(v_tree, tvb, optp, 1, "Padding");
+ return (optp+1);
+ } else if (subopt == 255) { /* End Option */
+ proto_tree_add_text(v_tree, tvb, optp, 1, "End option");
+ /* Make sure we skip any junk left this option */
+ return (optp+255);
+ }
+
+ subopt_len = tvb_get_guint8(tvb, optp+1);
+
+ if ( (subopt < 1 ) || (subopt > array_length(o43cablelabs_opt)) ) {
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: Unassigned (%d byte%s)", subopt, subopt_len,
+ PLURALIZE(subopt_len));
+ } else {
+ switch (o43cablelabs_opt[subopt].ft) {
+
+ case string:
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: %s = \"%.*s\"", subopt,
+ o43cablelabs_opt[subopt].text, subopt_len,
+ tvb_get_ptr(tvb, optp+2, subopt_len));
+ break;
+
+ case special:
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: %s (%d byte%s)" ,
+ subopt, o43cablelabs_opt[subopt].text,
+ subopt_len, PLURALIZE(subopt_len));
+ break;
+
+ default:
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,"ERROR, please report: Unknown subopt type handler %d", subopt);
+ break;
+ }
+ }
+ optp += (subopt_len + 2);
+ return optp;
+}
+
+static int
dissect_netware_ip_suboption(proto_tree *v_tree, tvbuff_t *tvb, int optp)
{
guint8 subopt;
@@ -1159,7 +1291,7 @@ dissect_netware_ip_suboption(proto_tree *v_tree, tvbuff_t *tvb, int optp)
};
subopt = tvb_get_guint8(tvb, optp);
- if (subopt > NUM_O63_SUBOPTS) {
+ if (subopt > array_length(o63_opt)) {
proto_tree_add_text(v_tree, tvb,optp,1,"Unknown suboption %d", subopt);
optp++;
} else {
@@ -1225,6 +1357,113 @@ dissect_netware_ip_suboption(proto_tree *v_tree, tvbuff_t *tvb, int optp)
return optp;
}
+static int
+dissect_cablelabs_clientconfig_suboption(proto_tree *v_tree, tvbuff_t *tvb, int optp)
+{
+ guint8 subopt;
+ guint8 subopt_len;
+ guint8 flag;
+ char dname[MAXDNAME];
+ int dname_len;
+
+ struct o122cablelabs_opt_info {
+ char *text;
+ enum field_type ft;
+ };
+
+ static struct o122cablelabs_opt_info o122cablelabs_opt[]= {
+ /* 0 */ {"nop", special}, /* dummy */
+ /* 1 */ {"TSP's Primary DHCP Server Address", ipv4},
+ /* 2 */ {"TSP's Secondary DHCP Server Address", ipv4},
+ /* 3 */ {"TSP's Provisioning Server Address", ipv4_or_fqdn},
+ /* 4 */ {"TSP's AS-REQ/AS-REP Backoff and Retry", special},
+ /* 5 */ {"TSP's AP-REQ/AP-REP Backoff and Retry", special},
+ /* 6 */ {"TSP's Kerberos Realm Name", fqdn},
+ /* 7 */ {"TSP's Ticket Granting Server Utilization", special},
+ /* 8 */ {"TSP's Provisioning Timer Value", special},
+ /* 9 */ {"PacketCable Security Ticket Control", special},
+ /* *** 10-255: Reserved for future use *** */
+ };
+
+ subopt = tvb_get_guint8(tvb, optp);
+ subopt_len = tvb_get_guint8(tvb, optp+1);
+
+ if ((subopt < 1 ) || (subopt > array_length(o122cablelabs_opt))) {
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: Unassigned (%d byte%s)", subopt, subopt_len,
+ PLURALIZE(subopt_len));
+ } else {
+ switch (o122cablelabs_opt[subopt].ft) {
+
+ case string:
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: %s = \"%.*s\"", subopt,
+ o122cablelabs_opt[subopt].text, subopt_len,
+ tvb_get_ptr(tvb, optp+2, subopt_len));
+ break;
+
+ case special:
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: %s (%d byte%s)" ,
+ subopt, o122cablelabs_opt[subopt].text,
+ subopt_len, PLURALIZE(subopt_len));
+ break;
+ case ipv4:
+ proto_tree_add_text(v_tree, tvb, optp, 6,
+ "Suboption %d: %s = %s",
+ subopt, o122cablelabs_opt[subopt].text,
+ ip_to_str(tvb_get_ptr(tvb, optp+2, 4)));
+ break;
+ case fqdn:
+ dname_len = get_dns_name(tvb, optp+2, optp+2, dname, sizeof(dname));
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: %s = %.*s", subopt,
+ o122cablelabs_opt[subopt].text,
+ dname_len, dname);
+ break;
+ case ipv4_or_fqdn:
+ flag = tvb_get_guint8(tvb, optp+2);
+ if (flag == 0) { /* FQDN */
+ dname_len = get_dns_name(tvb, optp+3, optp+3, dname, sizeof(dname));
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: %s = %.*s", subopt,
+ o122cablelabs_opt[subopt].text,
+ dname_len, dname);
+ } else if (flag == 1) { /* IPv4 */
+ proto_tree_add_text(v_tree, tvb, optp, 6,
+ "Suboption %d: %s = %s",
+ subopt, o122cablelabs_opt[subopt].text,
+ ip_to_str(tvb_get_ptr(tvb, optp+3, 4)));
+ } else {
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: %s = Invalid Value (%d byte%s)",
+ subopt, o122cablelabs_opt[subopt].text,
+ subopt_len, PLURALIZE(subopt_len));
+ }
+ break;
+ case yes_no:
+ flag = tvb_get_guint8(tvb, optp+2);
+ if (flag == 0 || flag == 1) {
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: %s = %s", subopt,
+ o122cablelabs_opt[subopt].text,
+ flag == 0 ? "No" : "Yes");
+ } else {
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,
+ "Suboption %d: %s = Invalid Value %d",
+ subopt, o122cablelabs_opt[subopt].text, flag);
+ }
+ break;
+ default:
+ proto_tree_add_text(v_tree, tvb, optp, subopt_len+2,"ERROR, please report: Unknown subopt type handler %d", subopt);
+ break;
+ }
+ }
+ optp += (subopt_len + 2);
+ return optp;
+}
+
+
#define BOOTREQUEST 1
#define BOOTREPLY 2