1998-09-16 02:39:15 +00:00
|
|
|
/* packet-bootp.c
|
|
|
|
* Routines for BOOTP/DHCP packet disassembly
|
2004-05-07 08:02:23 +00:00
|
|
|
* Copyright 1998, Gilbert Ramirez <gram@alumni.rice.edu>
|
|
|
|
* Copyright 2004, Thomas Anders <thomas.anders [AT] blue-cable.de>
|
1998-09-16 02:39:15 +00:00
|
|
|
*
|
2004-07-18 00:24:25 +00:00
|
|
|
* $Id$
|
1998-09-16 03:22:19 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* The information used comes from:
|
2000-07-25 21:26:08 +00:00
|
|
|
* RFC 951: Bootstrap Protocol
|
2001-12-27 22:49:02 +00:00
|
|
|
* RFC 1497: BOOTP extensions
|
1998-09-16 02:39:15 +00:00
|
|
|
* RFC 1542: Clarifications and Extensions for the Bootstrap Protocol
|
|
|
|
* RFC 2131: Dynamic Host Configuration Protocol
|
2000-07-25 21:26:08 +00:00
|
|
|
* RFC 2132: DHCP Options and BOOTP Vendor Extensions
|
2004-10-25 08:56:39 +00:00
|
|
|
* RFC 2241: DHCP Options for Novell Directory Services
|
|
|
|
* RFC 2242: NetWare/IP Domain Name and Information
|
2000-07-25 21:26:08 +00:00
|
|
|
* RFC 2489: Procedure for Defining New DHCP Options
|
2003-11-18 19:56:37 +00:00
|
|
|
* RFC 2610: DHCP Options for Service Location Protocol
|
2001-02-13 00:01:08 +00:00
|
|
|
* RFC 3046: DHCP Relay Agent Information Option
|
2001-10-31 08:43:09 +00:00
|
|
|
* RFC 3118: Authentication for DHCP Messages
|
2003-02-07 04:25:37 +00:00
|
|
|
* RFC 3203: DHCP reconfigure extension
|
2004-05-07 08:02:23 +00:00
|
|
|
* RFC 3495: DHCP Option (122) for CableLabs Client Configuration
|
|
|
|
* RFC 3594: PacketCable Security Ticket Control Sub-Option (122.9)
|
2007-07-24 21:23:55 +00:00
|
|
|
* RFC 3442: Classless Static Route Option for DHCP version 4
|
2008-10-08 18:26:53 +00:00
|
|
|
* RFC 3825: Dynamic Host Configuration Protocol Option for Coordinate-based Location Configuration Information
|
2007-10-09 18:48:46 +00:00
|
|
|
* RFC 4243: Vendor-Specific Information Suboption for the Dynamic Host Configuration Protocol (DHCP) Relay Agent Option
|
2008-02-21 07:05:44 +00:00
|
|
|
* RFC 4776: Dynamic Host Configuration Protocol (DHCPv4 and DHCPv6) Option for Civic Addresses Configuration Information
|
2008-09-11 20:44:19 +00:00
|
|
|
* RFC 5223: Discovering Location-to-Service Translation (LoST) Servers Using the Dynamic Host Configuration Protocol (DHCP)
|
2004-10-16 02:04:08 +00:00
|
|
|
* draft-ietf-dhc-fqdn-option-07.txt
|
2000-07-25 21:26:08 +00:00
|
|
|
* BOOTP and DHCP Parameters
|
2001-10-31 08:43:09 +00:00
|
|
|
* http://www.iana.org/assignments/bootp-dhcp-parameters
|
2004-10-18 14:24:25 +00:00
|
|
|
* DOCSIS(TM) 2.0 Radio Frequency Interface Specification
|
2006-04-17 08:38:08 +00:00
|
|
|
* http://www.cablemodem.com/downloads/specs/CM-SP-RFI2.0-I10-051209.pdf
|
2005-04-18 10:46:17 +00:00
|
|
|
* PacketCable(TM) 1.0 MTA Device Provisioning Specification
|
2006-04-17 08:38:08 +00:00
|
|
|
* http://www.packetcable.com/downloads/specs/PKT-SP-PROV-I11-050812.pdf
|
2004-10-18 14:24:25 +00:00
|
|
|
* http://www.cablelabs.com/specifications/archives/PKT-SP-PROV-I05-021127.pdf (superseded by above)
|
2005-04-18 10:46:17 +00:00
|
|
|
* PacketCable(TM) 1.5 MTA Device Provisioning Specification
|
2006-04-17 08:38:08 +00:00
|
|
|
* http://www.packetcable.com/downloads/specs/PKT-SP-PROV1.5-I02-050812.pdf
|
2004-10-05 17:44:53 +00:00
|
|
|
* CableHome(TM) 1.1 Specification
|
2006-04-17 08:38:08 +00:00
|
|
|
* http://www.cablelabs.com/projects/cablehome/downloads/specs/CH-SP-CH1.1-I11-060407.pdf
|
2007-02-11 03:36:04 +00:00
|
|
|
* DSL Forum TR-111
|
|
|
|
* http://www.dslforum.org/techwork/tr/TR-111.pdf
|
1998-09-16 02:39:15 +00:00
|
|
|
*
|
2006-05-21 04:49:01 +00:00
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
1998-09-16 02:39:15 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
2002-08-28 21:04:11 +00:00
|
|
|
*
|
1998-09-16 02:39:15 +00:00
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2004-10-05 17:44:53 +00:00
|
|
|
/*
|
|
|
|
* Some of the development of the BOOTP/DHCP protocol decoder was sponsored by
|
|
|
|
* Cable Television Laboratories, Inc. ("CableLabs") based upon proprietary
|
|
|
|
* CableLabs' specifications. Your license and use of this protocol decoder
|
|
|
|
* does not mean that you are licensed to use the CableLabs'
|
|
|
|
* specifications. If you have questions about this protocol, contact
|
|
|
|
* jf.mule [AT] cablelabs.com or c.stuart [AT] cablelabs.com for additional
|
|
|
|
* information.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2000-11-17 21:00:40 +00:00
|
|
|
#include <string.h>
|
1999-03-23 03:14:46 +00:00
|
|
|
#include <glib.h>
|
2002-01-21 07:37:49 +00:00
|
|
|
#include <epan/packet.h>
|
1999-11-27 04:48:14 +00:00
|
|
|
#include "packet-arp.h"
|
2004-05-07 08:02:23 +00:00
|
|
|
#include "packet-dns.h" /* for get_dns_name() */
|
2004-12-26 22:26:02 +00:00
|
|
|
#include <epan/addr_resolv.h>
|
2004-09-27 22:55:15 +00:00
|
|
|
#include <epan/prefs.h>
|
2004-09-29 00:06:36 +00:00
|
|
|
#include <epan/tap.h>
|
2004-10-05 17:44:53 +00:00
|
|
|
#include <epan/strutil.h>
|
2004-12-26 22:26:02 +00:00
|
|
|
#include <epan/arptypes.h>
|
2007-02-11 03:36:04 +00:00
|
|
|
#include <epan/sminmpec.h>
|
2004-10-05 17:44:53 +00:00
|
|
|
|
2008-10-08 18:26:53 +00:00
|
|
|
|
2003-09-02 22:47:59 +00:00
|
|
|
static int bootp_dhcp_tap = -1;
|
1999-07-29 05:47:07 +00:00
|
|
|
static int proto_bootp = -1;
|
1999-10-08 13:57:31 +00:00
|
|
|
static int hf_bootp_type = -1;
|
|
|
|
static int hf_bootp_hw_type = -1;
|
|
|
|
static int hf_bootp_hw_len = -1;
|
|
|
|
static int hf_bootp_hops = -1;
|
|
|
|
static int hf_bootp_id = -1;
|
|
|
|
static int hf_bootp_secs = -1;
|
2002-06-19 19:39:38 +00:00
|
|
|
static int hf_bootp_flags = -1;
|
|
|
|
static int hf_bootp_flags_broadcast = -1;
|
|
|
|
static int hf_bootp_flags_reserved = -1;
|
1999-10-08 13:57:31 +00:00
|
|
|
static int hf_bootp_ip_client = -1;
|
|
|
|
static int hf_bootp_ip_your = -1;
|
|
|
|
static int hf_bootp_ip_server = -1;
|
|
|
|
static int hf_bootp_ip_relay = -1;
|
|
|
|
static int hf_bootp_hw_addr = -1;
|
|
|
|
static int hf_bootp_server = -1;
|
|
|
|
static int hf_bootp_file = -1;
|
|
|
|
static int hf_bootp_cookie = -1;
|
2002-06-19 19:39:38 +00:00
|
|
|
static int hf_bootp_vendor = -1;
|
2000-05-19 02:16:17 +00:00
|
|
|
static int hf_bootp_dhcp = -1;
|
2004-10-16 02:04:08 +00:00
|
|
|
static int hf_bootp_fqdn_s = -1;
|
|
|
|
static int hf_bootp_fqdn_o = -1;
|
|
|
|
static int hf_bootp_fqdn_e = -1;
|
|
|
|
static int hf_bootp_fqdn_n = -1;
|
|
|
|
static int hf_bootp_fqdn_mbz = -1;
|
|
|
|
static int hf_bootp_fqdn_rcode1 = -1;
|
|
|
|
static int hf_bootp_fqdn_rcode2 = -1;
|
|
|
|
static int hf_bootp_fqdn_name = -1;
|
|
|
|
static int hf_bootp_fqdn_asciiname = -1;
|
2004-10-17 02:36:32 +00:00
|
|
|
static int hf_bootp_pkt_mtacap_len = -1;
|
|
|
|
static int hf_bootp_docsis_cmcap_len = -1;
|
2004-12-26 22:26:02 +00:00
|
|
|
static int hf_bootp_hw_ether_addr = -1;
|
2007-09-13 18:51:32 +00:00
|
|
|
static int hf_bootp_alu_vid = -1;
|
|
|
|
static int hf_bootp_alu_tftp1 = -1;
|
|
|
|
static int hf_bootp_alu_tftp2 = -1;
|
2006-03-09 04:31:10 +00:00
|
|
|
static int hf_bootp_client_identifier_uuid = -1;
|
|
|
|
static int hf_bootp_client_network_id_major_ver = -1;
|
|
|
|
static int hf_bootp_client_network_id_minor_ver = -1;
|
2006-08-15 13:24:02 +00:00
|
|
|
static int hf_bootp_option_type = -1;
|
|
|
|
static int hf_bootp_option_length = -1;
|
|
|
|
static int hf_bootp_option_value = -1;
|
1999-07-29 05:47:07 +00:00
|
|
|
|
2004-10-01 12:35:55 +00:00
|
|
|
static gint ett_bootp = -1;
|
|
|
|
static gint ett_bootp_flags = -1;
|
|
|
|
static gint ett_bootp_option = -1;
|
2004-10-16 02:04:08 +00:00
|
|
|
static gint ett_bootp_fqdn = -1;
|
1999-11-16 11:44:20 +00:00
|
|
|
|
2008-02-21 07:05:44 +00:00
|
|
|
|
2008-10-08 18:26:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* RFC3825decoder error codes of the conversion function */
|
|
|
|
#define RFC3825_NOERROR 0
|
|
|
|
#define RFC3825_LATITUDE_OUTOFRANGE 1
|
|
|
|
#define RFC3825_LATITUDE_UNCERTAINTY_OUTOFRANGE 2
|
|
|
|
#define RFC3825_LONGITUDE_OUTOFRANGE 3
|
|
|
|
#define RFC3825_LONGITUDE_UNCERTAINTY_OUTOFRANGE 4
|
|
|
|
#define RFC3825_ALTITUDE_OUTOFRANGE 5
|
|
|
|
#define RFC3825_ALTITUDE_UNCERTAINTY_OUTOFRANGE 6
|
|
|
|
#define RFC3825_ALTITUDE_TYPE_OUTOFRANGE 7
|
|
|
|
#define RFC3825_DATUM_TYPE_OUTOFRANGE 8
|
|
|
|
|
|
|
|
struct rfc3825_location_fixpoint_t {
|
|
|
|
|
|
|
|
gint64 latitude; /* latitude in degrees, allowed range from -90deg to 90deg.
|
|
|
|
Fixpoint A(8,25) with 34 bits */
|
|
|
|
guint8 latitude_res; /* the resolution of the latitude in bits, allowed range is from 0 to 34.
|
|
|
|
6 bits. */
|
|
|
|
gint64 longitude; /* longitude in degrees, range from -180deg to 180deg.
|
|
|
|
Fixpoint A(8,25) with 34 bits */
|
|
|
|
guint8 longitude_res; /* the resolution of the longitude in bits, allowed range is from 0 to 34.
|
|
|
|
6 bits. */
|
|
|
|
gint32 altitude; /* the altitude, 30 bits.
|
|
|
|
Depending on alt_type this are meters or floors, no range limit.
|
|
|
|
altitude_type==1: A(13,8) with 22 bits
|
|
|
|
altitude_type==2: A(13,8) with 22 bits */
|
|
|
|
guint8 altitude_res; /* the resolution of the altitude in bits, allowed range is from 0 to 30.
|
|
|
|
6 bits.
|
|
|
|
altitude_type==1: any value between 0 and 30
|
|
|
|
altitude_type==2: either 0 (floor unknown) or 30 */
|
|
|
|
guint8 altitude_type; /* the type of the altitude, 4 bits. allowed values are:
|
|
|
|
0: unknown
|
|
|
|
1: altitude in meters
|
|
|
|
2: altitude in floors */
|
|
|
|
guint8 datum_type; /* the map datum used for the coordinates. 8 bits.
|
|
|
|
All values are allowed although currently only the
|
|
|
|
following ones are defined:
|
|
|
|
1: WGS84
|
|
|
|
2: NAD83/NAVD88
|
|
|
|
3: NAD83/MLLW */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* The rfc3825_location_decimal_t structure holds the location parameters
|
|
|
|
* in decimal (floating point) format.
|
|
|
|
*/
|
|
|
|
struct rfc3825_location_decimal_t {
|
|
|
|
|
|
|
|
double latitude; /* latitude in degrees, allowed range from -90deg to 90deg */
|
|
|
|
double latitude_res; /* the uncertainty of the latitude in grad, "0.01" means +-0.01deg
|
|
|
|
from the altitude. During conversion this will be rounded to
|
|
|
|
next smaller value which can be respresented in fixpoint arithmetic */
|
|
|
|
double longitude; /* longitude in degrees, range from -180deg to 180deg */
|
|
|
|
double longitude_res; /* the uncertainty of the longitude in grad, "0.01" means +-0.01deg
|
|
|
|
from the longitude. During conversion this will be rounded to
|
|
|
|
next smaller value which can be respresented in fixpoint arithmetic */
|
|
|
|
double altitude; /* the altitude, depending on alt_type this are meters or floors, no range limit */
|
|
|
|
double altitude_res; /* the uncertainty of the altitude in either:
|
|
|
|
- altitude-type=meters: "10" means 10 meters which means +-10 meters from the altitude
|
|
|
|
- altitude-type=floors: either 0 (unknown) or 30 (exact) */
|
|
|
|
int altitude_type; /* the type of the altitude, allowed values are
|
|
|
|
0: unknown
|
|
|
|
1: altitude in meters
|
|
|
|
2: altitude in floors */
|
|
|
|
int datum_type; /* the map datum used for the coordinates.
|
|
|
|
All values are allowed although currently only the
|
|
|
|
following ones are defined:
|
|
|
|
1: WGS84
|
|
|
|
2: NAD83/NAVD88
|
|
|
|
3: NAD83/MLLW */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* converts fixpoint presentation into decimal presentation
|
|
|
|
also converts values which are out of range to allow decoding of received data */
|
|
|
|
static int rfc3825_fixpoint_to_decimal(struct rfc3825_location_fixpoint_t *fixpoint, struct rfc3825_location_decimal_t *decimal);
|
|
|
|
|
|
|
|
/* decodes the LCI string received from DHCP into the fixpoint values */
|
|
|
|
static void rfc3825_lci_to_fixpoint(const unsigned char lci[16], struct rfc3825_location_fixpoint_t *fixpoint);
|
|
|
|
|
|
|
|
|
|
|
|
/* Map Datum Types used for the coordinates (RFC 3825) */
|
|
|
|
static const value_string map_datum_type_values[] = {
|
|
|
|
{ 1, "WGS 84" },
|
|
|
|
{ 2, "NAD83 (NAVD88)" },
|
|
|
|
{ 3, "NAD83 (MLLW)" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Altitude Types used for the coordinates (RFC 3825) */
|
|
|
|
static const value_string altitude_type_values[] = {
|
|
|
|
{ 1, "Meters" },
|
|
|
|
{ 2, "Floors" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
/* Error Types for RFC 3825 coordinate location decoding */
|
|
|
|
static const value_string rfc3825_error_types[] = {
|
|
|
|
{1, "Latitude is out of range [-90,90]"},
|
|
|
|
{2, "Latitude Uncertainty is out of range [0,90]"},
|
|
|
|
{3, "Longitude is out of range [-180,180]"},
|
|
|
|
{4, "Longitude Uncertainty is out of range [0,180]"},
|
|
|
|
{5, "Altitude is out of range [-(2^21),(2^21)-1]"},
|
|
|
|
{6, "Altitude Uncertainty is out of range [0,2^20]"},
|
|
|
|
{7, "Altitude Type is out of range [0,2]"},
|
|
|
|
{8, "Datum is out of range [1,3]"},
|
|
|
|
{0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-02-21 07:05:44 +00:00
|
|
|
/* Civic Address What field (RFC 4776) */
|
|
|
|
static const value_string civic_address_what_values[] = {
|
|
|
|
{ 0, "Location of the DHCP server" },
|
|
|
|
{ 1, "Location of the network element believed to be closest to the client" },
|
|
|
|
{ 2, "Location of the client"},
|
|
|
|
{ 0, NULL}
|
|
|
|
};
|
|
|
|
|
2008-09-11 20:44:19 +00:00
|
|
|
/* Civic Address Type field (RFC 4119, RFC 4776, RFC 5139) */
|
2008-02-21 07:05:44 +00:00
|
|
|
static const value_string civic_address_type_values[] = {
|
|
|
|
{ 0, "Language" },
|
|
|
|
{ 1, "A1" },
|
|
|
|
{ 2, "A2" },
|
|
|
|
{ 3, "A3" },
|
|
|
|
{ 4, "A4" },
|
|
|
|
{ 5, "A5" },
|
|
|
|
{ 6, "A6" },
|
|
|
|
{ 16, "PRD (Leading street direction)" },
|
|
|
|
{ 17, "POD (Trailing street suffix)" },
|
|
|
|
{ 18, "STS (Street suffix)" },
|
|
|
|
{ 19, "HNO (House number)" },
|
|
|
|
{ 20, "HNS (House number suffix)" },
|
|
|
|
{ 21, "LMK (Landmark or vanity address)" },
|
|
|
|
{ 22, "LOC (Additional location information)" },
|
|
|
|
{ 23, "NAM" },
|
|
|
|
{ 24, "PC (Postal/ZIP code)" },
|
|
|
|
{ 25, "BLD (Building)" },
|
|
|
|
{ 26, "UNIT" },
|
|
|
|
{ 27, "FLR (Floor)" },
|
|
|
|
{ 28, "ROOM" },
|
|
|
|
{ 29, "PLC (Place-type)" },
|
|
|
|
{ 30, "PCN (Postal community name)" },
|
|
|
|
{ 31, "POBOX" },
|
|
|
|
{ 32, "ADDCODE (Additional Code)" },
|
|
|
|
{ 33, "SEAT" },
|
|
|
|
{ 34, "RD (Primary road or street)" },
|
|
|
|
{ 35, "RDSEC (Road section)" },
|
|
|
|
{ 36, "RDBR (Road branch)" },
|
|
|
|
{ 37, "RDSUBBR (Road sub-branch)" },
|
|
|
|
{ 38, "PRM (Road pre-modifier)" },
|
|
|
|
{ 39, "POM (Road post-modifier" },
|
|
|
|
{ 128, "Script" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2008-03-12 21:00:00 +00:00
|
|
|
static gboolean novell_string = FALSE;
|
2003-11-18 19:56:37 +00:00
|
|
|
|
2000-04-08 07:07:42 +00:00
|
|
|
#define UDP_PORT_BOOTPS 67
|
2002-05-28 20:08:09 +00:00
|
|
|
#define UDP_PORT_BOOTPC 68
|
2000-04-08 07:07:42 +00:00
|
|
|
|
2002-06-19 19:39:38 +00:00
|
|
|
#define BOOTP_BC 0x8000
|
|
|
|
#define BOOTP_MBZ 0x7FFF
|
|
|
|
|
2004-10-16 02:04:08 +00:00
|
|
|
/* FQDN stuff */
|
|
|
|
#define F_FQDN_S 0x01
|
|
|
|
#define F_FQDN_O 0x02
|
|
|
|
#define F_FQDN_E 0x04
|
|
|
|
#define F_FQDN_N 0x08
|
|
|
|
#define F_FQDN_MBZ 0xf0
|
|
|
|
|
|
|
|
static const true_false_string tfs_fqdn_s = {
|
|
|
|
"Server",
|
|
|
|
"Client"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_fqdn_o = {
|
|
|
|
"Override",
|
|
|
|
"No override"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_fqdn_e = {
|
|
|
|
"Binary encoding",
|
|
|
|
"ASCII encoding"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string tfs_fqdn_n = {
|
|
|
|
"No server updates",
|
|
|
|
"Some server updates"
|
|
|
|
};
|
|
|
|
|
2004-10-25 08:33:39 +00:00
|
|
|
enum field_type {
|
2004-10-25 08:56:39 +00:00
|
|
|
special,
|
2004-10-25 08:33:39 +00:00
|
|
|
none,
|
|
|
|
presence,
|
|
|
|
ipv4, /* single IPv4 address */
|
|
|
|
ipv4_list, /* list of IPv4 addresses */
|
|
|
|
string,
|
2004-10-25 08:56:39 +00:00
|
|
|
bytes,
|
|
|
|
opaque,
|
2004-10-26 16:08:16 +00:00
|
|
|
val_boolean,
|
2004-10-25 08:56:39 +00:00
|
|
|
val_u_byte,
|
|
|
|
val_u_short,
|
|
|
|
val_u_short_list,
|
|
|
|
val_u_le_short,
|
|
|
|
val_u_long,
|
1999-01-28 21:29:36 +00:00
|
|
|
time_in_secs,
|
2004-10-25 08:56:39 +00:00
|
|
|
fqdn,
|
|
|
|
ipv4_or_fqdn
|
2004-10-25 08:33:39 +00:00
|
|
|
};
|
1998-09-16 02:39:15 +00:00
|
|
|
|
|
|
|
struct opt_info {
|
2005-07-21 17:04:10 +00:00
|
|
|
const char *text;
|
1998-09-16 02:39:15 +00:00
|
|
|
enum field_type ftype;
|
2005-07-21 17:04:10 +00:00
|
|
|
const void *data;
|
1998-09-16 02:39:15 +00:00
|
|
|
};
|
|
|
|
|
2002-06-19 19:39:38 +00:00
|
|
|
static const true_false_string flag_set_broadcast = {
|
|
|
|
"Broadcast",
|
|
|
|
"Unicast"
|
|
|
|
};
|
|
|
|
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2005-04-18 10:46:17 +00:00
|
|
|
/* PacketCable/DOCSIS definitions */
|
2004-10-05 17:44:53 +00:00
|
|
|
#define PACKETCABLE_MTA_CAP10 "pktc1.0:"
|
2004-10-17 02:36:32 +00:00
|
|
|
#define PACKETCABLE_MTA_CAP15 "pktc1.5:"
|
2004-10-05 17:44:53 +00:00
|
|
|
#define PACKETCABLE_CM_CAP11 "docsis1.1:"
|
|
|
|
#define PACKETCABLE_CM_CAP20 "docsis2.0:"
|
|
|
|
|
|
|
|
#define PACKETCABLE_CCC_I05 1
|
|
|
|
#define PACKETCABLE_CCC_DRAFT5 2
|
|
|
|
#define PACKETCABLE_CCC_RFC_3495 3
|
|
|
|
|
|
|
|
static enum_val_t pkt_ccc_protocol_versions[] = {
|
|
|
|
{ "ccc_i05", "PKT-SP-PROV-I05-021127", PACKETCABLE_CCC_I05 },
|
|
|
|
{ "ccc_draft_5", "IETF Draft 5", PACKETCABLE_CCC_DRAFT5 },
|
|
|
|
{ "rfc_3495", "RFC 3495", PACKETCABLE_CCC_RFC_3495 },
|
2004-10-05 23:02:09 +00:00
|
|
|
{ NULL, NULL, 0 }
|
2004-10-05 17:44:53 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static gint pkt_ccc_protocol_version = PACKETCABLE_CCC_RFC_3495;
|
2007-03-26 11:06:26 +00:00
|
|
|
static guint pkt_ccc_option = 122;
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
|
2001-05-24 19:21:15 +00:00
|
|
|
static int dissect_vendor_pxeclient_suboption(proto_tree *v_tree, tvbuff_t *tvb,
|
2004-10-25 08:17:11 +00:00
|
|
|
int optoff, int optend);
|
2004-05-07 08:02:23 +00:00
|
|
|
static int dissect_vendor_cablelabs_suboption(proto_tree *v_tree, tvbuff_t *tvb,
|
2004-10-25 08:17:11 +00:00
|
|
|
int optoff, int optend);
|
2001-01-03 22:49:06 +00:00
|
|
|
static int dissect_netware_ip_suboption(proto_tree *v_tree, tvbuff_t *tvb,
|
2004-10-25 08:17:11 +00:00
|
|
|
int optoff, int optend);
|
2007-02-11 03:36:04 +00:00
|
|
|
static int dissect_vendor_tr111_suboption(proto_tree *v_tree, tvbuff_t *tvb,
|
|
|
|
int optoff, int optend);
|
2001-02-13 00:01:08 +00:00
|
|
|
static int bootp_dhcp_decode_agent_info(proto_tree *v_tree, tvbuff_t *tvb,
|
2004-10-25 08:17:11 +00:00
|
|
|
int optoff, int optend);
|
2004-10-05 17:44:53 +00:00
|
|
|
static void dissect_packetcable_mta_cap(proto_tree *v_tree, tvbuff_t *tvb,
|
|
|
|
int voff, int len);
|
2004-10-17 02:36:32 +00:00
|
|
|
static void dissect_docsis_cm_cap(proto_tree *v_tree, tvbuff_t *tvb,
|
2004-10-05 17:44:53 +00:00
|
|
|
int voff, int len);
|
2004-10-25 08:17:11 +00:00
|
|
|
static int dissect_packetcable_i05_ccc(proto_tree *v_tree, tvbuff_t *tvb,
|
|
|
|
int optoff, int optend);
|
|
|
|
static int dissect_packetcable_ietf_ccc(proto_tree *v_tree, tvbuff_t *tvb,
|
|
|
|
int optoff, int optend, int revision);
|
2004-10-05 17:44:53 +00:00
|
|
|
|
2007-05-24 17:36:07 +00:00
|
|
|
#define OPT53_DISCOVER "Discover"
|
2007-10-27 16:49:13 +00:00
|
|
|
/* http://www.iana.org/assignments/bootp-dhcp-parameters */
|
2005-12-22 02:37:22 +00:00
|
|
|
static const value_string opt53_text[] = {
|
2007-05-24 17:36:07 +00:00
|
|
|
{ 1, OPT53_DISCOVER },
|
2005-12-22 02:37:22 +00:00
|
|
|
{ 2, "Offer" },
|
|
|
|
{ 3, "Request" },
|
|
|
|
{ 4, "Decline" },
|
|
|
|
{ 5, "ACK" },
|
|
|
|
{ 6, "NAK" },
|
|
|
|
{ 7, "Release" },
|
|
|
|
{ 8, "Inform" },
|
|
|
|
{ 9, "Force Renew" },
|
2007-10-27 16:49:13 +00:00
|
|
|
{ 10, "Lease query" }, /* RFC4388 */
|
|
|
|
{ 11, "Lease Unassigned" }, /* RFC4388 */
|
|
|
|
{ 12, "Lease Unknown" }, /* RFC4388 */
|
|
|
|
{ 13, "Lease Active" }, /* RFC4388 */
|
2008-02-11 19:18:02 +00:00
|
|
|
/* draft-ietf-dhc-leasequery-09.txt
|
2007-10-27 16:49:13 +00:00
|
|
|
{ 13, "Lease query" }, */
|
2005-12-22 02:37:22 +00:00
|
|
|
{ 14, "Lease known" },
|
|
|
|
{ 15, "Lease unknown" },
|
|
|
|
{ 16, "Lease active" },
|
|
|
|
{ 17, "Unimplemented" },
|
|
|
|
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
2000-07-09 22:46:53 +00:00
|
|
|
|
2001-10-31 08:43:09 +00:00
|
|
|
/* DHCP Authentication protocols */
|
|
|
|
#define AUTHEN_PROTO_CONFIG_TOKEN 0
|
|
|
|
#define AUTHEN_PROTO_DELAYED_AUTHEN 1
|
|
|
|
|
|
|
|
/* DHCP Authentication algorithms for delayed authentication */
|
|
|
|
#define AUTHEN_DELAYED_ALGO_HMAC_MD5 1
|
|
|
|
|
|
|
|
/* DHCP Authentication Replay Detection Methods */
|
|
|
|
#define AUTHEN_RDM_MONOTONIC_COUNTER 0x00
|
|
|
|
|
2002-09-28 04:12:38 +00:00
|
|
|
/* 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
|
|
|
|
|
2004-10-26 07:00:23 +00:00
|
|
|
static const true_false_string toggle_tfs = {
|
|
|
|
"Enabled",
|
|
|
|
"Disabled"
|
|
|
|
};
|
|
|
|
|
|
|
|
static const true_false_string yes_no_tfs = {
|
|
|
|
"Yes",
|
|
|
|
"No"
|
|
|
|
};
|
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
static const value_string bootp_nbnt_vals[] = {
|
|
|
|
{0x1, "B-node" },
|
|
|
|
{0x2, "P-node" },
|
|
|
|
{0x4, "M-node" },
|
|
|
|
{0x8, "H-node" },
|
2006-02-08 23:09:17 +00:00
|
|
|
{0, NULL }
|
2005-12-23 23:54:35 +00:00
|
|
|
};
|
|
|
|
|
2006-03-09 04:31:10 +00:00
|
|
|
static const value_string bootp_client_arch[] = {
|
|
|
|
{ 0x0000, "IA x86 PC" },
|
|
|
|
{ 0x0001, "NEC/PC98" },
|
|
|
|
{ 0x0002, "IA64 PC" },
|
|
|
|
{ 0x0003, "DEC Alpha" },
|
|
|
|
{ 0x0004, "ArcX86" },
|
|
|
|
{ 0x0005, "Intel Lean Client" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
2005-12-23 23:54:35 +00:00
|
|
|
|
|
|
|
static struct opt_info bootp_opt[] = {
|
|
|
|
/* 0 */ { "Padding", none, NULL },
|
|
|
|
/* 1 */ { "Subnet Mask", ipv4, NULL },
|
|
|
|
/* 2 */ { "Time Offset", time_in_secs, NULL },
|
|
|
|
/* 3 */ { "Router", ipv4_list, NULL },
|
|
|
|
/* 4 */ { "Time Server", ipv4_list, NULL },
|
|
|
|
/* 5 */ { "Name Server", ipv4_list, NULL },
|
|
|
|
/* 6 */ { "Domain Name Server", ipv4_list, NULL },
|
|
|
|
/* 7 */ { "Log Server", ipv4_list, NULL },
|
|
|
|
/* 8 */ { "Cookie Server", ipv4_list, NULL },
|
|
|
|
/* 9 */ { "LPR Server", ipv4_list, NULL },
|
|
|
|
/* 10 */ { "Impress Server", ipv4_list, NULL },
|
|
|
|
/* 11 */ { "Resource Location Server", ipv4_list, NULL },
|
|
|
|
/* 12 */ { "Host Name", string, NULL },
|
|
|
|
/* 13 */ { "Boot File Size", val_u_short, NULL },
|
|
|
|
/* 14 */ { "Merit Dump File", string, NULL },
|
|
|
|
/* 15 */ { "Domain Name", string, NULL },
|
|
|
|
/* 16 */ { "Swap Server", ipv4, NULL },
|
|
|
|
/* 17 */ { "Root Path", string, NULL },
|
|
|
|
/* 18 */ { "Extensions Path", string, NULL },
|
|
|
|
/* 19 */ { "IP Forwarding", val_boolean, TFS(&toggle_tfs) },
|
|
|
|
/* 20 */ { "Non-Local Source Routing", val_boolean, TFS(&toggle_tfs) },
|
|
|
|
/* 21 */ { "Policy Filter", special, NULL },
|
|
|
|
/* 22 */ { "Maximum Datagram Reassembly Size", val_u_short, NULL },
|
|
|
|
/* 23 */ { "Default IP Time-to-Live", val_u_byte, NULL },
|
|
|
|
/* 24 */ { "Path MTU Aging Timeout", time_in_secs, NULL },
|
|
|
|
/* 25 */ { "Path MTU Plateau Table", val_u_short_list, NULL },
|
|
|
|
/* 26 */ { "Interface MTU", val_u_short, NULL },
|
|
|
|
/* 27 */ { "All Subnets are Local", val_boolean, TFS(&yes_no_tfs) },
|
|
|
|
/* 28 */ { "Broadcast Address", ipv4, NULL },
|
|
|
|
/* 29 */ { "Perform Mask Discovery", val_boolean, TFS(&toggle_tfs) },
|
|
|
|
/* 30 */ { "Mask Supplier", val_boolean, TFS(&yes_no_tfs) },
|
|
|
|
/* 31 */ { "Perform Router Discover", val_boolean, TFS(&toggle_tfs) },
|
|
|
|
/* 32 */ { "Router Solicitation Address", ipv4, NULL },
|
|
|
|
/* 33 */ { "Static Route", special, NULL },
|
|
|
|
/* 34 */ { "Trailer Encapsulation", val_boolean, TFS(&toggle_tfs) },
|
|
|
|
/* 35 */ { "ARP Cache Timeout", time_in_secs, NULL },
|
|
|
|
/* 36 */ { "Ethernet Encapsulation", val_boolean, TFS(&toggle_tfs) },
|
|
|
|
/* 37 */ { "TCP Default TTL", val_u_byte, NULL },
|
|
|
|
/* 38 */ { "TCP Keepalive Interval", time_in_secs, NULL },
|
|
|
|
/* 39 */ { "TCP Keepalive Garbage", val_boolean, TFS(&toggle_tfs) },
|
|
|
|
/* 40 */ { "Network Information Service Domain", string, NULL },
|
|
|
|
/* 41 */ { "Network Information Service Servers", ipv4_list, NULL },
|
|
|
|
/* 42 */ { "Network Time Protocol Servers", ipv4_list, NULL },
|
|
|
|
/* 43 */ { "Vendor-Specific Information", special, NULL },
|
|
|
|
/* 44 */ { "NetBIOS over TCP/IP Name Server", ipv4_list, NULL },
|
|
|
|
/* 45 */ { "NetBIOS over TCP/IP Datagram Distribution Name Server", ipv4_list, NULL },
|
|
|
|
/* 46 */ { "NetBIOS over TCP/IP Node Type", val_u_byte, VALS(bootp_nbnt_vals) },
|
|
|
|
/* 47 */ { "NetBIOS over TCP/IP Scope", string, NULL },
|
|
|
|
/* 48 */ { "X Window System Font Server", ipv4_list, NULL },
|
|
|
|
/* 49 */ { "X Window System Display Manager", ipv4_list, NULL },
|
|
|
|
/* 50 */ { "Requested IP Address", ipv4, NULL },
|
|
|
|
/* 51 */ { "IP Address Lease Time", time_in_secs, NULL },
|
|
|
|
/* 52 */ { "Option Overload", special, NULL },
|
|
|
|
/* 53 */ { "DHCP Message Type", special, NULL },
|
|
|
|
/* 54 */ { "Server Identifier", ipv4, NULL },
|
|
|
|
/* 55 */ { "Parameter Request List", special, NULL },
|
|
|
|
/* 56 */ { "Message", string, NULL },
|
|
|
|
/* 57 */ { "Maximum DHCP Message Size", val_u_short, NULL },
|
|
|
|
/* 58 */ { "Renewal Time Value", time_in_secs, NULL },
|
|
|
|
/* 59 */ { "Rebinding Time Value", time_in_secs, NULL },
|
|
|
|
/* 60 */ { "Vendor class identifier", special, NULL },
|
|
|
|
/* 61 */ { "Client identifier", special, NULL },
|
|
|
|
/* 62 */ { "Novell/Netware IP domain", string, NULL },
|
|
|
|
/* 63 */ { "Novell Options", special, NULL },
|
|
|
|
/* 64 */ { "Network Information Service+ Domain", string, NULL },
|
|
|
|
/* 65 */ { "Network Information Service+ Servers", ipv4_list, NULL },
|
|
|
|
/* 66 */ { "TFTP Server Name", string, NULL },
|
|
|
|
/* 67 */ { "Bootfile name", string, NULL },
|
|
|
|
/* 68 */ { "Mobile IP Home Agent", ipv4_list, NULL },
|
|
|
|
/* 69 */ { "SMTP Server", ipv4_list, NULL },
|
|
|
|
/* 70 */ { "POP3 Server", ipv4_list, NULL },
|
|
|
|
/* 71 */ { "NNTP Server", ipv4_list, NULL },
|
|
|
|
/* 72 */ { "Default WWW Server", ipv4_list, NULL },
|
|
|
|
/* 73 */ { "Default Finger Server", ipv4_list, NULL },
|
|
|
|
/* 74 */ { "Default IRC Server", ipv4_list, NULL },
|
|
|
|
/* 75 */ { "StreetTalk Server", ipv4_list, NULL },
|
|
|
|
/* 76 */ { "StreetTalk Directory Assistance Server", ipv4_list, NULL },
|
|
|
|
/* 77 */ { "User Class Information", opaque, NULL },
|
|
|
|
/* 78 */ { "Directory Agent Information", special, NULL },
|
|
|
|
/* 79 */ { "Service Location Agent Scope", special, NULL },
|
|
|
|
/* 80 */ { "Naming Authority", opaque, NULL },
|
|
|
|
/* 81 */ { "Client Fully Qualified Domain Name", special, NULL },
|
|
|
|
/* 82 */ { "Agent Information Option", special, NULL },
|
|
|
|
/* 83 */ { "Unassigned", opaque, NULL },
|
|
|
|
/* 84 */ { "Unassigned", opaque, NULL },
|
|
|
|
/* 85 */ { "Novell Directory Services Servers", special, NULL },
|
|
|
|
/* 86 */ { "Novell Directory Services Tree Name", string, NULL },
|
|
|
|
/* 87 */ { "Novell Directory Services Context", string, NULL },
|
|
|
|
/* 88 */ { "IEEE 1003.1 POSIX Timezone", opaque, NULL },
|
|
|
|
/* 89 */ { "Fully Qualified Domain Name", opaque, NULL },
|
|
|
|
/* 90 */ { "Authentication", special, NULL },
|
|
|
|
/* 91 */ { "Vines TCP/IP Server Option", opaque, NULL },
|
|
|
|
/* 92 */ { "Server Selection Option", opaque, NULL },
|
2006-03-09 04:31:10 +00:00
|
|
|
/* 93 */ { "Client System Architecture", val_u_short, VALS(bootp_client_arch) },
|
|
|
|
/* 94 */ { "Client Network Device Interface", special, NULL },
|
2005-12-23 23:54:35 +00:00
|
|
|
/* 95 */ { "Lightweight Directory Access Protocol", opaque, NULL },
|
|
|
|
/* 96 */ { "IPv6 Transitions", opaque, NULL },
|
2006-03-09 04:31:10 +00:00
|
|
|
/* 97 */ { "UUID/GUID-based Client Identifier", special, NULL },
|
2005-12-23 23:54:35 +00:00
|
|
|
/* 98 */ { "Open Group's User Authentication", opaque, NULL },
|
2008-02-21 07:05:44 +00:00
|
|
|
/* 99 */ { "Civic Addresses Configuration", opaque, NULL },
|
2005-12-23 23:54:35 +00:00
|
|
|
/* 100 */ { "Printer Name", opaque, NULL },
|
|
|
|
/* 101 */ { "MDHCP multicast address", opaque, NULL },
|
|
|
|
/* 102 */ { "Removed/unassigned", opaque, NULL },
|
|
|
|
/* 103 */ { "Removed/unassigned", opaque, NULL },
|
|
|
|
/* 104 */ { "Removed/unassigned", opaque, NULL },
|
|
|
|
/* 105 */ { "Removed/unassigned", opaque, NULL },
|
|
|
|
/* 106 */ { "Removed/unassigned", opaque, NULL },
|
|
|
|
/* 107 */ { "Removed/unassigned", opaque, NULL },
|
|
|
|
/* 108 */ { "Swap Path Option", opaque, NULL },
|
|
|
|
/* 109 */ { "Unassigned", opaque, NULL },
|
|
|
|
/* 110 */ { "IPX Compability", opaque, NULL },
|
|
|
|
/* 111 */ { "Unassigned", opaque, NULL },
|
|
|
|
/* 112 */ { "NetInfo Parent Server Address", ipv4_list, NULL },
|
|
|
|
/* 113 */ { "NetInfo Parent Server Tag", string, NULL },
|
|
|
|
/* 114 */ { "URL", opaque, NULL },
|
|
|
|
/* 115 */ { "DHCP Failover Protocol", opaque, NULL },
|
|
|
|
/* 116 */ { "DHCP Auto-Configuration", opaque, NULL },
|
|
|
|
/* 117 */ { "Name Service Search", opaque, NULL },
|
|
|
|
/* 118 */ { "Subnet Selection Option", ipv4_list, NULL },
|
|
|
|
/* 119 */ { "Domain Search", opaque, NULL },
|
|
|
|
/* 120 */ { "SIP Servers", opaque, NULL },
|
2007-07-24 21:23:55 +00:00
|
|
|
/* 121 */ { "Classless Static Route", special, NULL },
|
2005-12-23 23:54:35 +00:00
|
|
|
/* 122 */ { "CableLabs Client Configuration", opaque, NULL },
|
2008-02-21 07:05:44 +00:00
|
|
|
/* 123 */ { "Coordinate-based Location Configuration", opaque, NULL },
|
2007-02-11 03:36:04 +00:00
|
|
|
/* 124 */ { "V-I Vendor Class", opaque, NULL },
|
|
|
|
/* 125 */ { "V-I Vendor-specific Information", opaque, NULL },
|
2005-12-23 23:54:35 +00:00
|
|
|
/* 126 */ { "Extension", opaque, NULL },
|
|
|
|
/* 127 */ { "Extension", opaque, NULL },
|
|
|
|
/* 128 */ { "Private", opaque, NULL },
|
|
|
|
/* 129 */ { "Private", opaque, NULL },
|
|
|
|
/* 130 */ { "Private", opaque, NULL },
|
|
|
|
/* 131 */ { "Private", opaque, NULL },
|
|
|
|
/* 132 */ { "Private", opaque, NULL },
|
|
|
|
/* 133 */ { "Private", opaque, NULL },
|
|
|
|
/* 134 */ { "Private", opaque, NULL },
|
|
|
|
/* 135 */ { "Private", opaque, NULL },
|
|
|
|
/* 136 */ { "Private", opaque, NULL },
|
2008-09-11 20:44:19 +00:00
|
|
|
/* 137 */ { "LoST Server Domain Name", string, NULL },
|
2005-12-23 23:54:35 +00:00
|
|
|
/* 138 */ { "Private", opaque, NULL },
|
|
|
|
/* 139 */ { "Private", opaque, NULL },
|
|
|
|
/* 140 */ { "Private", opaque, NULL },
|
|
|
|
/* 141 */ { "Private", opaque, NULL },
|
|
|
|
/* 142 */ { "Private", opaque, NULL },
|
|
|
|
/* 143 */ { "Private", opaque, NULL },
|
|
|
|
/* 144 */ { "Private", opaque, NULL },
|
|
|
|
/* 145 */ { "Private", opaque, NULL },
|
|
|
|
/* 146 */ { "Private", opaque, NULL },
|
|
|
|
/* 147 */ { "Private", opaque, NULL },
|
|
|
|
/* 148 */ { "Private", opaque, NULL },
|
|
|
|
/* 149 */ { "Private", opaque, NULL },
|
|
|
|
/* 150 */ { "Private", opaque, NULL },
|
|
|
|
/* 151 */ { "Private", opaque, NULL },
|
|
|
|
/* 152 */ { "Private", opaque, NULL },
|
|
|
|
/* 153 */ { "Private", opaque, NULL },
|
|
|
|
/* 154 */ { "Private", opaque, NULL },
|
|
|
|
/* 155 */ { "Private", opaque, NULL },
|
|
|
|
/* 156 */ { "Private", opaque, NULL },
|
|
|
|
/* 157 */ { "Private", opaque, NULL },
|
|
|
|
/* 158 */ { "Private", opaque, NULL },
|
|
|
|
/* 159 */ { "Private", opaque, NULL },
|
|
|
|
/* 160 */ { "Private", opaque, NULL },
|
|
|
|
/* 161 */ { "Private", opaque, NULL },
|
|
|
|
/* 162 */ { "Private", opaque, NULL },
|
|
|
|
/* 163 */ { "Private", opaque, NULL },
|
|
|
|
/* 164 */ { "Private", opaque, NULL },
|
|
|
|
/* 165 */ { "Private", opaque, NULL },
|
|
|
|
/* 166 */ { "Private", opaque, NULL },
|
|
|
|
/* 167 */ { "Private", opaque, NULL },
|
|
|
|
/* 168 */ { "Private", opaque, NULL },
|
|
|
|
/* 169 */ { "Private", opaque, NULL },
|
|
|
|
/* 170 */ { "Private", opaque, NULL },
|
|
|
|
/* 171 */ { "Private", opaque, NULL },
|
|
|
|
/* 172 */ { "Private", opaque, NULL },
|
|
|
|
/* 173 */ { "Private", opaque, NULL },
|
|
|
|
/* 174 */ { "Private", opaque, NULL },
|
|
|
|
/* 175 */ { "Private", opaque, NULL },
|
|
|
|
/* 176 */ { "Private", opaque, NULL },
|
|
|
|
/* 177 */ { "Private", opaque, NULL },
|
|
|
|
/* 178 */ { "Private", opaque, NULL },
|
|
|
|
/* 179 */ { "Private", opaque, NULL },
|
|
|
|
/* 180 */ { "Private", opaque, NULL },
|
|
|
|
/* 181 */ { "Private", opaque, NULL },
|
|
|
|
/* 182 */ { "Private", opaque, NULL },
|
|
|
|
/* 183 */ { "Private", opaque, NULL },
|
|
|
|
/* 184 */ { "Private", opaque, NULL },
|
|
|
|
/* 185 */ { "Private", opaque, NULL },
|
|
|
|
/* 186 */ { "Private", opaque, NULL },
|
|
|
|
/* 187 */ { "Private", opaque, NULL },
|
|
|
|
/* 188 */ { "Private", opaque, NULL },
|
|
|
|
/* 189 */ { "Private", opaque, NULL },
|
|
|
|
/* 190 */ { "Private", opaque, NULL },
|
|
|
|
/* 191 */ { "Private", opaque, NULL },
|
|
|
|
/* 192 */ { "Private", opaque, NULL },
|
|
|
|
/* 193 */ { "Private", opaque, NULL },
|
|
|
|
/* 194 */ { "Private", opaque, NULL },
|
|
|
|
/* 195 */ { "Private", opaque, NULL },
|
|
|
|
/* 196 */ { "Private", opaque, NULL },
|
|
|
|
/* 197 */ { "Private", opaque, NULL },
|
|
|
|
/* 198 */ { "Private", opaque, NULL },
|
|
|
|
/* 199 */ { "Private", opaque, NULL },
|
|
|
|
/* 200 */ { "Private", opaque, NULL },
|
|
|
|
/* 201 */ { "Private", opaque, NULL },
|
|
|
|
/* 202 */ { "Private", opaque, NULL },
|
|
|
|
/* 203 */ { "Private", opaque, NULL },
|
|
|
|
/* 204 */ { "Private", opaque, NULL },
|
|
|
|
/* 205 */ { "Private", opaque, NULL },
|
|
|
|
/* 206 */ { "Private", opaque, NULL },
|
|
|
|
/* 207 */ { "Private", opaque, NULL },
|
|
|
|
/* 208 */ { "Private", opaque, NULL },
|
|
|
|
/* 209 */ { "Private", opaque, NULL },
|
|
|
|
/* 210 */ { "Authentication", special, NULL },
|
|
|
|
/* 211 */ { "Private", opaque, NULL },
|
|
|
|
/* 212 */ { "Private", opaque, NULL },
|
|
|
|
/* 213 */ { "Private", opaque, NULL },
|
|
|
|
/* 214 */ { "Private", opaque, NULL },
|
|
|
|
/* 215 */ { "Private", opaque, NULL },
|
|
|
|
/* 216 */ { "Private", opaque, NULL },
|
|
|
|
/* 217 */ { "Private", opaque, NULL },
|
|
|
|
/* 218 */ { "Private", opaque, NULL },
|
|
|
|
/* 219 */ { "Private", opaque, NULL },
|
|
|
|
/* 220 */ { "Private", opaque, NULL },
|
|
|
|
/* 221 */ { "Private", opaque, NULL },
|
|
|
|
/* 222 */ { "Private", opaque, NULL },
|
|
|
|
/* 223 */ { "Private", opaque, NULL },
|
|
|
|
/* 224 */ { "Private", opaque, NULL },
|
|
|
|
/* 225 */ { "Private", opaque, NULL },
|
|
|
|
/* 226 */ { "Private", opaque, NULL },
|
|
|
|
/* 227 */ { "Private", opaque, NULL },
|
|
|
|
/* 228 */ { "Private", opaque, NULL },
|
|
|
|
/* 229 */ { "Private", opaque, NULL },
|
|
|
|
/* 230 */ { "Private", opaque, NULL },
|
|
|
|
/* 231 */ { "Private", opaque, NULL },
|
|
|
|
/* 232 */ { "Private", opaque, NULL },
|
|
|
|
/* 233 */ { "Private", opaque, NULL },
|
|
|
|
/* 234 */ { "Private", opaque, NULL },
|
|
|
|
/* 235 */ { "Private", opaque, NULL },
|
|
|
|
/* 236 */ { "Private", opaque, NULL },
|
|
|
|
/* 237 */ { "Private", opaque, NULL },
|
|
|
|
/* 238 */ { "Private", opaque, NULL },
|
|
|
|
/* 239 */ { "Private", opaque, NULL },
|
|
|
|
/* 240 */ { "Private", opaque, NULL },
|
|
|
|
/* 241 */ { "Private", opaque, NULL },
|
|
|
|
/* 242 */ { "Private", opaque, NULL },
|
|
|
|
/* 243 */ { "Private", opaque, NULL },
|
|
|
|
/* 244 */ { "Private", opaque, NULL },
|
|
|
|
/* 245 */ { "Private", opaque, NULL },
|
|
|
|
/* 246 */ { "Private", opaque, NULL },
|
|
|
|
/* 247 */ { "Private", opaque, NULL },
|
|
|
|
/* 248 */ { "Private", opaque, NULL },
|
2007-08-21 21:40:18 +00:00
|
|
|
/* 249 */ { "Classless Static Route (Microsoft)", special, NULL },
|
2005-12-23 23:54:35 +00:00
|
|
|
/* 250 */ { "Private", opaque, NULL },
|
|
|
|
/* 251 */ { "Private", opaque, NULL },
|
|
|
|
/* 252 */ { "Proxy autodiscovery", string, NULL },
|
|
|
|
/* 253 */ { "Private", opaque, NULL },
|
|
|
|
/* 254 */ { "Private", opaque, NULL },
|
|
|
|
/* 255 */ { "Private", opaque, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *
|
2008-06-23 21:31:47 +00:00
|
|
|
bootp_get_opt_text(unsigned int idx)
|
2005-12-23 23:54:35 +00:00
|
|
|
{
|
2008-06-23 21:31:47 +00:00
|
|
|
if(idx>=(sizeof(bootp_opt)/sizeof(struct opt_info)))
|
2005-12-23 23:54:35 +00:00
|
|
|
return "unknown";
|
2008-06-23 21:31:47 +00:00
|
|
|
return bootp_opt[idx].text;
|
2005-12-23 23:54:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static const void *
|
2008-06-23 21:31:47 +00:00
|
|
|
bootp_get_opt_data(unsigned int idx)
|
2005-12-23 23:54:35 +00:00
|
|
|
{
|
2008-06-23 21:31:47 +00:00
|
|
|
if(idx>=(sizeof(bootp_opt)/sizeof(struct opt_info)))
|
2005-12-23 23:54:35 +00:00
|
|
|
return NULL;
|
2008-06-23 21:31:47 +00:00
|
|
|
return bootp_opt[idx].data;
|
2005-12-23 23:54:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static enum field_type
|
2008-06-23 21:31:47 +00:00
|
|
|
bootp_get_opt_ftype(unsigned int idx)
|
2005-12-23 23:54:35 +00:00
|
|
|
{
|
2008-06-23 21:31:47 +00:00
|
|
|
if(idx>=(sizeof(bootp_opt)/sizeof(struct opt_info)))
|
2005-12-23 23:54:35 +00:00
|
|
|
return none;
|
2008-06-23 21:31:47 +00:00
|
|
|
return bootp_opt[idx].ftype;
|
2005-12-23 23:54:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
/* Returns the number of bytes consumed by this option. */
|
|
|
|
static int
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
bootp_option(tvbuff_t *tvb, proto_tree *bp_tree, int voff, int eoff,
|
2001-12-27 23:53:10 +00:00
|
|
|
gboolean first_pass, gboolean *at_end, const char **dhcp_type_p,
|
2008-03-12 21:00:00 +00:00
|
|
|
const guint8 **vendor_class_id_p, guint8 *overload_p)
|
2000-07-09 22:46:53 +00:00
|
|
|
{
|
2005-07-21 17:17:16 +00:00
|
|
|
const char *text;
|
2000-07-09 22:46:53 +00:00
|
|
|
enum field_type ftype;
|
2002-08-02 23:36:07 +00:00
|
|
|
guchar code = tvb_get_guint8(tvb, voff);
|
2004-10-24 22:53:06 +00:00
|
|
|
int optlen;
|
2004-10-26 07:00:23 +00:00
|
|
|
const struct true_false_string *tfs;
|
|
|
|
const value_string *vs;
|
2002-08-02 23:36:07 +00:00
|
|
|
guchar byte;
|
2004-10-24 22:53:06 +00:00
|
|
|
int i, consumed;
|
|
|
|
int optoff, optleft, optend;
|
2002-08-02 23:36:07 +00:00
|
|
|
gulong time_secs;
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_tree *v_tree, *ft;
|
2000-07-09 22:46:53 +00:00
|
|
|
proto_item *vti;
|
2001-10-31 08:43:09 +00:00
|
|
|
guint8 protocol;
|
|
|
|
guint8 algorithm;
|
|
|
|
guint8 rdm;
|
2004-10-16 02:04:08 +00:00
|
|
|
guint8 fqdn_flags;
|
2002-09-28 04:12:38 +00:00
|
|
|
int o52voff, o52eoff;
|
|
|
|
gboolean o52at_end;
|
2004-10-05 17:44:53 +00:00
|
|
|
gboolean skip_opaque = FALSE;
|
2008-03-12 21:00:00 +00:00
|
|
|
guint8 s_option;
|
2006-01-11 22:05:43 +00:00
|
|
|
int ava_vid;
|
2008-08-11 12:00:27 +00:00
|
|
|
const gchar *dns_name;
|
2006-02-08 23:09:17 +00:00
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
static const value_string slpda_vals[] = {
|
|
|
|
{0x00, "Dynamic Discovery" },
|
|
|
|
{0x01, "Static Discovery" },
|
|
|
|
{0x80, "Backwards compatibility" },
|
|
|
|
{0, NULL } };
|
2003-11-18 19:56:37 +00:00
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
static const value_string slp_scope_vals[] = {
|
|
|
|
{0x00, "Preferred Scope" },
|
|
|
|
{0x01, "Mandatory Scope" },
|
|
|
|
{0, NULL } };
|
2003-11-18 19:56:37 +00:00
|
|
|
|
2001-10-31 08:43:09 +00:00
|
|
|
static const value_string authen_protocol_vals[] = {
|
|
|
|
{AUTHEN_PROTO_CONFIG_TOKEN, "configuration token" },
|
|
|
|
{AUTHEN_PROTO_DELAYED_AUTHEN, "delayed authentication" },
|
|
|
|
{0, NULL } };
|
|
|
|
|
|
|
|
static const value_string authen_da_algo_vals[] = {
|
|
|
|
{AUTHEN_DELAYED_ALGO_HMAC_MD5, "HMAC_MD5" },
|
|
|
|
{0, NULL } };
|
|
|
|
|
|
|
|
static const value_string authen_rdm_vals[] = {
|
|
|
|
{AUTHEN_RDM_MONOTONIC_COUNTER, "Monotonically-increasing counter" },
|
|
|
|
{0, NULL } };
|
|
|
|
|
2002-09-28 04:12:38 +00:00
|
|
|
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 } };
|
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
/* Options whose length isn't "optlen + 2". */
|
1998-09-16 02:39:15 +00:00
|
|
|
switch (code) {
|
2000-07-09 22:46:53 +00:00
|
|
|
|
|
|
|
case 0: /* Padding */
|
|
|
|
/* check how much padding we have */
|
|
|
|
for (i = voff + 1; i < eoff; i++ ) {
|
2001-01-03 22:49:06 +00:00
|
|
|
if (tvb_get_guint8(tvb, i) != 0) {
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
2000-07-09 22:46:53 +00:00
|
|
|
}
|
|
|
|
i = i - voff;
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
if (!first_pass) {
|
|
|
|
if (bp_tree != NULL) {
|
|
|
|
proto_tree_add_text(bp_tree, tvb, voff, i,
|
2006-08-16 00:12:02 +00:00
|
|
|
"Padding (%d byte%s)", i, (i>1)?"s":"");
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
}
|
|
|
|
}
|
2000-07-09 22:46:53 +00:00
|
|
|
consumed = i;
|
|
|
|
return consumed;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
case 255: /* End Option */
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
if (!first_pass) {
|
|
|
|
if (bp_tree != NULL) {
|
|
|
|
proto_tree_add_text(bp_tree, tvb, voff, 1,
|
2008-03-12 21:00:00 +00:00
|
|
|
"End Option%s", *overload_p?" (overload)":"");
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
}
|
|
|
|
}
|
2001-12-27 23:53:10 +00:00
|
|
|
*at_end = TRUE;
|
2000-07-09 22:46:53 +00:00
|
|
|
consumed = 1;
|
|
|
|
return consumed;
|
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-01-03 22:49:06 +00:00
|
|
|
/*
|
|
|
|
* Get the length of the option, and the number of bytes it
|
|
|
|
* consumes (the length doesn't include the option code or
|
|
|
|
* length bytes).
|
2001-12-27 22:49:02 +00:00
|
|
|
*
|
|
|
|
* On the first pass, check first whether we have the length
|
|
|
|
* byte, so that we don't throw an exception; if we throw an
|
|
|
|
* exception in the first pass, which is only checking for options
|
|
|
|
* whose values we need in order to properly dissect the packet
|
|
|
|
* on the second pass, we won't actually dissect the options, so
|
|
|
|
* you won't be able to see which option had the problem.
|
2001-01-03 22:49:06 +00:00
|
|
|
*/
|
2001-12-27 22:49:02 +00:00
|
|
|
if (first_pass) {
|
|
|
|
if (!tvb_bytes_exist(tvb, voff+1, 1)) {
|
|
|
|
/*
|
|
|
|
* We don't have the length byte; just return 1
|
|
|
|
* as the number of bytes we consumed, to count
|
|
|
|
* the code byte.
|
|
|
|
*/
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2004-10-24 22:53:06 +00:00
|
|
|
optlen = tvb_get_guint8(tvb, voff+1);
|
|
|
|
consumed = optlen + 2;
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* In the first pass, we don't put anything into the protocol
|
|
|
|
* tree; we just check for some options we have to look at
|
|
|
|
* in order to properly process the packet:
|
|
|
|
*
|
2008-03-12 21:00:00 +00:00
|
|
|
* 52 (Overload) - we need this to properly dissect the
|
|
|
|
* file and sname fields
|
|
|
|
*
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
* 53 (DHCP message type) - if this is present, this is DHCP
|
|
|
|
*
|
|
|
|
* 60 (Vendor class identifier) - we need this in order to
|
|
|
|
* interpret the vendor-specific info
|
2001-12-27 22:49:02 +00:00
|
|
|
*
|
|
|
|
* We also check, before fetching anything, to make sure we
|
|
|
|
* have the entire item we're fetching, so that we don't throw
|
|
|
|
* an exception.
|
2001-05-24 19:21:15 +00:00
|
|
|
*/
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
if (first_pass) {
|
2001-12-27 22:49:02 +00:00
|
|
|
if (tvb_bytes_exist(tvb, voff+2, consumed-2)) {
|
|
|
|
switch (code) {
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
|
2008-03-12 21:00:00 +00:00
|
|
|
case 52:
|
|
|
|
*overload_p = tvb_get_guint8(tvb, voff+2);
|
|
|
|
break;
|
|
|
|
|
2001-12-27 22:49:02 +00:00
|
|
|
case 53:
|
|
|
|
*dhcp_type_p =
|
2005-12-22 02:37:22 +00:00
|
|
|
val_to_str(tvb_get_guint8(tvb, voff+2),
|
|
|
|
opt53_text,
|
|
|
|
"Unknown Message Type (0x%02x)");
|
2001-12-27 22:49:02 +00:00
|
|
|
break;
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
|
2001-12-27 22:49:02 +00:00
|
|
|
case 60:
|
|
|
|
*vendor_class_id_p =
|
|
|
|
tvb_get_ptr(tvb, voff+2, consumed-2);
|
|
|
|
break;
|
|
|
|
}
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* We don't do anything else here.
|
|
|
|
*/
|
|
|
|
return consumed;
|
2001-05-24 19:21:15 +00:00
|
|
|
}
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This is the second pass - if there's a protocol tree to be
|
|
|
|
* built, we put stuff into it, otherwise we just return.
|
|
|
|
*/
|
2000-07-09 22:46:53 +00:00
|
|
|
if (bp_tree == NULL) {
|
|
|
|
/* Don't put anything in the protocol tree. */
|
|
|
|
return consumed;
|
|
|
|
}
|
|
|
|
|
2006-10-25 03:03:53 +00:00
|
|
|
/* Normal cases */
|
|
|
|
text = bootp_get_opt_text(code);
|
|
|
|
ftype = bootp_get_opt_ftype(code);
|
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
optoff = voff+2;
|
|
|
|
|
2006-08-15 20:32:08 +00:00
|
|
|
vti = proto_tree_add_text(bp_tree, tvb, voff, consumed,
|
2006-08-16 00:12:02 +00:00
|
|
|
"Option: (t=%d,l=%d) %s", code, optlen, text);
|
2006-08-15 20:32:08 +00:00
|
|
|
v_tree = proto_item_add_subtree(vti, ett_bootp_option);
|
2006-08-16 00:12:02 +00:00
|
|
|
proto_tree_add_uint_format_value(v_tree, hf_bootp_option_type,
|
|
|
|
tvb, voff, 1, code, "(%d) %s", code, text);
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_tree_add_item(v_tree, hf_bootp_option_length, tvb, voff+1, 1, FALSE);
|
|
|
|
if (optlen > 0) {
|
|
|
|
proto_tree_add_item(v_tree, hf_bootp_option_value, tvb, voff+2, optlen, FALSE);
|
|
|
|
}
|
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
/* Special cases */
|
|
|
|
switch (code) {
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
case 21: /* Policy Filter */
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optlen == 8) {
|
1998-09-16 02:39:15 +00:00
|
|
|
/* one IP address pair */
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " = %s/%s",
|
2004-10-24 22:53:06 +00:00
|
|
|
ip_to_str(tvb_get_ptr(tvb, optoff, 4)),
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, optoff+4, 4)));
|
2000-07-09 22:46:53 +00:00
|
|
|
} else {
|
1998-09-16 02:39:15 +00:00
|
|
|
/* > 1 IP address pair. Let's make a sub-tree */
|
2004-10-24 22:53:06 +00:00
|
|
|
for (i = optoff, optleft = optlen;
|
|
|
|
optleft > 0; i += 8, optleft -= 8) {
|
|
|
|
if (optleft < 8) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, i, optleft,
|
|
|
|
"Option length isn't a multiple of 8");
|
|
|
|
break;
|
|
|
|
}
|
2001-01-03 22:49:06 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, i, 8, "IP Address/Mask: %s/%s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, i, 4)),
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, i+4, 4)));
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
2000-07-09 22:46:53 +00:00
|
|
|
}
|
|
|
|
break;
|
1999-01-28 21:29:36 +00:00
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
case 33: /* Static Route */
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optlen == 8) {
|
2000-07-09 22:46:53 +00:00
|
|
|
/* one IP address pair */
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " = %s/%s",
|
2004-10-24 22:53:06 +00:00
|
|
|
ip_to_str(tvb_get_ptr(tvb, optoff, 4)),
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, optoff+4, 4)));
|
2000-07-09 22:46:53 +00:00
|
|
|
} else {
|
|
|
|
/* > 1 IP address pair. Let's make a sub-tree */
|
2004-10-24 22:53:06 +00:00
|
|
|
for (i = optoff, optleft = optlen; optleft > 0;
|
|
|
|
i += 8, optleft -= 8) {
|
|
|
|
if (optleft < 8) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, i, optleft,
|
|
|
|
"Option length isn't a multiple of 8");
|
|
|
|
break;
|
|
|
|
}
|
2001-01-03 22:49:06 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, i, 8,
|
2000-07-09 22:46:53 +00:00
|
|
|
"Destination IP Address/Router: %s/%s",
|
2001-01-03 22:49:06 +00:00
|
|
|
ip_to_str(tvb_get_ptr(tvb, i, 4)),
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, i+4, 4)));
|
1998-11-20 04:34:37 +00:00
|
|
|
}
|
2000-07-09 22:46:53 +00:00
|
|
|
}
|
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
case 43: /* Vendor-Specific Info */
|
2006-01-11 22:05:43 +00:00
|
|
|
s_option = tvb_get_guint8(tvb, optoff);
|
|
|
|
|
2007-09-13 18:51:32 +00:00
|
|
|
/* Alcatel-Lucent AVA */
|
2006-02-08 23:09:17 +00:00
|
|
|
if (optlen == 5 && s_option == 58)
|
|
|
|
{
|
2007-09-13 18:51:32 +00:00
|
|
|
proto_item_append_text(vti, " (Alcatel-Lucent AVA)");
|
2006-01-11 22:05:43 +00:00
|
|
|
ava_vid = tvb_get_ntohs(tvb, optoff + 2);
|
2007-09-13 18:51:32 +00:00
|
|
|
proto_tree_add_text (v_tree, tvb, optoff + 2,
|
|
|
|
2, "Opcode: 58");
|
2006-01-11 22:05:43 +00:00
|
|
|
|
2007-09-13 18:51:32 +00:00
|
|
|
proto_tree_add_uint (v_tree, hf_bootp_alu_vid, tvb, optoff + 2,
|
2006-01-11 22:05:43 +00:00
|
|
|
2, ava_vid);
|
|
|
|
|
|
|
|
if (ava_vid == 65535)
|
|
|
|
{
|
|
|
|
proto_tree_add_text (v_tree, tvb, optoff + 2,
|
2007-09-13 18:51:32 +00:00
|
|
|
2, "Type: Request from ALU IP Phone");
|
2006-01-11 22:05:43 +00:00
|
|
|
} else {
|
|
|
|
proto_tree_add_text (v_tree, tvb, optoff + 2,
|
2007-09-13 18:51:32 +00:00
|
|
|
2, "Type: Response from DHCP Server");
|
2006-01-11 22:05:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-09-13 18:51:32 +00:00
|
|
|
/* Alcatel-Lucent DHCP Extensions for Spatial Redundancy */
|
|
|
|
|
|
|
|
if ((optlen == 12 && s_option == 64) ||
|
|
|
|
(optlen == 6 && s_option == 64) ||
|
|
|
|
(optlen == 6 && s_option == 65))
|
|
|
|
{
|
|
|
|
if (optlen == 6 && s_option == 64)
|
|
|
|
{
|
|
|
|
proto_item_append_text(vti, " (Alcatel-Lucent TFTP Options)");
|
|
|
|
proto_tree_add_text (v_tree, tvb, optoff + 2,
|
|
|
|
2, "Opcode: 64");
|
|
|
|
proto_tree_add_ipv4(v_tree,hf_bootp_alu_tftp1 ,tvb,optoff+2, 4,
|
|
|
|
tvb_get_ipv4(tvb,optoff+2));
|
|
|
|
}
|
|
|
|
if (optlen == 6 && s_option == 65)
|
|
|
|
{
|
|
|
|
proto_item_append_text(vti, " (Alcatel-Lucent TFTP Options)");
|
|
|
|
proto_tree_add_text (v_tree, tvb, optoff + 2,
|
|
|
|
2, "Opcode: 65");
|
|
|
|
proto_tree_add_ipv4(v_tree,hf_bootp_alu_tftp2 ,tvb,optoff+2 ,4,
|
|
|
|
tvb_get_ipv4(tvb,optoff+2));
|
|
|
|
}
|
|
|
|
if (optlen == 12 && s_option == 64)
|
|
|
|
{
|
|
|
|
proto_item_append_text(vti, " (Alcatel-Lucent TFTP Options)");
|
|
|
|
proto_tree_add_text (v_tree, tvb, optoff + 2,
|
|
|
|
2, "Opcode: 64 and 65");
|
|
|
|
proto_tree_add_ipv4(v_tree,hf_bootp_alu_tftp1 ,tvb,optoff+2 ,4,
|
|
|
|
tvb_get_ipv4(tvb,optoff+2));
|
|
|
|
proto_tree_add_ipv4(v_tree,hf_bootp_alu_tftp2 ,tvb,optoff+8 ,4,
|
|
|
|
tvb_get_ipv4(tvb,optoff+8));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-05-24 19:21:15 +00:00
|
|
|
/* PXE protocol 2.1 as described in the intel specs */
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
if (*vendor_class_id_p != NULL &&
|
2007-04-23 10:59:26 +00:00
|
|
|
strncmp((const gchar*)*vendor_class_id_p, "PXEClient", strlen("PXEClient")) == 0) {
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " (PXEClient)");
|
2001-05-24 19:21:15 +00:00
|
|
|
v_tree = proto_item_add_subtree(vti, ett_bootp_option);
|
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
optend = optoff + optlen;
|
|
|
|
while (optoff < optend) {
|
|
|
|
optoff = dissect_vendor_pxeclient_suboption(v_tree,
|
2004-10-25 08:17:11 +00:00
|
|
|
tvb, optoff, optend);
|
2001-05-24 19:21:15 +00:00
|
|
|
}
|
2004-10-05 17:44:53 +00:00
|
|
|
} else if (*vendor_class_id_p != NULL &&
|
2007-04-23 10:59:26 +00:00
|
|
|
((strncmp((const gchar*)*vendor_class_id_p, "pktc", strlen("pktc")) == 0) ||
|
|
|
|
(strncmp((const gchar*)*vendor_class_id_p, "docsis", strlen("docsis")) == 0) ||
|
2007-12-14 20:14:15 +00:00
|
|
|
(strncmp((const gchar*)*vendor_class_id_p, "OpenCable2.0", strlen("OpenCable2.0")) == 0) ||
|
2007-04-23 10:59:26 +00:00
|
|
|
(strncmp((const gchar*)*vendor_class_id_p, "CableHome", strlen("CableHome")) == 0))) {
|
2004-05-07 08:02:23 +00:00
|
|
|
/* CableLabs standard - see www.cablelabs.com/projects */
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " (CableLabs)");
|
2004-05-07 08:02:23 +00:00
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
optend = optoff + optlen;
|
|
|
|
while (optoff < optend) {
|
|
|
|
optoff = dissect_vendor_cablelabs_suboption(v_tree,
|
2004-10-25 08:17:11 +00:00
|
|
|
tvb, optoff, optend);
|
2004-05-07 08:02:23 +00:00
|
|
|
}
|
2001-05-24 19:21:15 +00:00
|
|
|
}
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2002-09-28 04:12:38 +00:00
|
|
|
case 52: /* Option Overload */
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optlen < 1) {
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " length isn't >= 1");
|
2004-10-24 22:53:06 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
byte = tvb_get_guint8(tvb, optoff);
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " = %s",
|
2002-09-28 04:12:38 +00:00
|
|
|
val_to_str(byte, opt_overload_vals,
|
|
|
|
"Unknown (0x%02x)"));
|
2004-10-05 17:44:53 +00:00
|
|
|
|
2002-09-28 04:12:38 +00:00
|
|
|
/* Just in case we find an option 52 in sname or file */
|
|
|
|
if (voff > VENDOR_INFO_OFFSET && byte >= 1 && byte <= 3) {
|
2008-03-12 21:00:00 +00:00
|
|
|
if (byte & OPT_OVERLOAD_FILE) {
|
|
|
|
proto_tree_add_text (bp_tree, tvb,
|
2002-09-28 04:12:38 +00:00
|
|
|
FILE_NAME_OFFSET, FILE_NAME_LEN,
|
|
|
|
"Boot file name option overload");
|
|
|
|
o52voff = FILE_NAME_OFFSET;
|
|
|
|
o52eoff = FILE_NAME_OFFSET + FILE_NAME_LEN;
|
|
|
|
o52at_end = FALSE;
|
|
|
|
while (o52voff < o52eoff && !o52at_end) {
|
2008-03-12 21:00:00 +00:00
|
|
|
o52voff += bootp_option(tvb, bp_tree, o52voff,
|
2002-09-28 04:12:38 +00:00
|
|
|
o52eoff, FALSE, &o52at_end,
|
2008-03-12 21:00:00 +00:00
|
|
|
dhcp_type_p, vendor_class_id_p,
|
|
|
|
overload_p);
|
2002-09-28 04:12:38 +00:00
|
|
|
}
|
|
|
|
}
|
2008-03-12 21:00:00 +00:00
|
|
|
if (byte & OPT_OVERLOAD_SNAME) {
|
|
|
|
proto_tree_add_text (bp_tree, tvb,
|
2004-10-05 17:44:53 +00:00
|
|
|
SERVER_NAME_OFFSET, SERVER_NAME_LEN,
|
2002-09-28 04:12:38 +00:00
|
|
|
"Server host name option overload");
|
|
|
|
o52voff = SERVER_NAME_OFFSET;
|
|
|
|
o52eoff = SERVER_NAME_OFFSET + SERVER_NAME_LEN;
|
|
|
|
o52at_end = FALSE;
|
|
|
|
while (o52voff < o52eoff && !o52at_end) {
|
2008-03-12 21:00:00 +00:00
|
|
|
o52voff += bootp_option(tvb, bp_tree, o52voff,
|
2002-09-28 04:12:38 +00:00
|
|
|
o52eoff, FALSE, &o52at_end,
|
2008-03-12 21:00:00 +00:00
|
|
|
dhcp_type_p, vendor_class_id_p,
|
|
|
|
overload_p);
|
2002-09-28 04:12:38 +00:00
|
|
|
}
|
|
|
|
}
|
2008-03-12 21:00:00 +00:00
|
|
|
/* The final end option is not in overload */
|
|
|
|
*overload_p = 0;
|
2002-09-28 04:12:38 +00:00
|
|
|
}
|
|
|
|
break;
|
2004-10-26 07:00:23 +00:00
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
case 53: /* DHCP Message Type */
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optlen != 1) {
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " length isn't 1");
|
2004-10-24 22:53:06 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " = DHCP %s",
|
|
|
|
val_to_str(tvb_get_guint8(tvb, optoff),
|
|
|
|
opt53_text,
|
|
|
|
"Unknown Message Type (0x%02x)"));
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
2000-03-20 21:39:00 +00:00
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
case 55: /* Parameter Request List */
|
2004-10-24 22:53:06 +00:00
|
|
|
for (i = 0; i < optlen; i++) {
|
|
|
|
byte = tvb_get_guint8(tvb, optoff+i);
|
2005-12-23 23:54:35 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff+i, 1, "%d = %s",
|
|
|
|
byte, bootp_get_opt_text(byte));
|
2000-03-20 21:39:00 +00:00
|
|
|
}
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
2000-03-20 21:39:00 +00:00
|
|
|
|
2001-05-24 19:21:15 +00:00
|
|
|
case 60: /* Vendor class identifier */
|
2004-10-05 23:22:36 +00:00
|
|
|
/*
|
|
|
|
* XXX - RFC 2132 says this is a string of octets;
|
|
|
|
* should we check for non-printables?
|
|
|
|
*/
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " = \"%s\"",
|
2004-10-24 22:53:06 +00:00
|
|
|
tvb_format_stringzpad(tvb, optoff, consumed-2));
|
2007-05-24 17:36:07 +00:00
|
|
|
if ((tvb_memeql(tvb, optoff, (const guint8*)PACKETCABLE_MTA_CAP10,
|
2007-03-26 11:06:26 +00:00
|
|
|
strlen(PACKETCABLE_MTA_CAP10)) == 0)
|
|
|
|
||
|
2007-05-24 17:36:07 +00:00
|
|
|
(tvb_memeql(tvb, optoff, (const guint8*)PACKETCABLE_MTA_CAP15,
|
|
|
|
strlen(PACKETCABLE_MTA_CAP10)) == 0))
|
2007-03-26 11:06:26 +00:00
|
|
|
{
|
2004-10-24 22:53:06 +00:00
|
|
|
dissect_packetcable_mta_cap(v_tree, tvb, optoff, optlen);
|
2007-05-24 17:36:07 +00:00
|
|
|
}
|
2007-03-26 11:06:26 +00:00
|
|
|
else {
|
2007-05-24 17:36:07 +00:00
|
|
|
if (tvb_memeql(tvb, optoff, (const guint8*)PACKETCABLE_CM_CAP11,
|
2007-03-26 11:06:26 +00:00
|
|
|
strlen(PACKETCABLE_CM_CAP11)) == 0
|
|
|
|
||
|
2007-05-24 17:36:07 +00:00
|
|
|
tvb_memeql(tvb, optoff, (const guint8*)PACKETCABLE_CM_CAP20,
|
|
|
|
strlen(PACKETCABLE_CM_CAP20)) == 0 )
|
2007-03-26 11:06:26 +00:00
|
|
|
{
|
2004-10-24 22:53:06 +00:00
|
|
|
dissect_docsis_cm_cap(v_tree, tvb, optoff, optlen);
|
2007-03-26 11:06:26 +00:00
|
|
|
}
|
2004-10-05 17:44:53 +00:00
|
|
|
}
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
break;
|
2001-05-24 19:21:15 +00:00
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
case 61: /* Client Identifier */
|
2006-03-09 04:31:10 +00:00
|
|
|
case 97: /* Client Identifier (UUID) */
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optlen > 0)
|
|
|
|
byte = tvb_get_guint8(tvb, optoff);
|
2004-10-16 05:59:24 +00:00
|
|
|
else
|
|
|
|
byte = 0;
|
2004-10-16 00:19:07 +00:00
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
/* 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 */
|
2004-10-16 00:19:07 +00:00
|
|
|
/* See http://www.iana.org/assignments/arp-parameters */
|
|
|
|
/* RFC2132 9.14 Client-identifier has the following to say:
|
|
|
|
A hardware type of 0 (zero) should be used when the value
|
|
|
|
field contains an identifier other than a hardware address
|
|
|
|
(e.g. a fully qualified domain name). */
|
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optlen == 7 && byte > 0 && byte < 48) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
2000-07-09 22:46:53 +00:00
|
|
|
"Hardware type: %s",
|
2004-10-16 00:19:07 +00:00
|
|
|
arphrdtype_to_str(byte,
|
2000-07-09 22:46:53 +00:00
|
|
|
"Unknown (0x%02x)"));
|
2004-12-26 22:26:02 +00:00
|
|
|
if (byte == ARPHRD_ETHER || byte == ARPHRD_IEEE802)
|
|
|
|
proto_tree_add_item(v_tree,
|
|
|
|
hf_bootp_hw_ether_addr, tvb, optoff+1, 6,
|
|
|
|
FALSE);
|
|
|
|
else
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff+1, 6,
|
|
|
|
"Client hardware address: %s",
|
|
|
|
arphrdaddr_to_str(tvb_get_ptr(tvb, optoff+1, 6),
|
2004-10-16 00:19:07 +00:00
|
|
|
6, byte));
|
2006-03-09 04:31:10 +00:00
|
|
|
} else if (optlen == 17 && byte == 0) {
|
|
|
|
/* Identifier is a UUID */
|
|
|
|
proto_tree_add_item(v_tree, hf_bootp_client_identifier_uuid,
|
|
|
|
tvb, optoff + 1, 16, TRUE);
|
2000-07-09 22:46:53 +00:00
|
|
|
} else {
|
|
|
|
/* otherwise, it's opaque data */
|
2000-03-20 21:39:00 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
case 63: /* NetWare/IP options (RFC 2242) */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
optend = optoff + optlen;
|
|
|
|
while (optoff < optend)
|
2004-10-25 08:17:11 +00:00
|
|
|
optoff = dissect_netware_ip_suboption(v_tree, tvb, optoff, optend);
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-05 23:22:36 +00:00
|
|
|
case 78: /* SLP Directory Agent Option RFC2610 Added by Greg Morris (gmorris@novell.com)*/
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optlen < 1) {
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " length isn't >= 1");
|
2004-10-24 22:53:06 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
optleft = optlen;
|
|
|
|
byte = tvb_get_guint8(tvb, optoff);
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " = %s",
|
2003-11-18 19:56:37 +00:00
|
|
|
val_to_str(byte, slpda_vals,
|
2006-08-15 20:32:08 +00:00
|
|
|
"Unknown (0x%02x)"));
|
2004-10-24 22:53:06 +00:00
|
|
|
optoff++;
|
|
|
|
optleft--;
|
2004-10-05 23:22:36 +00:00
|
|
|
if (byte == 0x80) {
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optleft == 0)
|
|
|
|
break;
|
|
|
|
optoff++;
|
|
|
|
optleft--;
|
2004-10-05 23:22:36 +00:00
|
|
|
}
|
2004-10-24 22:53:06 +00:00
|
|
|
for (i = optoff; optleft > 0; i += 4, optleft -= 4) {
|
|
|
|
if (optleft < 4) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, i, optleft,
|
|
|
|
"Option length isn't a multiple of 4");
|
|
|
|
break;
|
|
|
|
}
|
2004-10-05 23:22:36 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, i, 4, "SLPDA Address: %s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, i, 4)));
|
|
|
|
}
|
2003-11-18 19:56:37 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-05 23:22:36 +00:00
|
|
|
case 79: /* SLP Service Scope Option RFC2610 Added by Greg Morris (gmorris@novell.com)*/
|
2004-10-24 22:53:06 +00:00
|
|
|
byte = tvb_get_guint8(tvb, optoff);
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " = %s",
|
2003-11-18 19:56:37 +00:00
|
|
|
val_to_str(byte, slp_scope_vals,
|
|
|
|
"Unknown (0x%02x)"));
|
2004-10-24 22:53:06 +00:00
|
|
|
optoff++;
|
|
|
|
optleft = optlen - 1;
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optleft,
|
2004-10-05 23:22:36 +00:00
|
|
|
"%s = \"%s\"", text,
|
2004-10-24 22:53:06 +00:00
|
|
|
tvb_format_stringzpad(tvb, optoff, optleft));
|
2003-11-18 19:56:37 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-16 02:04:08 +00:00
|
|
|
case 81: /* Client Fully Qualified Domain Name */
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optlen < 3) {
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " length isn't >= 3");
|
2004-10-24 22:53:06 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
fqdn_flags = tvb_get_guint8(tvb, optoff);
|
|
|
|
ft = proto_tree_add_text(v_tree, tvb, optoff, 1, "Flags: 0x%02x", fqdn_flags);
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_tree_add_item(v_tree, hf_bootp_fqdn_mbz, tvb, optoff, 1, FALSE);
|
|
|
|
proto_tree_add_item(v_tree, hf_bootp_fqdn_n, tvb, optoff, 1, FALSE);
|
|
|
|
proto_tree_add_item(v_tree, hf_bootp_fqdn_e, tvb, optoff, 1, FALSE);
|
|
|
|
proto_tree_add_item(v_tree, hf_bootp_fqdn_o, tvb, optoff, 1, FALSE);
|
|
|
|
proto_tree_add_item(v_tree, hf_bootp_fqdn_s, tvb, optoff, 1, FALSE);
|
2004-10-16 02:04:08 +00:00
|
|
|
/* XXX: use code from packet-dns for return code decoding */
|
2004-10-24 22:53:06 +00:00
|
|
|
proto_tree_add_item(v_tree, hf_bootp_fqdn_rcode1, tvb, optoff+1, 1, FALSE);
|
2004-10-16 02:04:08 +00:00
|
|
|
/* XXX: use code from packet-dns for return code decoding */
|
2004-10-24 22:53:06 +00:00
|
|
|
proto_tree_add_item(v_tree, hf_bootp_fqdn_rcode2, tvb, optoff+2, 1, FALSE);
|
|
|
|
if (optlen > 3) {
|
2004-10-24 10:30:03 +00:00
|
|
|
if (fqdn_flags & F_FQDN_E) {
|
2008-08-11 12:00:27 +00:00
|
|
|
get_dns_name(tvb, optoff+3, optlen-3, optoff+3, &dns_name);
|
|
|
|
proto_tree_add_string(v_tree, hf_bootp_fqdn_name,
|
|
|
|
tvb, optoff+3, optlen-3, dns_name);
|
2004-10-24 10:30:03 +00:00
|
|
|
} else {
|
|
|
|
proto_tree_add_item(v_tree, hf_bootp_fqdn_asciiname,
|
2004-10-24 22:53:06 +00:00
|
|
|
tvb, optoff+3, optlen-3, FALSE);
|
2004-10-24 10:30:03 +00:00
|
|
|
}
|
2004-10-16 02:04:08 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2001-02-13 00:01:08 +00:00
|
|
|
case 82: /* Relay Agent Information Option */
|
2004-10-24 22:53:06 +00:00
|
|
|
optend = optoff + optlen;
|
|
|
|
while (optoff < optend)
|
2004-10-25 08:17:11 +00:00
|
|
|
optoff = bootp_dhcp_decode_agent_info(v_tree, tvb, optoff, optend);
|
2001-02-13 00:01:08 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
case 85: /* Novell Servers (RFC 2241) */
|
2004-10-05 23:22:36 +00:00
|
|
|
/* Option 85 can be sent as a string */
|
|
|
|
/* Added by Greg Morris (gmorris[AT]novell.com) */
|
|
|
|
if (novell_string) {
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " = \"%s\"",
|
2004-10-24 22:53:06 +00:00
|
|
|
tvb_format_stringzpad(tvb, optoff, optlen));
|
2004-10-05 23:22:36 +00:00
|
|
|
} else {
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optlen == 4) {
|
2003-11-18 19:56:37 +00:00
|
|
|
/* one IP address */
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " = %s",
|
2004-10-24 22:53:06 +00:00
|
|
|
ip_to_str(tvb_get_ptr(tvb, optoff, 4)));
|
2003-11-18 19:56:37 +00:00
|
|
|
} else {
|
|
|
|
/* > 1 IP addresses. Let's make a sub-tree */
|
2004-10-24 22:53:06 +00:00
|
|
|
for (i = optoff, optleft = optlen; optleft > 0;
|
|
|
|
i += 4, optleft -= 4) {
|
|
|
|
if (optleft < 4) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, i, optleft,
|
|
|
|
"Option length isn't a multiple of 4");
|
|
|
|
break;
|
|
|
|
}
|
2003-11-18 19:56:37 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, i, 4, "IP Address: %s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, i, 4)));
|
|
|
|
}
|
|
|
|
}
|
2004-10-24 22:53:06 +00:00
|
|
|
}
|
|
|
|
break;
|
2003-11-18 19:56:37 +00:00
|
|
|
|
2006-03-09 04:31:10 +00:00
|
|
|
case 94: { /* Client network interface identifier */
|
|
|
|
guint8 id_type;
|
|
|
|
|
|
|
|
id_type = tvb_get_guint8(tvb, optoff);
|
|
|
|
|
|
|
|
if (id_type == 0x01) {
|
|
|
|
proto_tree_add_item(v_tree, hf_bootp_client_network_id_major_ver,
|
|
|
|
tvb, optoff + 1, 1, TRUE);
|
|
|
|
proto_tree_add_item(v_tree, hf_bootp_client_network_id_minor_ver,
|
|
|
|
tvb, optoff + 2, 1, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-10-31 08:43:09 +00:00
|
|
|
case 90: /* DHCP Authentication */
|
|
|
|
case 210: /* Was this used for authentication at one time? */
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optlen < 11) {
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti, " length isn't >= 11");
|
2004-10-24 22:53:06 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
optleft = optlen;
|
|
|
|
protocol = tvb_get_guint8(tvb, optoff);
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1, "Protocol: %s (%u)",
|
2001-10-31 08:43:09 +00:00
|
|
|
val_to_str(protocol, authen_protocol_vals, "Unknown"),
|
|
|
|
protocol);
|
2004-10-24 22:53:06 +00:00
|
|
|
optoff++;
|
|
|
|
optleft--;
|
2001-10-31 08:43:09 +00:00
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
algorithm = tvb_get_guint8(tvb, optoff);
|
2001-10-31 08:43:09 +00:00
|
|
|
switch (protocol) {
|
|
|
|
|
|
|
|
case AUTHEN_PROTO_DELAYED_AUTHEN:
|
2004-10-24 22:53:06 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
2001-10-31 08:43:09 +00:00
|
|
|
"Algorithm: %s (%u)",
|
|
|
|
val_to_str(algorithm, authen_da_algo_vals, "Unknown"),
|
|
|
|
algorithm);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2004-10-24 22:53:06 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
2001-10-31 08:43:09 +00:00
|
|
|
"Algorithm: %u", algorithm);
|
|
|
|
break;
|
|
|
|
}
|
2004-10-24 22:53:06 +00:00
|
|
|
optoff++;
|
|
|
|
optleft--;
|
2001-10-31 08:43:09 +00:00
|
|
|
|
2004-10-24 22:53:06 +00:00
|
|
|
rdm = tvb_get_guint8(tvb, optoff);
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
2001-10-31 08:43:09 +00:00
|
|
|
"Replay Detection Method: %s (%u)",
|
|
|
|
val_to_str(rdm, authen_rdm_vals, "Unknown"),
|
|
|
|
rdm);
|
2004-10-24 22:53:06 +00:00
|
|
|
optoff++;
|
|
|
|
optleft--;
|
2001-10-31 08:43:09 +00:00
|
|
|
|
|
|
|
switch (rdm) {
|
|
|
|
|
|
|
|
case AUTHEN_RDM_MONOTONIC_COUNTER:
|
2004-10-24 22:53:06 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 8,
|
2007-05-29 18:52:42 +00:00
|
|
|
"RDM Replay Detection Value: %" G_GINT64_MODIFIER "x",
|
2004-10-24 22:53:06 +00:00
|
|
|
tvb_get_ntoh64(tvb, optoff));
|
2001-10-31 08:43:09 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2004-10-24 22:53:06 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 8,
|
2002-08-28 21:04:11 +00:00
|
|
|
"Replay Detection Value: %s",
|
2004-10-24 22:53:06 +00:00
|
|
|
tvb_bytes_to_str(tvb, optoff, 8));
|
2001-10-31 08:43:09 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-10-24 22:53:06 +00:00
|
|
|
optoff += 8;
|
|
|
|
optleft -= 8;
|
2001-10-31 08:43:09 +00:00
|
|
|
|
|
|
|
switch (protocol) {
|
|
|
|
|
|
|
|
case AUTHEN_PROTO_DELAYED_AUTHEN:
|
|
|
|
switch (algorithm) {
|
|
|
|
|
|
|
|
case AUTHEN_DELAYED_ALGO_HMAC_MD5:
|
2007-05-24 17:36:07 +00:00
|
|
|
if (*dhcp_type_p && !strcmp(*dhcp_type_p, OPT53_DISCOVER)) {
|
2007-05-02 06:17:19 +00:00
|
|
|
/* Discover has no Secret ID nor HMAC MD5 Hash */
|
2004-10-24 22:53:06 +00:00
|
|
|
break;
|
2007-05-02 06:17:19 +00:00
|
|
|
} else {
|
|
|
|
if (optlen < 31) {
|
|
|
|
proto_item_append_text(vti,
|
|
|
|
" length isn't >= 31");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 4,
|
|
|
|
"Secret ID: 0x%08x",
|
|
|
|
tvb_get_ntohl(tvb, optoff));
|
|
|
|
optoff += 4;
|
|
|
|
optleft -= 4;
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 16,
|
|
|
|
"HMAC MD5 Hash: %s",
|
|
|
|
tvb_bytes_to_str(tvb, optoff, 16));
|
2007-05-24 17:36:07 +00:00
|
|
|
break;
|
2004-10-24 22:53:06 +00:00
|
|
|
}
|
2001-10-31 08:43:09 +00:00
|
|
|
default:
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optleft == 0)
|
|
|
|
break;
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optleft,
|
2001-10-31 08:43:09 +00:00
|
|
|
"Authentication Information: %s",
|
2004-10-24 22:53:06 +00:00
|
|
|
tvb_bytes_to_str(tvb, optoff, optleft));
|
2001-10-31 08:43:09 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2004-10-24 22:53:06 +00:00
|
|
|
if (optleft == 0)
|
|
|
|
break;
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optleft,
|
2001-10-31 08:43:09 +00:00
|
|
|
"Authentication Information: %s",
|
2004-10-24 22:53:06 +00:00
|
|
|
tvb_bytes_to_str(tvb, optoff, optleft));
|
2001-10-31 08:43:09 +00:00
|
|
|
break;
|
2001-05-01 03:54:04 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2008-02-21 07:05:44 +00:00
|
|
|
case 99: /* civic location (RFC 4776) */
|
2008-03-13 05:24:21 +00:00
|
|
|
|
2008-02-21 07:05:44 +00:00
|
|
|
optleft = optlen;
|
|
|
|
if (optleft >= 3)
|
|
|
|
{
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1, "What: %d (%s)",
|
|
|
|
tvb_get_guint8(tvb, optoff), val_to_str(tvb_get_guint8(tvb, optoff),
|
|
|
|
civic_address_what_values, "Unknown") );
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff + 1, 2, "Country: \"%s\"",
|
|
|
|
tvb_format_text(tvb, optoff + 1, 2) );
|
|
|
|
optleft = optleft - 3;
|
|
|
|
optoff = optoff + 3;
|
|
|
|
|
|
|
|
while (optleft >= 2)
|
|
|
|
{
|
|
|
|
int catype = tvb_get_guint8(tvb, optoff);
|
|
|
|
optoff++;
|
|
|
|
optleft--;
|
|
|
|
s_option = tvb_get_guint8(tvb, optoff);
|
|
|
|
optoff++;
|
|
|
|
optleft--;
|
|
|
|
|
|
|
|
if (s_option == 0)
|
|
|
|
{
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, s_option,
|
|
|
|
"CAType %d [%s] (l=%d): EMTPY", catype,
|
|
|
|
val_to_str(catype, civic_address_type_values,
|
|
|
|
"Unknown"), s_option);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2008-03-12 21:00:00 +00:00
|
|
|
if (optleft >= s_option)
|
2008-02-21 07:05:44 +00:00
|
|
|
{
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, s_option,
|
|
|
|
"CAType %d [%s] (l=%d): \"%s\"", catype,
|
|
|
|
val_to_str(catype, civic_address_type_values,
|
|
|
|
"Unknown"), s_option,
|
|
|
|
tvb_format_text(tvb, optoff, s_option));
|
|
|
|
optoff = optoff + s_option;
|
|
|
|
optleft = optleft - s_option;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
optleft = 0;
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, s_option,
|
|
|
|
"Error with CAType");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
2007-08-21 21:40:18 +00:00
|
|
|
case 121: /* Classless Static Route */
|
|
|
|
case 249: { /* Classless Static Route (Microsoft) */
|
2007-07-24 21:23:55 +00:00
|
|
|
int mask_width, significant_octets;
|
|
|
|
optend = optoff + optlen;
|
|
|
|
/* minimum length is 5 bytes */
|
|
|
|
if (optlen < 5) {
|
|
|
|
proto_item_append_text(vti, " [ERROR: Option length < 5 bytes]");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
while (optoff < optend) {
|
|
|
|
mask_width = tvb_get_guint8(tvb, optoff);
|
|
|
|
/* mask_width <= 32 */
|
|
|
|
if (mask_width > 32) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff,
|
|
|
|
optend - optoff,
|
|
|
|
"Subnet/MaskWidth-Router: [ERROR: Mask width (%d) > 32]",
|
|
|
|
mask_width);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
significant_octets = (mask_width + 7) / 8;
|
|
|
|
vti = proto_tree_add_text(v_tree, tvb, optoff,
|
|
|
|
1 + significant_octets + 4,
|
|
|
|
"Subnet/MaskWidth-Router: ");
|
|
|
|
optoff++;
|
|
|
|
/* significant octets + router(4) */
|
|
|
|
if (optend < optoff + significant_octets + 4) {
|
|
|
|
proto_item_append_text(vti, "[ERROR: Remaining length (%d) < %d bytes]",
|
|
|
|
optend - optoff, significant_octets + 4);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(mask_width == 0)
|
|
|
|
proto_item_append_text(vti, "default");
|
|
|
|
else {
|
|
|
|
for(i = 0 ; i < significant_octets ; i++) {
|
|
|
|
if (i > 0)
|
|
|
|
proto_item_append_text(vti, ".");
|
|
|
|
byte = tvb_get_guint8(tvb, optoff++);
|
|
|
|
proto_item_append_text(vti, "%d", byte);
|
|
|
|
}
|
|
|
|
for(i = significant_octets ; i < 4 ; i++)
|
|
|
|
proto_item_append_text(vti, ".0");
|
|
|
|
proto_item_append_text(vti, "/%d", mask_width);
|
|
|
|
}
|
|
|
|
proto_item_append_text(vti, "-%s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, optoff, 4)));
|
|
|
|
optoff += 4;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2008-10-08 18:26:53 +00:00
|
|
|
case 123: /* coordinate based location RFC 3825 */
|
|
|
|
if (optlen == 16) {
|
|
|
|
int c, i;
|
|
|
|
unsigned char lci[16];
|
|
|
|
struct rfc3825_location_fixpoint_t location_fp;
|
|
|
|
struct rfc3825_location_decimal_t location;
|
|
|
|
|
|
|
|
for (c=0; c < 16;c++)
|
|
|
|
lci[c] = (unsigned char) tvb_get_guint8(tvb, optoff + c);
|
|
|
|
|
|
|
|
/* convert lci encoding into fixpoint location */
|
|
|
|
rfc3825_lci_to_fixpoint(lci, &location_fp);
|
|
|
|
|
|
|
|
/* convert location from decimal to fixpoint */
|
|
|
|
i = rfc3825_fixpoint_to_decimal(&location_fp, &location);
|
|
|
|
|
|
|
|
if (i != RFC3825_NOERROR) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optlen, "Error: %s", val_to_str(i, rfc3825_error_types, "Unknown"));
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 5, "Latitude: %15.10f", location.latitude);
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff+5, 5, "Longitude: %15.10f", location.longitude);
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1, "Latitude resolution: %15.10f", location.latitude_res);
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff+5, 1, "Longitude resolution: %15.10f", location.longitude_res);
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff+12, 4, "Altitude: %15.10f", location.altitude);
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff+10, 2, "Altitude resolution: %15.10f", location.altitude_res);
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff+10, 1, "Altitude type: %s (%d)", val_to_str(location.altitude_type, altitude_type_values, "Unknown"), location.altitude_type);
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff+15, 1, "Map Datum: %s (%d)", val_to_str(location.datum_type, map_datum_type_values, "Unknown"), location.datum_type);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optlen, "Error: Invalid length of DHCP option!");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2007-02-11 03:36:04 +00:00
|
|
|
case 125: { /* V-I Vendor-specific Information */
|
|
|
|
int enterprise = 0;
|
|
|
|
int s_end = 0;
|
|
|
|
int s_option_len = 0;
|
|
|
|
proto_tree *e_tree = 0;
|
|
|
|
|
|
|
|
optend = optoff + optlen;
|
|
|
|
|
|
|
|
optleft = optlen;
|
|
|
|
|
|
|
|
while (optleft > 0) {
|
|
|
|
|
|
|
|
if (optleft < 5) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff,
|
|
|
|
optleft, "Vendor-specific Information: malformed option");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
enterprise = tvb_get_ntohl(tvb, optoff);
|
|
|
|
|
|
|
|
vti = proto_tree_add_text(v_tree, tvb, optoff, 4,
|
|
|
|
"Enterprise-number: %s-%u",
|
|
|
|
val_to_str( enterprise, sminmpec_values, "Unknown"),
|
|
|
|
enterprise);
|
|
|
|
|
|
|
|
s_option_len = tvb_get_guint8(tvb, optoff + 4);
|
|
|
|
|
|
|
|
optoff += 5;
|
|
|
|
optleft -= 5;
|
|
|
|
|
|
|
|
/* Handle DSL Forum TR-111 Option 125 */
|
|
|
|
if ( enterprise == 3561 ) {
|
2007-05-24 17:36:07 +00:00
|
|
|
|
|
|
|
s_end = optoff + s_option_len;
|
2007-02-11 03:36:04 +00:00
|
|
|
if ( s_end > optend ) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
|
|
|
"no room left in option for enterprise %u data", enterprise);
|
|
|
|
break;
|
|
|
|
}
|
2007-05-24 17:36:07 +00:00
|
|
|
|
|
|
|
|
2007-02-11 03:36:04 +00:00
|
|
|
e_tree = proto_item_add_subtree(vti, ett_bootp_option);
|
|
|
|
while (optoff < s_end) {
|
|
|
|
|
|
|
|
optoff = dissect_vendor_tr111_suboption(e_tree,
|
|
|
|
tvb, optoff, s_end);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
/* skip over the data and look for next enterprise number */
|
|
|
|
optoff += s_option_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
optleft -= s_option_len;
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
default: /* not special */
|
2004-10-05 17:44:53 +00:00
|
|
|
/* The PacketCable CCC option number can vary. If this is a CCC option,
|
|
|
|
handle it and skip the "opaque" case below.
|
|
|
|
*/
|
|
|
|
if (code == pkt_ccc_option) {
|
|
|
|
skip_opaque = TRUE;
|
2006-08-15 20:32:08 +00:00
|
|
|
proto_item_append_text(vti,
|
2006-10-25 03:03:53 +00:00
|
|
|
"CableLabs Client Configuration (%d bytes)",
|
|
|
|
optlen);
|
2004-10-24 22:53:06 +00:00
|
|
|
optend = optoff + optlen;
|
|
|
|
while (optoff < optend) {
|
2004-10-05 17:44:53 +00:00
|
|
|
switch (pkt_ccc_protocol_version) {
|
|
|
|
case PACKETCABLE_CCC_I05:
|
2004-10-25 08:17:11 +00:00
|
|
|
optoff = dissect_packetcable_i05_ccc(v_tree, tvb, optoff, optend);
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
case PACKETCABLE_CCC_DRAFT5:
|
|
|
|
case PACKETCABLE_CCC_RFC_3495:
|
2004-10-25 08:17:11 +00:00
|
|
|
optoff = dissect_packetcable_ietf_ccc(v_tree, tvb, optoff, optend, pkt_ccc_protocol_version);
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
default: /* XXX Should we do something here? */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
if (ftype == special)
|
|
|
|
return consumed;
|
|
|
|
if (ftype == opaque) {
|
|
|
|
if (skip_opaque) /* Currently used by PacketCable CCC */
|
2000-07-09 22:46:53 +00:00
|
|
|
return consumed;
|
2005-12-23 23:54:35 +00:00
|
|
|
}
|
2004-10-26 07:00:23 +00:00
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
switch (ftype) {
|
|
|
|
case ipv4:
|
|
|
|
if (optlen != 4) {
|
|
|
|
proto_item_append_text(vti,
|
|
|
|
" - length isn't 4");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
proto_item_append_text(vti, " = %s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, optoff, 4)));
|
|
|
|
break;
|
2000-07-09 22:46:53 +00:00
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
case ipv4_list:
|
|
|
|
if (optlen == 4) {
|
|
|
|
/* one IP address */
|
2004-10-26 07:00:23 +00:00
|
|
|
proto_item_append_text(vti, " = %s",
|
2004-10-25 08:56:39 +00:00
|
|
|
ip_to_str(tvb_get_ptr(tvb, optoff, 4)));
|
2005-12-23 23:54:35 +00:00
|
|
|
} else {
|
|
|
|
/* > 1 IP addresses. Let's make a sub-tree */
|
|
|
|
for (i = optoff, optleft = optlen; optleft > 0;
|
|
|
|
i += 4, optleft -= 4) {
|
|
|
|
if (optleft < 4) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, i, voff + consumed - i,
|
|
|
|
"Option length isn't a multiple of 4");
|
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
2005-12-23 23:54:35 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, i, 4, "IP Address: %s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, i, 4)));
|
2000-07-09 22:46:53 +00:00
|
|
|
}
|
2005-12-23 23:54:35 +00:00
|
|
|
}
|
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
case string:
|
|
|
|
/* Fix for non null-terminated string supplied by
|
|
|
|
* John Lines <John.Lines[AT]aeat.co.uk>
|
|
|
|
*/
|
|
|
|
proto_item_append_text(vti, " = \"%s\"",
|
|
|
|
tvb_format_stringzpad(tvb, optoff, consumed-2));
|
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
case opaque:
|
|
|
|
break;
|
1999-01-28 21:29:36 +00:00
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
case val_boolean:
|
|
|
|
if (optlen != 1) {
|
|
|
|
proto_item_append_text(vti,
|
|
|
|
" - length isn't 1");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
tfs = (const struct true_false_string *) bootp_get_opt_data(code);
|
|
|
|
if(tfs){
|
2004-10-24 22:53:06 +00:00
|
|
|
i = tvb_get_guint8(tvb, optoff);
|
2000-07-09 22:46:53 +00:00
|
|
|
if (i != 0 && i != 1) {
|
2004-10-26 07:00:23 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
" = Invalid Value %d", i);
|
2000-07-09 22:46:53 +00:00
|
|
|
} else {
|
2004-10-26 07:00:23 +00:00
|
|
|
proto_item_append_text(vti, " = %s",
|
2005-12-23 23:54:35 +00:00
|
|
|
i == 0 ? tfs->false_string : tfs->true_string);
|
2000-07-09 22:46:53 +00:00
|
|
|
}
|
2005-12-23 23:54:35 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case val_u_byte:
|
|
|
|
if (optlen != 1) {
|
|
|
|
proto_item_append_text(vti,
|
|
|
|
" - length isn't 1");
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
2005-12-23 23:54:35 +00:00
|
|
|
}
|
|
|
|
vs = (const value_string *) bootp_get_opt_data(code);
|
|
|
|
byte = tvb_get_guint8(tvb, optoff);
|
|
|
|
if (vs != NULL) {
|
|
|
|
proto_item_append_text(vti, " = %s",
|
|
|
|
val_to_str(byte, vs, "Unknown (%u)"));
|
|
|
|
} else
|
|
|
|
proto_item_append_text(vti, " = %u", byte);
|
|
|
|
break;
|
2000-07-09 22:46:53 +00:00
|
|
|
|
2006-03-09 04:31:10 +00:00
|
|
|
case val_u_short: {
|
|
|
|
gushort vd;
|
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
if (optlen != 2) {
|
|
|
|
proto_item_append_text(vti,
|
|
|
|
" - length isn't 2");
|
2004-10-25 08:56:39 +00:00
|
|
|
break;
|
2005-12-23 23:54:35 +00:00
|
|
|
}
|
2006-03-09 04:31:10 +00:00
|
|
|
|
|
|
|
vs = (const value_string *) bootp_get_opt_data(code);
|
|
|
|
vd = tvb_get_ntohs(tvb, optoff);
|
|
|
|
|
|
|
|
if (vs != NULL) {
|
|
|
|
proto_item_append_text(vti, " = %s",
|
|
|
|
val_to_str(vd, vs, "Unknown (%u)"));
|
|
|
|
} else
|
|
|
|
proto_item_append_text(vti, " = %u", vd);
|
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
break;
|
2006-03-09 04:31:10 +00:00
|
|
|
}
|
2004-10-25 08:56:39 +00:00
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
case val_u_short_list:
|
|
|
|
if (optlen == 2) {
|
|
|
|
/* one gushort */
|
2004-10-26 07:00:23 +00:00
|
|
|
proto_item_append_text(vti, " = %u",
|
|
|
|
tvb_get_ntohs(tvb, optoff));
|
2005-12-23 23:54:35 +00:00
|
|
|
} else {
|
|
|
|
/* > 1 gushort */
|
|
|
|
for (i = optoff, optleft = optlen; optleft > 0;
|
|
|
|
i += 2, optleft -= 2) {
|
|
|
|
if (optleft < 2) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, i, voff + consumed - i,
|
|
|
|
"Option length isn't a multiple of 2");
|
|
|
|
break;
|
2004-10-25 08:56:39 +00:00
|
|
|
}
|
2005-12-23 23:54:35 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, i, 4, "Value: %u",
|
|
|
|
tvb_get_ntohs(tvb, i));
|
2004-10-25 08:56:39 +00:00
|
|
|
}
|
2005-12-23 23:54:35 +00:00
|
|
|
}
|
|
|
|
break;
|
2004-10-25 08:56:39 +00:00
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
case val_u_long:
|
|
|
|
if (optlen != 4) {
|
|
|
|
proto_item_append_text(vti,
|
|
|
|
" - length isn't 4");
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
2005-12-23 23:54:35 +00:00
|
|
|
}
|
|
|
|
proto_item_append_text(vti, " = %u",
|
|
|
|
tvb_get_ntohl(tvb, optoff));
|
|
|
|
break;
|
2000-07-09 22:46:53 +00:00
|
|
|
|
2005-12-23 23:54:35 +00:00
|
|
|
case time_in_secs:
|
|
|
|
if (optlen != 4) {
|
|
|
|
proto_item_append_text(vti,
|
|
|
|
" - length isn't 4");
|
2004-10-26 07:00:23 +00:00
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
2005-12-23 23:54:35 +00:00
|
|
|
time_secs = tvb_get_ntohl(tvb, optoff);
|
|
|
|
proto_item_append_text(vti, " = %s",
|
|
|
|
((time_secs == 0xffffffff) ?
|
|
|
|
"infinity" :
|
|
|
|
time_secs_to_str(time_secs)));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return consumed;
|
|
|
|
}
|
|
|
|
|
2001-02-13 00:01:08 +00:00
|
|
|
static int
|
2004-10-25 08:17:11 +00:00
|
|
|
bootp_dhcp_decode_agent_info(proto_tree *v_tree, tvbuff_t *tvb, int optoff,
|
|
|
|
int optend)
|
2001-02-13 00:01:08 +00:00
|
|
|
{
|
2004-10-25 08:17:11 +00:00
|
|
|
int suboptoff = optoff;
|
2001-02-13 00:01:08 +00:00
|
|
|
guint8 subopt;
|
2007-10-09 18:48:46 +00:00
|
|
|
int subopt_len, datalen;
|
|
|
|
guint32 enterprise;
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
subopt = tvb_get_guint8(tvb, optoff);
|
|
|
|
suboptoff++;
|
|
|
|
|
|
|
|
if (suboptoff >= optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
|
|
|
"Suboption %d: no room left in option for suboption length",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
subopt_len = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff++;
|
|
|
|
|
2005-03-23 21:22:18 +00:00
|
|
|
if (suboptoff+subopt_len > optend) {
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optend-optoff,
|
|
|
|
"Suboption %d: no room left in option for suboption value",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
2001-02-13 00:01:08 +00:00
|
|
|
switch (subopt) {
|
2007-10-27 16:49:13 +00:00
|
|
|
case 1: /* 1 Agent Circuit ID Sub-option [RFC3046] */
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
2004-05-07 08:02:23 +00:00
|
|
|
"Agent Circuit ID: %s",
|
2004-10-25 08:17:11 +00:00
|
|
|
tvb_bytes_to_str(tvb, suboptoff, subopt_len));
|
2001-02-13 00:01:08 +00:00
|
|
|
break;
|
2007-10-27 16:49:13 +00:00
|
|
|
case 2: /* 2 Agent Remote ID Sub-option [RFC3046] */
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
2004-05-07 08:02:23 +00:00
|
|
|
"Agent Remote ID: %s",
|
2004-10-25 08:17:11 +00:00
|
|
|
tvb_bytes_to_str(tvb, suboptoff, subopt_len));
|
2001-02-13 00:01:08 +00:00
|
|
|
break;
|
2007-10-27 16:49:13 +00:00
|
|
|
case 3:
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"Reserved: %s",
|
|
|
|
tvb_bytes_to_str(tvb, suboptoff, subopt_len));
|
|
|
|
break;
|
|
|
|
case 4: /* 4 DOCSIS Device Class Suboption [RFC3256] */
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"DOCSIS Device Class: %s",
|
|
|
|
tvb_bytes_to_str(tvb, suboptoff, subopt_len));
|
|
|
|
break;
|
|
|
|
case 5: /* 5 Link selection Sub-option [RFC3527] */
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"Link selection: %s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, suboptoff, subopt_len)));
|
|
|
|
break;
|
|
|
|
case 6: /*Subscriber-ID Suboption [RFC3993] */
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"Subscriber ID: %s",
|
|
|
|
tvb_bytes_to_str(tvb, suboptoff, subopt_len));
|
|
|
|
break;
|
|
|
|
case 7: /* 7 RADIUS Attributes Sub-option [RFC4014] */
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"RADIUS Attributes: %s",
|
|
|
|
tvb_bytes_to_str(tvb, suboptoff, subopt_len));
|
|
|
|
case 8: /* 8 Authentication Suboption [RFC4030] */
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"Authentication: %s",
|
|
|
|
tvb_bytes_to_str(tvb, suboptoff, subopt_len));
|
2007-10-09 18:48:46 +00:00
|
|
|
case 9:
|
|
|
|
while (suboptoff < optend) {
|
|
|
|
enterprise = tvb_get_ntohl(tvb, suboptoff);
|
|
|
|
proto_tree_add_text(v_tree, tvb, suboptoff, 4,
|
|
|
|
"Enterprise-number: %s-%u",
|
|
|
|
val_to_str( enterprise, sminmpec_values, "Unknown"),
|
|
|
|
enterprise);
|
|
|
|
suboptoff += 4;
|
|
|
|
|
|
|
|
datalen = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
proto_tree_add_text(v_tree, tvb, suboptoff, 1,
|
|
|
|
"Data Length: %u", datalen);
|
|
|
|
suboptoff++;
|
|
|
|
|
|
|
|
proto_tree_add_text(v_tree, tvb, suboptoff, datalen,
|
|
|
|
"Suboption Data: %s", tvb_bytes_to_str(tvb, suboptoff, datalen));
|
|
|
|
suboptoff += datalen;
|
|
|
|
}
|
|
|
|
break;
|
2007-10-27 16:49:13 +00:00
|
|
|
case 10: /* 10 Relay Agent Flags [RFC5010] */
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"Flags: %s",
|
|
|
|
tvb_bytes_to_str(tvb, suboptoff, subopt_len));
|
2007-10-09 18:48:46 +00:00
|
|
|
|
2001-02-13 00:01:08 +00:00
|
|
|
default:
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
2007-10-27 16:49:13 +00:00
|
|
|
"Unknown agent suboption %d (%d bytes)",
|
2004-05-07 08:02:23 +00:00
|
|
|
subopt, subopt_len);
|
2001-02-13 00:01:08 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-10-25 08:17:11 +00:00
|
|
|
optoff += (subopt_len + 2);
|
|
|
|
return optoff;
|
2001-02-13 00:01:08 +00:00
|
|
|
}
|
|
|
|
|
2001-05-24 19:21:15 +00:00
|
|
|
static int
|
2004-10-25 08:17:11 +00:00
|
|
|
dissect_vendor_pxeclient_suboption(proto_tree *v_tree, tvbuff_t *tvb,
|
|
|
|
int optoff, int optend)
|
2001-05-24 19:21:15 +00:00
|
|
|
{
|
2004-10-25 08:17:11 +00:00
|
|
|
int suboptoff = optoff;
|
2001-05-24 19:21:15 +00:00
|
|
|
guint8 subopt;
|
|
|
|
guint8 subopt_len;
|
2004-10-25 08:17:11 +00:00
|
|
|
int suboptleft;
|
2001-05-24 19:21:15 +00:00
|
|
|
proto_tree *o43pxeclient_v_tree;
|
|
|
|
proto_item *vti;
|
|
|
|
|
2004-10-25 09:31:13 +00:00
|
|
|
static struct opt_info o43pxeclient_opt[]= {
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 0 */ {"nop", special, NULL}, /* dummy */
|
|
|
|
/* 1 */ {"PXE mtftp IP", ipv4_list, NULL},
|
|
|
|
/* 2 */ {"PXE mtftp client port", val_u_le_short, NULL},
|
|
|
|
/* 3 */ {"PXE mtftp server port",val_u_le_short, NULL},
|
|
|
|
/* 4 */ {"PXE mtftp timeout", val_u_byte, NULL},
|
|
|
|
/* 5 */ {"PXE mtftp delay", val_u_byte, NULL},
|
|
|
|
/* 6 */ {"PXE discovery control", val_u_byte, NULL},
|
2001-05-24 19:21:15 +00:00
|
|
|
/*
|
|
|
|
* Correct: b0 (lsb): disable broadcast discovery
|
|
|
|
* b1: disable multicast discovery
|
|
|
|
* b2: only use/accept servers in boot servers
|
|
|
|
* b3: download bootfile without prompt/menu/disc
|
|
|
|
*/
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 7 */ {"PXE multicast address", ipv4_list, NULL},
|
|
|
|
/* 8 */ {"PXE boot servers", special, NULL},
|
|
|
|
/* 9 */ {"PXE boot menu", special, NULL},
|
|
|
|
/* 10 */ {"PXE menu prompt", special, NULL},
|
|
|
|
/* 11 */ {"PXE multicast address alloc", special, NULL},
|
|
|
|
/* 12 */ {"PXE credential types", special, NULL},
|
|
|
|
/* 71 {"PXE boot item", special, NULL}, */
|
|
|
|
/* 255 {"PXE end options", special, NULL} */
|
2001-05-24 19:21:15 +00:00
|
|
|
};
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
subopt = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff++;
|
2001-05-24 19:21:15 +00:00
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt == 0) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1, "Padding");
|
|
|
|
return (suboptoff);
|
2001-05-24 19:21:15 +00:00
|
|
|
} else if (subopt == 255) { /* End Option */
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1, "End PXEClient option");
|
2001-05-24 19:21:15 +00:00
|
|
|
/* Make sure we skip any junk left this option */
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
2001-05-24 19:21:15 +00:00
|
|
|
}
|
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff >= optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
|
|
|
"Suboption %d: no room left in option for suboption length",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
subopt_len = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff++;
|
|
|
|
|
2005-03-23 21:22:18 +00:00
|
|
|
if (suboptoff+subopt_len > optend) {
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optend-optoff,
|
|
|
|
"Suboption %d: no room left in option for suboption value",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
2002-08-28 21:04:11 +00:00
|
|
|
if ( subopt == 71 ) { /* 71 {"PXE boot item", special} */
|
2001-05-24 19:21:15 +00:00
|
|
|
/* case special */
|
|
|
|
/* I may need to decode that properly one day */
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
2001-05-24 19:21:15 +00:00
|
|
|
"Suboption %d: %s (%d byte%s)" ,
|
|
|
|
subopt, "PXE boot item",
|
2004-10-05 17:44:53 +00:00
|
|
|
subopt_len, plurality(subopt_len, "", "s"));
|
2005-05-30 20:53:08 +00:00
|
|
|
} else if ((subopt < 1) || (subopt >= array_length(o43pxeclient_opt))) {
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
2001-05-24 19:21:15 +00:00
|
|
|
"Unknown suboption %d (%d byte%s)", subopt, subopt_len,
|
2004-10-05 17:44:53 +00:00
|
|
|
plurality(subopt_len, "", "s"));
|
2001-05-24 19:21:15 +00:00
|
|
|
} else {
|
2004-10-25 09:31:13 +00:00
|
|
|
switch (o43pxeclient_opt[subopt].ftype) {
|
2001-05-24 19:21:15 +00:00
|
|
|
|
2002-08-28 21:04:11 +00:00
|
|
|
case special:
|
2001-05-24 19:21:15 +00:00
|
|
|
/* I may need to decode that properly one day */
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: %s (%d byte%s)",
|
2001-05-24 19:21:15 +00:00
|
|
|
subopt, o43pxeclient_opt[subopt].text,
|
2004-10-05 17:44:53 +00:00
|
|
|
subopt_len, plurality(subopt_len, "", "s"));
|
2001-05-24 19:21:15 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-25 08:33:39 +00:00
|
|
|
case ipv4_list:
|
2001-05-24 19:21:15 +00:00
|
|
|
if (subopt_len == 4) {
|
|
|
|
/* one IP address */
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 6,
|
2001-05-24 19:21:15 +00:00
|
|
|
"Suboption %d : %s = %s",
|
|
|
|
subopt, o43pxeclient_opt[subopt].text,
|
2004-10-25 08:17:11 +00:00
|
|
|
ip_to_str(tvb_get_ptr(tvb, suboptoff, 4)));
|
2001-05-24 19:21:15 +00:00
|
|
|
} else {
|
|
|
|
/* > 1 IP addresses. Let's make a sub-tree */
|
2004-10-25 08:17:11 +00:00
|
|
|
vti = proto_tree_add_text(v_tree, tvb, optoff,
|
2001-05-24 19:21:15 +00:00
|
|
|
subopt_len+2, "Suboption %d: %s",
|
|
|
|
subopt, o43pxeclient_opt[subopt].text);
|
|
|
|
o43pxeclient_v_tree = proto_item_add_subtree(vti, ett_bootp_option);
|
2004-10-25 08:17:11 +00:00
|
|
|
for (suboptleft = subopt_len; suboptleft > 0;
|
|
|
|
suboptoff += 4, suboptleft -= 4) {
|
|
|
|
if (suboptleft < 4) {
|
|
|
|
proto_tree_add_text(o43pxeclient_v_tree,
|
|
|
|
tvb, suboptoff, suboptleft,
|
|
|
|
"Suboption length isn't a multiple of 4");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
proto_tree_add_text(o43pxeclient_v_tree,
|
|
|
|
tvb, suboptoff, 4, "IP Address: %s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, suboptoff, 4)));
|
2001-05-24 19:21:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-10-25 08:17:11 +00:00
|
|
|
|
2004-10-25 08:56:39 +00:00
|
|
|
/* XXX case string:
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: %s", subopt, o43pxeclient_opt[subopt].text);
|
|
|
|
break;
|
|
|
|
XXX */
|
|
|
|
|
|
|
|
case val_u_byte:
|
|
|
|
if (subopt_len != 1) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: suboption length isn't 1", subopt);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 3, "Suboption %d: %s = %u",
|
|
|
|
subopt, o43pxeclient_opt[subopt].text,
|
|
|
|
tvb_get_guint8(tvb, suboptoff));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case val_u_le_short:
|
|
|
|
if (subopt_len != 2) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: suboption length isn't 2", subopt);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 4, "Suboption %d: %s = %u",
|
|
|
|
subopt, o43pxeclient_opt[subopt].text,
|
|
|
|
tvb_get_letohs(tvb, suboptoff));
|
|
|
|
break;
|
|
|
|
|
2001-05-24 19:21:15 +00:00
|
|
|
default:
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,"ERROR, please report: Unknown subopt type handler %d", subopt);
|
2001-05-24 19:21:15 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-10-25 08:17:11 +00:00
|
|
|
optoff += (subopt_len + 2);
|
|
|
|
return optoff;
|
2001-05-24 19:21:15 +00:00
|
|
|
}
|
|
|
|
|
2008-10-08 18:26:53 +00:00
|
|
|
/* RFC3825Decoder: http://www.enum.at/rfc3825encoder.529.0.html */
|
|
|
|
static void
|
|
|
|
rfc3825_lci_to_fixpoint(const unsigned char lci[16], struct rfc3825_location_fixpoint_t *fixpoint)
|
|
|
|
{
|
|
|
|
fixpoint->latitude_res = (lci[0]>>2) & 0x3F; /* make sure that right-shift does not copy sign bit */
|
|
|
|
if (lci[0] & 2) { /* LSB<<1 contains the sign of the latitude */
|
|
|
|
/* Latitude is negative, expand two's complement */
|
|
|
|
fixpoint->latitude = (((gint64)lci[0] & 3)<<32) | ((gint64)lci[1]<<24) |
|
|
|
|
((gint64)lci[2]<<16) | ((gint64)lci[3]<<8) |
|
|
|
|
(gint64)lci[4] | ((gint64)0x3FFFFFFF<<34);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* Latitude is positive */
|
|
|
|
fixpoint->latitude = (((gint64)lci[0] & 3)<<32) | ((gint64)lci[1]<<24) |
|
|
|
|
((gint64)lci[2]<<16) | ((gint64)lci[3]<<8) |
|
|
|
|
(gint64)lci[4];
|
|
|
|
}
|
|
|
|
fixpoint->longitude_res = (lci[0]>>2) & 0x3F; /* make sure that right-shift does not copy sign bit */
|
|
|
|
if (lci[5] & 2) { /* LSB<<1 contains the sign of the latitude */
|
|
|
|
/* Longitude is negative, expand two's complement */
|
|
|
|
fixpoint->longitude = (((gint64)lci[5] & 3)<<32) | ((gint64)lci[6]<<24) |
|
|
|
|
((gint64)lci[7]<<16) | ((gint64)lci[8]<<8) |
|
|
|
|
(gint64)lci[9] | ((gint64)0x3FFFFFFF<<34);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* Longitude is positive */
|
|
|
|
fixpoint->longitude = (((gint64)lci[5] & 3)<<32) | ((gint64)lci[6]<<24) |
|
|
|
|
((gint64)lci[7]<<16) | ((gint64)lci[8]<<8) |
|
|
|
|
(gint64)lci[9];
|
|
|
|
}
|
|
|
|
fixpoint->altitude_type = (lci[10]>>4) & 0x0F; /* make sure that right-shift does not copy sign bit */
|
|
|
|
fixpoint->altitude_res = ((lci[10] & 0x0F) << 2) | ((lci[11]>>6) & 0x03);
|
|
|
|
if (lci[5] & 32) { /* LSB<<1 contains the sign of the latitude */
|
|
|
|
/* Altitude is negative, expand two's complement */
|
|
|
|
fixpoint->altitude = (((gint32)lci[11] & 0x3F)<<24) | ((gint32)lci[12]<<16) |
|
|
|
|
((gint32)lci[13]<<8) | ((gint32)lci[14]) |
|
|
|
|
((gint32)0x03<<30);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/* Altitudee is positive */
|
|
|
|
fixpoint->altitude = (((gint32)lci[11] & 0x3F)<<24) | ((gint32)lci[12]<<16) |
|
|
|
|
((gint32)lci[13]<<8) | ((gint32)lci[14]);
|
|
|
|
}
|
|
|
|
|
|
|
|
fixpoint->datum_type = lci[15];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* RFC3825Decoder: http://www.enum.at/rfc3825encoder.529.0.html */
|
|
|
|
static int
|
|
|
|
rfc3825_fixpoint_to_decimal(struct rfc3825_location_fixpoint_t *fixpoint, struct rfc3825_location_decimal_t *decimal)
|
|
|
|
{
|
|
|
|
/* Latitude */
|
|
|
|
decimal->latitude = (double) fixpoint->latitude / (1 << 25);
|
|
|
|
if ((decimal->latitude > 90) || (decimal->latitude < -90)) {
|
|
|
|
return RFC3825_LATITUDE_OUTOFRANGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Latitude Uncertainty */
|
|
|
|
if (fixpoint->latitude_res > 34) {
|
|
|
|
return RFC3825_LATITUDE_UNCERTAINTY_OUTOFRANGE;
|
|
|
|
}
|
|
|
|
if (fixpoint->latitude_res > 8 ) {
|
|
|
|
decimal->latitude_res = (double) 1 / (1 << (fixpoint->latitude_res - 8));
|
|
|
|
} else {
|
|
|
|
decimal->latitude_res = 1 << (8 - fixpoint->latitude_res);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Longitude */
|
|
|
|
decimal->longitude = (double) fixpoint->longitude / (1 << 25);
|
|
|
|
if ((decimal->longitude > 180) || (decimal->longitude < -180)) {
|
|
|
|
return RFC3825_LONGITUDE_OUTOFRANGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Longitude Uncertainty */
|
|
|
|
if (fixpoint->longitude_res > 34) {
|
|
|
|
return RFC3825_LONGITUDE_UNCERTAINTY_OUTOFRANGE;
|
|
|
|
}
|
|
|
|
if (fixpoint->longitude_res > 8 ) {
|
|
|
|
decimal->longitude_res = (double) 1 / (1 << (fixpoint->longitude_res - 8));
|
|
|
|
} else {
|
|
|
|
decimal->longitude_res = 1 << (8 - fixpoint->longitude_res);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Altitude Type */
|
|
|
|
decimal->altitude_type = fixpoint->altitude_type;
|
|
|
|
decimal->altitude = 0;
|
|
|
|
decimal->altitude_res = 0;
|
|
|
|
|
|
|
|
if (decimal->altitude_type == 0) { /* Unknown */
|
|
|
|
} else if (decimal->altitude_type == 1) { /* Meters */
|
|
|
|
/* Altitude */
|
|
|
|
decimal->altitude = (double) fixpoint->altitude / (1 << 8);
|
|
|
|
if ((decimal->altitude > ((gint32) 1<<21)-1) || (decimal->altitude < ((gint32) -(1<<21))))
|
|
|
|
return RFC3825_ALTITUDE_OUTOFRANGE;
|
|
|
|
|
|
|
|
/* Altitude Uncertainty */
|
|
|
|
if (fixpoint->altitude_res > 30) {
|
|
|
|
return RFC3825_ALTITUDE_UNCERTAINTY_OUTOFRANGE;
|
|
|
|
}
|
|
|
|
if (fixpoint->altitude_res > 21 ) {
|
|
|
|
decimal->altitude_res = (double) 1 / (1 << (fixpoint->altitude_res - 21));
|
|
|
|
} else {
|
|
|
|
decimal->altitude_res = 1 << (21 - fixpoint->altitude_res);
|
|
|
|
}
|
|
|
|
} else if (decimal->altitude_type == 2) { /* Floors */
|
|
|
|
/* Altitude */
|
|
|
|
if ((fixpoint->altitude_res != 30) && (fixpoint->altitude_res != 0)) {
|
|
|
|
return RFC3825_ALTITUDE_UNCERTAINTY_OUTOFRANGE;
|
|
|
|
}
|
|
|
|
decimal->altitude = (double) fixpoint->altitude / (1 << 8);
|
|
|
|
} else { /* invalid type */
|
|
|
|
return RFC3825_ALTITUDE_TYPE_OUTOFRANGE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Datum Type */
|
|
|
|
decimal->datum_type = 0;
|
|
|
|
if ((fixpoint->datum_type > 3) || (fixpoint->datum_type < 1)) {
|
|
|
|
return RFC3825_DATUM_TYPE_OUTOFRANGE;
|
|
|
|
}
|
|
|
|
decimal->datum_type = fixpoint->datum_type;
|
|
|
|
|
|
|
|
return RFC3825_NOERROR;
|
|
|
|
}
|
|
|
|
|
2004-10-05 17:44:53 +00:00
|
|
|
|
2004-05-07 08:02:23 +00:00
|
|
|
static int
|
2004-10-25 08:17:11 +00:00
|
|
|
dissect_vendor_cablelabs_suboption(proto_tree *v_tree, tvbuff_t *tvb,
|
|
|
|
int optoff, int optend)
|
2004-05-07 08:02:23 +00:00
|
|
|
{
|
2004-10-25 08:17:11 +00:00
|
|
|
int suboptoff = optoff;
|
2004-10-05 17:44:53 +00:00
|
|
|
guint8 subopt, byte_val;
|
2004-05-07 08:02:23 +00:00
|
|
|
guint8 subopt_len;
|
|
|
|
|
2004-10-25 09:31:13 +00:00
|
|
|
static struct opt_info o43cablelabs_opt[]= {
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 0 */ {"nop", special, NULL}, /* dummy */
|
|
|
|
/* 1 */ {"Suboption Request List", string, NULL},
|
|
|
|
/* 2 */ {"Device Type", string, NULL},
|
|
|
|
/* 3 */ {"eSAFE Types", string, NULL},
|
|
|
|
/* 4 */ {"Serial Number", string, NULL},
|
|
|
|
/* 5 */ {"Hardware Version", string, NULL},
|
|
|
|
/* 6 */ {"Software Version", string, NULL},
|
|
|
|
/* 7 */ {"Boot ROM version", string, NULL},
|
|
|
|
/* 8 */ {"Organizationally Unique Identifier", special, NULL},
|
|
|
|
/* 9 */ {"Model Number", string, NULL},
|
|
|
|
/* 10 */ {"Vendor Name", string, NULL},
|
2004-05-07 08:02:23 +00:00
|
|
|
/* *** 11-30: CableHome *** */
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 11 */ {"Address Realm", special, NULL},
|
|
|
|
/* 12 */ {"CM/PS System Description", string, NULL},
|
|
|
|
/* 13 */ {"CM/PS Firmware Revision", string, NULL},
|
|
|
|
/* 14 */ {"Firewall Policy File Version", string, NULL},
|
2007-12-14 20:14:15 +00:00
|
|
|
/* 15 */ {"eSafe Config File Devices", string, NULL},
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 16 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 17 */ {"Unassigned (CableHome)", special, NULL},
|
2007-12-14 20:14:15 +00:00
|
|
|
/* 18 */ {"Video Security Type", string, NULL},
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 19 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 20 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 21 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 22 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 23 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 24 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 25 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 26 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 27 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 28 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 29 */ {"Unassigned (CableHome)", special, NULL},
|
|
|
|
/* 30 */ {"Unassigned (CableHome)", special, NULL},
|
2004-05-07 08:02:23 +00:00
|
|
|
/* *** 31-50: PacketCable *** */
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 31 */ {"MTA MAC Address", special, NULL},
|
2005-03-23 22:30:37 +00:00
|
|
|
/* 32 */ {"Correlation ID", val_u_long, NULL},
|
2007-12-14 20:14:15 +00:00
|
|
|
/* 33 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 34 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 35 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 36 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 37 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 38 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 39 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 40 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 41 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 42 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 43 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 44 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 45 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 46 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 47 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 48 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 49 */ {"Unassigned (PacketCable)", special, NULL},
|
|
|
|
/* 50 */ {"Unassigned (PacketCable)", special, NULL},
|
2004-05-07 08:02:23 +00:00
|
|
|
/* *** 51-127: CableLabs *** */
|
2007-12-14 20:14:15 +00:00
|
|
|
/* 51 */ {"Vendor Name", string, NULL},
|
|
|
|
/* 52 */ {"CableCARD Capability", special, NULL},
|
|
|
|
/* 53 */ {"Device Identification (CA)", special, NULL},
|
|
|
|
/* 54 */ {"Device Identification (X.509)", string, NULL},
|
|
|
|
/* 55 */ {"Unassigned (CableLabs)", special, NULL},
|
2004-05-07 08:02:23 +00:00
|
|
|
/* *** 128-254: Vendors *** */
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 128-254 {"Unassigned (Vendors)", special, NULL}, */
|
|
|
|
/* 255 {"end options", special, NULL} */
|
2004-05-07 08:02:23 +00:00
|
|
|
};
|
|
|
|
|
2004-10-18 14:24:25 +00:00
|
|
|
static const value_string cablehome_subopt11_vals[] = {
|
2004-10-05 17:44:53 +00:00
|
|
|
{ 1, "PS WAN-Man" },
|
|
|
|
{ 2, "PS WAN-Data" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
subopt = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff++;
|
2004-05-07 08:02:23 +00:00
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt == 0) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1, "Padding");
|
|
|
|
return (suboptoff);
|
2004-05-07 08:02:23 +00:00
|
|
|
} else if (subopt == 255) { /* End Option */
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1, "End CableLabs option");
|
2004-05-07 08:02:23 +00:00
|
|
|
/* Make sure we skip any junk left this option */
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
2004-05-07 08:02:23 +00:00
|
|
|
}
|
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff >= optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
|
|
|
"Suboption %d: no room left in option for suboption length",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
subopt_len = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff++;
|
|
|
|
|
2005-03-23 21:22:18 +00:00
|
|
|
if (suboptoff+subopt_len > optend) {
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optend-optoff,
|
|
|
|
"Suboption %d: no room left in option for suboption value",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
2005-05-30 20:53:08 +00:00
|
|
|
if ( (subopt < 1 ) || (subopt >= array_length(o43cablelabs_opt)) ) {
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
2004-05-07 08:02:23 +00:00
|
|
|
"Suboption %d: Unassigned (%d byte%s)", subopt, subopt_len,
|
2004-10-05 17:44:53 +00:00
|
|
|
plurality(subopt_len, "", "s"));
|
2004-05-07 08:02:23 +00:00
|
|
|
} else {
|
2004-10-25 09:31:13 +00:00
|
|
|
switch (o43cablelabs_opt[subopt].ftype) {
|
2004-05-07 08:02:23 +00:00
|
|
|
|
|
|
|
case special:
|
2004-10-05 17:44:53 +00:00
|
|
|
if ( subopt == 8 ) { /* OUI */
|
2007-05-24 17:36:07 +00:00
|
|
|
/* CableLabs specs treat 43.8 inconsistently
|
2006-04-17 08:38:08 +00:00
|
|
|
* as either binary (3b) or string (6b) */
|
|
|
|
if (subopt_len == 3) {
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
2006-04-17 08:38:08 +00:00
|
|
|
"Suboption %d: OUI = %s", subopt,
|
|
|
|
bytes_to_str_punct(tvb_get_ptr(tvb, suboptoff, 3), 3, ':'));
|
|
|
|
} else if (subopt_len == 6) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: OUI = \"%s\"", subopt,
|
|
|
|
tvb_format_stringzpad(tvb, suboptoff, subopt_len));
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: suboption length isn't 3 or 6", subopt);
|
|
|
|
}
|
|
|
|
break;
|
2004-10-05 17:44:53 +00:00
|
|
|
} else if ( subopt == 11 ) { /* Address Realm */
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt_len != 1) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: suboption length isn't 1", subopt);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
byte_val = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
2004-10-18 14:24:25 +00:00
|
|
|
"Suboption %d: %s = %s (0x%02x)",
|
|
|
|
subopt, o43cablelabs_opt[subopt].text,
|
|
|
|
val_to_str(byte_val, cablehome_subopt11_vals, "Unknown"), byte_val);
|
2004-10-05 17:44:53 +00:00
|
|
|
} else if ( subopt == 31 ) { /* MTA MAC address */
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt_len != 6) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: suboption length isn't 6", subopt);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
2004-10-18 14:24:25 +00:00
|
|
|
"Suboption %d: %s = %s",
|
|
|
|
subopt, o43cablelabs_opt[subopt].text,
|
2004-10-25 08:17:11 +00:00
|
|
|
bytes_to_str_punct(tvb_get_ptr(tvb, suboptoff, 6), 6, ':'));
|
2004-10-05 17:44:53 +00:00
|
|
|
} else {
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
2004-10-05 17:44:53 +00:00
|
|
|
"Suboption %d: %s (%d byte%s)" ,
|
|
|
|
subopt, o43cablelabs_opt[subopt].text,
|
|
|
|
subopt_len, plurality(subopt_len, "", "s"));
|
|
|
|
}
|
2004-05-07 08:02:23 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-25 08:56:39 +00:00
|
|
|
case string:
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: %s = \"%s\"", subopt,
|
|
|
|
o43cablelabs_opt[subopt].text,
|
2005-03-23 21:22:18 +00:00
|
|
|
tvb_format_stringzpad(tvb, suboptoff, subopt_len));
|
2004-10-25 08:56:39 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case bytes:
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: %s = 0x%s", subopt,
|
|
|
|
o43cablelabs_opt[subopt].text,
|
|
|
|
tvb_bytes_to_str(tvb, suboptoff, subopt_len));
|
|
|
|
break;
|
|
|
|
|
2005-03-23 22:30:37 +00:00
|
|
|
case val_u_long:
|
|
|
|
if (subopt_len != 4) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: suboption length isn't 4", subopt);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: %s = %u", subopt,
|
|
|
|
o43cablelabs_opt[subopt].text,
|
|
|
|
tvb_get_ntohl(tvb, suboptoff));
|
|
|
|
break;
|
|
|
|
|
2004-05-07 08:02:23 +00:00
|
|
|
default:
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,"ERROR, please report: Unknown subopt type handler %d", subopt);
|
2004-05-07 08:02:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2004-10-25 08:17:11 +00:00
|
|
|
optoff += (subopt_len + 2);
|
|
|
|
return optoff;
|
2004-05-07 08:02:23 +00:00
|
|
|
}
|
|
|
|
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
static int
|
2004-10-25 08:17:11 +00:00
|
|
|
dissect_netware_ip_suboption(proto_tree *v_tree, tvbuff_t *tvb,
|
|
|
|
int optoff, int optend)
|
2000-07-09 22:46:53 +00:00
|
|
|
{
|
2004-10-25 08:17:11 +00:00
|
|
|
int suboptoff = optoff;
|
2001-01-03 22:49:06 +00:00
|
|
|
guint8 subopt;
|
|
|
|
guint8 subopt_len;
|
2004-10-25 08:17:11 +00:00
|
|
|
int suboptleft;
|
2004-10-26 07:00:23 +00:00
|
|
|
const struct true_false_string *tfs;
|
2004-10-25 23:25:59 +00:00
|
|
|
int i;
|
2000-07-09 22:46:53 +00:00
|
|
|
proto_tree *o63_v_tree;
|
|
|
|
proto_item *vti;
|
|
|
|
|
2004-10-25 23:25:59 +00:00
|
|
|
static struct opt_info o63_opt[]= {
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 0 */ {"",none,NULL},
|
|
|
|
/* 1 */ {"NWIP does not exist on subnet",presence,NULL},
|
2006-10-14 20:17:14 +00:00
|
|
|
/* 2 */ {"NWIP exists in options area",presence,NULL},
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 3 */ {"NWIP exists in sname/file",presence,NULL},
|
2006-09-21 17:42:23 +00:00
|
|
|
/* 4 */ {"NWIP exists, but too big",presence,NULL},
|
2004-10-26 16:08:16 +00:00
|
|
|
/* 5 */ {"Broadcast for nearest Netware server",val_boolean,TFS(&yes_no_tfs)},
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 6 */ {"Preferred DSS server",ipv4_list,NULL},
|
|
|
|
/* 7 */ {"Nearest NWIP server",ipv4_list,NULL},
|
|
|
|
/* 8 */ {"Autoretries",val_u_byte,NULL},
|
2006-09-21 17:42:23 +00:00
|
|
|
/* 9 */ {"Autoretry delay, secs",val_u_byte,NULL},
|
2004-10-26 16:08:16 +00:00
|
|
|
/* 10*/ {"Support NetWare/IP v1.1",val_boolean,TFS(&yes_no_tfs)},
|
2004-10-26 07:00:23 +00:00
|
|
|
/* 11*/ {"Primary DSS",ipv4,NULL}
|
2000-07-09 22:46:53 +00:00
|
|
|
};
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
subopt = tvb_get_guint8(tvb, optoff);
|
|
|
|
suboptoff++;
|
|
|
|
|
|
|
|
if (suboptoff >= optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
|
|
|
"Suboption %d: no room left in option for suboption length",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
subopt_len = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff++;
|
|
|
|
|
2005-05-30 20:53:08 +00:00
|
|
|
if (subopt >= array_length(o63_opt)) {
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2, "Unknown suboption %d", subopt);
|
2000-07-09 22:46:53 +00:00
|
|
|
} else {
|
2004-10-25 09:31:13 +00:00
|
|
|
switch (o63_opt[subopt].ftype) {
|
2000-07-09 22:46:53 +00:00
|
|
|
|
2004-10-25 08:33:39 +00:00
|
|
|
case presence:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt_len != 0) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"Suboption %d: length isn't 0", subopt);
|
|
|
|
break;
|
|
|
|
}
|
2004-10-25 23:25:59 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 2, "Suboption %d: %s", subopt, o63_opt[subopt].text);
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-25 08:33:39 +00:00
|
|
|
case ipv4:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt_len != 4) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"Suboption %d: length isn't 4", subopt);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (suboptoff+4 > optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optend-optoff,
|
|
|
|
"Suboption %d: no room left in option for suboption value",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 6,
|
2000-07-09 22:46:53 +00:00
|
|
|
"Suboption %d: %s = %s" ,
|
2004-10-25 23:25:59 +00:00
|
|
|
subopt, o63_opt[subopt].text,
|
2004-10-25 08:17:11 +00:00
|
|
|
ip_to_str(tvb_get_ptr(tvb, suboptoff, 4)));
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
|
|
|
|
2004-10-25 08:33:39 +00:00
|
|
|
case ipv4_list:
|
2001-01-03 22:49:06 +00:00
|
|
|
if (subopt_len == 4) {
|
2000-07-09 22:46:53 +00:00
|
|
|
/* one IP address */
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 6,
|
2000-07-09 22:46:53 +00:00
|
|
|
"Suboption %d : %s = %s",
|
2004-10-25 23:25:59 +00:00
|
|
|
subopt, o63_opt[subopt].text,
|
2004-10-25 08:17:11 +00:00
|
|
|
ip_to_str(tvb_get_ptr(tvb, suboptoff, 4)));
|
2000-07-09 22:46:53 +00:00
|
|
|
} else {
|
|
|
|
/* > 1 IP addresses. Let's make a sub-tree */
|
2004-10-25 08:17:11 +00:00
|
|
|
vti = proto_tree_add_text(v_tree, tvb, optoff,
|
2001-01-03 22:49:06 +00:00
|
|
|
subopt_len+2, "Suboption %d: %s",
|
2004-10-25 23:25:59 +00:00
|
|
|
subopt, o63_opt[subopt].text);
|
2000-07-09 22:46:53 +00:00
|
|
|
o63_v_tree = proto_item_add_subtree(vti, ett_bootp_option);
|
2004-10-25 08:17:11 +00:00
|
|
|
for (suboptleft = subopt_len; suboptleft > 0;
|
|
|
|
suboptoff += 4, suboptleft -= 4) {
|
|
|
|
if (suboptleft < 4) {
|
|
|
|
proto_tree_add_text(o63_v_tree,
|
|
|
|
tvb, suboptoff, suboptleft,
|
|
|
|
"Suboption length isn't a multiple of 4");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
proto_tree_add_text(o63_v_tree, tvb, suboptoff, 4, "IP Address: %s",
|
|
|
|
ip_to_str(tvb_get_ptr(tvb, suboptoff, 4)));
|
2000-07-09 22:46:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2004-10-25 08:17:11 +00:00
|
|
|
|
2004-10-26 16:08:16 +00:00
|
|
|
case val_boolean:
|
2004-10-25 08:56:39 +00:00
|
|
|
if (subopt_len != 1) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
2006-10-14 20:17:14 +00:00
|
|
|
"Suboption %d: suboption length isn't 1", subopt);
|
2004-10-25 08:56:39 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (suboptoff+1 > optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optend-optoff,
|
|
|
|
"Suboption %d: no room left in option for suboption value",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
2004-10-26 07:00:23 +00:00
|
|
|
tfs = (const struct true_false_string *) o63_opt[subopt].data;
|
2004-10-25 23:25:59 +00:00
|
|
|
i = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
if (i != 0 && i != 1) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 3,
|
2006-09-21 17:41:47 +00:00
|
|
|
"Suboption %d: %s = Invalid Value %d",
|
2004-10-25 23:25:59 +00:00
|
|
|
subopt, o63_opt[subopt].text, i);
|
2004-10-25 08:56:39 +00:00
|
|
|
} else {
|
2004-10-25 23:25:59 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 3,
|
2006-09-21 17:41:47 +00:00
|
|
|
"Suboption %d: %s = %s", subopt,
|
2004-10-25 23:25:59 +00:00
|
|
|
o63_opt[subopt].text,
|
2004-10-26 07:00:23 +00:00
|
|
|
i == 0 ? tfs->false_string : tfs->true_string);
|
2004-10-25 08:56:39 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case val_u_byte:
|
|
|
|
if (subopt_len != 1) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"Suboption %d: length isn't 1", subopt);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (suboptoff+1 > optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optend-optoff,
|
|
|
|
"Suboption %d: no room left in option for suboption value",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 3, "Suboption %d: %s = %u",
|
2004-10-25 23:25:59 +00:00
|
|
|
subopt, o63_opt[subopt].text,
|
2004-10-25 08:56:39 +00:00
|
|
|
tvb_get_guint8(tvb, suboptoff));
|
|
|
|
break;
|
|
|
|
|
2000-07-09 22:46:53 +00:00
|
|
|
default:
|
2004-10-25 08:17:11 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,"Unknown suboption %d", subopt);
|
2000-07-09 22:46:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-10-14 20:17:14 +00:00
|
|
|
optoff += (subopt_len + 2);
|
|
|
|
return optoff;
|
2000-07-09 22:46:53 +00:00
|
|
|
}
|
|
|
|
|
2004-10-05 17:44:53 +00:00
|
|
|
|
2007-02-11 03:36:04 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
dissect_vendor_tr111_suboption(proto_tree *v_tree, tvbuff_t *tvb,
|
|
|
|
int optoff, int optend)
|
|
|
|
{
|
|
|
|
int suboptoff = optoff;
|
|
|
|
guint8 subopt;
|
|
|
|
guint8 subopt_len;
|
|
|
|
|
|
|
|
/* Reference: TR-111 DHCP Option 125 Sub-Option Data Fields
|
2007-05-24 17:36:07 +00:00
|
|
|
Page 10.
|
2007-02-11 03:36:04 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
static struct opt_info o125_tr111_opt[]= {
|
|
|
|
/* 0 */ {"nop", special, NULL}, /* dummy */
|
|
|
|
/* 1 */ {"DeviceManufacturerOUI", string, NULL},
|
|
|
|
/* 2 */ {"DeviceSerialNumber", string, NULL},
|
|
|
|
/* 3 */ {"DeviceProductClass", string, NULL},
|
|
|
|
/* 4 */ {"GatewayManufacturerOUI", string, NULL},
|
|
|
|
/* 5 */ {"GatewaySerialNumber", string, NULL},
|
|
|
|
/* 6 */ {"GatewayProductClass", string, NULL},
|
|
|
|
};
|
|
|
|
|
|
|
|
subopt = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff++;
|
|
|
|
|
|
|
|
if (suboptoff >= optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
|
|
|
"Suboption %d: no room left in option for suboption length",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
subopt_len = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff++;
|
|
|
|
|
|
|
|
if (suboptoff+subopt_len > optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, optend-optoff,
|
|
|
|
"Suboption %d: no room left in option for suboption value",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((subopt < 1) || (subopt >= array_length(o125_tr111_opt))) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Unknown suboption %d (%d byte%s)", subopt, subopt_len,
|
|
|
|
plurality(subopt_len, "", "s"));
|
|
|
|
} else {
|
|
|
|
switch (o125_tr111_opt[subopt].ftype) {
|
|
|
|
|
|
|
|
case special:
|
|
|
|
/* I may need to decode that properly one day */
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: %s (%d byte%s)",
|
|
|
|
subopt, o125_tr111_opt[subopt].text,
|
|
|
|
subopt_len, plurality(subopt_len, "", "s"));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case string:
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,
|
|
|
|
"Suboption %d: %s = \"%s\"", subopt,
|
|
|
|
o125_tr111_opt[subopt].text,
|
|
|
|
tvb_format_stringzpad(tvb, suboptoff, subopt_len));
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, subopt_len+2,"ERROR, please report: Unknown subopt type handler %d", subopt);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
optoff += (subopt_len + 2);
|
|
|
|
return optoff;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-10-17 02:36:32 +00:00
|
|
|
/* PacketCable Multimedia Terminal Adapter device capabilities (option 60).
|
2004-10-05 17:44:53 +00:00
|
|
|
Ref: PKT-SP-I05-021127 sections 8.2 and 10 */
|
|
|
|
|
|
|
|
#define PKT_MDC_TLV_OFF 10
|
|
|
|
|
|
|
|
|
|
|
|
/* These are ASCII-encoded hexadecimal digits. We use the raw hex equivalent for
|
|
|
|
convenience. */
|
|
|
|
#define PKT_MDC_VERSION 0x3031 /* "01" */
|
|
|
|
#define PKT_MDC_TEL_END 0x3032 /* "02" */
|
|
|
|
#define PKT_MDC_TGT 0x3033 /* "03" */
|
|
|
|
#define PKT_MDC_HTTP_ACC 0x3034 /* "04" */
|
|
|
|
#define PKT_MDC_SYSLOG 0x3035 /* "05" */
|
|
|
|
#define PKT_MDC_NCS 0x3036 /* "06" */
|
|
|
|
#define PKT_MDC_PRI_LINE 0x3037 /* "07" */
|
|
|
|
#define PKT_MDC_VENDOR_TLV 0x3038 /* "08" */
|
|
|
|
#define PKT_MDC_NVRAM_STOR 0x3039 /* "09" */
|
|
|
|
#define PKT_MDC_PROV_REP 0x3041 /* "0A" */
|
|
|
|
#define PKT_MDC_PROV_REP_LC 0x3061 /* "0A" */
|
|
|
|
#define PKT_MDC_SUPP_CODECS 0x3042 /* "0B" */
|
|
|
|
#define PKT_MDC_SUPP_CODECS_LC 0x3062 /* "0b" */
|
|
|
|
#define PKT_MDC_SILENCE 0x3043 /* "0C" */
|
|
|
|
#define PKT_MDC_SILENCE_LC 0x3063 /* "0c" */
|
|
|
|
#define PKT_MDC_ECHO_CANCEL 0x3044 /* "0D" */
|
|
|
|
#define PKT_MDC_ECHO_CANCEL_LC 0x3064 /* "0d" */
|
2004-10-17 02:36:32 +00:00
|
|
|
#define PKT_MDC_RSVP 0x3045 /* "0E" */
|
|
|
|
#define PKT_MDC_RSVP_LC 0x3065 /* "0e" */
|
|
|
|
#define PKT_MDC_UGS_AD 0x3046 /* "0F" */
|
|
|
|
#define PKT_MDC_UGS_AD_LC 0x3066 /* "0f" */
|
2004-10-05 17:44:53 +00:00
|
|
|
#define PKT_MDC_IF_INDEX 0x3130 /* "10" */
|
|
|
|
#define PKT_MDC_FLOW_LOG 0x3131 /* "11" */
|
|
|
|
#define PKT_MDC_PROV_FLOWS 0x3132 /* "12" */
|
2004-10-17 02:36:32 +00:00
|
|
|
/* PacketCable 1.5: */
|
|
|
|
#define PKT_MDC_T38_VERSION 0x3133 /* "13" */
|
|
|
|
#define PKT_MDC_T38_EC 0x3134 /* "14" */
|
|
|
|
#define PKT_MDC_RFC2833_DTMF 0x3135 /* "15" */
|
|
|
|
#define PKT_MDC_VOICE_METRICS 0x3136 /* "16" */
|
|
|
|
#define PKT_MDC_MIBS 0x3137 /* "17" */
|
|
|
|
#define PKT_MDC_MGPI 0x3138 /* "18" */
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
static const value_string pkt_mdc_type_vals[] = {
|
|
|
|
{ PKT_MDC_VERSION, "PacketCable Version" },
|
|
|
|
{ PKT_MDC_TEL_END, "Number Of Telephony Endpoints" },
|
|
|
|
{ PKT_MDC_TGT, "TGT Support" },
|
|
|
|
{ PKT_MDC_HTTP_ACC, "HTTP Download File Access Method Support" },
|
|
|
|
{ PKT_MDC_SYSLOG, "MTA-24 Event SYSLOG Notification Support" },
|
|
|
|
{ PKT_MDC_NCS, "NCS Service Flow Support" },
|
|
|
|
{ PKT_MDC_PRI_LINE, "Primary Line Support" },
|
|
|
|
{ PKT_MDC_VENDOR_TLV, "Vendor Specific TLV Type(s)" },
|
|
|
|
{ PKT_MDC_NVRAM_STOR, "NVRAM Ticket/Session Keys Storage Support" },
|
|
|
|
{ PKT_MDC_PROV_REP, "Provisioning Event Reporting Support" },
|
|
|
|
{ PKT_MDC_PROV_REP_LC, "Provisioning Event Reporting Support" },
|
|
|
|
{ PKT_MDC_SUPP_CODECS, "Supported CODEC(s)" },
|
|
|
|
{ PKT_MDC_SUPP_CODECS_LC, "Supported CODEC(s)" },
|
|
|
|
{ PKT_MDC_SILENCE, "Silence Suppression Support" },
|
|
|
|
{ PKT_MDC_SILENCE_LC, "Silence Suppression Support" },
|
|
|
|
{ PKT_MDC_ECHO_CANCEL, "Echo Cancellation Support" },
|
|
|
|
{ PKT_MDC_ECHO_CANCEL_LC, "Echo Cancellation Support" },
|
2004-10-17 02:36:32 +00:00
|
|
|
{ PKT_MDC_RSVP, "RSVP Support/ Reserved" },
|
|
|
|
{ PKT_MDC_RSVP_LC, "RSVP Support/ Reserved" },
|
2004-10-05 17:44:53 +00:00
|
|
|
{ PKT_MDC_UGS_AD, "UGS-AD Support" },
|
|
|
|
{ PKT_MDC_UGS_AD_LC, "UGS-AD Support" },
|
|
|
|
{ PKT_MDC_IF_INDEX, "MTA's \"ifIndex\" starting number in \"ifTable\"" },
|
|
|
|
{ PKT_MDC_FLOW_LOG, "Provisioning Flow Logging Support" },
|
|
|
|
{ PKT_MDC_PROV_FLOWS, "Supported Provisioning Flows" },
|
2004-10-17 02:36:32 +00:00
|
|
|
/* PacketCable 1.5: */
|
|
|
|
{ PKT_MDC_T38_VERSION, "T38 Version Support" },
|
|
|
|
{ PKT_MDC_T38_EC, "T38 Error Correction Support" },
|
|
|
|
{ PKT_MDC_RFC2833_DTMF, "RFC 2833 DTMF Support" },
|
|
|
|
{ PKT_MDC_VOICE_METRICS, "Voice Metrics Support" },
|
|
|
|
{ PKT_MDC_MIBS, "MIB Support" },
|
|
|
|
{ PKT_MDC_MGPI, "Multiple Grants Per Interval Support" },
|
2004-10-05 17:44:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string pkt_mdc_version_vals[] = {
|
|
|
|
{ 0x3030, "PacketCable 1.0" },
|
2004-10-17 02:36:32 +00:00
|
|
|
{ 0x3031, "PacketCable 1.1/1.5" }, /* 1.5 replaces 1.1-1.3 */
|
2004-10-05 17:44:53 +00:00
|
|
|
{ 0x3032, "PacketCable 1.2" },
|
|
|
|
{ 0x3033, "PacketCable 1.3" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string pkt_mdc_boolean_vals[] = {
|
|
|
|
{ 0x3030, "No" },
|
|
|
|
{ 0x3031, "Yes" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string pkt_mdc_codec_vals[] = {
|
2004-10-17 02:36:32 +00:00
|
|
|
{ 0x3031, "other" }, /* "01" */
|
2004-10-05 17:44:53 +00:00
|
|
|
{ 0x3032, "unknown" },
|
|
|
|
{ 0x3033, "G.729" },
|
|
|
|
{ 0x3034, "reserved" },
|
|
|
|
{ 0x3035, "G.729E" },
|
|
|
|
{ 0x3036, "PCMU" },
|
|
|
|
{ 0x3037, "G.726-32" },
|
|
|
|
{ 0x3038, "G.728" },
|
2004-10-17 02:36:32 +00:00
|
|
|
{ 0x3039, "PCMA" }, /* "09" */
|
|
|
|
{ 0x3041, "G.726-16" }, /* "0A" */
|
2004-10-05 17:44:53 +00:00
|
|
|
{ 0x3042, "G.726-24" },
|
|
|
|
{ 0x3043, "G.726-40" },
|
2004-10-17 02:36:32 +00:00
|
|
|
{ 0x3044, "iLBC" },
|
|
|
|
{ 0x3045, "BV16" },
|
|
|
|
{ 0x3046, "telephone-event" }, /* "0F" */
|
2004-10-05 17:44:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2004-10-17 02:36:32 +00:00
|
|
|
static const value_string pkt_mdc_t38_version_vals[] = {
|
|
|
|
{ 0x3030, "Unsupported" },
|
|
|
|
{ 0x3031, "T.38 Version Zero" }, /* default */
|
|
|
|
{ 0x3032, "T.38 Version One" },
|
|
|
|
{ 0x3033, "T.38 Version Two" },
|
|
|
|
{ 0x3035, "T.38 Version Three" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string pkt_mdc_t38_ec_vals[] = {
|
|
|
|
{ 0x3030, "None" },
|
|
|
|
{ 0x3031, "Redundancy" }, /* default */
|
|
|
|
{ 0x3032, "FEC" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2006-02-08 23:09:17 +00:00
|
|
|
static const value_string pkt_mdc_mib_orgs[] = {
|
|
|
|
{ 0x3030, "CableLabs" },
|
|
|
|
{ 0x3031, "IETF" },
|
2004-10-17 02:36:32 +00:00
|
|
|
{ 0x3032, "Reserved" },
|
|
|
|
{ 0x3033, "Reserved" },
|
|
|
|
{ 0x3034, "Reserved" },
|
2006-02-08 23:09:17 +00:00
|
|
|
{ 0x3035, "Reserved" },
|
|
|
|
{ 0x3036, "Reserved" },
|
|
|
|
{ 0x3037, "Reserved" },
|
|
|
|
{ 0x3038, "Reserved" },
|
|
|
|
{ 0x3039, "Reserved" },
|
2004-10-17 02:36:32 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
/* DOCSIS Cable Modem device capabilities (option 60). */
|
2006-04-17 08:38:08 +00:00
|
|
|
#define DOCS_CM_TLV_OFF 12
|
|
|
|
|
|
|
|
#define DOCS_CM_CONCAT_SUP 0x3031 /* "01" */
|
|
|
|
#define DOCS_CM_DOCSIS_VER 0x3032 /* "02" */
|
|
|
|
#define DOCS_CM_FRAG_SUP 0x3033 /* "03" */
|
|
|
|
#define DOCS_CM_PHS_SUP 0x3034 /* "04" */
|
|
|
|
#define DOCS_CM_IGMP_SUP 0x3035 /* "05" */
|
|
|
|
#define DOCS_CM_PRIV_SUP 0x3036 /* "06" */
|
|
|
|
#define DOCS_CM_DSAID_SUP 0x3037 /* "07" */
|
|
|
|
#define DOCS_CM_USID_SUP 0x3038 /* "08" */
|
|
|
|
#define DOCS_CM_FILT_SUP 0x3039 /* "09" */
|
|
|
|
#define DOCS_CM_TET_MI 0x3041 /* "0A" */
|
|
|
|
#define DOCS_CM_TET_MI_LC 0x3061 /* "0a" */
|
|
|
|
#define DOCS_CM_TET 0x3042 /* "0B" */
|
|
|
|
#define DOCS_CM_TET_LC 0x3062 /* "0b" */
|
|
|
|
#define DOCS_CM_DCC_SUP 0x3043 /* "0C" */
|
|
|
|
#define DOCS_CM_DCC_SUP_LC 0x3063 /* "0c" */
|
|
|
|
#define DOCS_CM_IPFILT_SUP 0x3044 /* "0D" */
|
|
|
|
#define DOCS_CM_IPFILT_SUP_LC 0x3064 /* "0d" */
|
|
|
|
#define DOCS_CM_LLCFILT_SUP 0x3045 /* "0E" */
|
|
|
|
#define DOCS_CM_LLCFILT_SUP_LC 0x3065 /* "0e" */
|
|
|
|
|
|
|
|
static const value_string docs_cm_type_vals[] = {
|
|
|
|
{ DOCS_CM_CONCAT_SUP, "Concatenation Support" },
|
|
|
|
{ DOCS_CM_DOCSIS_VER, "DOCSIS Version" },
|
|
|
|
{ DOCS_CM_FRAG_SUP, "Fragmentation Support" },
|
|
|
|
{ DOCS_CM_PHS_SUP, "PHS Support" },
|
|
|
|
{ DOCS_CM_IGMP_SUP, "IGMP Support" },
|
|
|
|
{ DOCS_CM_PRIV_SUP, "Privacy Support" },
|
|
|
|
{ DOCS_CM_DSAID_SUP, "Downstream SAID Support" },
|
|
|
|
{ DOCS_CM_USID_SUP, "Upstream SID Support" },
|
|
|
|
{ DOCS_CM_FILT_SUP, "Optional Filtering Support" },
|
|
|
|
{ DOCS_CM_TET_MI, "Transmit Equalizer Taps per Modulation Interval" },
|
|
|
|
{ DOCS_CM_TET_MI_LC, "Transmit Equalizer Taps per Modulation Interval" },
|
|
|
|
{ DOCS_CM_TET, "Number of Transmit Equalizer Taps" },
|
|
|
|
{ DOCS_CM_TET_LC, "Number of Transmit Equalizer Taps" },
|
|
|
|
{ DOCS_CM_DCC_SUP, "DCC Support" },
|
|
|
|
{ DOCS_CM_DCC_SUP_LC, "DCC Support" },
|
|
|
|
{ DOCS_CM_IPFILT_SUP, "IP Filters Support" },
|
|
|
|
{ DOCS_CM_IPFILT_SUP_LC, "IP Filters Support" },
|
|
|
|
{ DOCS_CM_LLCFILT_SUP, "LLC Filters Support" },
|
|
|
|
{ DOCS_CM_LLCFILT_SUP_LC, "LLC Filters Support" },
|
2005-08-28 01:44:30 +00:00
|
|
|
{ 0, NULL }
|
2004-10-05 17:44:53 +00:00
|
|
|
};
|
|
|
|
|
2006-04-17 08:38:08 +00:00
|
|
|
static const value_string docs_cm_version_vals[] = {
|
2004-10-17 02:36:32 +00:00
|
|
|
{ 0x3030, "DOCSIS 1.0" },
|
|
|
|
{ 0x3031, "DOCSIS 1.1" },
|
|
|
|
{ 0x3032, "DOCSIS 2.0" },
|
2004-10-05 17:44:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2006-04-17 08:38:08 +00:00
|
|
|
static const value_string docs_cm_privacy_vals[] = {
|
2004-10-05 17:44:53 +00:00
|
|
|
{ 0x3030, "BPI Support" },
|
|
|
|
{ 0x3031, "BPI Plus Support" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static const value_string pkt_mdc_supp_flow_vals[] = {
|
|
|
|
{ 1 << 0, "Secure Flow (Full Secure Provisioning Flow)" },
|
|
|
|
{ 1 << 1, "Hybrid Flow" },
|
|
|
|
{ 1 << 2, "Basic Flow" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2006-02-08 23:09:17 +00:00
|
|
|
#define PKT_MDC_MIB_CL 0x3030
|
|
|
|
static const value_string pkt_mdc_cl_mib_vals[] = {
|
|
|
|
{ 1 << 0, "PacketCable 1.5 MTA MIB" },
|
|
|
|
{ 1 << 1, "PacketCable 1.5 Signaling MIB" },
|
|
|
|
{ 1 << 2, "PacketCable 1.5 Management Event MIB" },
|
|
|
|
{ 1 << 3, "PacketCable 1.5 MTA Extension MIB" },
|
|
|
|
{ 1 << 4, "PacketCable 1.5 Signaling Extension MIB" },
|
|
|
|
{ 1 << 5, "PacketCable 1.5 MEM Extension MIB" },
|
|
|
|
{ 1 << 6, "Reserved" },
|
|
|
|
{ 1 << 7, "Reserved" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
#define PKT_MDC_MIB_IETF 0x3031
|
|
|
|
static const value_string pkt_mdc_ietf_mib_vals[] = {
|
|
|
|
{ 1 << 0, "IETF MTA MIB" },
|
|
|
|
{ 1 << 1, "IETF Signaling MIB" },
|
|
|
|
{ 1 << 2, "IETF Management Event MIB" },
|
|
|
|
{ 1 << 3, "Reserved" },
|
|
|
|
{ 1 << 4, "Reserved" },
|
|
|
|
{ 1 << 5, "Reserved" },
|
|
|
|
{ 1 << 6, "Reserved" },
|
|
|
|
{ 1 << 7, "Reserved" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
dissect_packetcable_mta_cap(proto_tree *v_tree, tvbuff_t *tvb, int voff, int len)
|
2004-05-07 08:02:23 +00:00
|
|
|
{
|
2004-10-05 17:44:53 +00:00
|
|
|
guint16 raw_val;
|
2004-10-05 23:02:09 +00:00
|
|
|
unsigned long flow_val = 0;
|
2005-05-24 16:46:18 +00:00
|
|
|
int off = PKT_MDC_TLV_OFF + voff;
|
2008-03-12 21:00:00 +00:00
|
|
|
int subopt_off, max_len;
|
2008-03-12 21:43:37 +00:00
|
|
|
guint tlv_len, i, mib_val;
|
2004-10-05 17:44:53 +00:00
|
|
|
guint8 asc_val[3] = " ", flow_val_str[5];
|
|
|
|
char bit_fld[64];
|
2006-02-08 23:09:17 +00:00
|
|
|
proto_item *ti, *mib_ti;
|
|
|
|
proto_tree *subtree, *subtree2;
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
tvb_memcpy (tvb, asc_val, off, 2);
|
2008-03-13 05:24:21 +00:00
|
|
|
if (sscanf((gchar*)asc_val, "%x", &tlv_len) != 1 || tlv_len > 0xff) {
|
2004-10-05 17:44:53 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, off, len - off,
|
|
|
|
"Bogus length: %s", asc_val);
|
|
|
|
return;
|
|
|
|
} else {
|
2006-02-16 11:43:38 +00:00
|
|
|
proto_tree_add_uint_format_value(v_tree, hf_bootp_pkt_mtacap_len, tvb, off, 2,
|
|
|
|
tlv_len, "%d", tlv_len);
|
2004-10-05 17:44:53 +00:00
|
|
|
off += 2;
|
|
|
|
|
2005-05-24 16:46:18 +00:00
|
|
|
while (off - voff < len) {
|
2004-10-05 17:44:53 +00:00
|
|
|
/* Type */
|
|
|
|
raw_val = tvb_get_ntohs (tvb, off);
|
|
|
|
|
|
|
|
/* Length */
|
|
|
|
tvb_memcpy(tvb, asc_val, off + 2, 2);
|
2007-03-26 11:06:26 +00:00
|
|
|
if (sscanf((gchar*)asc_val, "%x", &tlv_len) != 1 || tlv_len < 1) {
|
2004-10-05 17:44:53 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, off, len - off,
|
2004-10-17 02:36:32 +00:00
|
|
|
"[Bogus length: %s]", asc_val);
|
2004-10-05 17:44:53 +00:00
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
/* Value(s) */
|
|
|
|
|
2005-09-01 10:38:41 +00:00
|
|
|
ti = proto_tree_add_text(v_tree,
|
|
|
|
tvb, off, (tlv_len * 2) + 4,
|
|
|
|
"0x%s: %s = ",
|
|
|
|
tvb_format_text(tvb, off, 2),
|
|
|
|
val_to_str(raw_val, pkt_mdc_type_vals, "unknown"));
|
2004-10-05 17:44:53 +00:00
|
|
|
switch (raw_val) {
|
|
|
|
case PKT_MDC_VERSION:
|
|
|
|
raw_val = tvb_get_ntohs(tvb, off + 4);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%s (%s)",
|
|
|
|
val_to_str(raw_val, pkt_mdc_version_vals, "Reserved"),
|
|
|
|
tvb_format_stringzpad(tvb, off + 4, 2) );
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
case PKT_MDC_TEL_END:
|
|
|
|
case PKT_MDC_IF_INDEX:
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%s",
|
|
|
|
tvb_format_stringzpad(tvb, off + 4, 2) );
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
case PKT_MDC_TGT:
|
|
|
|
case PKT_MDC_HTTP_ACC:
|
|
|
|
case PKT_MDC_SYSLOG:
|
|
|
|
case PKT_MDC_NCS:
|
|
|
|
case PKT_MDC_PRI_LINE:
|
|
|
|
case PKT_MDC_NVRAM_STOR:
|
|
|
|
case PKT_MDC_PROV_REP:
|
|
|
|
case PKT_MDC_PROV_REP_LC:
|
|
|
|
case PKT_MDC_SILENCE:
|
|
|
|
case PKT_MDC_SILENCE_LC:
|
|
|
|
case PKT_MDC_ECHO_CANCEL:
|
|
|
|
case PKT_MDC_ECHO_CANCEL_LC:
|
|
|
|
case PKT_MDC_RSVP:
|
|
|
|
case PKT_MDC_RSVP_LC:
|
|
|
|
case PKT_MDC_UGS_AD:
|
|
|
|
case PKT_MDC_UGS_AD_LC:
|
|
|
|
case PKT_MDC_FLOW_LOG:
|
2004-10-17 02:36:32 +00:00
|
|
|
case PKT_MDC_RFC2833_DTMF:
|
|
|
|
case PKT_MDC_VOICE_METRICS:
|
2004-10-05 17:44:53 +00:00
|
|
|
raw_val = tvb_get_ntohs(tvb, off + 4);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%s (%s)",
|
|
|
|
val_to_str(raw_val, pkt_mdc_boolean_vals, "unknown"),
|
|
|
|
tvb_format_stringzpad(tvb, off + 4, 2) );
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
case PKT_MDC_SUPP_CODECS:
|
|
|
|
case PKT_MDC_SUPP_CODECS_LC:
|
|
|
|
for (i = 0; i < tlv_len; i++) {
|
|
|
|
raw_val = tvb_get_ntohs(tvb, off + 4 + (i * 2) );
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%s%s (%s)",
|
|
|
|
plurality(i + 1, "", ", "),
|
|
|
|
val_to_str(raw_val, pkt_mdc_codec_vals, "unknown"),
|
|
|
|
tvb_format_stringzpad(tvb, off + 4 + (i * 2), 2) );
|
2004-10-05 17:44:53 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PKT_MDC_PROV_FLOWS:
|
|
|
|
tvb_memcpy(tvb, flow_val_str, off + 4, 4);
|
|
|
|
flow_val_str[4] = '\0';
|
2007-03-26 11:06:26 +00:00
|
|
|
flow_val = strtoul((gchar*)flow_val_str, NULL, 16);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"0x%04lx", flow_val);
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
2004-10-17 02:36:32 +00:00
|
|
|
case PKT_MDC_T38_VERSION:
|
|
|
|
raw_val = tvb_get_ntohs(tvb, off + 4);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%s (%s)",
|
|
|
|
val_to_str(raw_val, pkt_mdc_t38_version_vals, "unknown"),
|
|
|
|
tvb_format_stringzpad(tvb, off + 4, 2) );
|
2004-10-17 02:36:32 +00:00
|
|
|
break;
|
|
|
|
case PKT_MDC_T38_EC:
|
|
|
|
raw_val = tvb_get_ntohs(tvb, off + 4);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%s (%s)",
|
|
|
|
val_to_str(raw_val, pkt_mdc_t38_ec_vals, "unknown"),
|
|
|
|
tvb_format_stringzpad(tvb, off + 4, 2) );
|
2004-10-17 02:36:32 +00:00
|
|
|
break;
|
|
|
|
case PKT_MDC_MIBS:
|
|
|
|
break;
|
2004-10-05 17:44:53 +00:00
|
|
|
case PKT_MDC_VENDOR_TLV:
|
|
|
|
default:
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%s",
|
|
|
|
tvb_format_stringzpad(tvb, off + 4, tlv_len * 2) );
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
subtree = proto_item_add_subtree(ti, ett_bootp_option);
|
|
|
|
if (raw_val == PKT_MDC_PROV_FLOWS) {
|
|
|
|
for (i = 0 ; i < 3; i++) {
|
|
|
|
if (flow_val & pkt_mdc_supp_flow_vals[i].value) {
|
|
|
|
decode_bitfield_value(bit_fld, flow_val, pkt_mdc_supp_flow_vals[i].value, 16);
|
2006-02-08 23:09:17 +00:00
|
|
|
proto_tree_add_text(subtree, tvb, off + 4, 4, "%s%s",
|
2004-10-05 17:44:53 +00:00
|
|
|
bit_fld, pkt_mdc_supp_flow_vals[i].strptr);
|
|
|
|
}
|
|
|
|
}
|
2006-02-08 23:09:17 +00:00
|
|
|
} else if (raw_val == PKT_MDC_MIBS) {
|
|
|
|
/* 17 06 02 00 38 02 01 07 */
|
|
|
|
subopt_off = off + 4;
|
|
|
|
max_len = subopt_off + (tlv_len * 2);
|
|
|
|
while (subopt_off < max_len) {
|
|
|
|
raw_val = tvb_get_ntohs(tvb, subopt_off);
|
|
|
|
if (raw_val != 0x3032) { /* We only know how to handle a length of 2 */
|
|
|
|
tvb_memcpy(tvb, asc_val, subopt_off, 2);
|
|
|
|
proto_tree_add_text(subtree, tvb, subopt_off, 2,
|
|
|
|
"[Bogus length: %s]", asc_val);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
subopt_off += 2;
|
|
|
|
raw_val = tvb_get_ntohs(tvb, subopt_off);
|
|
|
|
tvb_memcpy(tvb, asc_val, subopt_off, 2);
|
|
|
|
|
|
|
|
mib_ti = proto_tree_add_text(subtree, tvb, subopt_off, 2, "%s (%s)",
|
|
|
|
val_to_str(raw_val, pkt_mdc_mib_orgs, "Unknown"), asc_val);
|
|
|
|
if (subopt_off > off + 4 + 2) {
|
|
|
|
proto_item_append_text(ti, ", ");
|
|
|
|
}
|
|
|
|
proto_item_append_text(ti, "%s", val_to_str(raw_val, pkt_mdc_mib_orgs, "Unknown"));
|
|
|
|
|
|
|
|
subopt_off += 2;
|
|
|
|
tvb_memcpy(tvb, asc_val, subopt_off, 2);
|
2007-03-26 11:06:26 +00:00
|
|
|
if (sscanf((gchar*)asc_val, "%x", &mib_val) != 1) {
|
2006-02-08 23:09:17 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, subopt_off, 2,
|
|
|
|
"[Bogus bitfield: %s]", asc_val);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (raw_val) {
|
|
|
|
case PKT_MDC_MIB_CL:
|
|
|
|
subtree2 = proto_item_add_subtree(mib_ti, ett_bootp_option);
|
|
|
|
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
if (mib_val & pkt_mdc_cl_mib_vals[i].value) {
|
|
|
|
decode_bitfield_value(bit_fld, mib_val, pkt_mdc_cl_mib_vals[i].value, 8);
|
|
|
|
proto_tree_add_text(subtree2, tvb, subopt_off, 2,
|
|
|
|
"%s%s", bit_fld, pkt_mdc_cl_mib_vals[i].strptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case PKT_MDC_MIB_IETF:
|
|
|
|
subtree2 = proto_item_add_subtree(mib_ti, ett_bootp_option);
|
|
|
|
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
if (mib_val & pkt_mdc_ietf_mib_vals[i].value) {
|
|
|
|
decode_bitfield_value(bit_fld, mib_val, pkt_mdc_ietf_mib_vals[i].value, 8);
|
|
|
|
proto_tree_add_text(subtree2, tvb, subopt_off, 2,
|
|
|
|
"%s%s", bit_fld, pkt_mdc_ietf_mib_vals[i].strptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
subopt_off += 2;
|
|
|
|
}
|
|
|
|
|
2004-10-05 17:44:53 +00:00
|
|
|
}
|
|
|
|
off += (tlv_len * 2) + 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-05-07 08:02:23 +00:00
|
|
|
|
2004-10-05 17:44:53 +00:00
|
|
|
static void
|
2004-10-17 02:36:32 +00:00
|
|
|
dissect_docsis_cm_cap(proto_tree *v_tree, tvbuff_t *tvb, int voff, int len)
|
2004-10-05 17:44:53 +00:00
|
|
|
{
|
2004-10-05 23:02:09 +00:00
|
|
|
unsigned long raw_val;
|
2006-04-17 08:38:08 +00:00
|
|
|
int off = DOCS_CM_TLV_OFF + voff;
|
2008-03-12 21:43:37 +00:00
|
|
|
guint tlv_len, i;
|
2007-05-26 00:38:53 +00:00
|
|
|
guint8 asc_val[4] = " ";
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item *ti;
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
tvb_memcpy (tvb, asc_val, off, 2);
|
2007-03-26 11:06:26 +00:00
|
|
|
if (sscanf((gchar*)asc_val, "%x", &tlv_len) != 1 || tlv_len < 1) {
|
2004-10-05 17:44:53 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, off, len - off,
|
|
|
|
"Bogus length: %s", asc_val);
|
|
|
|
return;
|
|
|
|
} else {
|
2006-02-16 11:43:38 +00:00
|
|
|
proto_tree_add_uint_format_value(v_tree, hf_bootp_docsis_cmcap_len, tvb, off, 2,
|
|
|
|
tlv_len, "%d", tlv_len);
|
2004-10-05 17:44:53 +00:00
|
|
|
off += 2;
|
|
|
|
|
2005-05-24 16:46:18 +00:00
|
|
|
while (off - voff < len) {
|
2004-10-05 17:44:53 +00:00
|
|
|
/* Type */
|
|
|
|
raw_val = tvb_get_ntohs (tvb, off);
|
|
|
|
|
|
|
|
/* Length */
|
|
|
|
tvb_memcpy(tvb, asc_val, off + 2, 2);
|
2008-03-13 05:24:21 +00:00
|
|
|
if (sscanf((gchar*)asc_val, "%x", &tlv_len) != 1 || tlv_len > 0xff) {
|
2004-10-05 17:44:53 +00:00
|
|
|
proto_tree_add_text(v_tree, tvb, off, len - off,
|
2004-10-17 02:36:32 +00:00
|
|
|
"[Bogus length: %s]", asc_val);
|
2004-10-05 17:44:53 +00:00
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
/* Value(s) */
|
2005-09-01 10:38:41 +00:00
|
|
|
ti = proto_tree_add_text(v_tree, tvb, off,
|
|
|
|
(tlv_len * 2) + 4,
|
|
|
|
"0x%s: %s = ",
|
|
|
|
tvb_format_text(tvb, off, 2),
|
2006-04-17 08:38:08 +00:00
|
|
|
val_to_str(raw_val, docs_cm_type_vals, "unknown"));
|
2004-10-05 17:44:53 +00:00
|
|
|
switch (raw_val) {
|
2006-04-17 08:38:08 +00:00
|
|
|
case DOCS_CM_CONCAT_SUP:
|
|
|
|
case DOCS_CM_FRAG_SUP:
|
|
|
|
case DOCS_CM_PHS_SUP:
|
|
|
|
case DOCS_CM_IGMP_SUP:
|
|
|
|
case DOCS_CM_DCC_SUP:
|
|
|
|
case DOCS_CM_DCC_SUP_LC:
|
2004-10-05 17:44:53 +00:00
|
|
|
for (i = 0; i < tlv_len; i++) {
|
|
|
|
raw_val = tvb_get_ntohs(tvb, off + 4 + (i * 2) );
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%s%s (%s)",
|
|
|
|
plurality(i + 1, "", ", "),
|
|
|
|
val_to_str(raw_val, pkt_mdc_boolean_vals, "unknown"),
|
|
|
|
tvb_format_text(tvb, off + 4 + (i * 2), 2) );
|
2004-10-05 17:44:53 +00:00
|
|
|
}
|
|
|
|
break;
|
2006-04-17 08:38:08 +00:00
|
|
|
case DOCS_CM_DOCSIS_VER:
|
2004-10-05 17:44:53 +00:00
|
|
|
raw_val = tvb_get_ntohs(tvb, off + 4);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%s (%s)",
|
2006-04-17 08:38:08 +00:00
|
|
|
val_to_str(raw_val, docs_cm_version_vals, "Reserved"),
|
2005-09-01 10:38:41 +00:00
|
|
|
tvb_format_text(tvb, off + 4, 2) );
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
2006-04-17 08:38:08 +00:00
|
|
|
case DOCS_CM_PRIV_SUP:
|
2004-10-05 17:44:53 +00:00
|
|
|
raw_val = tvb_get_ntohs(tvb, off + 4);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%s (%s)",
|
2006-04-17 08:38:08 +00:00
|
|
|
val_to_str(raw_val, docs_cm_privacy_vals, "Reserved"),
|
2005-09-01 10:38:41 +00:00
|
|
|
tvb_format_text(tvb, off + 4, 2) );
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
2006-04-17 08:38:08 +00:00
|
|
|
case DOCS_CM_DSAID_SUP:
|
|
|
|
case DOCS_CM_USID_SUP:
|
|
|
|
case DOCS_CM_TET_MI:
|
|
|
|
case DOCS_CM_TET_MI_LC:
|
|
|
|
case DOCS_CM_TET:
|
|
|
|
case DOCS_CM_TET_LC:
|
2004-10-05 17:44:53 +00:00
|
|
|
tvb_memcpy (tvb, asc_val, off + 4, 2);
|
2007-03-26 11:06:26 +00:00
|
|
|
raw_val = strtoul((gchar*)asc_val, NULL, 16);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%lu", raw_val);
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
2006-04-17 08:38:08 +00:00
|
|
|
case DOCS_CM_IPFILT_SUP:
|
|
|
|
case DOCS_CM_IPFILT_SUP_LC:
|
|
|
|
case DOCS_CM_LLCFILT_SUP:
|
|
|
|
case DOCS_CM_LLCFILT_SUP_LC:
|
|
|
|
tvb_memcpy (tvb, asc_val, off + 4, 4);
|
2007-03-26 11:06:26 +00:00
|
|
|
raw_val = strtoul((gchar*)asc_val, NULL, 16);
|
2006-04-17 08:38:08 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"%lu", raw_val);
|
|
|
|
break;
|
|
|
|
case DOCS_CM_FILT_SUP:
|
2004-10-05 17:44:53 +00:00
|
|
|
tvb_memcpy (tvb, asc_val, off + 4, 2);
|
2007-03-26 11:06:26 +00:00
|
|
|
raw_val = strtoul((gchar*)asc_val, NULL, 16);
|
2004-10-05 17:44:53 +00:00
|
|
|
if (raw_val & 0x01)
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"802.1p filtering");
|
2004-10-05 17:44:53 +00:00
|
|
|
if (raw_val & 0x02) {
|
|
|
|
if (raw_val & 0x01)
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti, ", ");
|
|
|
|
proto_item_append_text(ti,
|
|
|
|
"802.1Q filtering");
|
2004-10-05 17:44:53 +00:00
|
|
|
}
|
2007-10-17 18:25:49 +00:00
|
|
|
if (!(raw_val & 0x03))
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(ti,
|
|
|
|
"None");
|
|
|
|
proto_item_append_text(ti,
|
|
|
|
" (0x%02lx)", raw_val);
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
off += (tlv_len * 2) + 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2004-05-07 08:02:23 +00:00
|
|
|
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
/* Definitions specific to PKT-SP-PROV-I05-021127 begin with "PKT_CCC_I05".
|
|
|
|
Definitions specific to IETF draft 5 and RFC 3495 begin with "PKT_CCC_IETF".
|
|
|
|
Shared definitions begin with "PKT_CCC".
|
|
|
|
*/
|
|
|
|
#define PKT_CCC_PRI_DHCP 1
|
|
|
|
#define PKT_CCC_SEC_DHCP 2
|
|
|
|
#define PKT_CCC_I05_SNMP 3
|
|
|
|
#define PKT_CCC_IETF_PROV_SRV 3
|
|
|
|
#define PKT_CCC_I05_PRI_DNS 4
|
|
|
|
#define PKT_CCC_IETF_AS_KRB 4
|
|
|
|
#define PKT_CCC_I05_SEC_DNS 5
|
|
|
|
#define PKT_CCC_IETF_AP_KRB 5
|
|
|
|
#define PKT_CCC_KRB_REALM 6
|
|
|
|
#define PKT_CCC_TGT_FLAG 7
|
|
|
|
#define PKT_CCC_PROV_TIMER 8
|
|
|
|
#define PKT_CCC_CMS_FQDN 9
|
|
|
|
#define PKT_CCC_IETF_SEC_TKT 9
|
|
|
|
#define PKT_CCC_AS_KRB 10
|
|
|
|
#define PKT_CCC_AP_KRB 11
|
|
|
|
#define PKT_CCC_MTA_KRB_CLEAR 12
|
|
|
|
|
|
|
|
static const value_string pkt_i05_ccc_opt_vals[] = {
|
2007-10-27 16:49:13 +00:00
|
|
|
{ PKT_CCC_PRI_DHCP, "Primary DHCP Server" },
|
|
|
|
{ PKT_CCC_SEC_DHCP, "Secondary DHCP Server" },
|
|
|
|
{ PKT_CCC_I05_SNMP, "SNMP Entity" },
|
2004-10-05 17:44:53 +00:00
|
|
|
{ PKT_CCC_I05_PRI_DNS, "Primary DNS Server" },
|
|
|
|
{ PKT_CCC_I05_SEC_DNS, "Secondary DNS Server" },
|
|
|
|
{ PKT_CCC_KRB_REALM, "Kerberos Realm" },
|
2007-10-27 16:49:13 +00:00
|
|
|
{ PKT_CCC_TGT_FLAG, "MTA should fetch TGT?" },
|
2004-10-05 17:44:53 +00:00
|
|
|
{ PKT_CCC_PROV_TIMER, "Provisioning Timer" },
|
2007-10-27 16:49:13 +00:00
|
|
|
{ PKT_CCC_CMS_FQDN, "CMS FQDN" },
|
|
|
|
{ PKT_CCC_AS_KRB, "AS-REQ/AS-REP Backoff and Retry" },
|
|
|
|
{ PKT_CCC_AP_KRB, "AP-REQ/AP-REP Backoff and Retry" },
|
2004-10-05 17:44:53 +00:00
|
|
|
{ PKT_CCC_MTA_KRB_CLEAR, "MTA should clear Kerberos tickets?" },
|
|
|
|
{ 0, NULL },
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string pkt_draft5_ccc_opt_vals[] = {
|
2004-10-18 14:24:25 +00:00
|
|
|
{ PKT_CCC_PRI_DHCP, "TSP's Primary DHCP Server" },
|
|
|
|
{ PKT_CCC_SEC_DHCP, "TSP's Secondary DHCP Server" },
|
|
|
|
{ PKT_CCC_IETF_PROV_SRV, "TSP's Provisioning Server" },
|
|
|
|
{ PKT_CCC_IETF_AS_KRB, "TSP's AS-REQ/AS-REP Backoff and Retry" },
|
|
|
|
{ PKT_CCC_IETF_AP_KRB, "TSP's AP-REQ/AP-REP Backoff and Retry" },
|
|
|
|
{ PKT_CCC_KRB_REALM, "TSP's Kerberos Realm Name" },
|
|
|
|
{ PKT_CCC_TGT_FLAG, "TSP's Ticket Granting Server Utilization" },
|
|
|
|
{ PKT_CCC_PROV_TIMER, "TSP's Provisioning Timer Value" },
|
|
|
|
{ PKT_CCC_IETF_SEC_TKT, "PacketCable Security Ticket Control" },
|
2004-10-05 17:44:53 +00:00
|
|
|
{ 0, NULL },
|
|
|
|
};
|
|
|
|
|
|
|
|
static const value_string pkt_i05_ccc_ticket_ctl_vals[] = {
|
|
|
|
{ 1, "Invalidate Provisioning Application Server's ticket" },
|
|
|
|
{ 2, "Invalidate all CMS Application Server tickets" },
|
|
|
|
{ 3, "Invalidate all Application Server tickets" },
|
|
|
|
{ 0, NULL },
|
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
2004-10-25 08:17:11 +00:00
|
|
|
dissect_packetcable_i05_ccc(proto_tree *v_tree, tvbuff_t *tvb, int optoff,
|
|
|
|
int optend)
|
2004-10-05 17:44:53 +00:00
|
|
|
{
|
2004-10-25 08:17:11 +00:00
|
|
|
int suboptoff = optoff;
|
2004-10-05 17:44:53 +00:00
|
|
|
guint8 subopt, subopt_len, fetch_tgt, timer_val, ticket_ctl;
|
|
|
|
proto_tree *pkt_s_tree;
|
|
|
|
proto_item *vti;
|
2004-05-07 08:02:23 +00:00
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
subopt = tvb_get_guint8(tvb, optoff);
|
|
|
|
suboptoff++;
|
|
|
|
|
|
|
|
if (suboptoff >= optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
|
|
|
"Suboption %d: no room left in option for suboption length",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
subopt_len = tvb_get_guint8(tvb, optoff);
|
|
|
|
suboptoff++;
|
2004-05-07 08:02:23 +00:00
|
|
|
|
2005-09-01 10:38:41 +00:00
|
|
|
vti = proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"Suboption %u: %s: ", subopt,
|
|
|
|
val_to_str(subopt, pkt_i05_ccc_opt_vals, "unknown/reserved") );
|
2004-05-07 08:02:23 +00:00
|
|
|
|
2004-10-05 17:44:53 +00:00
|
|
|
switch (subopt) {
|
|
|
|
case PKT_CCC_PRI_DHCP: /* String values */
|
|
|
|
case PKT_CCC_SEC_DHCP:
|
|
|
|
case PKT_CCC_I05_SNMP:
|
|
|
|
case PKT_CCC_I05_PRI_DNS:
|
|
|
|
case PKT_CCC_I05_SEC_DNS:
|
|
|
|
case PKT_CCC_KRB_REALM:
|
|
|
|
case PKT_CCC_CMS_FQDN:
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "%s (%u byte%s)",
|
2004-10-25 08:17:11 +00:00
|
|
|
tvb_format_stringzpad(tvb, suboptoff, subopt_len),
|
2004-10-05 17:44:53 +00:00
|
|
|
subopt_len,
|
|
|
|
plurality(subopt_len, "", "s") );
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += subopt_len;
|
2004-05-07 08:02:23 +00:00
|
|
|
break;
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
case PKT_CCC_TGT_FLAG:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+1 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
fetch_tgt = tvb_get_guint8(tvb, suboptoff);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "%s (%u byte%s%s)",
|
2004-10-05 17:44:53 +00:00
|
|
|
fetch_tgt ? "Yes" : "No",
|
|
|
|
subopt_len,
|
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 1 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += subopt_len;
|
2004-05-07 08:02:23 +00:00
|
|
|
break;
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
case PKT_CCC_PROV_TIMER:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+1 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
timer_val = tvb_get_guint8(tvb, suboptoff);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "%u%s (%u byte%s%s)", timer_val,
|
2004-10-05 17:44:53 +00:00
|
|
|
timer_val > 30 ? " [Invalid]" : "",
|
|
|
|
subopt_len,
|
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 1 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += subopt_len;
|
2004-05-07 08:02:23 +00:00
|
|
|
break;
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
case PKT_CCC_AS_KRB:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+12 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
|
2004-10-05 17:44:53 +00:00
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 12 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt_len == 12) {
|
|
|
|
pkt_s_tree = proto_item_add_subtree(vti, ett_bootp_option);
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff, 4,
|
|
|
|
"pktcMtaDevRealmUnsolicitedKeyNomTimeout: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff));
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 4, 4,
|
|
|
|
"pktcMtaDevRealmUnsolicitedKeyMaxTimeout: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff + 4));
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 8, 4,
|
|
|
|
"pktcMtaDevRealmUnsolicitedKeyMaxRetries: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff + 8));
|
|
|
|
}
|
|
|
|
suboptoff += subopt_len;
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PKT_CCC_AP_KRB:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+12 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
|
2004-10-05 17:44:53 +00:00
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 12 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt_len == 12) {
|
|
|
|
pkt_s_tree = proto_item_add_subtree(vti, ett_bootp_option);
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff, 4,
|
|
|
|
"pktcMtaDevProvUnsolicitedKeyNomTimeout: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff));
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 4, 4,
|
|
|
|
"pktcMtaDevProvUnsolicitedKeyMaxTimeout: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff + 4));
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 8, 4,
|
|
|
|
"pktcMtaDevProvUnsolicitedKeyMaxRetries: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff + 8));
|
|
|
|
}
|
|
|
|
suboptoff += subopt_len;
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PKT_CCC_MTA_KRB_CLEAR:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+1 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
ticket_ctl = tvb_get_guint8(tvb, suboptoff);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "%s (%u) (%u byte%s%s)",
|
2004-10-05 17:44:53 +00:00
|
|
|
val_to_str (ticket_ctl, pkt_i05_ccc_ticket_ctl_vals, "unknown/invalid"),
|
|
|
|
ticket_ctl,
|
|
|
|
subopt_len,
|
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 1 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += subopt_len;
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += subopt_len;
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
2004-10-25 08:17:11 +00:00
|
|
|
return suboptoff;
|
2004-10-05 17:44:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const value_string sec_tcm_vals[] = {
|
|
|
|
{ 1 << 0, "PacketCable Provisioning Server" },
|
2004-10-18 14:24:25 +00:00
|
|
|
{ 1 << 1, "All PacketCable Call Management Servers" },
|
2004-10-05 17:44:53 +00:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static int
|
2004-10-25 08:17:11 +00:00
|
|
|
dissect_packetcable_ietf_ccc(proto_tree *v_tree, tvbuff_t *tvb, int optoff,
|
|
|
|
int optend, int revision)
|
2004-10-05 17:44:53 +00:00
|
|
|
{
|
2004-10-25 08:17:11 +00:00
|
|
|
int suboptoff = optoff;
|
2005-09-13 00:50:43 +00:00
|
|
|
guint8 subopt, subopt_len;
|
2008-06-23 21:31:47 +00:00
|
|
|
guint32 ipv4addr;
|
2004-10-05 17:44:53 +00:00
|
|
|
guint8 prov_type, fetch_tgt, timer_val;
|
|
|
|
guint16 sec_tcm;
|
|
|
|
proto_tree *pkt_s_tree;
|
|
|
|
proto_item *vti;
|
|
|
|
int max_timer_val = 255, i;
|
2007-04-23 10:59:26 +00:00
|
|
|
const char *dns_name;
|
|
|
|
char bit_fld[24];
|
2004-10-05 17:44:53 +00:00
|
|
|
|
2004-10-25 08:17:11 +00:00
|
|
|
subopt = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff++;
|
|
|
|
|
|
|
|
if (suboptoff >= optend) {
|
|
|
|
proto_tree_add_text(v_tree, tvb, optoff, 1,
|
|
|
|
"Suboption %d: no room left in option for suboption length",
|
|
|
|
subopt);
|
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
subopt_len = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff++;
|
2004-10-05 17:44:53 +00:00
|
|
|
|
2005-09-01 10:38:41 +00:00
|
|
|
vti = proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
|
|
|
|
"Suboption %u: %s: ", subopt,
|
|
|
|
val_to_str(subopt, pkt_draft5_ccc_opt_vals, "unknown/reserved") );
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
switch (subopt) {
|
|
|
|
case PKT_CCC_PRI_DHCP: /* IPv4 values */
|
|
|
|
case PKT_CCC_SEC_DHCP:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+4 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
2008-06-23 21:31:47 +00:00
|
|
|
ipv4addr = tvb_get_ipv4(tvb, suboptoff);
|
2005-09-13 00:50:43 +00:00
|
|
|
proto_item_append_text(vti, "%s (%u byte%s%s)",
|
2008-06-23 21:31:47 +00:00
|
|
|
ip_to_str((guint8 *)&ipv4addr),
|
2004-10-05 17:44:53 +00:00
|
|
|
subopt_len,
|
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 4 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += subopt_len;
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PKT_CCC_IETF_PROV_SRV:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+1 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
prov_type = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
suboptoff += 1;
|
2004-10-05 17:44:53 +00:00
|
|
|
switch (prov_type) {
|
|
|
|
case 0:
|
2008-08-11 12:00:27 +00:00
|
|
|
get_dns_name(tvb, suboptoff, subopt_len, suboptoff, &dns_name);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "%s (%u byte%s)", dns_name,
|
2004-10-05 17:44:53 +00:00
|
|
|
subopt_len - 1, plurality(subopt_len, "", "s") );
|
|
|
|
break;
|
|
|
|
case 1:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+4 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
2008-06-23 21:31:47 +00:00
|
|
|
ipv4addr = tvb_get_ipv4(tvb, suboptoff);
|
2005-09-13 00:50:43 +00:00
|
|
|
proto_item_append_text(vti, "%s (%u byte%s%s)",
|
2008-06-23 21:31:47 +00:00
|
|
|
ip_to_str((guint8 *)&ipv4addr),
|
2004-10-05 17:44:53 +00:00
|
|
|
subopt_len,
|
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 5 ? " [Invalid]" : "");
|
|
|
|
break;
|
|
|
|
default:
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "Invalid type: %u (%u byte%s)",
|
2004-10-25 08:17:11 +00:00
|
|
|
prov_type,
|
2004-10-05 17:44:53 +00:00
|
|
|
subopt_len,
|
|
|
|
plurality(subopt_len, "", "s") );
|
|
|
|
break;
|
2004-05-07 08:02:23 +00:00
|
|
|
}
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += subopt_len - 1;
|
2004-05-07 08:02:23 +00:00
|
|
|
break;
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
case PKT_CCC_IETF_AS_KRB:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+12 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
|
2004-10-05 17:44:53 +00:00
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 12 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt_len == 12) {
|
|
|
|
pkt_s_tree = proto_item_add_subtree(vti, ett_bootp_option);
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff, 4,
|
|
|
|
"pktcMtaDevRealmUnsolicitedKeyNomTimeout: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff));
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 4, 4,
|
|
|
|
"pktcMtaDevRealmUnsolicitedKeyMaxTimeout: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff + 4));
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 8, 4,
|
|
|
|
"pktcMtaDevRealmUnsolicitedKeyMaxRetries: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff + 8));
|
|
|
|
}
|
|
|
|
suboptoff += subopt_len;
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PKT_CCC_IETF_AP_KRB:
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
|
2004-10-05 17:44:53 +00:00
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 12 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt_len == 12) {
|
|
|
|
pkt_s_tree = proto_item_add_subtree(vti, ett_bootp_option);
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff, 4,
|
|
|
|
"pktcMtaDevProvUnsolicitedKeyNomTimeout: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff));
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 4, 4,
|
|
|
|
"pktcMtaDevProvUnsolicitedKeyMaxTimeout: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff + 4));
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 8, 4,
|
|
|
|
"pktcMtaDevProvUnsolicitedKeyMaxRetries: %u",
|
|
|
|
tvb_get_ntohl(tvb, suboptoff + 8));
|
|
|
|
}
|
|
|
|
suboptoff += subopt_len;
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PKT_CCC_KRB_REALM: /* String values */
|
2008-08-11 12:00:27 +00:00
|
|
|
get_dns_name(tvb, suboptoff, subopt_len, suboptoff, &dns_name);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "%s (%u byte%s)", dns_name,
|
2004-10-05 17:44:53 +00:00
|
|
|
subopt_len, plurality(subopt_len, "", "s") );
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += subopt_len;
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PKT_CCC_TGT_FLAG:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+1 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
fetch_tgt = tvb_get_guint8(tvb, suboptoff);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "%s (%u byte%s%s)",
|
2004-10-05 17:44:53 +00:00
|
|
|
fetch_tgt ? "Yes" : "No",
|
|
|
|
subopt_len,
|
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 1 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += 1;
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PKT_CCC_PROV_TIMER:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+1 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
2004-10-05 17:44:53 +00:00
|
|
|
if (revision == PACKETCABLE_CCC_DRAFT5)
|
|
|
|
max_timer_val = 30;
|
2004-10-25 08:17:11 +00:00
|
|
|
timer_val = tvb_get_guint8(tvb, suboptoff);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "%u%s (%u byte%s%s)", timer_val,
|
2004-10-05 17:44:53 +00:00
|
|
|
timer_val > max_timer_val ? " [Invalid]" : "",
|
|
|
|
subopt_len,
|
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 1 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += 1;
|
2004-10-05 17:44:53 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PKT_CCC_IETF_SEC_TKT:
|
2004-10-25 08:17:11 +00:00
|
|
|
if (suboptoff+2 > optend) {
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti,
|
|
|
|
"no room left in option for suboption value");
|
2004-10-25 08:17:11 +00:00
|
|
|
return (optend);
|
|
|
|
}
|
|
|
|
sec_tcm = tvb_get_ntohs(tvb, suboptoff);
|
2005-09-01 10:38:41 +00:00
|
|
|
proto_item_append_text(vti, "0x%04x (%u byte%s%s)", sec_tcm, subopt_len,
|
2004-10-05 17:44:53 +00:00
|
|
|
plurality(subopt_len, "", "s"),
|
|
|
|
subopt_len != 2 ? " [Invalid]" : "");
|
2004-10-25 08:17:11 +00:00
|
|
|
if (subopt_len == 2) {
|
|
|
|
pkt_s_tree = proto_item_add_subtree(vti, ett_bootp_option);
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
|
|
if (sec_tcm & sec_tcm_vals[i].value) {
|
|
|
|
decode_bitfield_value(bit_fld, sec_tcm, sec_tcm_vals[i].value, 16);
|
|
|
|
proto_tree_add_text(pkt_s_tree, tvb, suboptoff, 2, "%sInvalidate %s",
|
|
|
|
bit_fld, sec_tcm_vals[i].strptr);
|
|
|
|
}
|
2004-10-05 17:44:53 +00:00
|
|
|
}
|
2004-05-07 08:02:23 +00:00
|
|
|
}
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += subopt_len;
|
2004-05-07 08:02:23 +00:00
|
|
|
break;
|
2004-10-05 17:44:53 +00:00
|
|
|
|
2004-05-07 08:02:23 +00:00
|
|
|
default:
|
2004-10-25 08:17:11 +00:00
|
|
|
suboptoff += subopt_len;
|
2004-05-07 08:02:23 +00:00
|
|
|
break;
|
|
|
|
}
|
2004-10-25 08:17:11 +00:00
|
|
|
return suboptoff;
|
2004-05-07 08:02:23 +00:00
|
|
|
}
|
|
|
|
|
2001-01-03 22:49:06 +00:00
|
|
|
#define BOOTREQUEST 1
|
|
|
|
#define BOOTREPLY 2
|
|
|
|
|
|
|
|
static const value_string op_vals[] = {
|
|
|
|
{ BOOTREQUEST, "Boot Request" },
|
|
|
|
{ BOOTREPLY, "Boot Reply" },
|
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
|
2000-04-08 07:07:42 +00:00
|
|
|
static void
|
2001-01-03 22:49:06 +00:00
|
|
|
dissect_bootp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
1998-09-16 02:39:15 +00:00
|
|
|
{
|
2008-03-30 21:53:59 +00:00
|
|
|
proto_tree *bp_tree;
|
1999-03-23 03:14:46 +00:00
|
|
|
proto_item *ti;
|
2008-03-30 21:53:59 +00:00
|
|
|
proto_tree *flag_tree;
|
2008-05-14 01:47:41 +00:00
|
|
|
proto_item *fi, *hidden_item;
|
2001-01-03 22:49:06 +00:00
|
|
|
guint8 op;
|
|
|
|
guint8 htype, hlen;
|
2001-03-13 21:34:28 +00:00
|
|
|
const guint8 *haddr;
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
int voff, eoff, tmpvoff; /* vendor offset, end offset */
|
1999-10-08 13:57:31 +00:00
|
|
|
guint32 ip_addr;
|
2001-12-27 23:53:10 +00:00
|
|
|
gboolean at_end;
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
const char *dhcp_type = NULL;
|
|
|
|
const guint8 *vendor_class_id = NULL;
|
2008-02-11 19:18:02 +00:00
|
|
|
guint16 flags, secs;
|
2005-05-06 02:08:30 +00:00
|
|
|
int offset_delta;
|
2008-03-12 21:00:00 +00:00
|
|
|
guint8 overload = 0; /* DHCP option overload */
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "BOOTP");
|
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
2001-01-03 22:49:06 +00:00
|
|
|
/*
|
|
|
|
* In case we throw an exception fetching the opcode, etc.
|
|
|
|
*/
|
2001-12-10 00:26:21 +00:00
|
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
2001-01-03 22:49:06 +00:00
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2001-01-03 22:49:06 +00:00
|
|
|
op = tvb_get_guint8(tvb, 0);
|
|
|
|
htype = tvb_get_guint8(tvb, 1);
|
|
|
|
hlen = tvb_get_guint8(tvb, 2);
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_INFO)) {
|
2001-01-03 22:49:06 +00:00
|
|
|
switch (op) {
|
|
|
|
|
|
|
|
case BOOTREQUEST:
|
2005-01-13 07:49:31 +00:00
|
|
|
if ((htype == ARPHRD_ETHER || htype == ARPHRD_IEEE802)
|
|
|
|
&& hlen == 6)
|
2004-12-26 22:26:02 +00:00
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Boot Request from %s (%s)",
|
|
|
|
arphrdaddr_to_str(tvb_get_ptr(tvb, 28, hlen),
|
|
|
|
hlen, htype),
|
|
|
|
get_ether_name(tvb_get_ptr(tvb, 28, hlen)));
|
|
|
|
else
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Boot Request from %s",
|
|
|
|
arphrdaddr_to_str(tvb_get_ptr(tvb, 28, hlen),
|
2001-01-03 22:49:06 +00:00
|
|
|
hlen, htype));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BOOTREPLY:
|
2001-12-10 00:26:21 +00:00
|
|
|
col_set_str(pinfo->cinfo, COL_INFO, "Boot Reply");
|
2001-01-03 22:49:06 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2001-12-10 00:26:21 +00:00
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown BOOTP message type (%u)",
|
2001-01-03 22:49:06 +00:00
|
|
|
op);
|
|
|
|
break;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-09-28 04:12:38 +00:00
|
|
|
voff = VENDOR_INFO_OFFSET;
|
1998-09-16 02:39:15 +00:00
|
|
|
|
2002-06-29 19:45:01 +00:00
|
|
|
/* rfc2132 says it SHOULD exist, not that it MUST exist */
|
2008-03-30 21:53:59 +00:00
|
|
|
if (tvb_bytes_exist(tvb, voff, 4) &&
|
|
|
|
(tvb_get_ntohl(tvb, voff) == 0x63825363)) {
|
|
|
|
voff += 4;
|
|
|
|
} else {
|
|
|
|
voff += 64;
|
2000-07-09 22:46:53 +00:00
|
|
|
}
|
2002-06-29 19:45:01 +00:00
|
|
|
eoff = tvb_reported_length(tvb);
|
|
|
|
|
2001-05-24 19:21:15 +00:00
|
|
|
/*
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
* In the first pass, we just look for the DHCP message type
|
|
|
|
* and Vendor class identifier options.
|
2001-05-24 19:21:15 +00:00
|
|
|
*/
|
|
|
|
tmpvoff = voff;
|
2001-12-27 23:53:10 +00:00
|
|
|
at_end = FALSE;
|
|
|
|
while (tmpvoff < eoff && !at_end) {
|
2005-05-06 02:08:30 +00:00
|
|
|
offset_delta = bootp_option(tvb, 0, tmpvoff, eoff, TRUE, &at_end,
|
2008-03-12 21:00:00 +00:00
|
|
|
&dhcp_type, &vendor_class_id, &overload);
|
2005-05-06 01:56:40 +00:00
|
|
|
if (offset_delta <= 0) {
|
|
|
|
THROW(ReportedBoundsError);
|
|
|
|
}
|
|
|
|
tmpvoff += offset_delta;
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If there was a DHCP message type option, flag this packet
|
|
|
|
* as DHCP.
|
|
|
|
*/
|
|
|
|
if (dhcp_type != NULL) {
|
|
|
|
/*
|
|
|
|
* Yes, this is a DHCP packet, and "dhcp_type" is the
|
|
|
|
* packet type.
|
|
|
|
*/
|
2001-12-10 00:26:21 +00:00
|
|
|
if (check_col(pinfo->cinfo, COL_PROTOCOL))
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCP");
|
|
|
|
if (check_col(pinfo->cinfo, COL_INFO))
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "DHCP %-8s - Transaction ID 0x%x",
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
dhcp_type, tvb_get_ntohl(tvb, 4));
|
2005-01-01 02:57:02 +00:00
|
|
|
tap_queue_packet( bootp_dhcp_tap, pinfo, dhcp_type);
|
2001-05-24 19:21:15 +00:00
|
|
|
}
|
We always have to make one pass over the BOOTP options to see if the
packet is BOOTP or DHCP; have "bootp_option()" take a flag indicating
whether it's the first pass or the second and, in the first pass, don't
put anything in the protocol tree - just return, through pointers, the
DHCP packet type and the vendor class ID. On the second pass, don't
modify what those pointers point to, just use them as appropriate.
Make the vendor class ID pointer local to "dissect_bootp()", and have
"dissect_bootp()" do the first pass, set the Protocol and Info columns
appropriately if the packet is DHCP, and then, if a protocol tree is to
be built, make a second pass, handing "bootp_option()" the DHCP packet
type and vendor class ID we found.
If the vendor class ID is null, don't try to compare it with Intel's PXE
client indicator.
svn path=/trunk/; revision=3449
2001-05-25 06:56:53 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If we're not building the protocol tree, we don't need to
|
|
|
|
* make a second pass.
|
|
|
|
*/
|
|
|
|
if (tree == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* OK, now build the protocol tree.
|
|
|
|
*/
|
2008-03-12 21:00:00 +00:00
|
|
|
|
|
|
|
ti = proto_tree_add_item(tree, proto_bootp, tvb, 0, -1, FALSE);
|
|
|
|
bp_tree = proto_item_add_subtree(ti, ett_bootp);
|
|
|
|
|
|
|
|
proto_tree_add_uint(bp_tree, hf_bootp_type, tvb,
|
|
|
|
0, 1,
|
|
|
|
op);
|
|
|
|
proto_tree_add_uint_format_value(bp_tree, hf_bootp_hw_type, tvb,
|
|
|
|
1, 1,
|
|
|
|
htype,
|
|
|
|
"%s",
|
|
|
|
arphrdtype_to_str(htype,
|
|
|
|
"Unknown (0x%02x)"));
|
|
|
|
proto_tree_add_uint(bp_tree, hf_bootp_hw_len, tvb,
|
|
|
|
2, 1, hlen);
|
|
|
|
proto_tree_add_item(bp_tree, hf_bootp_hops, tvb,
|
|
|
|
3, 1, FALSE);
|
|
|
|
proto_tree_add_item(bp_tree, hf_bootp_id, tvb,
|
|
|
|
4, 4, FALSE);
|
|
|
|
/*
|
|
|
|
* Windows (98, XP and Vista tested) sends the "secs" value on
|
|
|
|
* the wire formatted as little-endian. See if the LE value
|
|
|
|
* makes sense.
|
|
|
|
*/
|
|
|
|
secs = tvb_get_letohs(tvb, 8);
|
|
|
|
if (secs > 0 && secs <= 0xff) {
|
|
|
|
proto_tree_add_uint_format(bp_tree, hf_bootp_secs, tvb,
|
|
|
|
8, 2, secs, "Seconds elapsed: %u (little endian bug?)", secs);
|
|
|
|
} else {
|
|
|
|
proto_tree_add_item(bp_tree, hf_bootp_secs, tvb,
|
|
|
|
8, 2, FALSE);
|
|
|
|
}
|
|
|
|
flags = tvb_get_ntohs(tvb, 10);
|
|
|
|
fi = proto_tree_add_uint(bp_tree, hf_bootp_flags, tvb,
|
|
|
|
10, 2, flags);
|
|
|
|
proto_item_append_text(fi, " (%s)",
|
|
|
|
(flags & BOOTP_BC) ? "Broadcast" : "Unicast");
|
|
|
|
flag_tree = proto_item_add_subtree(fi, ett_bootp_flags);
|
|
|
|
proto_tree_add_boolean(flag_tree, hf_bootp_flags_broadcast, tvb,
|
|
|
|
10, 2, flags);
|
|
|
|
proto_tree_add_uint(flag_tree, hf_bootp_flags_reserved, tvb,
|
|
|
|
10, 2, flags);
|
|
|
|
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,
|
|
|
|
16, 4, FALSE);
|
|
|
|
proto_tree_add_item(bp_tree, hf_bootp_ip_server, tvb,
|
|
|
|
20, 4, FALSE);
|
|
|
|
proto_tree_add_item(bp_tree, hf_bootp_ip_relay, tvb,
|
|
|
|
24, 4, FALSE);
|
|
|
|
|
|
|
|
if (hlen > 0 && hlen <= 16) {
|
|
|
|
haddr = tvb_get_ptr(tvb, 28, hlen);
|
|
|
|
if ((htype == ARPHRD_ETHER || htype == ARPHRD_IEEE802)
|
|
|
|
&& hlen == 6)
|
|
|
|
proto_tree_add_ether(bp_tree, hf_bootp_hw_ether_addr, tvb, 28, 6, haddr);
|
|
|
|
else
|
|
|
|
/* The chaddr element is 16 bytes in length,
|
|
|
|
although only the first hlen bytes are used */
|
|
|
|
proto_tree_add_bytes_format_value(bp_tree, hf_bootp_hw_addr, tvb,
|
|
|
|
28, 16,
|
|
|
|
haddr,
|
|
|
|
"%s",
|
|
|
|
arphrdaddr_to_str(haddr,
|
|
|
|
hlen,
|
|
|
|
htype));
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(bp_tree, tvb,
|
|
|
|
28, 16, "Client address not given");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The server host name is optional */
|
|
|
|
if (tvb_get_guint8(tvb, SERVER_NAME_OFFSET) != '\0') {
|
|
|
|
if (overload & OPT_OVERLOAD_SNAME) {
|
|
|
|
proto_tree_add_text (bp_tree, tvb,
|
|
|
|
SERVER_NAME_OFFSET, SERVER_NAME_LEN,
|
|
|
|
"Server name option overloaded by DHCP");
|
|
|
|
} else {
|
|
|
|
proto_tree_add_item(bp_tree, hf_bootp_server, tvb,
|
|
|
|
SERVER_NAME_OFFSET,
|
|
|
|
SERVER_NAME_LEN, FALSE);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
proto_tree_add_string_format(bp_tree, hf_bootp_server, tvb,
|
|
|
|
SERVER_NAME_OFFSET,
|
|
|
|
SERVER_NAME_LEN,
|
|
|
|
(const gchar*)tvb_get_ptr(tvb, SERVER_NAME_OFFSET, 1),
|
|
|
|
"Server host name not given");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Boot file */
|
|
|
|
if (tvb_get_guint8(tvb, FILE_NAME_OFFSET) != '\0') {
|
|
|
|
if (overload & OPT_OVERLOAD_FILE) {
|
|
|
|
proto_tree_add_text (bp_tree, tvb,
|
|
|
|
FILE_NAME_OFFSET, FILE_NAME_LEN,
|
|
|
|
"Boot file name option overloaded by DHCP");
|
|
|
|
} else {
|
|
|
|
proto_tree_add_item(bp_tree, hf_bootp_file, tvb,
|
|
|
|
FILE_NAME_OFFSET,
|
|
|
|
FILE_NAME_LEN, FALSE);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
proto_tree_add_string_format(bp_tree, hf_bootp_file, tvb,
|
|
|
|
FILE_NAME_OFFSET,
|
|
|
|
FILE_NAME_LEN,
|
|
|
|
(const gchar*)tvb_get_ptr(tvb, FILE_NAME_OFFSET, 1),
|
|
|
|
"Boot file name not given");
|
|
|
|
}
|
|
|
|
|
2008-03-30 21:53:59 +00:00
|
|
|
voff = VENDOR_INFO_OFFSET;
|
2008-05-14 01:47:41 +00:00
|
|
|
if (dhcp_type != NULL) {
|
|
|
|
hidden_item = proto_tree_add_boolean(bp_tree, hf_bootp_dhcp, tvb, 0, 0, 1);
|
|
|
|
PROTO_ITEM_SET_HIDDEN(hidden_item);
|
|
|
|
}
|
2008-03-30 21:53:59 +00:00
|
|
|
if (tvb_bytes_exist(tvb, voff, 4) &&
|
|
|
|
(tvb_get_ntohl(tvb, voff) == 0x63825363)) {
|
|
|
|
ip_addr = tvb_get_ipv4(tvb, voff);
|
|
|
|
proto_tree_add_ipv4_format_value(bp_tree, hf_bootp_cookie, tvb,
|
|
|
|
voff, 4, ip_addr, "(OK)");
|
|
|
|
voff += 4;
|
|
|
|
} else {
|
|
|
|
proto_tree_add_text(bp_tree, tvb,
|
|
|
|
voff, 64, "Bootp vendor specific options");
|
|
|
|
voff += 64;
|
|
|
|
}
|
|
|
|
|
2001-12-27 23:53:10 +00:00
|
|
|
at_end = FALSE;
|
|
|
|
while (voff < eoff && !at_end) {
|
2005-05-06 02:08:30 +00:00
|
|
|
offset_delta = bootp_option(tvb, bp_tree, voff, eoff, FALSE, &at_end,
|
2008-03-12 21:00:00 +00:00
|
|
|
&dhcp_type, &vendor_class_id, &overload);
|
2005-05-06 01:56:40 +00:00
|
|
|
if (offset_delta <= 0) {
|
|
|
|
THROW(ReportedBoundsError);
|
|
|
|
}
|
|
|
|
voff += offset_delta;
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
2001-12-27 23:53:10 +00:00
|
|
|
if (voff < eoff) {
|
|
|
|
/*
|
|
|
|
* Padding after the end option.
|
|
|
|
*/
|
|
|
|
proto_tree_add_text(bp_tree, tvb, voff, eoff - voff, "Padding");
|
|
|
|
}
|
1998-09-16 02:39:15 +00:00
|
|
|
}
|
|
|
|
|
1999-07-29 05:47:07 +00:00
|
|
|
void
|
|
|
|
proto_register_bootp(void)
|
|
|
|
{
|
1999-10-08 13:57:31 +00:00
|
|
|
static hf_register_info hf[] = {
|
2000-05-19 02:16:17 +00:00
|
|
|
{ &hf_bootp_dhcp,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Frame is DHCP", "bootp.dhcp", FT_BOOLEAN,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
2002-08-28 21:04:11 +00:00
|
|
|
"", HFILL }},
|
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_type,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Message type", "bootp.type", FT_UINT8,
|
|
|
|
BASE_DEC, VALS(op_vals), 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_hw_type,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Hardware type", "bootp.hw.type", FT_UINT8,
|
|
|
|
BASE_HEX, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_hw_len,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Hardware address length", "bootp.hw.len", FT_UINT8,
|
|
|
|
BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_hops,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Hops", "bootp.hops", FT_UINT8,
|
|
|
|
BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_id,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Transaction ID", "bootp.id", FT_UINT32,
|
|
|
|
BASE_HEX, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_secs,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Seconds elapsed", "bootp.secs", FT_UINT16,
|
|
|
|
BASE_DEC, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
2002-06-19 19:39:38 +00:00
|
|
|
{ &hf_bootp_flags,
|
|
|
|
{ "Bootp flags", "bootp.flags", FT_UINT16,
|
2001-01-03 22:49:06 +00:00
|
|
|
BASE_HEX, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
2002-06-19 19:39:38 +00:00
|
|
|
{ &hf_bootp_flags_broadcast,
|
|
|
|
{ "Broadcast flag", "bootp.flags.bc", FT_BOOLEAN,
|
|
|
|
16, TFS(&flag_set_broadcast), BOOTP_BC,
|
|
|
|
"", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_bootp_flags_reserved,
|
|
|
|
{ "Reserved flags", "bootp.flags.reserved", FT_UINT16,
|
|
|
|
BASE_HEX, NULL, BOOTP_MBZ,
|
|
|
|
"", HFILL }},
|
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_ip_client,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Client IP address", "bootp.ip.client",FT_IPv4,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_ip_your,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Your (client) IP address", "bootp.ip.your", FT_IPv4,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_ip_server,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Next server IP address", "bootp.ip.server",FT_IPv4,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_ip_relay,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Relay agent IP address", "bootp.ip.relay", FT_IPv4,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_hw_addr,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Client hardware address", "bootp.hw.addr", FT_BYTES,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
2004-12-26 22:26:02 +00:00
|
|
|
{ &hf_bootp_hw_ether_addr,
|
|
|
|
{ "Client MAC address", "bootp.hw.mac_addr", FT_ETHER,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
|
|
|
"", HFILL }},
|
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_server,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Server host name", "bootp.server", FT_STRING,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_file,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Boot file name", "bootp.file", FT_STRING,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
1999-10-12 06:21:15 +00:00
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
{ &hf_bootp_cookie,
|
2001-01-03 22:49:06 +00:00
|
|
|
{ "Magic cookie", "bootp.cookie", FT_IPv4,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
2001-06-18 02:18:27 +00:00
|
|
|
"", HFILL }},
|
2002-06-19 19:39:38 +00:00
|
|
|
|
|
|
|
{ &hf_bootp_vendor,
|
|
|
|
{ "Bootp Vendor Options", "bootp.vendor", FT_BYTES,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
|
|
|
"", HFILL }},
|
2004-10-05 17:44:53 +00:00
|
|
|
|
2004-10-16 02:04:08 +00:00
|
|
|
{ &hf_bootp_fqdn_s,
|
|
|
|
{ "Server", "bootp.fqdn.s", FT_BOOLEAN,
|
|
|
|
8, TFS(&tfs_fqdn_s), F_FQDN_S,
|
2004-10-24 10:30:03 +00:00
|
|
|
"If true, server should do DDNS update", HFILL }},
|
2004-10-16 02:04:08 +00:00
|
|
|
|
|
|
|
{ &hf_bootp_fqdn_o,
|
2004-10-16 05:59:24 +00:00
|
|
|
{ "Server overrides", "bootp.fqdn.o", FT_BOOLEAN,
|
2004-10-16 02:04:08 +00:00
|
|
|
8, TFS(&tfs_fqdn_o), F_FQDN_O,
|
2004-10-24 10:30:03 +00:00
|
|
|
"If true, server insists on doing DDNS update", HFILL }},
|
2004-10-16 02:04:08 +00:00
|
|
|
|
|
|
|
{ &hf_bootp_fqdn_e,
|
2004-10-24 10:30:03 +00:00
|
|
|
{ "Encoding", "bootp.fqdn.e", FT_BOOLEAN,
|
2004-10-16 02:04:08 +00:00
|
|
|
8, TFS(&tfs_fqdn_e), F_FQDN_E,
|
2004-10-24 10:30:03 +00:00
|
|
|
"If true, name is binary encoded", HFILL }},
|
2004-10-16 02:04:08 +00:00
|
|
|
|
|
|
|
{ &hf_bootp_fqdn_n,
|
2004-10-24 10:30:03 +00:00
|
|
|
{ "Server DDNS", "bootp.fqdn.n", FT_BOOLEAN,
|
2004-10-16 02:04:08 +00:00
|
|
|
8, TFS(&tfs_fqdn_n), F_FQDN_N,
|
2004-10-24 10:30:03 +00:00
|
|
|
"If true, server should not do any DDNS updates", HFILL }},
|
2004-10-16 02:04:08 +00:00
|
|
|
|
|
|
|
{ &hf_bootp_fqdn_mbz,
|
|
|
|
{ "Reserved flags", "bootp.fqdn.mbz", FT_UINT8,
|
|
|
|
BASE_HEX, NULL, F_FQDN_MBZ,
|
|
|
|
"", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_bootp_fqdn_rcode1,
|
|
|
|
{ "A-RR result", "bootp.fqdn.rcode1", FT_UINT8,
|
|
|
|
BASE_DEC, NULL, 0x0,
|
|
|
|
"Result code of A-RR update", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_bootp_fqdn_rcode2,
|
|
|
|
{ "PTR-RR result", "bootp.fqdn.rcode2", FT_UINT8,
|
|
|
|
BASE_DEC, NULL, 0x0,
|
|
|
|
"Result code of PTR-RR update", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_bootp_fqdn_name,
|
2008-08-11 12:00:27 +00:00
|
|
|
{ "Client name", "bootp.fqdn.name", FT_STRING,
|
2004-10-16 02:04:08 +00:00
|
|
|
BASE_NONE, NULL, 0x0,
|
2004-10-24 10:30:03 +00:00
|
|
|
"Name to register via DDNS", HFILL }},
|
2004-10-16 02:04:08 +00:00
|
|
|
|
|
|
|
{ &hf_bootp_fqdn_asciiname,
|
|
|
|
{ "Client name", "bootp.fqdn.name", FT_STRING,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
2004-10-24 10:30:03 +00:00
|
|
|
"Name to register via DDNS", HFILL }},
|
2004-10-16 02:04:08 +00:00
|
|
|
|
2004-10-17 02:36:32 +00:00
|
|
|
{ &hf_bootp_pkt_mtacap_len,
|
2006-02-16 11:43:38 +00:00
|
|
|
{ "MTA DC Length", "bootp.vendor.pktc.mtacap_len",
|
2004-10-05 17:44:53 +00:00
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
|
|
"PacketCable MTA Device Capabilities Length", HFILL }},
|
2006-01-11 22:05:43 +00:00
|
|
|
|
2004-10-17 02:36:32 +00:00
|
|
|
{ &hf_bootp_docsis_cmcap_len,
|
2006-02-16 11:43:38 +00:00
|
|
|
{ "CM DC Length", "bootp.vendor.docsis.cmcap_len",
|
2004-10-05 17:44:53 +00:00
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
2004-10-17 02:36:32 +00:00
|
|
|
"DOCSIS Cable Modem Device Capabilities Length", HFILL }},
|
2006-01-11 22:05:43 +00:00
|
|
|
|
2007-09-13 18:51:32 +00:00
|
|
|
{ &hf_bootp_alu_vid,
|
|
|
|
{ "Voice VLAN ID", "bootp.vendor.alu.vid",
|
2006-01-11 22:05:43 +00:00
|
|
|
FT_UINT16, BASE_DEC, NULL, 0x0,
|
2007-09-13 18:51:32 +00:00
|
|
|
"Alcatel-Lucent VLAN ID to define Voice VLAN", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_bootp_alu_tftp1,
|
|
|
|
{ "Spatial Redundancy TFTP1", "bootp.vendor.alu.tftp1" ,FT_IPv4,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
|
|
|
"", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_bootp_alu_tftp2,
|
|
|
|
{ "Spatial Redundancy TFTP2", "bootp.vendor.alu.tftp2" ,FT_IPv4,
|
|
|
|
BASE_NONE, NULL, 0x0,
|
|
|
|
"", HFILL }},
|
2006-03-09 04:31:10 +00:00
|
|
|
|
|
|
|
{ &hf_bootp_client_identifier_uuid,
|
|
|
|
{ "Client Identifier (UUID)", "bootp.client_id_uuid",
|
|
|
|
FT_GUID, BASE_NONE, NULL, 0x0,
|
|
|
|
"Client Machine Identifier (UUID)", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_bootp_client_network_id_major_ver,
|
|
|
|
{ "Client Network ID Major Version", "bootp.client_network_id_major",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
|
|
"Client Machine Identifier, Major Version", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_bootp_client_network_id_minor_ver,
|
|
|
|
{ "Client Network ID Minor Version", "bootp.client_network_id_minor",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
|
|
"Client Machine Identifier, Major Version", HFILL }},
|
2006-08-15 13:24:02 +00:00
|
|
|
|
|
|
|
{ &hf_bootp_option_type,
|
|
|
|
{ "Option", "bootp.option.type",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
|
|
"Bootp/Dhcp option type", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_bootp_option_length,
|
|
|
|
{ "Length", "bootp.option.length",
|
|
|
|
FT_UINT8, BASE_DEC, NULL, 0x0,
|
|
|
|
"Bootp/Dhcp option length", HFILL }},
|
|
|
|
|
|
|
|
{ &hf_bootp_option_value,
|
|
|
|
{ "Value", "bootp.option.value",
|
|
|
|
FT_BYTES, BASE_NONE, NULL, 0x0,
|
|
|
|
"Bootp/Dhcp option value", HFILL }},
|
|
|
|
|
1999-10-08 13:57:31 +00:00
|
|
|
};
|
2004-10-16 02:04:08 +00:00
|
|
|
|
1999-11-16 11:44:20 +00:00
|
|
|
static gint *ett[] = {
|
|
|
|
&ett_bootp,
|
2002-06-19 19:39:38 +00:00
|
|
|
&ett_bootp_flags,
|
1999-11-16 11:44:20 +00:00
|
|
|
&ett_bootp_option,
|
2004-10-16 02:04:08 +00:00
|
|
|
&ett_bootp_fqdn,
|
1999-11-16 11:44:20 +00:00
|
|
|
};
|
2002-08-28 21:04:11 +00:00
|
|
|
|
2003-11-18 19:56:37 +00:00
|
|
|
module_t *bootp_module;
|
|
|
|
|
2001-01-03 06:56:03 +00:00
|
|
|
proto_bootp = proto_register_protocol("Bootstrap Protocol", "BOOTP/DHCP",
|
|
|
|
"bootp");
|
1999-10-08 13:57:31 +00:00
|
|
|
proto_register_field_array(proto_bootp, hf, array_length(hf));
|
1999-11-16 11:44:20 +00:00
|
|
|
proto_register_subtree_array(ett, array_length(ett));
|
2003-09-02 22:47:59 +00:00
|
|
|
bootp_dhcp_tap = register_tap("bootp");
|
2003-11-18 19:56:37 +00:00
|
|
|
|
2007-05-01 09:45:34 +00:00
|
|
|
/* Allow dissector to find be found by name. */
|
|
|
|
register_dissector("bootp", dissect_bootp, proto_bootp);
|
2007-05-24 17:36:07 +00:00
|
|
|
|
2003-11-18 19:56:37 +00:00
|
|
|
bootp_module = prefs_register_protocol(proto_bootp, NULL);
|
|
|
|
|
|
|
|
prefs_register_bool_preference(bootp_module, "novellserverstring",
|
|
|
|
"Decode Option 85 as String",
|
|
|
|
"Novell Servers option 85 can be configured as a string instead of address",
|
|
|
|
&novell_string);
|
2004-10-05 17:44:53 +00:00
|
|
|
|
|
|
|
prefs_register_enum_preference(bootp_module, "pkt.ccc.protocol_version",
|
|
|
|
"PacketCable CCC protocol version",
|
|
|
|
"The PacketCable CCC protocol version",
|
|
|
|
&pkt_ccc_protocol_version,
|
|
|
|
pkt_ccc_protocol_versions,
|
|
|
|
FALSE);
|
|
|
|
|
|
|
|
prefs_register_uint_preference(bootp_module, "pkt.ccc.option",
|
|
|
|
"PacketCable CCC option",
|
|
|
|
"Option Number for PacketCable CableLabs Client Configuration",
|
|
|
|
10,
|
|
|
|
&pkt_ccc_option);
|
|
|
|
|
|
|
|
|
1999-07-29 05:47:07 +00:00
|
|
|
}
|
2000-04-08 07:07:42 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
proto_reg_handoff_bootp(void)
|
|
|
|
{
|
2001-12-03 04:00:26 +00:00
|
|
|
dissector_handle_t bootp_handle;
|
|
|
|
|
|
|
|
bootp_handle = create_dissector_handle(dissect_bootp, proto_bootp);
|
|
|
|
dissector_add("udp.port", UDP_PORT_BOOTPS, bootp_handle);
|
2002-05-28 20:08:09 +00:00
|
|
|
dissector_add("udp.port", UDP_PORT_BOOTPC, bootp_handle);
|
2000-04-08 07:07:42 +00:00
|
|
|
}
|