![Michael Mann](/assets/img/avatar_default.png)
Now that "bytes consumed" can be determined, should tcp_dissect_pdus() take advantage of that? Should tcp_dissect_pdus return length (bytes consumed)? There are many dissectors that just call tcp_dissect_pdus() then return tvb_length(tvb). Seems like that could all be rolled into one. svn path=/trunk/; revision=53198
2544 lines
113 KiB
C
2544 lines
113 KiB
C
/* packet-dhpcv6.c
|
|
* Routines for DHCPv6 packet disassembly
|
|
* Copyright 2004, Nicolas DICHTEL - 6WIND - <nicolas.dichtel@6wind.com>
|
|
* Jun-ichiro itojun Hagino <itojun@iijlab.net>
|
|
* IItom Tsutomu MIENO <iitom@utouto.com>
|
|
* SHIRASAKI Yasuhiro <yasuhiro@gnome.gr.jp>
|
|
* Tony Lindstrom <tony.lindstrom@ericsson.com>
|
|
* Copyright 2012, Jerome LAFORGE <jerome.laforge@gmail.com>
|
|
*
|
|
* $Id$
|
|
*
|
|
* The information used comes from:
|
|
* RFC3315.txt (DHCPv6)
|
|
* RFC3319.txt (SIP options)
|
|
* RFC3633.txt (Prefix options)
|
|
* RFC3646.txt (DNS servers/domains)
|
|
* RFC3898.txt (NIS options)
|
|
* RFC4075.txt (Simple Network Time Protocol Option)
|
|
* RFC4242.txt (Information Refresh Time Option)
|
|
* RFC4280.txt (Broadcast and Multicast Control Servers Options)
|
|
* RFC4649.txt (Remote ID option)
|
|
* RFC4704.txt (Client FQDN)
|
|
* RFC5007.txt (DHCPv6 Leasequery)
|
|
* RFC5417.txt (CAPWAP Access Controller DHCP Option)
|
|
* RFC5460.txt (DHCPv6 Bulk Leasequery)
|
|
* RFC5908.txt (Network Time Protocol (NTP) Server Option)
|
|
* RFC6334.txt (Dual-Stack Lite Option)
|
|
* RFC6603.txt (Prefix Exclude Option)
|
|
* draft-ietf-dhc-dhcpv6-opt-timeconfig-03.txt
|
|
* draft-ietf-dhc-dhcpv6-opt-lifetime-00.txt
|
|
* CL-SP-CANN-DHCP-Reg-I06-110210.doc
|
|
*
|
|
* Note that protocol constants are still subject to change, based on IANA
|
|
* assignment decisions.
|
|
*
|
|
* Wireshark - Network traffic analyzer
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
* Copyright 1998 Gerald Combs
|
|
*
|
|
* 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.
|
|
*
|
|
* 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.
|
|
*
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <glib.h>
|
|
#include <epan/packet.h>
|
|
#include <epan/sminmpec.h>
|
|
#include <epan/strutil.h>
|
|
#include <epan/arptypes.h>
|
|
#include <epan/expert.h>
|
|
#include <epan/prefs.h>
|
|
#include <epan/wmem/wmem.h>
|
|
#include "packet-tcp.h"
|
|
#include "packet-arp.h"
|
|
#include "packet-dns.h" /* for get_dns_name() */
|
|
|
|
void proto_register_dhcpv6(void);
|
|
void proto_reg_handoff_dhcpv6(void);
|
|
|
|
static gboolean dhcpv6_bulk_leasequery_desegment = TRUE;
|
|
|
|
static int proto_dhcpv6 = -1;
|
|
static int proto_dhcpv6_bulk_leasequery = -1;
|
|
static int hf_dhcpv6_msgtype = -1;
|
|
static int hf_dhcpv6_domain = -1;
|
|
static int hf_clientfqdn_reserved = -1;
|
|
static int hf_clientfqdn_n = -1;
|
|
static int hf_clientfqdn_o = -1;
|
|
static int hf_clientfqdn_s = -1;
|
|
static int hf_option_type = -1;
|
|
static int hf_option_length = -1;
|
|
static int hf_option_value = -1;
|
|
static int hf_remoteid_enterprise = -1;
|
|
static int hf_vendoropts_enterprise = -1;
|
|
static int hf_duid_bytes = -1;
|
|
static int hf_duid_type = -1;
|
|
static int hf_duidllt_time = -1;
|
|
static int hf_duidllt_link_layer_addr = -1;
|
|
static int hf_duidllt_hwtype = -1;
|
|
static int hf_duidll_hwtype = -1;
|
|
static int hf_duiden_enterprise = -1;
|
|
static int hf_duiden_identifier = -1;
|
|
static int hf_duidll_link_layer_addr = -1;
|
|
static int hf_iaid = -1;
|
|
static int hf_iaid_t1 = -1;
|
|
static int hf_iaid_t2 = -1;
|
|
static int hf_iata = -1;
|
|
static int hf_iaaddr_ip = -1;
|
|
static int hf_iaaddr_pref_lifetime = -1;
|
|
static int hf_iaaddr_valid_lifetime = -1;
|
|
static int hf_requested_option_code = -1;
|
|
static int hf_option_preference = -1;
|
|
static int hf_elapsed_time = -1;
|
|
static int hf_auth_protocol = -1;
|
|
static int hf_auth_algorithm = -1;
|
|
static int hf_auth_rdm = -1;
|
|
static int hf_auth_replay_detection = -1;
|
|
static int hf_auth_info = -1;
|
|
static int hf_opt_unicast = -1;
|
|
static int hf_opt_status_code = -1;
|
|
static int hf_opt_status_msg = -1;
|
|
static int hf_vendorclass_enterprise = -1;
|
|
static int hf_vendorclass_data = -1;
|
|
static int hf_vendoropts_enterprise_option_code = -1;
|
|
static int hf_vendoropts_enterprise_option_length = -1;
|
|
static int hf_vendoropts_enterprise_option_data = -1;
|
|
static int hf_interface_id = -1;
|
|
static int hf_interface_id_link_address = -1;
|
|
static int hf_reconf_msg = -1;
|
|
static int hf_sip_server_a = -1;
|
|
static int hf_dns_servers = -1;
|
|
static int hf_nis_servers = -1;
|
|
static int hf_nisp_servers = -1;
|
|
static int hf_sntp_servers = -1;
|
|
static int hf_opt_lifetime = -1;
|
|
static int hf_bcmcs_servers_a = -1;
|
|
static int hf_remoteid_enterprise_id = -1;
|
|
static int hf_subscriber_id = -1;
|
|
static int hf_pana_agent = -1;
|
|
static int hf_opt_timezone = -1;
|
|
static int hf_opt_tzdb = -1;
|
|
static int hf_lq_query = -1;
|
|
static int hf_lq_query_link_address = -1;
|
|
static int hf_clt_time = -1;
|
|
static int hf_lq_relay_data_peer_addr = -1;
|
|
static int hf_lq_relay_data_msg = -1;
|
|
static int hf_lq_client_link = -1;
|
|
static int hf_capwap_ac_v6 = -1;
|
|
static int hf_aftr_name = -1;
|
|
static int hf_iaprefix_pref_lifetime = -1;
|
|
static int hf_iaprefix_valid_lifetime = -1;
|
|
static int hf_iaprefix_pref_len = -1;
|
|
static int hf_iaprefix_pref_addr = -1;
|
|
static int hf_mip6_ha = -1;
|
|
static int hf_mip6_hoa = -1;
|
|
static int hf_nai = -1;
|
|
static int hf_pd_exclude_pref_len = -1;
|
|
static int hf_pd_exclude_subnet_id = -1;
|
|
static int hf_dhcpv6_hopcount = -1;
|
|
static int hf_dhcpv6_xid = -1;
|
|
static int hf_dhcpv6_peeraddr = -1;
|
|
static int hf_dhcpv6_linkaddr = -1;
|
|
static int hf_option_ntpserver_type = -1;
|
|
static int hf_option_ntpserver_length = -1;
|
|
static int hf_option_ntpserver_addr = -1;
|
|
static int hf_option_ntpserver_mc_addr = -1;
|
|
static int hf_packetcable_ccc_suboption = -1;
|
|
static int hf_packetcable_ccc_pri_dhcp = -1;
|
|
static int hf_packetcable_ccc_sec_dhcp = -1;
|
|
static int hf_packetcable_ccc_prov_srv_type = -1;
|
|
static int hf_packetcable_ccc_prov_srv_fqdn = -1;
|
|
static int hf_packetcable_ccc_prov_srv_ipv4 = -1;
|
|
static int hf_packetcable_ccc_as_krb_nominal_timeout = -1;
|
|
static int hf_packetcable_ccc_as_krb_max_timeout = -1;
|
|
static int hf_packetcable_ccc_as_krb_max_retry_count = -1;
|
|
static int hf_packetcable_ccc_ap_krb_nominal_timeout = -1;
|
|
static int hf_packetcable_ccc_ap_krb_max_timeout = -1;
|
|
static int hf_packetcable_ccc_ap_krb_max_retry_count = -1;
|
|
static int hf_packetcable_ccc_krb_realm = -1;
|
|
static int hf_packetcable_ccc_tgt_flag = -1;
|
|
static int hf_packetcable_ccc_tgt_flag_fetch = -1;
|
|
static int hf_packetcable_ccc_prov_timer = -1;
|
|
static int hf_packetcable_ccc_sec_tcm = -1;
|
|
static int hf_packetcable_ccc_sec_tcm_provisioning_server = -1;
|
|
static int hf_packetcable_ccc_sec_tcm_call_manager_server = -1;
|
|
static int hf_packetcable_cccV6_suboption = -1;
|
|
static int hf_packetcable_cccV6_pri_dss = -1;
|
|
static int hf_packetcable_cccV6_sec_dss = -1;
|
|
static int hf_packetcable_cccV6_prov_srv_type = -1;
|
|
static int hf_packetcable_cccV6_prov_srv_fqdn = -1;
|
|
static int hf_packetcable_cccV6_prov_srv_ipv6 = -1;
|
|
static int hf_packetcable_cccV6_as_krb_nominal_timeout = -1;
|
|
static int hf_packetcable_cccV6_as_krb_max_timeout = -1;
|
|
static int hf_packetcable_cccV6_as_krb_max_retry_count = -1;
|
|
static int hf_packetcable_cccV6_ap_krb_nominal_timeout = -1;
|
|
static int hf_packetcable_cccV6_ap_krb_max_timeout = -1;
|
|
static int hf_packetcable_cccV6_ap_krb_max_retry_count = -1;
|
|
static int hf_packetcable_cccV6_krb_realm = -1;
|
|
static int hf_packetcable_cccV6_tgt_flag = -1;
|
|
static int hf_packetcable_cccV6_tgt_flag_fetch = -1;
|
|
static int hf_packetcable_cccV6_prov_timer = -1;
|
|
static int hf_packetcable_cccV6_sec_tcm = -1;
|
|
static int hf_packetcable_cccV6_sec_tcm_provisioning_server = -1;
|
|
static int hf_packetcable_cccV6_sec_tcm_call_manager_server = -1;
|
|
static int hf_cablelabs_opts = -1;
|
|
static int hf_modem_capabilities_encoding_type = -1;
|
|
static int hf_eue_capabilities_encoding_type = -1;
|
|
static int hf_capabilities_encoding_length = -1;
|
|
static int hf_capabilities_encoding_bytes = -1;
|
|
static int hf_capabilities_encoding_number = -1;
|
|
static int hf_cablelabs_ipv6_server = -1;
|
|
|
|
static gint ett_dhcpv6 = -1;
|
|
static gint ett_dhcpv6_option = -1;
|
|
static gint ett_dhcpv6_option_vsoption = -1;
|
|
static gint ett_dhcpv6_vendor_option = -1;
|
|
static gint ett_dhcpv6_pkt_option = -1;
|
|
static gint ett_dhcpv6_netserver_option = -1;
|
|
static gint ett_dhcpv6_tlv5_type = -1;
|
|
|
|
static expert_field ei_dhcpv6_bogus_length = EI_INIT;
|
|
static expert_field ei_dhcpv6_malformed_option = EI_INIT;
|
|
static expert_field ei_dhcpv6_no_suboption_len = EI_INIT;
|
|
static expert_field ei_dhcpv6_invalid_byte = EI_INIT;
|
|
static expert_field ei_dhcpv6_invalid_time_value = EI_INIT;
|
|
static expert_field ei_dhcpv6_invalid_type = EI_INIT;
|
|
static expert_field ei_dhcpv6_malformed_dns = EI_INIT;
|
|
|
|
|
|
static int hf_dhcpv6_bulk_leasequery_size = -1;
|
|
static int hf_dhcpv6_bulk_leasequery_msgtype = -1;
|
|
static int hf_dhcpv6_bulk_leasequery_reserved = -1;
|
|
static int hf_dhcpv6_bulk_leasequery_trans_id = -1;
|
|
|
|
static gint ett_dhcpv6_bulk_leasequery = -1;
|
|
static gint ett_dhcpv6_bulk_leasequery_options = -1;
|
|
|
|
static expert_field ei_dhcpv6_bulk_leasequery_bad_query_type = EI_INIT;
|
|
static expert_field ei_dhcpv6_bulk_leasequery_no_lq_relay_data = EI_INIT;
|
|
static expert_field ei_dhcpv6_bulk_leasequery_bad_msg_type = EI_INIT;
|
|
|
|
#define UDP_PORT_DHCPV6_DOWNSTREAM 546
|
|
#define UDP_PORT_DHCPV6_UPSTREAM 547
|
|
|
|
#define DHCPV6_LEASEDURATION_INFINITY 0xffffffff
|
|
|
|
#define SOLICIT 1
|
|
#define ADVERTISE 2
|
|
#define REQUEST 3
|
|
#define CONFIRM 4
|
|
#define RENEW 5
|
|
#define REBIND 6
|
|
#define REPLY 7
|
|
#define RELEASE 8
|
|
#define DECLINE 9
|
|
#define RECONFIGURE 10
|
|
#define INFORMATION_REQUEST 11
|
|
#define RELAY_FORW 12
|
|
#define RELAY_REPLY 13
|
|
#define LEASEQUERY 14
|
|
#define LEASEQUERY_REPLY 15
|
|
#define LEASEQUERY_DONE 16
|
|
#define LEASEQUERY_DATA 17
|
|
|
|
#define OPTION_CLIENTID 1
|
|
#define OPTION_SERVERID 2
|
|
#define OPTION_IA_NA 3
|
|
#define OPTION_IA_TA 4
|
|
#define OPTION_IAADDR 5
|
|
#define OPTION_ORO 6
|
|
#define OPTION_PREFERENCE 7
|
|
#define OPTION_ELAPSED_TIME 8
|
|
#define OPTION_RELAY_MSG 9
|
|
/* #define OPTION_SERVER_MSG 10 */
|
|
#define OPTION_AUTH 11
|
|
#define OPTION_UNICAST 12
|
|
#define OPTION_STATUS_CODE 13
|
|
#define OPTION_RAPID_COMMIT 14
|
|
#define OPTION_USER_CLASS 15
|
|
#define OPTION_VENDOR_CLASS 16
|
|
#define OPTION_VENDOR_OPTS 17
|
|
#define OPTION_INTERFACE_ID 18
|
|
#define OPTION_RECONF_MSG 19
|
|
#define OPTION_RECONF_ACCEPT 20
|
|
#define OPTION_SIP_SERVER_D 21
|
|
#define OPTION_SIP_SERVER_A 22
|
|
#define OPTION_DNS_SERVERS 23
|
|
#define OPTION_DOMAIN_LIST 24
|
|
#define OPTION_IA_PD 25
|
|
#define OPTION_IAPREFIX 26
|
|
#define OPTION_NIS_SERVERS 27
|
|
#define OPTION_NISP_SERVERS 28
|
|
#define OPTION_NIS_DOMAIN_NAME 29
|
|
#define OPTION_NISP_DOMAIN_NAME 30
|
|
#define OPTION_SNTP_SERVERS 31
|
|
#define OPTION_LIFETIME 32
|
|
#define OPTION_BCMCS_SERVER_D 33
|
|
#define OPTION_BCMCS_SERVER_A 34
|
|
#define OPTION_GEOCONF_CIVIC 36
|
|
#define OPTION_REMOTE_ID 37
|
|
#define OPTION_SUBSCRIBER_ID 38
|
|
#define OPTION_CLIENT_FQDN 39
|
|
#define OPTION_PANA_AGENT 40
|
|
#define OPTION_TIME_ZONE 41
|
|
#define OPTION_TZDB 42
|
|
#define OPTION_ERO 43
|
|
#define OPTION_LQ_QUERY 44
|
|
#define OPTION_CLIENT_DATA 45
|
|
#define OPTION_CLT_TIME 46
|
|
#define OPTION_LQ_RELAY_DATA 47
|
|
#define OPTION_LQ_CLIENT_LINK 48
|
|
#define OPTION_CAPWAP_AC_V6 52
|
|
#define OPTION_RELAYID 53
|
|
#define OPTION_NTP_SERVER 56
|
|
#define OPTION_AFTR_NAME 64
|
|
#define OPTION_PD_EXCLUDE 67
|
|
|
|
/* temporary value until defined by IETF */
|
|
#define OPTION_MIP6_HA 165
|
|
#define OPTION_MIP6_HOA 166
|
|
#define OPTION_NAI 167
|
|
|
|
#define DUID_LLT 1
|
|
#define DUID_EN 2
|
|
#define DUID_LL 3
|
|
#define DUID_LL_OLD 4
|
|
|
|
static const value_string msgtype_vals[] = {
|
|
{ SOLICIT, "Solicit" },
|
|
{ ADVERTISE, "Advertise" },
|
|
{ REQUEST, "Request" },
|
|
{ CONFIRM, "Confirm" },
|
|
{ RENEW, "Renew" },
|
|
{ REBIND, "Rebind" },
|
|
{ REPLY, "Reply" },
|
|
{ RELEASE, "Release" },
|
|
{ DECLINE, "Decline" },
|
|
{ RECONFIGURE, "Reconfigure" },
|
|
{ INFORMATION_REQUEST, "Information-request" },
|
|
{ RELAY_FORW, "Relay-forw" },
|
|
{ RELAY_REPLY, "Relay-reply" },
|
|
{ LEASEQUERY, "Leasequery" },
|
|
{ LEASEQUERY_REPLY, "Leasequery-reply" },
|
|
{ LEASEQUERY_DONE, "Leasequery-done" },
|
|
{ LEASEQUERY_DATA, "Leasequery-data" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string opttype_vals[] = {
|
|
{ OPTION_CLIENTID, "Client Identifier" },
|
|
{ OPTION_SERVERID, "Server Identifier" },
|
|
{ OPTION_IA_NA, "Identity Association for Non-temporary Address" },
|
|
{ OPTION_IA_TA, "Identity Association for Temporary Address" },
|
|
{ OPTION_IAADDR, "IA Address" },
|
|
{ OPTION_ORO, "Option Request" },
|
|
{ OPTION_PREFERENCE, "Preference" },
|
|
{ OPTION_ELAPSED_TIME, "Elapsed time" },
|
|
{ OPTION_RELAY_MSG, "Relay Message" },
|
|
/* { OPTION_SERVER_MSG, "Server message" }, */
|
|
{ OPTION_AUTH, "Authentication" },
|
|
{ OPTION_UNICAST, "Server unicast" },
|
|
{ OPTION_STATUS_CODE, "Status code" },
|
|
{ OPTION_RAPID_COMMIT, "Rapid Commit" },
|
|
{ OPTION_USER_CLASS, "User Class" },
|
|
{ OPTION_VENDOR_CLASS, "Vendor Class" },
|
|
{ OPTION_VENDOR_OPTS, "Vendor-specific Information" },
|
|
{ OPTION_INTERFACE_ID, "Interface-Id" },
|
|
{ OPTION_RECONF_MSG, "Reconfigure Message" },
|
|
{ OPTION_RECONF_ACCEPT, "Reconfigure Accept" },
|
|
{ OPTION_SIP_SERVER_D, "SIP Server Domain Name List" },
|
|
{ OPTION_SIP_SERVER_A, "SIP Servers IPv6 Address List" },
|
|
{ OPTION_DNS_SERVERS, "DNS recursive name server" },
|
|
{ OPTION_DOMAIN_LIST, "Domain Search List" },
|
|
{ OPTION_IA_PD, "Identity Association for Prefix Delegation" },
|
|
{ OPTION_IAPREFIX, "IA Prefix" },
|
|
{ OPTION_NIS_SERVERS, "Network Information Server" },
|
|
{ OPTION_NISP_SERVERS, "Network Information Server V2" },
|
|
{ OPTION_NIS_DOMAIN_NAME, "Network Information Server Domain Name" },
|
|
{ OPTION_NISP_DOMAIN_NAME, "Network Information Server V2 Domain Name" },
|
|
{ OPTION_SNTP_SERVERS, "Simple Network Time Protocol Server" },
|
|
{ OPTION_LIFETIME, "Lifetime" },
|
|
{ OPTION_BCMCS_SERVER_D, "BCMCS Server Domain" },
|
|
{ OPTION_BCMCS_SERVER_A, "BCMCS Servers IPv6 Address List" },
|
|
{ OPTION_GEOCONF_CIVIC, "Geoconf Civic Address" },
|
|
{ OPTION_REMOTE_ID, "Remote Identifier" },
|
|
{ OPTION_SUBSCRIBER_ID, "Subscriber Identifier" },
|
|
{ OPTION_CLIENT_FQDN, "Fully Qualified Domain Name" },
|
|
{ OPTION_PANA_AGENT, "PANA Agents IPv6 Address List" },
|
|
{ OPTION_TIME_ZONE, "Time Zone" },
|
|
{ OPTION_TZDB, "Time Zone Database" },
|
|
{ OPTION_ERO, "Echo Request Option" },
|
|
{ OPTION_LQ_QUERY, "Leasequery Query" },
|
|
{ OPTION_CLIENT_DATA, "Leasequery Client Data" },
|
|
{ OPTION_CLT_TIME, "Client Last Transaction Time" },
|
|
{ OPTION_LQ_RELAY_DATA, "Leasequery Relay Data" },
|
|
{ OPTION_LQ_CLIENT_LINK, "Leasequery Client Link Address List" },
|
|
{ OPTION_CAPWAP_AC_V6, "CAPWAP Access Controllers" },
|
|
{ OPTION_AFTR_NAME, "Dual-Stack Lite AFTR Name" },
|
|
{ OPTION_PD_EXCLUDE, "Prefix Exclude" },
|
|
{ OPTION_MIP6_HA, "Mobile IPv6 Home Agent" },
|
|
{ OPTION_MIP6_HOA, "Mobile IPv6 Home Address" },
|
|
{ OPTION_NAI, "Network Access Identifier" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
static const value_string statuscode_vals[] =
|
|
{
|
|
{0, "Success" },
|
|
{1, "UnspecFail" },
|
|
{2, "NoAddrAvail" },
|
|
{3, "NoBinding" },
|
|
{4, "NotOnLink" },
|
|
{5, "UseMulticast" },
|
|
{6, "NoPrefixAvail" },
|
|
{7, "UnknownQueryType" },
|
|
{8, "MalformedQuery" },
|
|
{9, "NotConfigured" },
|
|
{10, "NotAllowed" },
|
|
{11, "QueryTerminated" },
|
|
{0, NULL }
|
|
};
|
|
|
|
static const value_string duidtype_vals[] =
|
|
{
|
|
{ DUID_LLT, "link-layer address plus time" },
|
|
{ DUID_EN, "assigned by vendor based on Enterprise number" },
|
|
{ DUID_LL, "link-layer address" },
|
|
{ DUID_LL_OLD, "link-layer address (old)" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
#define NTP_SUBOPTION_SRV_ADDR 1
|
|
#define NTP_SUBOPTION_MC_ADDR 2
|
|
#define NTP_SUBOPTION_SRV_FQDN 3
|
|
|
|
static const value_string ntp_server_opttype_vals[] =
|
|
{
|
|
{ NTP_SUBOPTION_SRV_ADDR, "NTP Server Address" },
|
|
{ NTP_SUBOPTION_MC_ADDR, "NTP Multicast Address" },
|
|
{ NTP_SUBOPTION_SRV_FQDN, "NTP Server FQDN" },
|
|
|
|
{ 0, NULL }
|
|
};
|
|
|
|
|
|
static const true_false_string fqdn_n = {
|
|
"Server should not perform DNS updates",
|
|
"Server should perform DNS updates"
|
|
};
|
|
|
|
static const true_false_string fqdn_o = {
|
|
"Server has overridden client's S bit preference",
|
|
"Server has not overridden client's S bit preference"
|
|
};
|
|
|
|
static const true_false_string fqdn_s = {
|
|
"Server should perform forward DNS updates",
|
|
"Server should not perform forward DNS updates"
|
|
};
|
|
|
|
#define LQ_QUERY_ADDRESS 1
|
|
#define LQ_QUERY_CLIENTID 2
|
|
#define LQ_QUERY_RELAYID 3
|
|
#define LQ_QUERY_LINK_ADDRESS 4
|
|
#define LQ_QUERY_REMOTEID 5
|
|
|
|
static const value_string lq_query_vals[] = {
|
|
{ LQ_QUERY_ADDRESS, "by-address" },
|
|
{ LQ_QUERY_CLIENTID, "by-clientID" },
|
|
{ LQ_QUERY_RELAYID, "by-relayID" },
|
|
{ LQ_QUERY_LINK_ADDRESS, "by-linkAddress" },
|
|
{ LQ_QUERY_REMOTEID, "by-remoteID" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
/* CableLabs Common Vendor Specific Options */
|
|
#define CL_OPTION_ORO 0x0001 /* 1 */
|
|
#define CL_OPTION_DEVICE_TYPE 0x0002 /* 2 */
|
|
#define CL_OPTION_EMBEDDED_COMPONENT_LIST 0x0003 /* 3 */
|
|
#define CL_OPTION_DEVICE_SERIAL_NUMBER 0x0004 /* 4 */
|
|
#define CL_OPTION_HARDWARE_VERSION_NUMBER 0x0005 /* 5 */
|
|
#define CL_OPTION_SOFTWARE_VERSION_NUMBER 0x0006 /* 6 */
|
|
#define CL_OPTION_BOOT_ROM_VERSION 0x0007 /* 7 */
|
|
#define CL_OPTION_VENDOR_OUI 0x0008 /* 8 */
|
|
#define CL_OPTION_MODEL_NUMBER 0x0009 /* 9 */
|
|
#define CL_OPTION_VENDOR_NAME 0x000a /* 10 */
|
|
/* 11-32 is currently reserved */
|
|
#define CL_OPTION_TFTP_SERVERS 0x0020 /* 32 */
|
|
#define CL_OPTION_CONFIG_FILE_NAME 0x0021 /* 33 */
|
|
#define CL_OPTION_SYSLOG_SERVERS 0x0022 /* 34 */
|
|
#define CL_OPTION_TLV5 0x0023 /* 35 */
|
|
#define CL_OPTION_DEVICE_ID 0x0024 /* 36 */
|
|
#define CL_OPTION_RFC868_SERVERS 0x0025 /* 37 */
|
|
#define CL_OPTION_TIME_OFFSET 0x0026 /* 38 */
|
|
#define CL_OPTION_IP_PREF 0x0027 /* 39 */
|
|
|
|
/** CableLabs DOCSIS Project Vendor Specific Options */
|
|
#define CL_OPTION_DOCS_CMTS_CAP 0x0401 /* 1025 */
|
|
#define CL_CM_MAC_ADDR 0x0402 /* 1026 */
|
|
#define CL_EROUTER_CONTAINER_OPTION 0x403 /* 1027 */
|
|
|
|
/** CableLabs PacketCable Project Vendor Specific Options **/
|
|
#define CL_OPTION_CCC 0x087a /* 2170 */
|
|
#define CL_OPTION_CCCV6 0x087b /* 2171 */
|
|
#define CL_OPTION_CORRELATION_ID 0x087c /*2172 */
|
|
|
|
/** CableLabs TLVs for DOCS_CMTS_CAP Vendor Option **/
|
|
#define CL_OPTION_DOCS_CMTS_TLV_VERS_NUM 0x01 /* 1 */
|
|
|
|
static const value_string cl_vendor_subopt_values[] = {
|
|
/* 1 */ { CL_OPTION_ORO, "Option Request = " },
|
|
/* 2 */ { CL_OPTION_DEVICE_TYPE, "Device Type = " },
|
|
/* 3 */ { CL_OPTION_EMBEDDED_COMPONENT_LIST, "Embedded Components = " },
|
|
/* 4 */ { CL_OPTION_DEVICE_SERIAL_NUMBER, "Serial Number = " },
|
|
/* 5 */ { CL_OPTION_HARDWARE_VERSION_NUMBER, "Hardware Version = " },
|
|
/* 6 */ { CL_OPTION_SOFTWARE_VERSION_NUMBER, "Software Version = " },
|
|
/* 7 */ { CL_OPTION_BOOT_ROM_VERSION, "Boot ROM Version = " },
|
|
/* 8 */ { CL_OPTION_VENDOR_OUI, "Organization Unique Identifier = " },
|
|
/* 9 */ { CL_OPTION_MODEL_NUMBER, "Model Number = " },
|
|
/* 10 */ { CL_OPTION_VENDOR_NAME, "Vendor Name = " },
|
|
/* 32 */ { CL_OPTION_TFTP_SERVERS, "TFTP Server Addresses : " },
|
|
/* 33 */ { CL_OPTION_CONFIG_FILE_NAME, "Configuration File Name = " },
|
|
/* 34 */ { CL_OPTION_SYSLOG_SERVERS, "Syslog Servers : " },
|
|
/* 35 */ { CL_OPTION_TLV5, "TLV5 = " },
|
|
/* 36 */ { CL_OPTION_DEVICE_ID, "Device Identifier = " },
|
|
/* 37 */ { CL_OPTION_RFC868_SERVERS, "Time Protocol Servers : " },
|
|
/* 38 */ { CL_OPTION_TIME_OFFSET, "Time Offset = " },
|
|
/* 39 */ { CL_OPTION_IP_PREF, "IP preference : " },
|
|
/* 1025 */ { CL_OPTION_DOCS_CMTS_CAP, "CMTS Capabilities Option : " },
|
|
/* 1026 */ { CL_CM_MAC_ADDR, "CM MAC Address Option = " },
|
|
/* 1027 */ { CL_EROUTER_CONTAINER_OPTION, "eRouter Container Option : " },
|
|
/* 2170 */ { CL_OPTION_CCC, "CableLabs Client Configuration : " },
|
|
/* 2171 */ { CL_OPTION_CCCV6, "CableLabs Client Configuration IPv6 : " },
|
|
/* 2172 */ { CL_OPTION_CORRELATION_ID, "CableLabs Correlation ID = " },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
#define PKT_CCC_PRI_DHCP 0x0001
|
|
#define PKT_CCC_SEC_DHCP 0x0002
|
|
#define PKT_CCC_IETF_PROV_SRV 0x0003
|
|
#define PKT_CCC_IETF_AS_KRB 0x0004
|
|
#define PKT_CCC_IETF_AP_KRB 0x0005
|
|
#define PKT_CCC_KRB_REALM 0x0006
|
|
#define PKT_CCC_TGT_FLAG 0x0007
|
|
#define PKT_CCC_PROV_TIMER 0x0008
|
|
#define PKT_CCC_IETF_SEC_TKT 0x0009
|
|
/** 10 -255 Reserved for future extensions **/
|
|
|
|
#define PKT_CCCV6_PRI_DSS 0x0001
|
|
#define PKT_CCCV6_SEC_DSS 0x0002
|
|
#define PKT_CCCV6_IETF_PROV_SRV 0x0003
|
|
#define PKT_CCCV6_IETF_AS_KRB 0x0004
|
|
#define PKT_CCCV6_IETF_AP_KRB 0x0005
|
|
#define PKT_CCCV6_KRB_REALM 0x0006
|
|
#define PKT_CCCV6_TGT_FLAG 0x0007
|
|
#define PKT_CCCV6_PROV_TIMER 0x0008
|
|
#define PKT_CCCV6_IETF_SEC_TKT 0x0009
|
|
/** 10 -255 Reserved for future extensions **/
|
|
|
|
static const value_string pkt_ccc_opt_vals[] = {
|
|
{ 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" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const value_string pkt_ccc_prov_srv_type_vals[] = {
|
|
{ 0, "FQDN" },
|
|
{ 1, "IPv4" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const value_string pkt_cccV6_prov_srv_type_vals[] = {
|
|
{ 0, "FQDN" },
|
|
{ 1, "IPv6" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const value_string pkt_cccV6_opt_vals[] = {
|
|
{ PKT_CCCV6_PRI_DSS, "TSP's Primary DHCPv6 Server Selector ID" },
|
|
{ PKT_CCCV6_SEC_DSS, "TSP's Secondary DHCPv6 Server Selector ID " },
|
|
{ PKT_CCCV6_IETF_PROV_SRV, "TSP's Provisioning Server" },
|
|
{ PKT_CCCV6_IETF_AS_KRB, "TSP's AS-REQ/AS-REP Backoff and Retry" },
|
|
{ PKT_CCCV6_IETF_AP_KRB, "TSP's AP-REQ/AP-REP Backoff and Retry" },
|
|
{ PKT_CCCV6_KRB_REALM, "TSP's Kerberos Realm Name" },
|
|
{ PKT_CCCV6_TGT_FLAG, "TSP's Ticket Granting Server Utilization" },
|
|
{ PKT_CCCV6_PROV_TIMER, "TSP's Provisioning Timer Value" },
|
|
{ PKT_CCCV6_IETF_SEC_TKT, "PacketCable Security Ticket Control" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
#if 0
|
|
static const value_string sec_tcm_vals[] = {
|
|
{ 1 << 0, "PacketCable Provisioning Server" },
|
|
{ 1 << 1, "PacketCable Call Manager Servers" },
|
|
{ 0, NULL },
|
|
};
|
|
#endif
|
|
|
|
static const value_string modem_capabilities_encoding [] = {
|
|
{ 1, "Concatenation Support" },
|
|
{ 2, "DOCSIS Version" },
|
|
{ 3, "Fragmentation Support" },
|
|
{ 4, "Payload Header Suppression Support" },
|
|
{ 5, "IGMP Support" },
|
|
{ 6, "Privacy Support" },
|
|
{ 7, "Downstream SAID Support" },
|
|
{ 8, "Upstream Service Flow Support" },
|
|
{ 9, "Optional Filtering Support" },
|
|
{ 10, "Transmit Pre-Equalizer Taps per Modulation Interval" },
|
|
{ 11, "Number of Transmit Equalizer Taps" },
|
|
{ 12, "DCC Support" },
|
|
{ 13, "IP Filters Support" },
|
|
{ 14, "LLC Filters Support" },
|
|
{ 15, "Expanded Unicast SID Space" },
|
|
{ 16, "Ranging Hold-Off Support" },
|
|
{ 17, "L2VPN Capability" },
|
|
{ 18, "L2VPN eSAFE Host Capability" },
|
|
{ 19, "Downstream Unencrypted Traffic (DUT) Filtering" },
|
|
{ 20, "Upstream Frequency Range Support" },
|
|
{ 21, "Upstream Symbol Rate Support" },
|
|
{ 22, "Selectable Active Code Mode 2 Support" },
|
|
{ 23, "Code Hopping Mode 2 Support" },
|
|
{ 24, "Multiple Transmit Channel Support" },
|
|
{ 25, "5.12 Msps UpstreamTransmit Channel Support" },
|
|
{ 26, "2.56 Msps Upstream Transmit Channel Support" },
|
|
{ 27, "Total SID Cluster Support" },
|
|
{ 28, "SID Clusters per Service Flow Support" },
|
|
{ 29, "Multiple Receive Channel Support" },
|
|
{ 30, "Total Downstream Service ID (DSID) Support" },
|
|
{ 31, "Resequencing Downstream Service ID (DSID) Support" },
|
|
{ 32, "Multicast Downstream Service ID (DSID) Support" },
|
|
{ 33, "Multicast DSID Forwarding" },
|
|
{ 34, "Frame Control Type Forwarding Capability" },
|
|
{ 35, "DPV Capability" },
|
|
{ 36, "Unsolicited Grant Service/Upstream Service Flow Support" },
|
|
{ 37, "MAP and UCD Receipt Support" },
|
|
{ 38, "Upstream Drop Classifier Support" },
|
|
{ 39, "IPv6 Support" },
|
|
{ 40, "Extended Upstream Transmit Power Capability" },
|
|
{ 41, "Optional 802.1ad, 802.1ah, MPLS Classification Support" },
|
|
{ 42, "D-ONU Capabilities Encoding" },
|
|
{ 43, "TBD" },
|
|
{ 44, "Energy Management Capabilities" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
static const value_string eue_capabilities_encoding [] = {
|
|
{ 1, "PacketCable Version" },
|
|
{ 2, "Number Of Telephony Endpoints" },
|
|
{ 3, "TGT Support" },
|
|
{ 4, "HTTP Download File Access Method Support" },
|
|
{ 5, "MTA-24 Event SYSLOG Notification Support" },
|
|
{ 6, "NCS Service Flow Support" },
|
|
{ 7, "Primary Line Support" },
|
|
{ 8, "Vendor Specific TLV Type(s)" },
|
|
{ 9, "NVRAM Ticket/Ticket Information Storage Support" },
|
|
{ 10, "Provisioning Event Reporting Support" },
|
|
{ 11, "Supported CODEC(s)" },
|
|
{ 12, "Silence Suppression Support" },
|
|
{ 13, "Echo Cancellation Support" },
|
|
{ 14, "RSVP Support" },
|
|
{ 15, "UGS-AD Support" },
|
|
{ 16, "MTA's \"ifIndex\" starting number in \"ifTable\"" },
|
|
{ 17, "Provisioning Flow Logging Support" },
|
|
{ 18, "Supported Provisioning Flows" },
|
|
{ 19, "T38 Version Support" },
|
|
{ 20, "T38 Error Correction Support" },
|
|
{ 21, "RFC2833 DTMF Support" },
|
|
{ 22, "Voice Metrics Support" },
|
|
{ 23, "Device MIB Support" },
|
|
{ 24, "Multiple Grants Per Interval Support" },
|
|
{ 25, "V.152 Support" },
|
|
{ 26, "Certificate Bootstrapping Support" },
|
|
{ 38, "IP Address Provisioning Capability" },
|
|
{ 0, NULL },
|
|
};
|
|
|
|
/* May be called recursively */
|
|
static void
|
|
dissect_dhcpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|
gboolean downstream, int off, int eoff);
|
|
|
|
static gint
|
|
swap_field_length_with_char(tvbuff_t* tvb, wmem_strbuf_t* strbuf, gint offset, gint subopt_len, gchar replacement)
|
|
{
|
|
gint len_cnt = 0;
|
|
gint next_length = 0;
|
|
|
|
while (len_cnt < subopt_len) {
|
|
next_length = tvb_get_guint8(tvb, offset);
|
|
offset++;
|
|
len_cnt++;
|
|
|
|
wmem_strbuf_append(strbuf, tvb_get_string(wmem_packet_scope(), tvb, offset, next_length));
|
|
len_cnt += next_length;
|
|
|
|
/* Do not append replacement character to end of string. */
|
|
if (len_cnt+2 < subopt_len) {
|
|
wmem_strbuf_append_c(strbuf, replacement);
|
|
}
|
|
offset += next_length;
|
|
}
|
|
return len_cnt;
|
|
}
|
|
|
|
static int
|
|
dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_info *pinfo, tvbuff_t *tvb, int optoff,
|
|
int optend)
|
|
{
|
|
/** THE ENCODING OF THIS SUBOPTION HAS CHANGED FROM DHCPv4
|
|
the code and length fields have grown from a single octet to
|
|
two octets each. **/
|
|
int suboptoff = optoff;
|
|
guint16 subopt, subopt_len;
|
|
guint8 type;
|
|
proto_item *vti, *ti;
|
|
proto_tree *pkt_s_tree;
|
|
guchar kr_name; /** A character in the kerberos realm name option */
|
|
guint8 kr_value; /* The integer value of the character currently being tested */
|
|
int kr_fail_flag = 0; /* Flag indicating an invalid character was found */
|
|
int kr_pos = 0; /* The position of the first invalid character */
|
|
gint i = 0;
|
|
|
|
subopt = tvb_get_ntohs(tvb, optoff);
|
|
suboptoff += 2;
|
|
|
|
subopt_len = tvb_get_ntohs(tvb, suboptoff);
|
|
suboptoff += 2;
|
|
|
|
/* There must be at least five octets left to be a valid sub element */
|
|
if (optend <= 0) {
|
|
expert_add_info_format(pinfo, v_item, &ei_dhcpv6_no_suboption_len, "Sub element %d: no room left in option for suboption length", subopt);
|
|
return (optend);
|
|
}
|
|
/* g_print("dissect packetcable ccc option subopt_len=%d optend=%d\n\n", subopt_len, optend); */
|
|
|
|
vti = proto_tree_add_item(v_tree, hf_packetcable_ccc_suboption, tvb, optoff, 2, ENC_BIG_ENDIAN);
|
|
pkt_s_tree = proto_item_add_subtree(vti, ett_dhcpv6_pkt_option);
|
|
|
|
switch (subopt) {
|
|
case PKT_CCC_PRI_DHCP: /* IPv4 address values */
|
|
if (subopt_len == 4) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_pri_dhcp, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCC_SEC_DHCP:
|
|
if (subopt_len == 4) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_sec_dhcp, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCC_IETF_PROV_SRV :
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_prov_srv_type, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
|
|
type = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
/** Type 0 is FQDN **/
|
|
if (type == 0) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_prov_srv_fqdn, tvb, suboptoff+1, subopt_len-1, ENC_ASCII|ENC_NA);
|
|
}
|
|
/** Type 1 is IPv4 **/
|
|
else if (type == 1) {
|
|
if (subopt_len == 5) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_prov_srv_ipv4, tvb, suboptoff+1, 4, ENC_BIG_ENDIAN);
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_invalid_type, "Invalid type: %u (%u byte%s)",
|
|
type, subopt_len, plurality(subopt_len, "", "s"));
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCC_IETF_AS_KRB :
|
|
if (subopt_len == 12) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_as_krb_nominal_timeout, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_as_krb_max_timeout, tvb, suboptoff+4, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_as_krb_max_retry_count, tvb, suboptoff+8, 4, ENC_BIG_ENDIAN);
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCC_IETF_AP_KRB :
|
|
if (subopt_len == 12) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_ap_krb_nominal_timeout, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_ap_krb_max_timeout, tvb, suboptoff+4, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_ap_krb_max_retry_count, tvb, suboptoff+8, 4, ENC_BIG_ENDIAN);
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCC_KRB_REALM:
|
|
if (subopt_len > 0) {
|
|
/** The only allowable characters are
|
|
A-Z (upper case only) 65-90
|
|
'.', 46
|
|
'/', 47
|
|
'\', 92
|
|
'=', 61
|
|
'"', 34
|
|
',', 44
|
|
and
|
|
':' 58
|
|
so loop through and
|
|
make sure it conforms to the expected syntax.
|
|
**/
|
|
for (i=0; i < subopt_len; i++) {
|
|
kr_name = tvb_get_guint8(tvb, suboptoff + i);
|
|
kr_value = (int)kr_name;
|
|
if ((kr_value >= 65 && kr_value <= 90) ||
|
|
kr_value == 34 ||
|
|
kr_value == 44 ||
|
|
kr_value == 46 ||
|
|
kr_value == 47 ||
|
|
kr_value == 58 ||
|
|
kr_value == 61 ||
|
|
kr_value == 92) {
|
|
}
|
|
else if (!kr_fail_flag) {
|
|
kr_pos = i;
|
|
kr_fail_flag = 1;
|
|
}
|
|
}
|
|
|
|
ti = proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_krb_realm, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
|
|
if (kr_fail_flag)
|
|
expert_add_info_format(pinfo, ti, &ei_dhcpv6_invalid_byte, "Invalid at byte=%d", kr_pos);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCC_TGT_FLAG:
|
|
if (subopt_len == 1) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_tgt_flag, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_tgt_flag_fetch, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCC_PROV_TIMER:
|
|
if (subopt_len == 1) {
|
|
ti = proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_prov_timer, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
|
|
if (tvb_get_guint8(tvb, suboptoff ) > 30)
|
|
expert_add_info(pinfo, ti, &ei_dhcpv6_invalid_time_value);
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCC_IETF_SEC_TKT :
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_sec_tcm, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
|
|
if (subopt_len == 2) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_sec_tcm_provisioning_server, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_sec_tcm_call_manager_server, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
|
|
} else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
default:
|
|
suboptoff += subopt_len;
|
|
break;
|
|
|
|
}
|
|
|
|
/** Return the number of bytes processed **/
|
|
return (suboptoff - optoff);
|
|
}
|
|
|
|
static int
|
|
dissect_packetcable_cccV6_option(proto_tree *v_tree, proto_item *v_item, packet_info *pinfo, tvbuff_t *tvb, int optoff,
|
|
int optend)
|
|
{
|
|
int suboptoff = optoff;
|
|
guint16 subopt, subopt_len;
|
|
guint8 type;
|
|
proto_item *vti, *ti;
|
|
proto_tree *pkt_s_tree;
|
|
/* guchar kr_name; */ /* A character in the kerberos realm name option */
|
|
guint8 kr_value; /* The integer value of the character currently being tested */
|
|
int kr_fail_flag = 0; /* Flag indicating an invalid character was found */
|
|
int kr_pos = 0; /* The position of the first invalid character */
|
|
int i = 0;
|
|
|
|
subopt = tvb_get_ntohs(tvb, optoff);
|
|
suboptoff += 2;
|
|
|
|
subopt_len = tvb_get_ntohs(tvb, suboptoff);
|
|
suboptoff += 2;
|
|
|
|
/* There must be at least five octets left to be a valid sub element */
|
|
if (optend <= 0) {
|
|
expert_add_info_format(pinfo, v_item, &ei_dhcpv6_no_suboption_len, "Sub element %d: no room left in option for suboption length", subopt);
|
|
return (optend);
|
|
}
|
|
|
|
vti = proto_tree_add_item(v_tree, hf_packetcable_cccV6_suboption, tvb, optoff, 2, ENC_BIG_ENDIAN);
|
|
pkt_s_tree = proto_item_add_subtree(vti, ett_dhcpv6_pkt_option);
|
|
|
|
switch (subopt) {
|
|
case PKT_CCCV6_PRI_DSS:
|
|
if (subopt_len < 35) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_pri_dss, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
|
|
} else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCCV6_SEC_DSS:
|
|
if (subopt_len < 35) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_dss, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
|
|
} else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCCV6_IETF_PROV_SRV:
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_prov_srv_type, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
|
|
type = tvb_get_guint8(tvb, suboptoff);
|
|
|
|
/** Type 0 is FQDN **/
|
|
if (type == 0) {
|
|
|
|
gint len_cnt;
|
|
wmem_strbuf_t* strbuf = NULL;
|
|
strbuf = wmem_strbuf_new(wmem_packet_scope(), "");
|
|
|
|
len_cnt = swap_field_length_with_char(tvb, strbuf, suboptoff+1, subopt_len, '.');
|
|
|
|
if (len_cnt < 1) {
|
|
proto_tree_add_string(pkt_s_tree, hf_packetcable_cccV6_prov_srv_fqdn, tvb, suboptoff+2, 28,
|
|
"Packet does not contain FQDN");
|
|
} else {
|
|
proto_tree_add_string(pkt_s_tree, hf_packetcable_cccV6_prov_srv_fqdn, tvb,
|
|
suboptoff+2, subopt_len-3, wmem_strbuf_get_str(strbuf));
|
|
}
|
|
|
|
/** Type 1 is IPv6 **/
|
|
} else if (type == 1) {
|
|
if ((subopt_len % 16) == 0) {
|
|
for (i = 0; i < subopt_len/16; i++) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_prov_srv_ipv6, tvb, suboptoff+1, 4, ENC_NA);
|
|
suboptoff += 16;
|
|
}
|
|
}
|
|
} else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_invalid_type, "Invalid type: %u (%u byte%s)",
|
|
type, subopt_len, plurality(subopt_len, "", "s"));
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCCV6_IETF_AS_KRB:
|
|
if (subopt_len == 12) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_as_krb_nominal_timeout, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_as_krb_max_timeout, tvb, suboptoff+4, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_as_krb_max_retry_count, tvb, suboptoff+8, 4, ENC_BIG_ENDIAN);
|
|
} else {
|
|
proto_item_append_text(vti, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCCV6_IETF_AP_KRB:
|
|
if (subopt_len == 12) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_ap_krb_nominal_timeout, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_ap_krb_max_timeout, tvb, suboptoff+4, 4, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_ap_krb_max_retry_count, tvb, suboptoff+8, 4, ENC_BIG_ENDIAN);
|
|
} else {
|
|
proto_item_append_text(vti, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCCV6_KRB_REALM:
|
|
if (subopt_len > 0) {
|
|
gint cnt;
|
|
gint len_cnt;
|
|
proto_item* pi_tmp = NULL;
|
|
wmem_strbuf_t* strbuf = NULL;
|
|
strbuf = wmem_strbuf_new(wmem_packet_scope(), "");
|
|
|
|
len_cnt = swap_field_length_with_char(tvb, strbuf, suboptoff, subopt_len, '.');
|
|
|
|
if (len_cnt < 1) {
|
|
proto_tree_add_string(pkt_s_tree, hf_packetcable_cccV6_prov_srv_fqdn, tvb, suboptoff+2, 34,
|
|
"Packet does not contain KRB Realm");
|
|
} else {
|
|
pi_tmp = proto_tree_add_string(pkt_s_tree, hf_packetcable_cccV6_krb_realm, tvb,
|
|
suboptoff+1, subopt_len-2, wmem_strbuf_get_str(strbuf));
|
|
}
|
|
|
|
/* Validate KRB Realm name encoding (sort of) and syntax per RFCs 3495, 1510, and 1035 */
|
|
for (cnt=0; cnt < len_cnt-2; cnt++) {
|
|
kr_value = (int) wmem_strbuf_get_str(strbuf)[cnt];
|
|
if ((kr_value >= 65 && kr_value <= 90)
|
|
|| kr_value == 34
|
|
|| kr_value == 44
|
|
|| kr_value == 46
|
|
|| kr_value == 47
|
|
|| kr_value == 58
|
|
|| kr_value == 61
|
|
|| kr_value == 92) {
|
|
} else if (!kr_fail_flag) {
|
|
kr_pos = cnt;
|
|
kr_fail_flag = 1;
|
|
}
|
|
}
|
|
if (kr_fail_flag)
|
|
expert_add_info_format(pinfo, pi_tmp, &ei_dhcpv6_invalid_byte, "Invalid at byte=%d", kr_pos);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCCV6_TGT_FLAG:
|
|
if (subopt_len == 1) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_tgt_flag, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_tgt_flag_fetch, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCCV6_PROV_TIMER:
|
|
if (subopt_len == 1) {
|
|
ti = proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_prov_timer, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
|
|
if (tvb_get_guint8(tvb, suboptoff ) > 30)
|
|
expert_add_info(pinfo, ti, &ei_dhcpv6_invalid_time_value);
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
case PKT_CCCV6_IETF_SEC_TKT:
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_tcm, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
|
|
if (subopt_len == 2) {
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_tcm_provisioning_server, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_tcm_call_manager_server, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
|
|
} else {
|
|
expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
|
|
}
|
|
suboptoff += subopt_len;
|
|
break;
|
|
default:
|
|
suboptoff += subopt_len;
|
|
break;
|
|
}
|
|
/** Return the number of bytes processed **/
|
|
return (suboptoff - optoff);
|
|
}
|
|
|
|
static void
|
|
dissect_cablelabs_specific_opts(proto_tree *v_tree, proto_item *v_item, packet_info *pinfo, tvbuff_t *tvb, int voff, int len)
|
|
{
|
|
guint16 type,
|
|
tlv_len, /* holds the number of elements in the tlv */
|
|
opt_len, /* holds the length of the suboption */
|
|
sub_value;
|
|
proto_item *ti;
|
|
proto_item *ti2;
|
|
proto_tree *subtree;
|
|
proto_tree *subtree2;
|
|
gint tlv5_cap_index,
|
|
tlv5_counter,
|
|
tlv5_cap_len;
|
|
int off = voff,
|
|
sub_off, /** The offset for the sub-option */
|
|
i,
|
|
field_len, /* holds the length of one occurrence of a field */
|
|
field_value;
|
|
gchar* device_type = NULL;
|
|
|
|
if (len > 4) {
|
|
while (off - voff < len) {
|
|
|
|
/* Type */
|
|
type = tvb_get_ntohs(tvb, off);
|
|
ti = proto_tree_add_item(v_tree, hf_cablelabs_opts, tvb, off, 2, ENC_BIG_ENDIAN);
|
|
/* Length */
|
|
tlv_len = tvb_get_ntohs(tvb, off+2);
|
|
|
|
/* Values */
|
|
sub_off = off + 4;
|
|
|
|
switch(type) {
|
|
/* String types */
|
|
case CL_OPTION_DEVICE_TYPE :
|
|
opt_len = tlv_len;
|
|
field_len = tlv_len;
|
|
|
|
device_type = tvb_get_string(wmem_packet_scope(), tvb, sub_off, field_len);
|
|
|
|
if (device_type == NULL || strlen(device_type) == 0) {
|
|
proto_item_append_text(ti, "Packet does not contain Device Type.");
|
|
} else {
|
|
proto_item_append_text(ti, "\"%s\"", device_type);
|
|
}
|
|
break;
|
|
case CL_OPTION_DEVICE_SERIAL_NUMBER :
|
|
case CL_OPTION_HARDWARE_VERSION_NUMBER :
|
|
case CL_OPTION_SOFTWARE_VERSION_NUMBER :
|
|
case CL_OPTION_BOOT_ROM_VERSION :
|
|
case CL_OPTION_MODEL_NUMBER :
|
|
case CL_OPTION_VENDOR_NAME :
|
|
case CL_OPTION_CONFIG_FILE_NAME :
|
|
case CL_OPTION_EMBEDDED_COMPONENT_LIST :
|
|
opt_len = tlv_len;
|
|
field_len = tlv_len;
|
|
proto_item_append_text(ti, "\"%s\"",
|
|
tvb_format_stringzpad(tvb, sub_off, field_len));
|
|
break;
|
|
case CL_OPTION_VENDOR_OUI :
|
|
/* CableLabs specs treat 17.8 inconsistently
|
|
* as either binary (3b) or string (6b) */
|
|
opt_len = tlv_len;
|
|
if (tlv_len == 3) {
|
|
proto_item_append_text(ti, "%s",
|
|
tvb_bytes_to_str_punct(tvb, sub_off, 3, ':'));
|
|
} else if (tlv_len == 6) {
|
|
proto_item_append_text(ti, "\"%s\"", tvb_format_stringzpad(tvb, sub_off, tlv_len));
|
|
} else {
|
|
expert_add_info_format(pinfo, ti, &ei_dhcpv6_bogus_length, "Suboption %d: suboption length isn't 3 or 6", type);
|
|
}
|
|
break;
|
|
case CL_OPTION_ORO :
|
|
field_len = 2;
|
|
opt_len = tlv_len;
|
|
if (opt_len > 0) {
|
|
for (i = 0; i < tlv_len; i += field_len) {
|
|
sub_value = tvb_get_ntohs(tvb, sub_off);
|
|
proto_item_append_text(ti, " %d", sub_value);
|
|
sub_off += field_len;
|
|
}
|
|
}
|
|
break;
|
|
/* List of IPv6 Address */
|
|
case CL_OPTION_TFTP_SERVERS :
|
|
case CL_OPTION_SYSLOG_SERVERS :
|
|
case CL_OPTION_RFC868_SERVERS :
|
|
field_len = 16;
|
|
opt_len = tlv_len;
|
|
subtree = proto_item_add_subtree(ti, ett_dhcpv6_vendor_option);
|
|
|
|
if ((tlv_len % field_len) == 0) {
|
|
for (i = 0; i < tlv_len/field_len; i++) {
|
|
ti = proto_tree_add_item(subtree, hf_cablelabs_ipv6_server, tvb, sub_off, 16, ENC_NA);
|
|
proto_item_prepend_text(ti, " %d ", i + 1);
|
|
sub_off += field_len;
|
|
}
|
|
}
|
|
break;
|
|
case CL_OPTION_DEVICE_ID :
|
|
opt_len = tlv_len;
|
|
field_len = tlv_len;
|
|
if (tlv_len != 6) {
|
|
expert_add_info_format(pinfo, ti, &ei_dhcpv6_bogus_length, "Bogus length: %d", tlv_len);
|
|
}
|
|
else {
|
|
proto_item_append_text(ti, "%s",
|
|
tvb_bytes_to_str(tvb, sub_off, field_len));
|
|
}
|
|
break;
|
|
case CL_OPTION_TLV5 :
|
|
opt_len = tlv_len;
|
|
|
|
if (device_type == NULL)
|
|
break;
|
|
|
|
tlv5_counter = 0;
|
|
tlv5_cap_index = sub_off;
|
|
|
|
subtree = proto_item_add_subtree(ti, ett_dhcpv6_tlv5_type);
|
|
|
|
while (tlv5_counter < tlv_len) {
|
|
|
|
if (!g_ascii_strncasecmp(device_type, "ecm", 3)) {
|
|
ti2 = proto_tree_add_item(subtree, hf_modem_capabilities_encoding_type, tvb, tlv5_cap_index, 1, ENC_BIG_ENDIAN);
|
|
} else if (!g_ascii_strncasecmp(device_type, "edva", 3)) {
|
|
ti2 = proto_tree_add_item(subtree, hf_eue_capabilities_encoding_type, tvb, tlv5_cap_index, 1, ENC_BIG_ENDIAN);
|
|
} else {
|
|
break;
|
|
}
|
|
|
|
tlv5_cap_index++;
|
|
tlv5_counter++;
|
|
|
|
/* Why make another subtree (subtree2) below?
|
|
The addition of a subtree is not needed for the display.
|
|
However, when parsing the PDML, each Type 'contains' it's Length and Value.
|
|
*/
|
|
subtree2 = proto_item_add_subtree(ti2, ett_dhcpv6_tlv5_type);
|
|
|
|
proto_tree_add_item(subtree2, hf_capabilities_encoding_length, tvb, tlv5_cap_index, 1, ENC_BIG_ENDIAN);
|
|
tlv5_cap_len = (guint8) tvb_get_guint8(tvb, tlv5_cap_index);
|
|
|
|
tlv5_cap_index++;
|
|
tlv5_counter += tlv5_cap_len;
|
|
|
|
/* In cases where the TLV length is greater than 2, the value fields should be displayed
|
|
according to the encoding of the values as described in the CL-SP-CANN-DHCP-Reg specification.
|
|
Below, these values are simply displayed as hex.
|
|
*/
|
|
if (tlv5_cap_len > 2) {
|
|
proto_tree_add_item(subtree2, hf_capabilities_encoding_bytes, tvb, tlv5_cap_index, tlv5_cap_len, ENC_NA);
|
|
} else {
|
|
proto_tree_add_item(subtree2, hf_capabilities_encoding_number, tvb, tlv5_cap_index, tlv5_cap_len, ENC_BIG_ENDIAN);
|
|
}
|
|
|
|
tlv5_cap_index += tlv5_cap_len;
|
|
tlv5_counter++;
|
|
}
|
|
break;
|
|
case CL_OPTION_TIME_OFFSET :
|
|
opt_len = tlv_len;
|
|
proto_item_append_text(ti, "%d", tvb_get_ntohl(tvb, sub_off));
|
|
break;
|
|
case CL_OPTION_IP_PREF :
|
|
opt_len = tlv_len;
|
|
field_value = tvb_get_guint8(tvb, sub_off);
|
|
if (field_value == 1) {
|
|
proto_item_append_text(ti, "%s", "IPv4");
|
|
} else if (field_value == 2) {
|
|
proto_item_append_text(ti, "%s", "IPv6");
|
|
} else if (field_value == 6) {
|
|
proto_item_append_text(ti, "%s", "Dual Stack");
|
|
} else {
|
|
proto_item_append_text(ti, "%s%d", "Invalid IP Preference value ", field_value);
|
|
}
|
|
break;
|
|
case CL_OPTION_DOCS_CMTS_CAP :
|
|
opt_len = tlv_len;
|
|
field_len = 0;
|
|
subtree = proto_item_add_subtree(ti, ett_dhcpv6_vendor_option);
|
|
|
|
/* tlv_len contains the total length of all the TLVs for this
|
|
option */
|
|
if (tlv_len > 0) {
|
|
for (i = 0; field_len < opt_len; i++) {
|
|
int tagLen = 0;
|
|
int tag = 0;
|
|
tag = tvb_get_guint8(tvb, sub_off);
|
|
sub_off++;
|
|
tagLen = tvb_get_guint8(tvb, sub_off);
|
|
sub_off++;
|
|
if (tag == CL_OPTION_DOCS_CMTS_TLV_VERS_NUM &&
|
|
tagLen == 2) {
|
|
int major = 0;
|
|
int minor = 0;
|
|
major = tvb_get_guint8(tvb, sub_off);
|
|
sub_off++;
|
|
minor = tvb_get_guint8(tvb, sub_off);
|
|
sub_off++;
|
|
proto_tree_add_text(subtree, tvb, sub_off-2,
|
|
2, "DOCSIS Version Number %d.%d",
|
|
major, minor);
|
|
}
|
|
else
|
|
sub_off += tagLen;
|
|
|
|
field_len += tagLen + 2;
|
|
}
|
|
}
|
|
else
|
|
proto_tree_add_text(subtree, tvb, sub_off, 0, "empty");
|
|
break;
|
|
case CL_CM_MAC_ADDR :
|
|
opt_len = tlv_len;
|
|
if (tlv_len != 6) {
|
|
expert_add_info_format(pinfo, ti, &ei_dhcpv6_bogus_length, "Bogus length: %d", tlv_len);
|
|
}
|
|
else {
|
|
/*proto_item_append_text(ti, "CM MAC Address Option = %s", */
|
|
proto_item_append_text(ti, "%s", tvb_bytes_to_str_punct(tvb, sub_off, opt_len, ':'));
|
|
/* tvb_bytes_to_str(tvb, sub_off, opt_len)); */
|
|
}
|
|
break;
|
|
case CL_EROUTER_CONTAINER_OPTION :
|
|
opt_len = tlv_len;
|
|
proto_item_append_text(ti, " %s (len=%d)",
|
|
tvb_bytes_to_str(tvb, sub_off, opt_len), tlv_len);
|
|
break;
|
|
case CL_OPTION_CCC :
|
|
opt_len = tlv_len;
|
|
field_len = 0;
|
|
subtree = proto_item_add_subtree(ti, ett_dhcpv6_vendor_option);
|
|
proto_item_append_text(ti, " (%d bytes)", opt_len);
|
|
while (field_len < opt_len) {
|
|
sub_value = dissect_packetcable_ccc_option(subtree, ti, pinfo, tvb,
|
|
sub_off, (opt_len - field_len));
|
|
sub_off += sub_value;
|
|
field_len += sub_value;
|
|
}
|
|
break;
|
|
case CL_OPTION_CCCV6 :
|
|
opt_len = tlv_len;
|
|
field_len = 0;
|
|
subtree = proto_item_add_subtree(ti, ett_dhcpv6_vendor_option);
|
|
proto_item_append_text(ti, " (%d bytes)", opt_len);
|
|
while (field_len < opt_len) {
|
|
sub_value = dissect_packetcable_cccV6_option(subtree, ti, pinfo, tvb,
|
|
sub_off, (opt_len - field_len));
|
|
sub_off += sub_value;
|
|
field_len += sub_value;
|
|
}
|
|
break;
|
|
case CL_OPTION_CORRELATION_ID :
|
|
opt_len = tlv_len;
|
|
if (tlv_len != 4) {
|
|
proto_item_append_text(ti, "Bogus value length=%d",
|
|
tlv_len);
|
|
}
|
|
else {
|
|
proto_item_append_text(ti, "%u", tvb_get_ntohl(tvb, sub_off));
|
|
}
|
|
break;
|
|
default:
|
|
opt_len = tlv_len;
|
|
break;
|
|
}
|
|
off += (opt_len + 4);
|
|
|
|
}
|
|
}
|
|
else {
|
|
expert_add_info_format(pinfo, v_item, &ei_dhcpv6_bogus_length, "Bogus length: %d", len);
|
|
}
|
|
}
|
|
|
|
/* Adds domain */
|
|
static void
|
|
dhcpv6_domain(proto_tree * subtree, proto_item *v_item, packet_info *pinfo, tvbuff_t *tvb, int offset, guint16 optlen)
|
|
{
|
|
int start_offset=offset;
|
|
char domain[256];
|
|
int pos;
|
|
guint8 len;
|
|
|
|
pos=0;
|
|
while(optlen){
|
|
/* this is the start of the domain name */
|
|
if(!pos){
|
|
start_offset=offset;
|
|
}
|
|
domain[pos]=0;
|
|
|
|
/* read length of the next substring */
|
|
len = tvb_get_guint8(tvb, offset);
|
|
/* Microsoft dhcpv6 clients aren't currently RFC 4704 conformant: They send an
|
|
* ASCII string instead of a DNS record encoded domain name. Catch that case
|
|
* to allow us to continue after such a malformed record.
|
|
*/
|
|
if ( optlen < len ) {
|
|
expert_add_info(pinfo, v_item, &ei_dhcpv6_malformed_dns);
|
|
return;
|
|
}
|
|
offset++;
|
|
optlen--;
|
|
/* if len==0 and pos>0 we have read an entire domain string */
|
|
if(!len){
|
|
if(!pos){
|
|
/* empty string, this must be an error? */
|
|
expert_add_info(pinfo, v_item, &ei_dhcpv6_malformed_option);
|
|
return;
|
|
} else {
|
|
proto_tree_add_string(subtree, hf_dhcpv6_domain, tvb, start_offset, offset-start_offset, domain);
|
|
pos=0;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
/* add the substring to domain */
|
|
if(pos){
|
|
domain[pos]='.';
|
|
pos++;
|
|
}
|
|
if(pos+len>254){
|
|
/* too long string, this must be an error? */
|
|
expert_add_info(pinfo, v_item, &ei_dhcpv6_malformed_option);
|
|
return;
|
|
}
|
|
tvb_memcpy(tvb, domain+pos, offset, len);
|
|
pos+=len;
|
|
offset+=len;
|
|
optlen-=len;
|
|
}
|
|
|
|
if(pos){
|
|
domain[pos]=0;
|
|
proto_tree_add_string(subtree, hf_dhcpv6_domain, tvb, start_offset, offset-start_offset, domain);
|
|
}
|
|
}
|
|
|
|
/* Returns the number of bytes consumed by this option. */
|
|
static int
|
|
dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
|
|
gboolean downstream, int off, int eoff, gboolean *at_end, int protocol)
|
|
{
|
|
guint16 opttype, hwtype, subopt_type;
|
|
int temp_optlen = 0, optlen, subopt_len; /* 16-bit values that need 16-bit rollover protection */
|
|
proto_item *ti = NULL, *option_item;
|
|
proto_tree *subtree;
|
|
proto_tree *subtree_2;
|
|
int i;
|
|
guint16 duidtype;
|
|
guint32 enterprise_no;
|
|
|
|
/* option type and length must be present */
|
|
if (eoff - off < 4) {
|
|
*at_end = TRUE;
|
|
return 0;
|
|
}
|
|
|
|
opttype = tvb_get_ntohs(tvb, off);
|
|
optlen = tvb_get_ntohs(tvb, off + 2);
|
|
|
|
/* all option data must be present */
|
|
if (eoff - off < 4 + optlen) {
|
|
*at_end = TRUE;
|
|
return 0;
|
|
}
|
|
|
|
option_item = proto_tree_add_text(bp_tree, tvb, off, 4 + optlen,
|
|
"%s", val_to_str(opttype, opttype_vals, "DHCP option %u"));
|
|
|
|
subtree = proto_item_add_subtree(option_item, ett_dhcpv6_option);
|
|
proto_tree_add_item(subtree, hf_option_type, tvb, off, 2, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree, hf_option_length, tvb, off + 2, 2, ENC_BIG_ENDIAN);
|
|
off += 4;
|
|
/* Right now, none of the options can be filtered at, so provide a hex
|
|
array for minimalistic filtering */
|
|
if (optlen)
|
|
proto_tree_add_item(subtree, hf_option_value, tvb, off, optlen, ENC_NA);
|
|
|
|
switch (opttype) {
|
|
case OPTION_CLIENTID:
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "CID: %s ", tvb_bytes_to_str(tvb, off, optlen));
|
|
/* Fall through */
|
|
case OPTION_SERVERID:
|
|
case OPTION_RELAYID:
|
|
if (optlen < 2) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_duid_bytes, tvb, off, optlen, ENC_NA);
|
|
duidtype = tvb_get_ntohs(tvb, off);
|
|
proto_tree_add_item(subtree, hf_duid_type, tvb, off, 2, ENC_BIG_ENDIAN);
|
|
switch (duidtype) {
|
|
case DUID_LLT:
|
|
{
|
|
nstime_t llt_time;
|
|
|
|
if (optlen < 8) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_duidllt_hwtype, tvb, off + 2, 2, ENC_BIG_ENDIAN);
|
|
|
|
/* Packet specifies seconds since Jan 1 2000, so add 946684800U (30 years) to get back to epoch */
|
|
llt_time.secs = tvb_get_ntohl(tvb, off + 4)+946684800U;
|
|
llt_time.nsecs = 0;
|
|
|
|
proto_tree_add_time(subtree, hf_duidllt_time, tvb, off + 4, 4, &llt_time);
|
|
if (optlen > 8) {
|
|
hwtype=tvb_get_ntohs(tvb, off + 2);
|
|
proto_tree_add_string(subtree, hf_duidllt_link_layer_addr, tvb, off + 8,
|
|
optlen - 8, tvb_arphrdaddr_to_str(tvb, off+8, optlen-8, hwtype));
|
|
}
|
|
}
|
|
break;
|
|
case DUID_EN:
|
|
if (optlen < 6) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_duiden_enterprise, tvb, off + 2, 4, ENC_BIG_ENDIAN);
|
|
if (optlen > 6) {
|
|
proto_tree_add_item(subtree, hf_duiden_identifier, tvb, off + 6, optlen - 6, ENC_NA);
|
|
}
|
|
break;
|
|
case DUID_LL:
|
|
case DUID_LL_OLD:
|
|
if (optlen < 4) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_duidll_hwtype, tvb, off + 2, 2, ENC_BIG_ENDIAN);
|
|
if (optlen > 4) {
|
|
hwtype=tvb_get_ntohs(tvb, off + 2);
|
|
proto_tree_add_string(subtree, hf_duidll_link_layer_addr, tvb, off + 4,
|
|
optlen - 4, tvb_arphrdaddr_to_str(tvb, off+4, optlen-4, hwtype));
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case OPTION_NTP_SERVER:
|
|
if (optlen < 4) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "NTP Server: malformed option");
|
|
break;
|
|
}
|
|
while (optlen > temp_optlen) {
|
|
subopt_type = tvb_get_ntohs(tvb, off+temp_optlen);
|
|
subopt_len = tvb_get_ntohs(tvb, off+2+temp_optlen);
|
|
ti = proto_tree_add_text(subtree, tvb, off+temp_optlen, 4 + subopt_len,
|
|
"%s", val_to_str(opttype, ntp_server_opttype_vals, "NTP Server suboption %u"));
|
|
subtree_2 = proto_item_add_subtree(option_item, ett_dhcpv6_netserver_option);
|
|
proto_tree_add_item(subtree_2, hf_option_ntpserver_type, tvb, off + temp_optlen, 2, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree_2, hf_option_ntpserver_length, tvb, off + 2 + temp_optlen, 2, ENC_BIG_ENDIAN);
|
|
temp_optlen += 4;
|
|
switch(subopt_type) {
|
|
case NTP_SUBOPTION_SRV_ADDR:
|
|
proto_tree_add_item(subtree_2, hf_option_ntpserver_addr, tvb, off + temp_optlen, 16, ENC_NA);
|
|
break;
|
|
case NTP_SUBOPTION_MC_ADDR:
|
|
proto_tree_add_item(subtree_2, hf_option_ntpserver_mc_addr, tvb, off + temp_optlen, 16, ENC_NA);
|
|
break;
|
|
case NTP_SUBOPTION_SRV_FQDN:
|
|
dhcpv6_domain(subtree_2, ti, pinfo, tvb, off + temp_optlen, subopt_len);
|
|
break;
|
|
}
|
|
|
|
temp_optlen += subopt_len;
|
|
}
|
|
break;
|
|
case OPTION_IA_NA:
|
|
case OPTION_IA_PD:
|
|
if (optlen < 12) {
|
|
if (opttype == OPTION_IA_NA)
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_NA: malformed option");
|
|
else
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_PD: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_string(subtree, hf_iaid, tvb, off,
|
|
4, tvb_arphrdaddr_to_str(tvb, off, 4, opttype));
|
|
if (tvb_get_ntohl(tvb, off+4) == DHCPV6_LEASEDURATION_INFINITY) {
|
|
proto_tree_add_uint_format_value(subtree, hf_iaid_t1, tvb, off+4,
|
|
4, DHCPV6_LEASEDURATION_INFINITY, "infinity");
|
|
} else {
|
|
proto_tree_add_item(subtree, hf_iaid_t1, tvb, off+4,
|
|
4, ENC_BIG_ENDIAN);
|
|
}
|
|
|
|
if (tvb_get_ntohl(tvb, off+8) == DHCPV6_LEASEDURATION_INFINITY) {
|
|
proto_tree_add_uint_format_value(subtree, hf_iaid_t2, tvb, off+8,
|
|
4, DHCPV6_LEASEDURATION_INFINITY, "infinity");
|
|
} else {
|
|
proto_tree_add_item(subtree, hf_iaid_t2, tvb, off+8,
|
|
4, ENC_BIG_ENDIAN);
|
|
}
|
|
|
|
temp_optlen = 12;
|
|
while ((optlen - temp_optlen) > 0) {
|
|
temp_optlen += dhcpv6_option(tvb, pinfo, subtree, downstream,
|
|
off+temp_optlen, off + optlen, at_end, protocol);
|
|
if (*at_end) {
|
|
/* Bad option - just skip to the end */
|
|
temp_optlen = optlen;
|
|
}
|
|
}
|
|
break;
|
|
case OPTION_IA_TA:
|
|
if (optlen < 4) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_TA: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_string(subtree, hf_iata, tvb, off,
|
|
4, tvb_arphrdaddr_to_str(tvb, off, 4, opttype));
|
|
temp_optlen = 4;
|
|
while ((optlen - temp_optlen) > 0) {
|
|
temp_optlen += dhcpv6_option(tvb, pinfo, subtree, downstream,
|
|
off+temp_optlen, off + optlen, at_end, protocol);
|
|
if (*at_end) {
|
|
/* Bad option - just skip to the end */
|
|
temp_optlen = optlen;
|
|
}
|
|
}
|
|
break;
|
|
case OPTION_IAADDR:
|
|
{
|
|
guint32 preferred_lifetime, valid_lifetime;
|
|
|
|
if (optlen < 24) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_TA: malformed option");
|
|
break;
|
|
}
|
|
|
|
proto_tree_add_item(subtree, hf_iaaddr_ip, tvb, off, 16, ENC_NA);
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "IAA: %s ", tvb_ip6_to_str(tvb, off));
|
|
|
|
preferred_lifetime = tvb_get_ntohl(tvb, off + 16);
|
|
valid_lifetime = tvb_get_ntohl(tvb, off + 20);
|
|
|
|
if (preferred_lifetime == DHCPV6_LEASEDURATION_INFINITY) {
|
|
proto_tree_add_uint_format_value(subtree, hf_iaaddr_pref_lifetime, tvb, off+16,
|
|
4, DHCPV6_LEASEDURATION_INFINITY, "infinity");
|
|
} else {
|
|
proto_tree_add_item(subtree, hf_iaaddr_pref_lifetime, tvb, off+16,
|
|
4, ENC_BIG_ENDIAN);
|
|
}
|
|
if (valid_lifetime == DHCPV6_LEASEDURATION_INFINITY) {
|
|
proto_tree_add_uint_format(subtree, hf_iaaddr_valid_lifetime, tvb, off+20,
|
|
4, DHCPV6_LEASEDURATION_INFINITY, "Preferred lifetime: infinity");
|
|
} else {
|
|
proto_tree_add_item(subtree, hf_iaaddr_valid_lifetime, tvb, off+20,
|
|
4, ENC_BIG_ENDIAN);
|
|
}
|
|
|
|
temp_optlen = 24;
|
|
while ((optlen - temp_optlen) > 0) {
|
|
temp_optlen += dhcpv6_option(tvb, pinfo, subtree, downstream,
|
|
off+temp_optlen, off + optlen, at_end, protocol);
|
|
if (*at_end) {
|
|
/* Bad option - just skip to the end */
|
|
temp_optlen = optlen;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case OPTION_ORO:
|
|
case OPTION_ERO:
|
|
for (i = 0; i < optlen; i += 2) {
|
|
proto_tree_add_item(subtree, hf_requested_option_code, tvb, off+i,
|
|
2, ENC_BIG_ENDIAN);
|
|
}
|
|
break;
|
|
case OPTION_PREFERENCE:
|
|
if (optlen != 1) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "PREFERENCE: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_option_preference, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
break;
|
|
case OPTION_ELAPSED_TIME:
|
|
if (optlen != 2) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "ELAPSED-TIME: malformed option");
|
|
break;
|
|
}
|
|
|
|
temp_optlen = tvb_get_ntohs(tvb, off);
|
|
proto_tree_add_uint_format_value(subtree, hf_elapsed_time, tvb, off,
|
|
2, temp_optlen*10, "%u ms", temp_optlen*10);
|
|
break;
|
|
case OPTION_RELAY_MSG:
|
|
if (optlen == 0) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "RELAY-MSG: malformed option");
|
|
} else {
|
|
/* here, we should dissect a full DHCP message */
|
|
dissect_dhcpv6(tvb, pinfo, subtree, downstream, off, off + optlen);
|
|
}
|
|
break;
|
|
case OPTION_AUTH:
|
|
if (optlen < 11) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "AUTH: malformed option");
|
|
break;
|
|
}
|
|
|
|
proto_tree_add_item(subtree, hf_auth_protocol, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree, hf_auth_algorithm, tvb, off+1, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree, hf_auth_rdm, tvb, off+2, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree, hf_auth_replay_detection, tvb, off+3, 8, ENC_NA);
|
|
if (optlen != 11)
|
|
proto_tree_add_item(subtree, hf_auth_info, tvb, off+11, optlen-11, ENC_NA);
|
|
break;
|
|
case OPTION_UNICAST:
|
|
if (optlen != 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "UNICAST: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_opt_unicast, tvb, off, 16, ENC_NA);
|
|
break;
|
|
case OPTION_STATUS_CODE:
|
|
proto_tree_add_item(subtree, hf_opt_status_code, tvb, off, 2, ENC_BIG_ENDIAN);
|
|
if (optlen > 2)
|
|
proto_tree_add_item(subtree, hf_opt_status_msg, tvb, off+2, optlen - 2, ENC_ASCII|ENC_NA);
|
|
break;
|
|
case OPTION_VENDOR_CLASS:
|
|
if (optlen < 4) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "VENDOR_CLASS: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_vendorclass_enterprise, tvb, off, 4, ENC_BIG_ENDIAN);
|
|
if (optlen > 4)
|
|
proto_tree_add_item(subtree, hf_vendorclass_data, tvb, off+6, optlen-6, ENC_ASCII|ENC_NA);
|
|
break;
|
|
case OPTION_VENDOR_OPTS:
|
|
if (optlen < 4) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "VENDOR_OPTS: malformed option");
|
|
break;
|
|
}
|
|
|
|
enterprise_no = tvb_get_ntohl(tvb, off);
|
|
ti = proto_tree_add_item(subtree, hf_vendoropts_enterprise, tvb, off, 4, ENC_BIG_ENDIAN);
|
|
|
|
if (optlen >= 4) {
|
|
if (enterprise_no == 4491) {
|
|
dissect_cablelabs_specific_opts(subtree, ti, pinfo, tvb, off+4, optlen-4);
|
|
} else {
|
|
int optoffset = 0;
|
|
|
|
while((optlen - 4 - optoffset) > 0) {
|
|
int olen = tvb_get_ntohs(tvb, off + optoffset + 6);
|
|
ti = proto_tree_add_text(subtree, tvb, off + optoffset + 4,
|
|
4 + olen, "option");
|
|
subtree_2 = proto_item_add_subtree(ti, ett_dhcpv6_option_vsoption);
|
|
proto_tree_add_item(subtree_2, hf_vendoropts_enterprise_option_code, tvb, off + optoffset + 4, 2, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree_2, hf_vendoropts_enterprise_option_length, tvb, off + optoffset + 6, 2, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree_2, hf_vendoropts_enterprise_option_data, tvb, off + optoffset + 8, olen, ENC_NA);
|
|
optoffset += (4 + olen);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case OPTION_INTERFACE_ID:
|
|
{
|
|
gint namelen;
|
|
|
|
if (optlen == 0) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "INTERFACE_ID: malformed option");
|
|
break;
|
|
}
|
|
|
|
namelen = tvb_strnlen(tvb, off, optlen)+1;
|
|
if (namelen == 0) {
|
|
proto_tree_add_item(subtree, hf_interface_id, tvb, off, optlen, ENC_ASCII|ENC_NA);
|
|
} else {
|
|
proto_tree_add_item(subtree, hf_interface_id, tvb, off, namelen-1, ENC_ASCII|ENC_NA);
|
|
|
|
temp_optlen = optlen - namelen;
|
|
off += namelen;
|
|
if (temp_optlen >= 6)
|
|
proto_tree_add_string(subtree, hf_interface_id_link_address, tvb, off, temp_optlen, tvb_arphrdaddr_to_str(tvb, off, 6, ARPHRD_ETHER));
|
|
}
|
|
}
|
|
break;
|
|
case OPTION_RECONF_MSG:
|
|
if (optlen != 1) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "RECONF_MSG: malformed option");
|
|
break;
|
|
}
|
|
|
|
proto_tree_add_item(subtree, hf_reconf_msg, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
break;
|
|
case OPTION_RECONF_ACCEPT:
|
|
if (optlen)
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "RECONF_ACCEPT: malformed option");
|
|
break;
|
|
case OPTION_SIP_SERVER_D:
|
|
if (optlen > 0) {
|
|
ti = proto_tree_add_text(subtree, tvb, off, optlen, "SIP Servers Domain Search List");
|
|
dhcpv6_domain(subtree, ti, pinfo, tvb, off, optlen);
|
|
}
|
|
break;
|
|
case OPTION_SIP_SERVER_A:
|
|
if (optlen % 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "SIP servers address: malformed option");
|
|
break;
|
|
}
|
|
|
|
for (i = 0; i < optlen; i += 16)
|
|
proto_tree_add_item(subtree, hf_sip_server_a, tvb, off + i, 16, ENC_NA);
|
|
break;
|
|
case OPTION_DNS_SERVERS:
|
|
if (optlen % 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DNS servers address: malformed option");
|
|
break;
|
|
}
|
|
|
|
for (i = 0; i < optlen; i += 16) {
|
|
ti = proto_tree_add_item(subtree, hf_dns_servers, tvb, off + i, 16, ENC_NA);
|
|
proto_item_prepend_text(ti, " %d ", i/16 + 1);
|
|
}
|
|
break;
|
|
case OPTION_DOMAIN_LIST:
|
|
if (optlen > 0) {
|
|
ti = proto_tree_add_text(subtree, tvb, off, optlen, "DNS Domain Search List");
|
|
dhcpv6_domain(subtree, ti, pinfo, tvb, off, optlen);
|
|
}
|
|
break;
|
|
case OPTION_NIS_SERVERS:
|
|
if (optlen % 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "NIS servers address: malformed option");
|
|
break;
|
|
}
|
|
for (i = 0; i < optlen; i += 16)
|
|
proto_tree_add_item(subtree, hf_nis_servers, tvb, off + i, 16, ENC_NA);
|
|
break;
|
|
case OPTION_NISP_SERVERS:
|
|
if (optlen % 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "NISP servers address: malformed option");
|
|
break;
|
|
}
|
|
for (i = 0; i < optlen; i += 16)
|
|
proto_tree_add_item(subtree, hf_nisp_servers, tvb, off + i, 16, ENC_NA);
|
|
break;
|
|
case OPTION_NIS_DOMAIN_NAME:
|
|
if (optlen > 0) {
|
|
ti = proto_tree_add_text(subtree, tvb, off, optlen, "nis-domain-name");
|
|
dhcpv6_domain(subtree, ti, pinfo, tvb, off, optlen);
|
|
}
|
|
break;
|
|
case OPTION_NISP_DOMAIN_NAME:
|
|
if (optlen > 0) {
|
|
ti = proto_tree_add_text(subtree, tvb, off, optlen, "nisp-domain-name");
|
|
dhcpv6_domain(subtree, ti, pinfo, tvb, off, optlen);
|
|
}
|
|
break;
|
|
case OPTION_SNTP_SERVERS:
|
|
if (optlen % 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "SNTP servers address: malformed option");
|
|
break;
|
|
}
|
|
for (i = 0; i < optlen; i += 16)
|
|
ti = proto_tree_add_item(subtree, hf_sntp_servers, tvb, off + i, 16, ENC_NA);
|
|
proto_item_prepend_text(ti, " %d ", i/16 + 1);
|
|
break;
|
|
case OPTION_LIFETIME:
|
|
if (optlen != 4) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "LIFETIME: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_opt_lifetime, tvb, off, 4, ENC_BIG_ENDIAN);
|
|
break;
|
|
case OPTION_BCMCS_SERVER_D:
|
|
if (optlen > 0) {
|
|
ti = proto_tree_add_text(subtree, tvb, off, optlen, "BCMCS Servers Domain Search List");
|
|
dhcpv6_domain(subtree, ti, pinfo, tvb, off, optlen);
|
|
}
|
|
break;
|
|
case OPTION_BCMCS_SERVER_A:
|
|
if (optlen % 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "BCMCS servers address: malformed option");
|
|
break;
|
|
}
|
|
for (i = 0; i < optlen; i += 16)
|
|
proto_tree_add_item(subtree, hf_bcmcs_servers_a, tvb, off + i, 16, ENC_NA);
|
|
break;
|
|
case OPTION_REMOTE_ID:
|
|
if (optlen < 4) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "REMOTE_ID: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_remoteid_enterprise, tvb, off, 4, ENC_BIG_ENDIAN);
|
|
off += 4;
|
|
proto_tree_add_item(subtree, hf_remoteid_enterprise_id, tvb, off, optlen - 4, ENC_ASCII|ENC_NA);
|
|
break;
|
|
case OPTION_SUBSCRIBER_ID:
|
|
if (optlen == 0) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "SUBSCRIBER_ID: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_subscriber_id, tvb, off, optlen, ENC_ASCII|ENC_NA);
|
|
break;
|
|
case OPTION_CLIENT_FQDN:
|
|
if (optlen < 1) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "FQDN: malformed option");
|
|
} else {
|
|
/*
|
|
* +-----+-+-+-+
|
|
* | MBZ |N|O|S|
|
|
* +-----+-+-+-+
|
|
*/
|
|
proto_tree_add_item(subtree, hf_clientfqdn_reserved, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree, hf_clientfqdn_n, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree, hf_clientfqdn_o, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree, hf_clientfqdn_s, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
|
|
dhcpv6_domain(subtree, option_item, pinfo, tvb, off+1, optlen-1);
|
|
}
|
|
break;
|
|
case OPTION_PANA_AGENT:
|
|
if (optlen % 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "PANA agent address: malformed option");
|
|
break;
|
|
}
|
|
for (i = 0; i < optlen; i += 16)
|
|
proto_tree_add_item(subtree, hf_pana_agent, tvb, off + i, 16, ENC_NA);
|
|
break;
|
|
case OPTION_TIME_ZONE:
|
|
if (optlen > 0)
|
|
proto_tree_add_item(subtree, hf_opt_timezone, tvb, off, optlen, ENC_ASCII|ENC_NA);
|
|
break;
|
|
case OPTION_TZDB:
|
|
if (optlen > 0)
|
|
proto_tree_add_item(subtree, hf_opt_tzdb, tvb, off, optlen, ENC_ASCII|ENC_NA);
|
|
break;
|
|
case OPTION_LQ_QUERY:
|
|
{
|
|
guint8 query_type;
|
|
if (optlen < 17) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "LQ-QUERY: malformed option");
|
|
break;
|
|
}
|
|
query_type = tvb_get_guint8(tvb, off);
|
|
ti = proto_tree_add_item(subtree, hf_lq_query, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
if ((protocol == proto_dhcpv6) &&
|
|
((query_type == LQ_QUERY_RELAYID) ||
|
|
(query_type == LQ_QUERY_LINK_ADDRESS) ||
|
|
(query_type == LQ_QUERY_REMOTEID))) {
|
|
expert_add_info(pinfo, ti, &ei_dhcpv6_bulk_leasequery_bad_query_type);
|
|
}
|
|
|
|
proto_tree_add_item(subtree, hf_lq_query_link_address, tvb, off+1, 16, ENC_NA);
|
|
temp_optlen = 17;
|
|
while ((optlen - temp_optlen) > 0) {
|
|
temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
|
|
downstream, off + temp_optlen,
|
|
off + optlen, at_end, protocol);
|
|
if (*at_end) {
|
|
/* Bad option - just skip to the end */
|
|
temp_optlen = optlen;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case OPTION_CLIENT_DATA:
|
|
temp_optlen = 0;
|
|
while ((optlen - temp_optlen) > 0) {
|
|
temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
|
|
downstream, off + temp_optlen,
|
|
off + optlen, at_end, protocol);
|
|
if (*at_end) {
|
|
/* Bad option - just skip to the end */
|
|
temp_optlen = optlen;
|
|
}
|
|
}
|
|
break;
|
|
case OPTION_CLT_TIME:
|
|
if (optlen != 4) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "CLT_TIME: malformed option");
|
|
break;
|
|
}
|
|
|
|
proto_tree_add_item(subtree, hf_clt_time, tvb, off, 4, ENC_BIG_ENDIAN);
|
|
break;
|
|
case OPTION_LQ_RELAY_DATA:
|
|
if (optlen < 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "LQ_RELAY_DATA: malformed option");
|
|
break;
|
|
}
|
|
|
|
if (protocol == proto_dhcpv6_bulk_leasequery) {
|
|
expert_add_info(pinfo, option_item, &ei_dhcpv6_bulk_leasequery_no_lq_relay_data);
|
|
}
|
|
|
|
proto_tree_add_item(subtree, hf_lq_relay_data_peer_addr, tvb, off, 16, ENC_NA);
|
|
proto_tree_add_item(subtree, hf_lq_relay_data_msg, tvb, off+16, optlen - 16, ENC_ASCII|ENC_NA);
|
|
break;
|
|
case OPTION_LQ_CLIENT_LINK:
|
|
if (optlen % 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "LQ client links address: malformed option");
|
|
break;
|
|
}
|
|
for (i = 0; i < optlen; i += 16)
|
|
proto_tree_add_item(subtree, hf_lq_client_link, tvb, off + i, 16, ENC_NA);
|
|
break;
|
|
case OPTION_CAPWAP_AC_V6:
|
|
if (optlen % 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "CAPWAP Access Controllers address: malformed option");
|
|
break;
|
|
}
|
|
for (i = 0; i < optlen; i += 16)
|
|
proto_tree_add_item(subtree, hf_capwap_ac_v6, tvb, off + i, 16, ENC_NA);
|
|
break;
|
|
case OPTION_AFTR_NAME:
|
|
{
|
|
const guchar *dns_name;
|
|
get_dns_name(tvb, off, optlen, off, &dns_name);
|
|
proto_tree_add_string(subtree, hf_aftr_name, tvb, off, optlen, dns_name);
|
|
break;
|
|
}
|
|
case OPTION_IAPREFIX:
|
|
if (optlen < 25) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "IAPREFIX: malformed option");
|
|
break;
|
|
}
|
|
|
|
if (tvb_get_ntohl(tvb, off) == DHCPV6_LEASEDURATION_INFINITY) {
|
|
proto_tree_add_uint_format_value(subtree, hf_iaprefix_pref_lifetime, tvb, off,
|
|
4, DHCPV6_LEASEDURATION_INFINITY, "infinity");
|
|
} else {
|
|
proto_tree_add_item(subtree, hf_iaprefix_pref_lifetime, tvb, off,
|
|
4, ENC_BIG_ENDIAN);
|
|
}
|
|
if (tvb_get_ntohl(tvb, off + 4) == DHCPV6_LEASEDURATION_INFINITY) {
|
|
proto_tree_add_uint_format_value(subtree, hf_iaprefix_valid_lifetime, tvb, off+4,
|
|
4, DHCPV6_LEASEDURATION_INFINITY, "infinity");
|
|
} else {
|
|
proto_tree_add_item(subtree, hf_iaprefix_valid_lifetime, tvb, off+4,
|
|
4, ENC_BIG_ENDIAN);
|
|
}
|
|
proto_tree_add_item(subtree, hf_iaprefix_pref_len, tvb, off+8, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree, hf_iaprefix_pref_addr, tvb, off+9, 16, ENC_NA);
|
|
temp_optlen = 25;
|
|
while ((optlen - temp_optlen) > 0) {
|
|
temp_optlen += dhcpv6_option(tvb, pinfo, subtree, downstream,
|
|
off+temp_optlen, off + optlen, at_end, protocol);
|
|
if (*at_end) {
|
|
/* Bad option - just skip to the end */
|
|
temp_optlen = optlen;
|
|
}
|
|
}
|
|
break;
|
|
case OPTION_MIP6_HA:
|
|
if (optlen != 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "MIP6_HA: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_mip6_ha, tvb, off, 16, ENC_NA);
|
|
break;
|
|
case OPTION_MIP6_HOA:
|
|
if (optlen != 16) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "MIP6_HOA: malformed option");
|
|
break;
|
|
}
|
|
|
|
proto_tree_add_item(subtree, hf_mip6_hoa, tvb, off, 16, ENC_NA);
|
|
break;
|
|
case OPTION_NAI:
|
|
if (optlen < 4) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "NAI: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_nai, tvb, off, optlen - 2, ENC_ASCII|ENC_NA);
|
|
break;
|
|
case OPTION_PD_EXCLUDE:
|
|
if ((optlen < 2) || (optlen > 17)) {
|
|
expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "PD_EXCLUDE: malformed option");
|
|
break;
|
|
}
|
|
proto_tree_add_item(subtree, hf_pd_exclude_pref_len, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(subtree, hf_pd_exclude_subnet_id , tvb, off+1, optlen-1, ENC_NA);
|
|
break;
|
|
}
|
|
|
|
return 4 + optlen;
|
|
}
|
|
|
|
|
|
static void
|
|
dissect_dhcpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|
gboolean downstream, int off, int eoff)
|
|
{
|
|
proto_tree *bp_tree = NULL;
|
|
proto_item *ti;
|
|
guint8 msgtype;
|
|
gboolean at_end;
|
|
struct e_in6_addr in6;
|
|
|
|
msgtype = tvb_get_guint8(tvb, off);
|
|
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(msgtype, msgtype_vals, "Message Type %u"));
|
|
|
|
if (tree) {
|
|
ti = proto_tree_add_item(tree, proto_dhcpv6, tvb, off, eoff - off, ENC_NA);
|
|
bp_tree = proto_item_add_subtree(ti, ett_dhcpv6);
|
|
}
|
|
|
|
|
|
if (msgtype == RELAY_FORW || msgtype == RELAY_REPLY) {
|
|
if (tree) {
|
|
proto_tree_add_item(bp_tree, hf_dhcpv6_msgtype, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(bp_tree, hf_dhcpv6_hopcount, tvb, off + 1, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(bp_tree, hf_dhcpv6_linkaddr, tvb, off + 2, 16, ENC_NA);
|
|
tvb_get_ipv6(tvb, off + 2, &in6);
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "L: %s ", ip6_to_str(&in6));
|
|
proto_tree_add_item(bp_tree, hf_dhcpv6_peeraddr, tvb, off + 18, 16, ENC_NA);
|
|
}
|
|
off += 34;
|
|
} else {
|
|
if (tree) {
|
|
proto_tree_add_item(bp_tree, hf_dhcpv6_msgtype, tvb, off, 1, ENC_BIG_ENDIAN);
|
|
proto_tree_add_item(bp_tree, hf_dhcpv6_xid, tvb, off + 1, 3, ENC_BIG_ENDIAN);
|
|
}
|
|
col_append_fstr(pinfo->cinfo, COL_INFO, "XID: 0x%x ", tvb_get_ntoh24(tvb, off + 1));
|
|
off += 4;
|
|
}
|
|
|
|
at_end = FALSE;
|
|
while (off < eoff && !at_end)
|
|
off += dhcpv6_option(tvb, pinfo, bp_tree, downstream, off, eoff, &at_end, proto_dhcpv6);
|
|
}
|
|
|
|
static void
|
|
dissect_dhcpv6_downstream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
{
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv6");
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
dissect_dhcpv6(tvb, pinfo, tree, TRUE, 0, tvb_reported_length(tvb));
|
|
}
|
|
|
|
static void
|
|
dissect_dhcpv6_upstream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
{
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv6");
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
dissect_dhcpv6(tvb, pinfo, tree, FALSE, 0, tvb_reported_length(tvb));
|
|
}
|
|
|
|
|
|
static guint
|
|
get_dhcpv6_bulk_leasequery_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
|
|
{
|
|
return (tvb_get_ntohs(tvb, offset)+2);
|
|
}
|
|
|
|
static int
|
|
dissect_dhcpv6_bulk_leasequery_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
|
|
{
|
|
proto_item *ti;
|
|
proto_tree *bulk_tree, *option_tree;
|
|
gint offset = 0, end;
|
|
guint16 size, trans_id;
|
|
guint8 msg_type;
|
|
gboolean at_end = FALSE;
|
|
|
|
col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv6 BulkLease");
|
|
col_clear(pinfo->cinfo, COL_INFO);
|
|
|
|
ti = proto_tree_add_item(tree, proto_dhcpv6_bulk_leasequery, tvb, 0, -1, ENC_NA );
|
|
bulk_tree = proto_item_add_subtree(ti, ett_dhcpv6_bulk_leasequery);
|
|
|
|
size = tvb_get_ntohs(tvb, offset);
|
|
proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_size, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
|
|
msg_type = tvb_get_guint8( tvb, offset );
|
|
ti = proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_msgtype, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
if ((msg_type != LEASEQUERY) &&
|
|
(msg_type != LEASEQUERY_REPLY) &&
|
|
(msg_type != LEASEQUERY_DONE) &&
|
|
(msg_type != LEASEQUERY_DATA))
|
|
expert_add_info_format(pinfo, ti, &ei_dhcpv6_bulk_leasequery_bad_msg_type,
|
|
"Message Type %d not allowed by DHCPv6 Bulk Leasequery", msg_type);
|
|
|
|
offset++;
|
|
proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
|
|
offset++;
|
|
|
|
trans_id = tvb_get_ntohs(tvb, offset);
|
|
proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_trans_id, tvb, offset, 2, ENC_BIG_ENDIAN);
|
|
offset += 2;
|
|
|
|
col_add_fstr(pinfo->cinfo, COL_INFO, "%s, Transaction ID: %5u",
|
|
val_to_str_const(msg_type, msgtype_vals, "Unknown"), trans_id);
|
|
|
|
ti = proto_tree_add_text(bulk_tree, tvb, offset, -1, "DHCPv6 Options");
|
|
option_tree = proto_item_add_subtree(ti, ett_dhcpv6_bulk_leasequery_options);
|
|
end = size+2;
|
|
while ((offset < end) && !at_end)
|
|
offset += dhcpv6_option(tvb, pinfo, option_tree, FALSE, offset,
|
|
end, &at_end, proto_dhcpv6_bulk_leasequery);
|
|
|
|
return tvb_length(tvb);
|
|
}
|
|
|
|
static int
|
|
dissect_dhcpv6_bulk_leasequery(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
|
|
{
|
|
tcp_dissect_pdus(tvb, pinfo, tree, dhcpv6_bulk_leasequery_desegment, 2,
|
|
get_dhcpv6_bulk_leasequery_pdu_len, dissect_dhcpv6_bulk_leasequery_pdu, data);
|
|
return tvb_length(tvb);
|
|
}
|
|
|
|
void
|
|
proto_register_dhcpv6(void)
|
|
{
|
|
module_t *bulkquery_module;
|
|
|
|
static hf_register_info hf[] = {
|
|
|
|
/* DHCPv6 header */
|
|
{ &hf_dhcpv6_msgtype,
|
|
{ "Message type", "dhcpv6.msgtype", FT_UINT8, BASE_DEC, VALS(msgtype_vals), 0x0, NULL, HFILL }},
|
|
{ &hf_dhcpv6_domain,
|
|
{ "Domain", "dhcpv6.domain", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_dhcpv6_hopcount,
|
|
{ "Hopcount", "dhcpv6.hopcount", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_dhcpv6_xid,
|
|
{ "Transaction ID", "dhcpv6.xid", FT_UINT24, BASE_HEX, NULL, 0, NULL, HFILL}},
|
|
{ &hf_dhcpv6_linkaddr,
|
|
{ "Link address", "dhcpv6.linkaddr", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL}},
|
|
{ &hf_dhcpv6_peeraddr,
|
|
{ "Peer address", "dhcpv6.peeraddr", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL}},
|
|
/* Generic option stuff */
|
|
{ &hf_option_type,
|
|
{ "Option", "dhcpv6.option.type", FT_UINT16, BASE_DEC, VALS(opttype_vals), 0x0, NULL, HFILL}},
|
|
{ &hf_option_length,
|
|
{ "Length", "dhcpv6.option.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_option_value,
|
|
{ "Value", "dhcpv6.option.value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
/* Individual options */
|
|
{ &hf_clientfqdn_reserved,
|
|
{ "Reserved", "dhcpv6.clientfqdn.reserved", FT_UINT8, BASE_HEX, NULL, 0xF8, NULL, HFILL}},
|
|
{ &hf_clientfqdn_n,
|
|
{ "N bit", "dhcpv6.clientfqdn.n", FT_BOOLEAN, 8, TFS(&fqdn_n), 0x4, "Whether the server SHOULD NOT perform any DNS updates", HFILL}},
|
|
{ &hf_clientfqdn_o,
|
|
{ "O bit", "dhcpv6.clientfqdn.o", FT_BOOLEAN, 8, TFS(&fqdn_o), 0x2, "Whether the server has overridden the client's preference for the S bit. Must be 0 when sent from client", HFILL}},
|
|
{ &hf_clientfqdn_s,
|
|
{ "S bit", "dhcpv6.clientfqdn.s", FT_BOOLEAN, 8, TFS(&fqdn_s), 0x1, "Whether the server SHOULD or SHOULD NOT perform the AAAA RR (FQDN-to-address) DNS updates", HFILL}},
|
|
{ &hf_remoteid_enterprise,
|
|
{ "Enterprise ID", "dhcpv6.remoteid.enterprise", FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0, "RemoteID Enterprise Number", HFILL }},
|
|
{ &hf_duid_bytes,
|
|
{ "DUID", "dhcpv6.duid.bytes", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_duid_type,
|
|
{ "DUID Type", "dhcpv6.duid.type", FT_UINT16, BASE_DEC, VALS(duidtype_vals), 0x0, NULL, HFILL}},
|
|
{ &hf_duidllt_time,
|
|
{ "DUID Time", "dhcpv6.duidllt.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_duidllt_link_layer_addr,
|
|
{ "Link-layer address", "dhcpv6.duidllt.link_layer_addr", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_duidllt_hwtype,
|
|
{ "Hardware type", "dhcpv6.duidllt.hwtype", FT_UINT16, BASE_DEC, VALS(arp_hrd_vals), 0, "DUID LLT Hardware Type", HFILL }},
|
|
{ &hf_duidll_hwtype,
|
|
{ "Hardware type", "dhcpv6.duidll.hwtype", FT_UINT16, BASE_DEC, VALS(arp_hrd_vals), 0, "DUID LL Hardware Type", HFILL }},
|
|
{ &hf_duiden_enterprise,
|
|
{ "Enterprise ID", "dhcpv6.duiden.enterprise", FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0, "DUID EN Enterprise Number", HFILL }},
|
|
{ &hf_duiden_identifier,
|
|
{ "Identifier", "dhcpv6.duiden.identifier", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_duidll_link_layer_addr,
|
|
{ "Link-layer address", "dhcpv6.duidll.link_layer_addr", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_iaid,
|
|
{ "IAID", "dhcpv6.iaid", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_iaid_t1,
|
|
{ "T1", "dhcpv6.iaid.t1", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_iaid_t2,
|
|
{ "T2", "dhcpv6.iaid.t2", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_iata,
|
|
{ "IATA", "dhcpv6.iata", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_iaaddr_ip,
|
|
{ "IPv6 address", "dhcpv6.iaaddr.ip", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_iaaddr_pref_lifetime,
|
|
{ "Preferred lifetime", "dhcpv6.iaaddr.pref_lifetime", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_iaaddr_valid_lifetime,
|
|
{ "Valid lifetime", "dhcpv6.iaaddr.valid_lifetime", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_requested_option_code,
|
|
{ "Requested Option code", "dhcpv6.requested_option_code", FT_UINT16, BASE_DEC, VALS(opttype_vals), 0, NULL, HFILL }},
|
|
{ &hf_option_preference,
|
|
{ "Pref-value", "dhcpv6.option_preference", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_elapsed_time,
|
|
{ "Elapsed time", "dhcpv6.elapsed_time", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_auth_protocol,
|
|
{ "Protocol", "dhcpv6.auth.protocol", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_auth_algorithm,
|
|
{ "Algorithm", "dhcpv6.auth.algorithm", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_auth_rdm,
|
|
{ "RDM", "dhcpv6.auth.rdm", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_auth_replay_detection,
|
|
{ "Replay Detection", "dhcpv6.auth.replay_detection", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_auth_info,
|
|
{ "Authentication Information", "dhcpv6.auth.info", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_opt_unicast,
|
|
{ "IPv6 address", "dhcpv6.unicast", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_opt_status_code,
|
|
{ "Status Code", "dhcpv6.status_code", FT_UINT16, BASE_DEC, VALS(statuscode_vals), 0, NULL, HFILL }},
|
|
{ &hf_opt_status_msg,
|
|
{ "Status Message", "dhcpv6.status_msg", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_vendorclass_enterprise,
|
|
{ "Enterprise ID", "dhcpv6.vendorclass.enterprise", FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0, "Vendor Class Enterprise Number", HFILL }},
|
|
{ &hf_vendorclass_data,
|
|
{ "vendor-class-data", "dhcpv6.vendorclass.data", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_vendoropts_enterprise,
|
|
{ "Enterprise ID", "dhcpv6.vendoropts.enterprise", FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0, "Vendor opts Enterprise Number", HFILL }},
|
|
{ &hf_vendoropts_enterprise_option_code,
|
|
{ "Option code", "dhcpv6.vendoropts.enterprise.option_code", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_vendoropts_enterprise_option_length,
|
|
{ "Option length", "dhcpv6.vendoropts.enterprise.option_length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_vendoropts_enterprise_option_data,
|
|
{ "Option data", "dhcpv6.vendoropts.enterprise.option_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_interface_id,
|
|
{ "Interface-ID", "dhcpv6.interface_id", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_interface_id_link_address,
|
|
{ "Link Address", "dhcpv6.interface_id_link_address", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_reconf_msg,
|
|
{ "Reconfigure message type", "dhcpv6.reconf_msg", FT_UINT8, BASE_DEC, VALS(msgtype_vals), 0, NULL, HFILL }},
|
|
{ &hf_sip_server_a,
|
|
{ "SIP server address", "dhcpv6.sip_server_a", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_dns_servers,
|
|
{ "DNS server address", "dhcpv6.dns_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_nis_servers,
|
|
{ "NIS server address", "dhcpv6.nis_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_nisp_servers,
|
|
{ "NISP server address", "dhcpv6.nisp_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_sntp_servers,
|
|
{ "SNTP server address", "dhcpv6.sntp_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_opt_lifetime,
|
|
{ "Lifetime", "dhcpv6.lifetime", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_bcmcs_servers_a,
|
|
{ "BCMCS server address", "dhcpv6.bcmcs_server_a", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_remoteid_enterprise_id,
|
|
{ "Remote-ID", "dhcpv6.remoteid_enterprise_id", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_subscriber_id,
|
|
{ "Subscriber-ID", "dhcpv6.subscriber_id", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_pana_agent,
|
|
{ "PANA agents address", "dhcpv6.pana_agent", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_opt_timezone,
|
|
{ "Time-zone", "dhcpv6.timezone", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_opt_tzdb,
|
|
{ "TZ-database", "dhcpv6.tzdb", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_lq_query,
|
|
{ "Query-type", "dhcpv6.lq_query", FT_UINT8, BASE_DEC, VALS(lq_query_vals), 0, NULL, HFILL }},
|
|
{ &hf_lq_query_link_address,
|
|
{ "Link address", "dhcpv6.lq_query_link_address", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_clt_time,
|
|
{ "Clt_time", "dhcpv6.clt_time", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_lq_relay_data_peer_addr,
|
|
{ "Peer address", "dhcpv6.lq_relay_data_peer_addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_lq_relay_data_msg,
|
|
{ "DHCPv6 relay message", "dhcpv6.lq_relay_data_msg", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_lq_client_link,
|
|
{ "LQ client links address", "dhcpv6.lq_client_link", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_capwap_ac_v6,
|
|
{ "CAPWAP Access Controllers address", "dhcpv6.capwap_ac_v6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_aftr_name,
|
|
{ "DS-Lite AFTR Name", "dhcpv6.aftr_name", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_iaprefix_pref_lifetime,
|
|
{ "Preferred lifetime", "dhcpv6.iaprefix.pref_lifetime", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_iaprefix_valid_lifetime,
|
|
{ "Valid lifetime", "dhcpv6.iaprefix.valid_lifetime", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
|
|
{ &hf_iaprefix_pref_len,
|
|
{ "Prefix length", "dhcpv6.iaprefix.pref_len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_iaprefix_pref_addr,
|
|
{ "Prefix address", "dhcpv6.iaprefix.pref_addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_mip6_ha,
|
|
{ "Home Agent", "dhcpv6.mip6_home_agent", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_mip6_hoa,
|
|
{ "Home Address", "dhcpv6.mip6_home_address", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_nai,
|
|
{ "NAI", "dhcpv6.nai", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_pd_exclude_pref_len,
|
|
{ "Prefix length", "dhcpv6.pd_exclude.pref_len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_pd_exclude_subnet_id,
|
|
{ "IPv6 subnet ID", "dhcpv6.pd_exclude.subnet_id", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_option_ntpserver_type,
|
|
{ "Suboption", "dhcpv6.ntpserver.option.type", FT_UINT16, BASE_DEC, VALS(ntp_server_opttype_vals), 0x0, NULL, HFILL}},
|
|
{ &hf_option_ntpserver_length,
|
|
{ "Length", "dhcpv6.ntpserver.option.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_option_ntpserver_addr,
|
|
{ "NTP Server Address", "dhcpv6.ntpserver.addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_option_ntpserver_mc_addr,
|
|
{ "NTP Multicast Address", "dhcpv6.ntpserver.mc_addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
{ &hf_packetcable_ccc_suboption,
|
|
{ "Sub element", "dhcpv6.packetcable.ccc.suboption", FT_UINT16, BASE_DEC, VALS(pkt_ccc_opt_vals), 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_pri_dhcp,
|
|
{ "Primary DHCP", "dhcpv6.packetcable.ccc.pri_dhcp", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_sec_dhcp,
|
|
{ "Secondary DHCP", "dhcpv6.packetcable.ccc.sec_dhcp", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_prov_srv_type,
|
|
{ "Type", "dhcpv6.packetcable.ccc.prov_srv.type", FT_UINT8, BASE_DEC, VALS(pkt_ccc_prov_srv_type_vals), 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_prov_srv_fqdn,
|
|
{ "FQDN", "dhcpv6.packetcable.ccc.prov_srv.fqdn", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_prov_srv_ipv4,
|
|
{ "IPv4 address", "dhcpv6.packetcable.ccc.prov_srv.ipv4", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_as_krb_nominal_timeout,
|
|
{ "Nominal Timeout", "dhcpv6.packetcable.ccc.as_krb.nominal_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_as_krb_max_timeout,
|
|
{ "Maximum Timeout", "dhcpv6.packetcable.ccc.as_krb.max_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_as_krb_max_retry_count,
|
|
{ "Maximum Retry Count", "dhcpv6.packetcable.ccc.as_krb.max_retry_count", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_ap_krb_nominal_timeout,
|
|
{ "Nominal Timeout", "dhcpv6.packetcable.ccc.ap_krb.nominal_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_ap_krb_max_timeout,
|
|
{ "Maximum Timeout", "dhcpv6.packetcable.ccc.ap_krb.max_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_ap_krb_max_retry_count,
|
|
{ "Maximum Retry Count", "dhcpv6.packetcable.ccc.ap_krb.max_retry_count", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_krb_realm,
|
|
{ "KRB Realm", "dhcpv6.packetcable.ccc.krb_realm", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_tgt_flag,
|
|
{ "TGT Flags", "dhcpv6.packetcable.ccc.tgt_flag", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_tgt_flag_fetch,
|
|
{ "Fetch TGT", "dhcpv6.packetcable.ccc.tgt_flag.fetch", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x01, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_prov_timer,
|
|
{ "Provisioning timer", "dhcpv6.packetcable.ccc.prov_timer", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_sec_tcm,
|
|
{ "SEC TCM Flags", "dhcpv6.packetcable.ccc.sec_tcm", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_sec_tcm_provisioning_server,
|
|
{ "Provisioning Server", "dhcpv6.packetcable.ccc.sec_tcm.provisioning_server", FT_BOOLEAN, 16, TFS(&tfs_on_off), 0x01, NULL, HFILL }},
|
|
{ &hf_packetcable_ccc_sec_tcm_call_manager_server,
|
|
{ "Call Manager Servers", "dhcpv6.packetcable.ccc.tgt_flag.call_manager_server", FT_BOOLEAN, 16, TFS(&tfs_on_off), 0x02, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_suboption,
|
|
{ "Sub element", "dhcpv6.packetcable.cccV6.suboption", FT_UINT16, BASE_DEC, VALS(pkt_cccV6_opt_vals), 0, NULL, HFILL }},
|
|
{ &hf_modem_capabilities_encoding_type,
|
|
{ "Type", "dhcpv6.docsis.cccV6.tlv5.suboption", FT_UINT16, BASE_DEC, VALS(modem_capabilities_encoding), 0, NULL, HFILL }},
|
|
{ &hf_eue_capabilities_encoding_type,
|
|
{ "Type", "dhcpv6.packetcable.cccV6.tlv5.suboption", FT_UINT16, BASE_DEC, VALS(eue_capabilities_encoding), 0, NULL, HFILL }},
|
|
{ &hf_capabilities_encoding_length,
|
|
{ "Length", "dhcpv6.cccV6.tlv5.suboption.length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_capabilities_encoding_bytes,
|
|
{ "Value", "dhcpv6.cccV6.tlv5.suboption.value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_capabilities_encoding_number,
|
|
{ "Value", "dhcpv6.cccV6.tlv5.suboption.value", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_pri_dss,
|
|
{ "Primary SSID", "dhcpv6.packetcable.cccV6.pri_dss", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_sec_dss,
|
|
{ "Secondary SSID", "dhcpv6.packetcable.cccV6.sec_dss", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_prov_srv_type,
|
|
{ "Type", "dhcpv6.packetcable.cccV6.prov_srv.type", FT_UINT8, BASE_DEC, VALS(pkt_cccV6_prov_srv_type_vals), 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_prov_srv_fqdn,
|
|
{ "FQDN", "dhcpv6.packetcable.cccV6.prov_srv.fqdn", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_prov_srv_ipv6,
|
|
{ "IPv6 address", "dhcpv6.packetcable.cccV6.prov_srv.ipv6", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_as_krb_nominal_timeout,
|
|
{ "Nominal Timeout", "dhcpv6.packetcable.cccV6.as_krb.nominal_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_as_krb_max_timeout,
|
|
{ "Maximum Timeout", "dhcpv6.packetcable.cccV6.as_krb.max_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_as_krb_max_retry_count,
|
|
{ "Maximum Retry Count", "dhcpv6.packetcable.cccV6.as_krb.max_retry_count", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_ap_krb_nominal_timeout,
|
|
{ "Nominal Timeout", "dhcpv6.packetcable.cccV6.ap_krb.nominal_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_ap_krb_max_timeout,
|
|
{ "Maximum Timeout", "dhcpv6.packetcable.cccV6.ap_krb.max_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_ap_krb_max_retry_count,
|
|
{ "Maximum Retry Count", "dhcpv6.packetcable.cccV6.ap_krb.max_retry_count", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_krb_realm,
|
|
{ "KRB Realm", "dhcpv6.packetcable.cccV6.krb_realm", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_tgt_flag,
|
|
{ "TGT Flags", "dhcpv6.packetcable.cccV6.tgt_flag", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_tgt_flag_fetch,
|
|
{ "Fetch TGT", "dhcpv6.packetcable.cccV6.tgt_flag.fetch", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x01, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_prov_timer,
|
|
{ "Provisioning timer", "dhcpv6.packetcable.cccV6.prov_timer", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_sec_tcm,
|
|
{ "SEC TCM Flags", "dhcpv6.packetcable.cccV6.sec_tcm", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_sec_tcm_provisioning_server,
|
|
{ "Provisioning Server", "dhcpv6.packetcable.cccV6.sec_tcm.provisioning_server", FT_BOOLEAN, 16, TFS(&tfs_on_off), 0x01, NULL, HFILL }},
|
|
{ &hf_packetcable_cccV6_sec_tcm_call_manager_server,
|
|
{ "Call Manager Servers", "dhcpv6.packetcable.cccV6.tgt_flag.call_manager_server", FT_BOOLEAN, 16, TFS(&tfs_on_off), 0x02, NULL, HFILL }},
|
|
{ &hf_cablelabs_opts,
|
|
{ "Suboption", "dhcpv6.cablelabs.opt", FT_UINT16, BASE_DEC, VALS(cl_vendor_subopt_values), 0, NULL, HFILL }},
|
|
{ &hf_cablelabs_ipv6_server,
|
|
{ "IPv6 address", "dhcpv6.cablelabs.ipv6_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
|
|
};
|
|
|
|
static gint *ett[] = {
|
|
&ett_dhcpv6,
|
|
&ett_dhcpv6_option,
|
|
&ett_dhcpv6_option_vsoption,
|
|
&ett_dhcpv6_vendor_option,
|
|
&ett_dhcpv6_pkt_option,
|
|
&ett_dhcpv6_netserver_option,
|
|
&ett_dhcpv6_tlv5_type
|
|
};
|
|
|
|
static ei_register_info ei[] = {
|
|
{ &ei_dhcpv6_bogus_length, { "dhcpv6.bogus_length", PI_MALFORMED, PI_ERROR, "Bogus length", EXPFILL }},
|
|
{ &ei_dhcpv6_malformed_option, { "dhcpv6.malformed_option", PI_MALFORMED, PI_ERROR, "Malformed option", EXPFILL }},
|
|
{ &ei_dhcpv6_no_suboption_len, { "dhcpv6.no_suboption_len", PI_PROTOCOL, PI_WARN, "no room left in option for suboption length", EXPFILL }},
|
|
{ &ei_dhcpv6_invalid_byte, { "dhcpv6.invalid_byte", PI_PROTOCOL, PI_WARN, "Invalid at byte", EXPFILL }},
|
|
{ &ei_dhcpv6_invalid_time_value, { "dhcpv6.invalid_time_value", PI_PROTOCOL, PI_WARN, "Invalid time value", EXPFILL }},
|
|
{ &ei_dhcpv6_invalid_type, { "dhcpv6.invalid_type", PI_PROTOCOL, PI_WARN, "Invalid type", EXPFILL }},
|
|
{ &ei_dhcpv6_malformed_dns, { "dhcpv6.malformed_dns", PI_PROTOCOL, PI_WARN, "Malformed DNS name record (MS Vista client?)", EXPFILL }},
|
|
};
|
|
|
|
static hf_register_info bulk_leasequery_hf[] = {
|
|
{ &hf_dhcpv6_bulk_leasequery_size,
|
|
{ "Message size", "dhcpv6.bulk_leasequery.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_dhcpv6_bulk_leasequery_msgtype,
|
|
{ "Message type", "dhcpv6.bulk_leasequery.msgtype", FT_UINT8, BASE_DEC, VALS(msgtype_vals), 0x0, NULL, HFILL }},
|
|
{ &hf_dhcpv6_bulk_leasequery_reserved,
|
|
{ "Reserved", "dhcpv6.bulk_leasequery.reserved", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
{ &hf_dhcpv6_bulk_leasequery_trans_id,
|
|
{ "Transaction ID", "dhcpv6.bulk_leasequery.trans_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
|
|
};
|
|
|
|
static gint *ett_bulk_leasequery[] = {
|
|
&ett_dhcpv6_bulk_leasequery,
|
|
&ett_dhcpv6_bulk_leasequery_options
|
|
};
|
|
|
|
static ei_register_info ei_bulk_leasequery[] = {
|
|
{ &ei_dhcpv6_bulk_leasequery_bad_query_type, { "dhcpv6.bulk_leasequery.bad_query_type", PI_MALFORMED, PI_WARN, "LQ-QUERY: Query types only supported by Bulk Leasequery", EXPFILL }},
|
|
{ &ei_dhcpv6_bulk_leasequery_no_lq_relay_data, { "dhcpv6.bulk_leasequery.no_lq_relay_data", PI_MALFORMED, PI_WARN, "LQ_RELAY_DATA: Not allowed in Bulk Leasequery", EXPFILL }},
|
|
{ &ei_dhcpv6_bulk_leasequery_bad_msg_type, { "dhcpv6.bulk_leasequery.bad_msg_type", PI_MALFORMED, PI_WARN, "Message Type %d not allowed by DHCPv6 Bulk Leasequery", EXPFILL }},
|
|
};
|
|
|
|
expert_module_t* expert_dhcpv6;
|
|
expert_module_t* expert_dhcpv6_bulk_leasequery;
|
|
|
|
proto_dhcpv6 = proto_register_protocol("DHCPv6", "DHCPv6", "dhcpv6");
|
|
proto_register_field_array(proto_dhcpv6, hf, array_length(hf));
|
|
proto_register_subtree_array(ett, array_length(ett));
|
|
|
|
expert_dhcpv6 = expert_register_protocol(proto_dhcpv6);
|
|
expert_register_field_array(expert_dhcpv6, ei, array_length(ei));
|
|
|
|
proto_dhcpv6_bulk_leasequery = proto_register_protocol("DHCPv6 Bulk Leasequery", "DHCPv6 Bulk Leasequery", "dhcpv6.bulk_leasequery");
|
|
proto_register_field_array(proto_dhcpv6_bulk_leasequery, bulk_leasequery_hf, array_length(bulk_leasequery_hf));
|
|
proto_register_subtree_array(ett_bulk_leasequery, array_length(ett_bulk_leasequery));
|
|
|
|
expert_dhcpv6_bulk_leasequery = expert_register_protocol(proto_dhcpv6_bulk_leasequery);
|
|
expert_register_field_array(expert_dhcpv6_bulk_leasequery, ei_bulk_leasequery, array_length(ei_bulk_leasequery));
|
|
|
|
/* Allow other dissectors to find this one by name.
|
|
Just choose upstream version for now as they are identical. */
|
|
register_dissector("dhcpv6", dissect_dhcpv6_upstream, proto_dhcpv6);
|
|
|
|
bulkquery_module = prefs_register_protocol(proto_dhcpv6_bulk_leasequery, NULL);
|
|
prefs_register_bool_preference(bulkquery_module, "desegment",
|
|
"Desegment all Bulk Leasequery messages spanning multiple TCP segments",
|
|
"Whether the Bulk Leasequery dissector should desegment all messages spanning multiple TCP segments",
|
|
&dhcpv6_bulk_leasequery_desegment);
|
|
|
|
}
|
|
|
|
void
|
|
proto_reg_handoff_dhcpv6(void)
|
|
{
|
|
dissector_handle_t dhcpv6_handle, dhcpv6_bulkquery_handle;
|
|
|
|
dhcpv6_handle = create_dissector_handle(dissect_dhcpv6_downstream,
|
|
proto_dhcpv6);
|
|
dissector_add_uint("udp.port", UDP_PORT_DHCPV6_DOWNSTREAM, dhcpv6_handle);
|
|
dhcpv6_handle = create_dissector_handle(dissect_dhcpv6_upstream,
|
|
proto_dhcpv6);
|
|
dissector_add_uint("udp.port", UDP_PORT_DHCPV6_UPSTREAM, dhcpv6_handle);
|
|
dhcpv6_bulkquery_handle = new_create_dissector_handle(dissect_dhcpv6_bulk_leasequery,
|
|
proto_dhcpv6_bulk_leasequery);
|
|
dissector_add_uint("tcp.port", UDP_PORT_DHCPV6_UPSTREAM, dhcpv6_bulkquery_handle);
|
|
}
|
|
|
|
/*
|
|
* Editor modelines
|
|
*
|
|
* Local Variables:
|
|
* c-basic-offset: 4
|
|
* tab-width: 8
|
|
* indent-tabs-mode: nil
|
|
* End:
|
|
*
|
|
* ex: set shiftwidth=4 tabstop=8 expandtab:
|
|
* :indentSize=4:tabSize=8:noTabs=true:
|
|
*/
|