diff options
author | Darius Davis <darius@vmware.com> | 2018-11-03 16:09:54 +1000 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-11-05 08:43:27 +0000 |
commit | 83a71674a1c3edaa098934d81de1cf2052c2b740 (patch) | |
tree | bc88e5425e996fbb2de9701cbfd4299ab4f968c0 | |
parent | 0a5770a78a82147142bb7e2ead914eef1b254724 (diff) |
DHCP: Handle proxyDHCP on UDP port 4011.
Proxy DHCP (proxyDHCP) is described in the PXE specification ver 2.1 (section
2.2.3) as a mechanism to allow a PXE client to query a separate service,
listening on port 4011, to obtain boot file information. Other than the UDP
port number used, the protocol is identical to regular DHCP.
This change implements support for dissecting proxyDHCP packets.
The change expands the default pref value for the DHCP/BOOTP UDP ports list to
include port 4011, and if the dissector receives a packet for port 4011 which
passes a rough heuristic (the DHCP magic number is mandatory for proxyDHCP --
there is no such thing as BOOTP-only proxyDHCP), the packet passes through to
the regular DHCP dissector.
There's currently no separate preference to allow configuration of the expected
proxyDHCP port number... This seems reasonable, since the port number 4011 is
stipulated in the PXE specification, and variations would seem unlikely.
Testing Done: Opened a capture file containing a DHCP conversation using
proxyDHCP, and saw the traffic on UDP port 4011 was now decoded as DHCP and
reported as "proxyDHCP", instead of being generic UDP. Regular DHCP traffic
in the same capture file is still decoded as it was before. Produced some
deliberately malformed requests (bad magic number) and tweaked the
DHCP/BOOTP port list in prefs, and saw the expected behavior in each case.
20,000 iterations of fuzz-test.sh with a small corpus of captures from
PXE-booting systems.
Change-Id: Ifd485cd75834a51bdfd6f3ba3fe517c4a892d9d0
Reviewed-on: https://code.wireshark.org/review/30498
Petri-Dish: Anders Broman <a.broman58@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
-rw-r--r-- | epan/dissectors/packet-dhcp.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/epan/dissectors/packet-dhcp.c b/epan/dissectors/packet-dhcp.c index 987a4296dc..71052d90aa 100644 --- a/epan/dissectors/packet-dhcp.c +++ b/epan/dissectors/packet-dhcp.c @@ -913,7 +913,8 @@ static const enum_val_t dhcp_uuid_endian_vals[] = { { NULL, NULL, 0 } }; -#define DHCP_UDP_PORT_RANGE "67-68" +#define DHCP_UDP_PORT_RANGE "67-68,4011" +#define PROXYDHCP_UDP_PORT 4011 #define BOOTP_BC 0x8000 #define BOOTP_MBZ 0x7FFF @@ -6351,6 +6352,7 @@ dissect_dhcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ int voff, eoff, tmpvoff; /* vendor offset, end offset */ guint32 ip_addr; gboolean at_end; + gboolean isProxyDhcp; const char *dhcp_type = NULL; const guint8 *vendor_class_id = NULL; guint16 flags, secs; @@ -6367,6 +6369,19 @@ dissect_dhcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ rfc3396_sip_server.total_number_of_block = 0; rfc3396_sip_server.tvb_composite = NULL; + if (pinfo->srcport == PROXYDHCP_UDP_PORT || + pinfo->destport == PROXYDHCP_UDP_PORT) { + /* The "DHCP magic" is mandatory for proxyDHCP. Use it as a heuristic. */ + if (!tvb_bytes_exist(tvb, VENDOR_INFO_OFFSET, 4) || + tvb_get_ntohl(tvb, VENDOR_INFO_OFFSET) != 0x63825363) { + /* Not a DHCP packet at all. */ + return 0; + } + isProxyDhcp = TRUE; + } else { + isProxyDhcp = FALSE; + } + col_set_str(pinfo->cinfo, COL_PROTOCOL, "BOOTP"); /* * In case we throw an exception fetching the opcode, etc. @@ -6444,8 +6459,8 @@ dissect_dhcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCP"); - col_add_fstr(pinfo->cinfo, COL_INFO, "DHCP %-8s - Transaction ID 0x%x", - dhcp_type, tvb_get_ntohl(tvb, 4)); + col_add_fstr(pinfo->cinfo, COL_INFO, "%sDHCP %-8s - Transaction ID 0x%x", + isProxyDhcp ? "proxy" : "", dhcp_type, tvb_get_ntohl(tvb, 4)); tap_queue_packet( dhcp_bootp_tap, pinfo, dhcp_type); } |