Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-dhcpv6.c
blob21956a3ba0f3c7a776804fde3bbca85bbf985529
1 /* packet-dhcpv6.c
2 * Routines for DHCPv6 packet disassembly
3 * Copyright 2004, Nicolas DICHTEL - 6WIND - <nicolas.dichtel@6wind.com>
4 * Jun-ichiro itojun Hagino <itojun@iijlab.net>
5 * IItom Tsutomu MIENO <iitom@utouto.com>
6 * SHIRASAKI Yasuhiro <yasuhiro@gnome.gr.jp>
7 * Tony Lindstrom <tony.lindstrom@ericsson.com>
8 * Copyright 2012, Jerome LAFORGE <jerome.laforge@gmail.com>
10 * The information used comes from:
11 * RFC1034 (DOMAIN NAMES - CONCEPTS AND FACILITIES)
12 * RFC1035 (DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION)
13 * RFC1535 (A Security Problem with DNS) [clear definition of Partial names]
14 * RFC2181 (Clarifications to the DNS Specification)
15 * RFC3319 (SIP options)
16 * RFC3633 (Prefix options) replaces draft-ietf-dhc-dhcpv6-opt-lifetime-00
17 * RFC3646 (DNS Configuration options for DHCP for IPv6 (DHCPv6))
18 * RFC3898 (NIS options)
19 * RFC4075 (SNTP - Configuration Option for DHCPv6)
20 - replaces "draft-ietf-dhc-dhcpv6-opt-timeconfig-03"
21 * RFC4242 (Information Refresh Time Option)
22 * RFC4280 (Broadcast and Multicast Control Servers Options)
23 * RFC4649 (Remote ID option)
24 * RFC4704 (DHCPv6 Client FQDN Option)
25 * RFC5007 (DHCPv6 Leasequery)
26 * RFC5417 (CAPWAP Access Controller DHCP Option)
27 * RFC5460 (DHCPv6 Bulk Leasequery)
28 * RFC5908 (Network Time Protocol (NTP) Server Option)
29 * RFC6334 (Dual-Stack Lite Option)
30 * RFC6603 (Prefix Exclude Option)
31 * RFC6939 (Client Link-Layer Address Option in DHCPv6)
32 * RFC7598 (Configuration of Softwire Address and Port-Mapped Clients)
33 * RFC8415 (Dynamic Host Configuration Protocol for IPv6 (DHCPv6))
34 * RFC8520 (Manufacturer Usage Descriptions) replaces "draft-ietf-opsawg-mud-02"
35 * CL-SP-CANN-DHCP-Reg-I15-180509 (CableLabs' DHCP Options Registry) latest
37 * Note that protocol constants are still subject to change, based on IANA
38 * assignment decisions.
40 * Wireshark - Network traffic analyzer
41 * By Gerald Combs <gerald@wireshark.org>
42 * Copyright 1998 Gerald Combs
44 * SPDX-License-Identifier: GPL-2.0-or-later
47 #include "config.h"
49 #include <epan/packet.h>
50 #include <epan/addr_resolv.h>
51 #include <epan/expert.h>
52 #include <epan/prefs.h>
53 #include <epan/arptypes.h>
54 #include <epan/sminmpec.h>
55 #include <epan/strutil.h>
56 #include <epan/tfs.h>
57 #include <epan/unit_strings.h>
58 #include "packet-tcp.h"
59 #include "packet-arp.h"
60 #include "packet-dns.h"
62 void proto_register_dhcpv6(void);
63 void proto_reg_handoff_dhcpv6(void);
65 static bool dhcpv6_bulk_leasequery_desegment = true;
66 static bool cablelabs_interface_id;
68 static int proto_dhcpv6;
69 static int proto_dhcpv6_bulk_leasequery;
70 static int proto_dhcpv6_cablelabs;
72 static int hf_dhcpv6_msgtype;
73 static int hf_clientfqdn_bad_msgtype;
74 static int hf_clientfqdn_flags;
75 static int hf_clientfqdn_client_n;
76 static int hf_clientfqdn_client_s;
77 static int hf_clientfqdn_server_n;
78 static int hf_clientfqdn_server_o;
79 static int hf_clientfqdn_server_s;
80 static int hf_option_type_str;
81 static int hf_option_type_num;
82 static int hf_option_length;
83 static int hf_empty_domain_name;
84 static int hf_remoteid_enterprise;
85 static int hf_vendoropts_enterprise;
86 static int hf_duid_bytes;
87 static int hf_duid_type;
88 static int hf_duidllt_time;
89 static int hf_duidllt_link_layer_addr;
90 static int hf_duidllt_link_layer_addr_ether;
91 static int hf_duidllt_hwtype;
92 static int hf_duidll_hwtype;
93 static int hf_duiden_enterprise;
94 static int hf_duiden_identifier;
95 static int hf_duidll_link_layer_addr;
96 static int hf_duidll_link_layer_addr_ether;
97 static int hf_duiduuid_bytes;
98 static int hf_iaid;
99 static int hf_iaid_t1;
100 static int hf_iaid_t2;
101 static int hf_iata;
102 static int hf_iaaddr_ip;
103 static int hf_iaaddr_pref_lifetime;
104 static int hf_iaaddr_valid_lifetime;
105 static int hf_requested_option_code;
106 static int hf_option_preference;
107 static int hf_elapsed_time;
108 static int hf_auth_protocol;
109 static int hf_auth_algorithm;
110 static int hf_auth_rdm;
111 static int hf_auth_replay_detection;
112 static int hf_auth_info;
113 static int hf_auth_realm;
114 static int hf_auth_key_id;
115 static int hf_auth_md5_data;
116 static int hf_opt_unicast;
117 static int hf_opt_status_code;
118 static int hf_opt_status_msg;
119 static int hf_vendorclass_enterprise;
120 static int hf_vendorclass_data;
121 static int hf_vendoropts_enterprise_option_code;
122 static int hf_vendoropts_enterprise_option_length;
123 static int hf_vendoropts_enterprise_option_data;
124 static int hf_interface_id;
125 static int hf_reconf_msg;
126 static int hf_sip_server_domain_search_fqdn;
127 static int hf_sip_server_a;
128 static int hf_dns_servers;
129 static int hf_dhcp4o6_servers;
130 static int hf_domain_search_list_entry;
131 static int hf_nis_servers;
132 static int hf_nisp_servers;
133 static int hf_nis_fqdn;
134 static int hf_nisp_fqdn;
135 static int hf_sntp_servers;
136 static int hf_opt_lifetime;
137 static int hf_bcmcs_servers_fqdn;
138 static int hf_bcmcs_servers_a;
139 static int hf_remoteid_enterprise_id;
140 static int hf_subscriber_id;
141 static int hf_client_fqdn;
142 static int hf_pana_agent;
143 static int hf_opt_timezone;
144 static int hf_opt_tzdb;
145 static int hf_lq_query;
146 static int hf_lq_query_link_address;
147 static int hf_clt_time;
148 static int hf_lq_relay_data_peer_addr;
149 static int hf_lq_relay_data_msg;
150 static int hf_lq_client_link;
151 static int hf_capwap_ac_v6;
152 static int hf_aftr_name;
153 static int hf_iaprefix_pref_lifetime;
154 static int hf_iaprefix_valid_lifetime;
155 static int hf_iaprefix_pref_len;
156 static int hf_iaprefix_pref_addr;
157 static int hf_mip6_ha;
158 static int hf_mip6_hoa;
159 static int hf_nai;
160 static int hf_pd_exclude_pref_len;
161 static int hf_pd_exclude_subnet_id;
162 static int hf_option_captive_portal;
163 static int hf_option_s46_option_code;
164 static int hf_option_failover_binding_status;
165 static int hf_option_failover_connect_flags;
166 static int hf_option_failover_connect_reserved_flag;
167 static int hf_option_failover_connect_f_flag;
168 static int hf_option_failover_dns_hostname;
169 static int hf_option_failover_dns_zonename;
170 static int hf_option_failover_dns_flags;
171 static int hf_option_failover_dns_reserved_flag;
172 static int hf_option_failover_dns_u_flag;
173 static int hf_option_failover_dns_s_flag;
174 static int hf_option_failover_dns_r_flag;
175 static int hf_option_failover_dns_f_flag;
176 static int hf_option_failover_expiration_time;
177 static int hf_option_failover_max_unacked_bndupd;
178 static int hf_option_failover_mclt;
179 static int hf_option_failover_partner_lifetime;
180 static int hf_option_failover_partner_lifetime_sent;
181 static int hf_option_failover_partner_downtime;
182 static int hf_option_failover_partner_raw_clt_time;
183 static int hf_option_failover_major_version;
184 static int hf_option_failover_minor_version;
185 static int hf_option_failover_keepalive_time;
186 static int hf_option_failover_reconfigure_time;
187 static int hf_option_failover_reconfigure_key;
188 static int hf_option_failover_relationship_name;
189 static int hf_option_failover_server_flags;
190 static int hf_option_failover_server_reserved_flag;
191 static int hf_option_failover_server_a_flag;
192 static int hf_option_failover_server_s_flag;
193 static int hf_option_failover_server_c_flag;
194 static int hf_option_failover_server_state;
195 static int hf_option_failover_start_time_of_state;
196 static int hf_option_failover_state_expiration_time;
197 static int hf_option_relay_port;
198 static int hf_dhcpv6_hopcount;
199 static int hf_dhcpv6_xid;
200 static int hf_dhcpv6_peeraddr;
201 static int hf_dhcpv6_linkaddr;
202 static int hf_opt_mudurl;
203 static int hf_option_userclass_length;
204 static int hf_option_userclass_opaque_data;
205 static int hf_option_ntpserver_type;
206 static int hf_option_ntpserver_length;
207 static int hf_option_ntpserver_addr;
208 static int hf_option_ntpserver_mc_addr;
209 static int hf_option_ntpserver_fqdn;
210 static int hf_packetcable_ccc_suboption;
211 static int hf_packetcable_ccc_pri_dhcp;
212 static int hf_packetcable_ccc_sec_dhcp;
213 static int hf_packetcable_cccV6_suboption;
214 static int hf_packetcable_cccV6_pri_dss;
215 static int hf_packetcable_cccV6_sec_dss;
216 static int hf_packetcable_cccV6_prov_srv_type;
217 static int hf_packetcable_cccV6_prov_srv_fqdn;
218 static int hf_packetcable_cccV6_prov_srv_ipv6;
219 static int hf_packetcable_cccV6_as_krb_nominal_timeout;
220 static int hf_packetcable_cccV6_as_krb_max_timeout;
221 static int hf_packetcable_cccV6_as_krb_max_retry_count;
222 static int hf_packetcable_cccV6_ap_krb_nominal_timeout;
223 static int hf_packetcable_cccV6_ap_krb_max_timeout;
224 static int hf_packetcable_cccV6_ap_krb_max_retry_count;
225 static int hf_packetcable_cccV6_krb_realm;
226 static int hf_packetcable_cccV6_tgt_flag;
227 static int hf_packetcable_cccV6_tgt_flag_fetch;
228 static int hf_packetcable_cccV6_prov_timer;
229 static int hf_packetcable_cccV6_sec_tcm;
230 static int hf_packetcable_cccV6_sec_tcm_provisioning_server;
231 static int hf_packetcable_cccV6_sec_tcm_call_manager_server;
232 static int hf_cablelabs_opts;
233 static int hf_modem_capabilities_encoding_type;
234 static int hf_eue_capabilities_encoding_type;
235 static int hf_capabilities_encoding_length;
236 static int hf_capabilities_encoding_bytes;
237 static int hf_capabilities_encoding_number;
238 static int hf_cablelabs_ipv6_server;
239 static int hf_cablelabs_docsis_version_number;
240 static int hf_cablelabs_dpoe_server_version_number;
241 static int hf_cablelabs_interface_id;
242 static int hf_cablelabs_interface_id_link_address;
243 static int hf_option_s46_rule_flags;
244 static int hf_option_s46_rule_reserved_flag;
245 static int hf_option_s46_rule_fmr_flag;
246 static int hf_option_s46_rule_ea_len;
247 static int hf_option_s46_rule_ipv4_pref_len;
248 static int hf_option_s46_rule_ipv4_prefix;
249 static int hf_option_s46_rule_ipv6_pref_len;
250 static int hf_option_s46_rule_ipv6_prefix;
251 static int hf_option_s46_br_address;
252 static int hf_option_s46_dmr_pref_len;
253 static int hf_option_s46_dmr_prefix;
254 static int hf_option_s46_v4v6bind_ipv4_address;
255 static int hf_option_s46_v4v6bind_ipv6_pref_len;
256 static int hf_option_s46_v4v6bind_ipv6_prefix;
257 static int hf_option_s46_portparam_offset;
258 static int hf_option_s46_portparam_psid_len;
259 static int hf_option_s46_portparam_psid;
260 static int hf_client_link_layer_addr_hwtype;
261 static int hf_client_link_layer_addr;
262 static int hf_client_link_layer_addr_ether;
264 static int hf_dnr_svcpriority;
265 static int hf_dnr_auth_domain_name_len;
266 static int hf_dnr_auth_domain_name;
267 static int hf_dnr_addrs_len;
268 static int hf_dnr_addrs;
269 static int hf_dnr_svcparams;
270 static int hf_dnr_svcparams_key;
271 static int hf_dnr_svcparams_length;
272 static int hf_dnr_svcparams_value;
273 static int hf_dnr_svcparams_mandatory_key;
274 static int hf_dnr_svcparams_alpn_length;
275 static int hf_dnr_svcparams_alpn;
276 static int hf_dnr_svcparams_port;
277 static int hf_dnr_svcparams_ipv4hint_ip;
278 static int hf_dnr_svcparams_ipv6hint_ip;
279 static int hf_dnr_svcparams_dohpath;
280 static int hf_dnr_svcparams_odohconfig;
283 static int hf_dhcpv6_non_dns_encoded_name;
284 static int hf_dhcpv6_domain_field_len_exceeded;
285 static int hf_dhcpv6_decoded_portion;
286 static int hf_dhcpv6_encoded_fqdn_len_gt_255;
287 static int hf_dhcpv6_root_only_domain_name;
288 static int hf_dhcpv6_tld;
289 static int hf_dhcpv6_partial_name_preceded_by_fqdn;
291 static int ett_dhcpv6;
292 static int ett_dhcpv6_option;
293 static int ett_dhcpv6_option_vsoption;
294 static int ett_dhcpv6_vendor_option;
295 static int ett_dhcpv6_pkt_option;
296 static int ett_dhcpv6_userclass_option;
297 static int ett_dhcpv6_netserver_option;
298 static int ett_dhcpv6_tlv5_type;
299 static int ett_dhcpv6_sip_server_domain_search_list_option;
300 static int ett_dhcpv6_dns_domain_search_list_option;
301 static int ett_dhcpv6_nis_domain_name_option;
302 static int ett_dhcpv6_nisp_domain_name_option;
303 static int ett_dhcpv6_bcmcs_servers_domain_search_list_option;
304 static int ett_dhcpv6_s46_rule_flags;
305 static int ett_dhcpv6_failover_connect_flags;
306 static int ett_dhcpv6_failover_dns_flags;
307 static int ett_dhcpv6_failover_server_flags;
308 static int ett_dhcpv6_dnr_svcparams;
309 static int ett_clientfqdn_flags;
310 static int ett_clientfqdn_expert;
312 /* Expert fields relating to domain names */
313 static expert_field ei_dhcpv6_non_dns_encoded_name;
314 static expert_field ei_dhcpv6_domain_field_len_exceeded;
315 static expert_field ei_dhcpv6_encoded_fqdn_len_gt_255;
316 static expert_field ei_dhcpv6_root_only_domain_name;
317 static expert_field ei_dhcpv6_tld_lookup;
318 static expert_field ei_dhcpv6_partial_name_preceded_by_fqdn;
320 * Expert fields triggered in dhcpv6_option() and others */
321 static expert_field ei_dhcpv6_bogus_length;
322 static expert_field ei_dhcpv6_malformed_option;
323 static expert_field ei_dhcpv6_no_suboption_len;
324 static expert_field ei_dhcpv6_invalid_time_value;
325 static expert_field ei_dhcpv6_invalid_type;
326 static expert_field ei_dhcpv6_error_hopcount;
327 static expert_field ei_dhcpv6_clientfqdn_bad_msgtype;
328 static expert_field ei_dhcpv6_s_bit_should_be_zero;
331 static int hf_dhcpv6_bulk_leasequery_size;
332 static int hf_dhcpv6_bulk_leasequery_msgtype;
333 static int hf_dhcpv6_bulk_leasequery_reserved;
334 static int hf_dhcpv6_bulk_leasequery_trans_id;
336 static int ett_dhcpv6_bulk_leasequery;
337 static int ett_dhcpv6_bulk_leasequery_options;
339 static expert_field ei_dhcpv6_bulk_leasequery_bad_query_type;
340 static expert_field ei_dhcpv6_bulk_leasequery_bad_msg_type;
342 static dissector_handle_t dhcpv6_handle;
343 static dissector_handle_t dhcpv6_cablelabs_handle;
344 static dissector_handle_t dhcpv4_handle;
346 static dissector_table_t dhcpv6_enterprise_opts_dissector_table;
348 #define DHCPV6_HW_IS_ETHER(hwtype, length) ((hwtype == 1 || hwtype == 6) && length == 6)
350 #define TCP_PORT_DHCPV6_UPSTREAM 547
351 #define UDP_PORT_DHCPV6_RANGE "546-547" /* Downstream + Upstream */
353 #define DHCPV6_LEASEDURATION_INFINITY 0xffffffff
354 #define HOP_COUNT_LIMIT 32
356 /********************************************************************************************/
357 /********************************** MESSAGE TYPES *******************************************/
358 /********************************************************************************************/
359 /* SENT BY */
360 /* ------- */
361 #define SOLICIT 1 /* CLIENT */
362 #define ADVERTISE 2 /* SERVER(S) */
363 #define REQUEST 3 /* CLIENT */
364 #define CONFIRM 4 /* CLIENT */
365 #define RENEW 5 /* CLIENT */
366 #define REBIND 6 /* CLIENT */
367 #define REPLY 7 /* SERVER(S) */
368 #define RELEASE 8 /* CLIENT */
369 #define DECLINE 9 /* CLIENT */
370 #define RECONFIGURE 10 /* SERVER(S) (see 18-19) */
371 #define INFORMATION_REQUEST 11 /* CLIENT */
372 #define RELAY_FORW 12 /* relay agents */
373 #define RELAY_REPLY 13 /* relay agents */
374 #define LEASEQUERY 14 /* */
375 #define LEASEQUERY_REPLY 15 /* */
376 #define LEASEQUERY_DONE 16 /* */
377 #define LEASEQUERY_DATA 17 /* */
378 #define RECONFIGURE_REQUEST 18 /* SERVER (Server requests client to send requests) */
379 #define RECONFIGURE_REPLY 19 /* CLIENT (Client replies with the requested requests) */
381 #define DHCPV4_QUERY 20 /* [RFC7341] */
382 #define DHCPV4_RESPONSE 21 /* [RFC7341] */
383 /* TODO: add support the following message types
384 #define ACTIVELEASEQUERY 22 [RFC7653]
385 #define STARTTLS 23 [RFC7653]
386 #define BNDUPD 24 [RFC8156]
387 #define BNDREPLY 25 [RFC8156]
388 #define POOLREQ 26 [RFC8156]
389 #define POOLRESP 27 [RFC8156]
390 #define UPDREQ 28 [RFC8156]
391 #define UPDREQALL 29 [RFC8156]
392 #define UPDDONE 30 [RFC8156]
393 #define CONNECT 31 [RFC8156]
394 #define CONNECTREPLY 32 [RFC8156]
395 #define DISCONNECT 33 [RFC8156]
396 #define STATE 34 [RFC8156]
397 #define CONTACT 35 [RFC8156]
398 36-255 Unassigned
399 *********************************************************************************************/
401 /********************************************************************************************/
402 /**************************************** OPTIONS *******************************************/
403 /********************************************************************************************/
404 #define OPTION_CLIENTID 1
405 #define OPTION_SERVERID 2
406 #define OPTION_IA_NA 3
407 #define OPTION_IA_TA 4
408 #define OPTION_IAADDR 5
409 #define OPTION_ORO 6
410 #define OPTION_PREFERENCE 7
411 #define OPTION_ELAPSED_TIME 8
412 #define OPTION_RELAY_MSG 9
413 /* #define OPTION_SERVER_MSG 10 */
414 #define OPTION_AUTH 11
415 #define OPTION_UNICAST 12
416 #define OPTION_STATUS_CODE 13
417 #define OPTION_RAPID_COMMIT 14
418 #define OPTION_USER_CLASS 15
419 #define OPTION_VENDOR_CLASS 16
420 #define OPTION_VENDOR_OPTS 17
421 #define OPTION_INTERFACE_ID 18
422 #define OPTION_RECONF_MSG 19
423 #define OPTION_RECONF_ACCEPT 20
424 #define OPTION_SIP_SERVER_D 21 /* RFC 3319 */
425 #define OPTION_SIP_SERVER_A 22 /* RFC 3319 */
426 #define OPTION_DNS_SERVERS 23 /* RFC 3646 */
427 #define OPTION_DOMAIN_LIST 24 /* RFC 3646 */
428 #define OPTION_IA_PD 25 /* RFC 3633 */
429 #define OPTION_IAPREFIX 26 /* RFC 3633 */
430 #define OPTION_NIS_SERVERS 27 /* RFC 3898 */
431 #define OPTION_NISP_SERVERS 28 /* RFC 3898 */
432 #define OPTION_NIS_DOMAIN_NAME 29 /* RFC 3898 */
433 #define OPTION_NISP_DOMAIN_NAME 30 /* RFC 3898 */
434 #define OPTION_SNTP_SERVERS 31 /* RFC 4075 */
435 #define OPTION_LIFETIME 32 /* RFC 4242: OPTION_INFORMATION_REFRESH_TIME */
436 #define OPTION_BCMCS_SERVER_D 33 /* RFC 4280 */
437 #define OPTION_BCMCS_SERVER_A 34 /* RFC 4280 */
438 /* 35 - Unassigned */
439 #define OPTION_GEOCONF_CIVIC 36 /* RFC 4776 */
440 #define OPTION_REMOTE_ID 37 /* RFC 4649 */
441 #define OPTION_SUBSCRIBER_ID 38 /* RFC 4580 */
442 #define OPTION_CLIENT_FQDN 39 /* RFC 4704 */
443 #define OPTION_PANA_AGENT 40 /* RFC 5192 */
444 #define OPTION_TIME_ZONE 41 /* RFC 4833: OPTION_NEW_POSIX_TIMEZONE */
445 #define OPTION_TZDB 42 /* RFC 4833: OPTION_NEW_TZDB_TIMEZONE */
446 #define OPTION_ERO 43 /* RFC 4994 */
447 #define OPTION_LQ_QUERY 44 /* RFC 5007 */
448 #define OPTION_CLIENT_DATA 45 /* RFC 5007 */
449 #define OPTION_CLT_TIME 46 /* RFC 5007 */
450 #define OPTION_LQ_RELAY_DATA 47 /* RFC 5007 */
451 #define OPTION_LQ_CLIENT_LINK 48 /* RFC 5007 */
452 #define OPTION_MIP6_HNIDF 49 /* RFC 6610 */
453 #define OPTION_MIP6_VDINF 50 /* RFC 6610 */
454 #define OPTION_V6_LOST 51 /* RFC 5223 */
455 #define OPTION_CAPWAP_AC_V6 52 /* RFC 5417 */
456 #define OPTION_RELAYID 53 /* RFC 5460 */
457 #define OPTION_IPV6_ADDRESS_MOS 54 /* RFC 5678: OPTION-IPv6_Address-MoS */
458 #define OPTION_IPV6_FQDN_MOS 55 /* RFC 5678: OPTION-IPv6_FQDN-MoS */
459 #define OPTION_NTP_SERVER 56 /* RFC 5908 */
460 #define OPTION_V6_ACCESS_DOMAIN 57 /* RFC 5986 */
461 #define OPTION_SIP_UA_CS_LIST 58 /* RFC 6011 */
462 #define OPTION_BOOTFILE_URL 59 /* RFC 5970: OPT_BOOTFILE_URL */
463 #define OPTION_BOOTFILE_PARAM 60 /* RFC 5970: OPT_BOOTFILE_PARAM */
464 #define OPTION_CLIENT_ARCH_TYPE 61 /* RFC 5970 */
465 #define OPTION_NII 62 /* RFC 5970 */
466 #define OPTION_GEOLOCATION 63 /* RFC 6225 */
467 #define OPTION_AFTR_NAME 64 /* RFC 6334 */
468 #define OPTION_ERP_LOCAL_DOMAIN_NAME 65 /* RFC 6440 */
469 #define OPTION_RSOO 66 /* RFC 6422 */
470 #define OPTION_PD_EXCLUDE 67 /* RFC 6603 */
471 #define OPTION_VSS 68 /* RFC 6607 */
472 #define OPTION_MIP6_IDINF 69 /* RFC 6610 */
473 #define OPTION_MIP6_UDINF 70 /* RFC 6610 */
474 #define OPTION_MIP6_HNP 71 /* RFC 6610 */
475 #define OPTION_MIP6_HAA 72 /* RFC 6610 */
476 #define OPTION_MIP6_HAF 73 /* RFC 6610 */
477 #define OPTION_RDNSS_SELECTION 74 /* RFC 6731 */
478 #define OPTION_KRB_PRINCIPAL_NAME 75 /* RFC 6784 */
479 #define OPTION_KRB_REALM_NAME 76 /* RFC 6784 */
480 #define OPTION_KRB_DEFAULT_REALM_NAME 77 /* RFC 6784 */
481 #define OPTION_KRB_KDC 78 /* RFC 6784 */
482 #define OPTION_CLIENT_LINKLAYER_ADDR 79 /* RFC 6939 */
483 #define OPTION_LINK_ADDRESS 80 /* RFC 6977 */
484 #define OPTION_RADIUS 81 /* RFC 7037 */
485 #define OPTION_SOL_MAX_RT 82 /* RFC 7083 */
486 #define OPTION_INF_MAX_RT 83 /* RFC 7083 */
487 #define OPTION_ADDRSEL 84 /* RFC 7078 */
488 #define OPTION_ADDRSEL_TABLE 85 /* RFC 7078 */
489 #define OPTION_V6_PCP_SERVER 86 /* RFC 7291 */
490 #define OPTION_DHCPV4_MSG 87 /* RFC 7341 */
491 #define OPTION_DHCP4_O_DHCP6_SERVER 88 /* RFC 7341 */
492 #define OPTION_S46_RULE 89 /* RFC 7598 */
493 #define OPTION_S46_BR 90 /* RFC 7598 */
494 #define OPTION_S46_DMR 91 /* RFC 7598 */
495 #define OPTION_S46_V4V6BIND 92 /* RFC 7598 */
496 #define OPTION_S46_PORTPARAMS 93 /* RFC 7598 */
497 #define OPTION_S46_CONT_MAPE 94 /* RFC 7598 */
498 #define OPTION_S46_CONT_MAPT 95 /* RFC 7598 */
499 #define OPTION_S46_CONT_LW 96 /* RFC 7598 */
500 #define OPTION_4RD 97 /* RFC 7600 */
501 #define OPTION_4RD_MAP_RULE 98 /* RFC 7600 */
502 #define OPTION_4RD_NON_MAP_RULE 99 /* RFC 7600 */
503 #define OPTION_LQ_BASE_TIME 100 /* RFC 7653 */
504 #define OPTION_LQ_START_TIME 101 /* RFC 7653 */
505 #define OPTION_LQ_END_TIME 102 /* RFC 7653 */
506 #define OPTION_CAPTIVE_PORTAL 103 /* RFC 7710: DHCP Captive-Portal */
507 #define OPTION_MPL_PARAMETERS 104 /* RFC 7774 */
508 #define OPTION_ANI_ATT 105 /* RFC 7839 */
509 #define OPTION_ANI_NETWORK_NAME 106 /* RFC 7839 */
510 #define OPTION_ANI_AP_NAME 107 /* RFC 7839 */
511 #define OPTION_ANI_AP_BSSID 108 /* RFC 7839 */
512 #define OPTION_ANI_OPERATOR_ID 109 /* RFC 7839 */
513 #define OPTION_ANI_OPERATOR_REALM 110 /* RFC 7839 */
514 #define OPTION_S46_PRIORITY 111 /* RFC 8026 */
515 #define OPTION_MUDURL 112 /* MUDURL */
516 #define OPTION_V6_PREFIX64 113 /* RFC 8115 */
517 #define OPTION_F_BINDING_STATUS 114 /* RFC 8156 */
518 #define OPTION_F_CONNECT_FLAGS 115 /* RFC 8156 */
519 #define OPTION_F_DNS_REMOVAL_INFO 116 /* RFC 8156 */
520 #define OPTION_F_DNS_HOST_NAME 117 /* RFC 8156 */
521 #define OPTION_F_DNS_ZONE_NAME 118 /* RFC 8156 */
522 #define OPTION_F_DNS_FLAGS 119 /* RFC 8156 */
523 #define OPTION_F_EXPIRATION_TIME 120 /* RFC 8156 */
524 #define OPTION_F_MAX_UNACKED_BNDUPD 121 /* RFC 8156 */
525 #define OPTION_F_MCLT 122 /* RFC 8156 */
526 #define OPTION_F_PARTNER_LIFETIME 123 /* RFC 8156 */
527 #define OPTION_F_PARTNER_LIFETIME_SENT 124 /* RFC 8156 */
528 #define OPTION_F_PARTNER_DOWN_TIME 125 /* RFC 8156 */
529 #define OPTION_F_PARTNER_RAW_CLT_TIME 126 /* RFC 8156 */
530 #define OPTION_F_PROTOCOL_VERSION 127 /* RFC 8156 */
531 #define OPTION_F_KEEPALIVE_TIME 128 /* RFC 8156 */
532 #define OPTION_F_RECONFIGURE_DATA 129 /* RFC 8156 */
533 #define OPTION_F_RELATIONSHIP_NAME 130 /* RFC 8156 */
534 #define OPTION_F_SERVER_FLAGS 131 /* RFC 8156 */
535 #define OPTION_F_SERVER_STATE 132 /* RFC 8156 */
536 #define OPTION_F_START_TIME_OF_STATE 133 /* RFC 8156 */
537 #define OPTION_F_STATE_EXPIRATION_TIME 134 /* RFC 8156 */
538 #define OPTION_RELAY_PORT 135 /* RFC 8357 */
539 #define OPTION_V6_SZTP_REDIRECT 136 /* RFC-ietf-netconf-zerotouch-29 */
540 #define OPTION_S46_BIND_IPV6_PREFIX 137 /* RFC 8539 */
541 #define OPTION_IPv6_ADDRESS_ANDSF 143 /* RFC 6153 */
542 #define OPTION_V6_DNR 144 /* RFC 9463 */
544 /* temporary value until defined by IETF */
545 #define OPTION_MIP6_HA 165
546 #define OPTION_MIP6_HOA 166
547 #define OPTION_NAI 167
548 /********************************************************************************************/
550 #define DUID_LLT 1
551 #define DUID_EN 2
552 #define DUID_LL 3
553 #define DUID_UUID 4
555 static const value_string msgtype_vals[] = {
556 { SOLICIT, "Solicit" },
557 { ADVERTISE, "Advertise" },
558 { REQUEST, "Request" },
559 { CONFIRM, "Confirm" },
560 { RENEW, "Renew" },
561 { REBIND, "Rebind" },
562 { REPLY, "Reply" },
563 { RELEASE, "Release" },
564 { DECLINE, "Decline" },
565 { RECONFIGURE, "Reconfigure" },
566 { INFORMATION_REQUEST, "Information-request" },
567 { RELAY_FORW, "Relay-forw" },
568 { RELAY_REPLY, "Relay-reply" },
569 { LEASEQUERY, "Leasequery" },
570 { LEASEQUERY_REPLY, "Leasequery-reply" },
571 { LEASEQUERY_DONE, "Leasequery-done" },
572 { LEASEQUERY_DATA, "Leasequery-data" },
573 { RECONFIGURE_REQUEST, "Reconfigure-request" },
574 { RECONFIGURE_REPLY, "Reconfigure-reply" },
575 { DHCPV4_QUERY, "4o6 Query" },
576 { DHCPV4_RESPONSE, "4o6 Response" },
577 { 0, NULL }
579 static value_string_ext msgtype_vals_ext = VALUE_STRING_EXT_INIT(msgtype_vals);
581 static const value_string opttype_vals[] = {
582 { OPTION_CLIENTID, "Client Identifier" },
583 { OPTION_SERVERID, "Server Identifier" },
584 { OPTION_IA_NA, "Identity Association for Non-temporary Address" },
585 { OPTION_IA_TA, "Identity Association for Temporary Address" },
586 { OPTION_IAADDR, "IA Address" },
587 { OPTION_ORO, "Option Request" },
588 { OPTION_PREFERENCE, "Preference" },
589 { OPTION_ELAPSED_TIME, "Elapsed time" },
590 { OPTION_RELAY_MSG, "Relay Message" },
591 /* { OPTION_SERVER_MSG, "Server message" }, */
592 { OPTION_AUTH, "Authentication" },
593 { OPTION_UNICAST, "Server unicast" },
594 { OPTION_STATUS_CODE, "Status code" },
595 { OPTION_RAPID_COMMIT, "Rapid Commit" },
596 { OPTION_USER_CLASS, "User Class" },
597 { OPTION_VENDOR_CLASS, "Vendor Class" },
598 { OPTION_VENDOR_OPTS, "Vendor-specific Information" },
599 { OPTION_INTERFACE_ID, "Interface-Id" },
600 { OPTION_RECONF_MSG, "Reconfigure Message" },
601 { OPTION_RECONF_ACCEPT, "Reconfigure Accept" },
602 { OPTION_SIP_SERVER_D, "SIP Server Domain Name List" },
603 { OPTION_SIP_SERVER_A, "SIP Servers IPv6 Address List" },
604 { OPTION_DNS_SERVERS, "DNS recursive name server" },
605 { OPTION_DOMAIN_LIST, "Domain Search List" },
606 { OPTION_IA_PD, "Identity Association for Prefix Delegation" },
607 { OPTION_IAPREFIX, "IA Prefix" },
608 { OPTION_NIS_SERVERS, "Network Information Server" },
609 { OPTION_NISP_SERVERS, "Network Information Server V2" },
610 { OPTION_NIS_DOMAIN_NAME, "Network Information Server Domain Name" },
611 { OPTION_NISP_DOMAIN_NAME, "Network Information Server V2 Domain Name" },
612 { OPTION_SNTP_SERVERS, "Simple Network Time Protocol Server" },
613 { OPTION_LIFETIME, "Lifetime" },
614 { OPTION_BCMCS_SERVER_D, "BCMCS Server Domain" },
615 { OPTION_BCMCS_SERVER_A, "BCMCS Servers IPv6 Address List" },
616 { OPTION_GEOCONF_CIVIC, "Geoconf Civic Address" },
617 { OPTION_REMOTE_ID, "Remote Identifier" },
618 { OPTION_SUBSCRIBER_ID, "Subscriber Identifier" },
619 { OPTION_CLIENT_FQDN, "Client Fully Qualified Domain Name" },
620 { OPTION_PANA_AGENT, "PANA Agents IPv6 Address List" },
621 { OPTION_TIME_ZONE, "Time Zone" },
622 { OPTION_TZDB, "Time Zone Database" },
623 { OPTION_ERO, "Echo Request Option" },
624 { OPTION_LQ_QUERY, "Leasequery Query" },
625 { OPTION_CLIENT_DATA, "Leasequery Client Data" },
626 { OPTION_CLT_TIME, "Client Last Transaction Time" },
627 { OPTION_LQ_RELAY_DATA, "Leasequery Relay Data" },
628 { OPTION_LQ_CLIENT_LINK, "Leasequery Client Link Address List" },
629 { OPTION_MIP6_HNIDF, "Home Network Identifier FQDN" },
630 { OPTION_MIP6_VDINF, "Visited Home Network Information" },
631 { OPTION_V6_LOST, "LoST Server" },
632 { OPTION_CAPWAP_AC_V6, "CAPWAP Access Controllers" },
633 { OPTION_RELAYID, "Relay-ID" },
634 { OPTION_IPV6_ADDRESS_MOS, "MoS IPv6 Address" },
635 { OPTION_IPV6_FQDN_MOS, "MoS Domain Name List" },
636 { OPTION_NTP_SERVER, "NTP Server" },
637 { OPTION_V6_ACCESS_DOMAIN, "Access Network Domain Name" },
638 { OPTION_SIP_UA_CS_LIST, "SIP User Agent Configuration Service Domains" },
639 { OPTION_BOOTFILE_URL, "Boot File URL" },
640 { OPTION_BOOTFILE_PARAM, "Boot File Parameters" },
641 { OPTION_CLIENT_ARCH_TYPE, "Client System Architecture Type" },
642 { OPTION_NII, "Client Network Interface Identifier" },
643 { OPTION_GEOLOCATION, "Geolocation" },
644 { OPTION_AFTR_NAME, "Dual-Stack Lite AFTR Name" },
645 { OPTION_ERP_LOCAL_DOMAIN_NAME, "ERP Local Domain Name" },
646 { OPTION_RSOO, "Relay-Supplied Options" },
647 { OPTION_PD_EXCLUDE, "Prefix Exclude" },
648 { OPTION_VSS, "Virtual Subnet Selection" },
649 { OPTION_MIP6_IDINF, "Identified Home Network Information" },
650 { OPTION_MIP6_UDINF, "Unrestricted Home Network Information" },
651 { OPTION_MIP6_HNP, "Home Network Prefix" },
652 { OPTION_MIP6_HAA, "Home Agent Address" },
653 { OPTION_MIP6_HAF, "Home Agent FQDN" },
654 { OPTION_RDNSS_SELECTION, "RDNSS Selection" },
655 { OPTION_KRB_PRINCIPAL_NAME, "Kerberos Principal Name" },
656 { OPTION_KRB_REALM_NAME, "Kerberos Realm Name" },
657 { OPTION_KRB_DEFAULT_REALM_NAME, "Kerberos Default Realm Name" },
658 { OPTION_KRB_KDC, "Kerberos KDC" },
659 { OPTION_CLIENT_LINKLAYER_ADDR, "Client Link-Layer Address" },
660 { OPTION_LINK_ADDRESS, "Link Address" },
661 { OPTION_RADIUS, "RADIUS" },
662 { OPTION_SOL_MAX_RT, "SOL_MAX_RT" },
663 { OPTION_INF_MAX_RT, "INF_MAX_RT" },
664 { OPTION_ADDRSEL, "Address Selection" },
665 { OPTION_ADDRSEL_TABLE, "Address Selection table" },
666 { OPTION_V6_PCP_SERVER, "PCP Server" },
667 { OPTION_DHCPV4_MSG, "DHCPv4 Message" },
668 { OPTION_DHCP4_O_DHCP6_SERVER, "DHCP 4o6 Servers Address" },
669 { OPTION_S46_RULE, "S46 Rule" },
670 { OPTION_S46_BR, "S46 BR" },
671 { OPTION_S46_DMR, "S46 DMR" },
672 { OPTION_S46_V4V6BIND, "S46 IPv4/IPv6 Address Binding" },
673 { OPTION_S46_PORTPARAMS, "S46 Port Parameters" },
674 { OPTION_S46_CONT_MAPE, "S46 MAP-E Container" },
675 { OPTION_S46_CONT_MAPT, "S46 MAP-T Container" },
676 { OPTION_S46_CONT_LW, "S46 Lightweight 4over6 Container" },
677 { OPTION_4RD, "4rd Options" },
678 { OPTION_4RD_MAP_RULE, "4rd Mapping Rule" },
679 { OPTION_4RD_NON_MAP_RULE, "4rd Non-Mapping Rule" },
680 { OPTION_LQ_BASE_TIME, "LQ Server Base Time" },
681 { OPTION_LQ_START_TIME, "LQ Server Query Start Time" },
682 { OPTION_LQ_END_TIME, "LQ Server Query End Time" },
683 { OPTION_CAPTIVE_PORTAL, "Captive Portal" },
684 { OPTION_MPL_PARAMETERS, "MPL Parameter Configuration" },
685 { OPTION_ANI_ATT, "Access Technology Type" },
686 { OPTION_ANI_NETWORK_NAME, "Access Network Name" },
687 { OPTION_ANI_AP_NAME, "Access Point Name" },
688 { OPTION_ANI_AP_BSSID, "Access Point BSSID" },
689 { OPTION_ANI_OPERATOR_ID, "Access Network Operator ID" },
690 { OPTION_ANI_OPERATOR_REALM, "Access Network Operator Realm" },
691 { OPTION_S46_PRIORITY, "S46 Priority" },
692 { OPTION_MUDURL, "Manufacturer Usage Description" },
693 { OPTION_V6_PREFIX64, "IPv4/IPv6 Multicast Prefixes" },
694 { OPTION_F_BINDING_STATUS, "Failover Binding Status" },
695 { OPTION_F_CONNECT_FLAGS, "Failover Connect Flags" },
696 { OPTION_F_DNS_REMOVAL_INFO, "Failover DNS Removal Info" },
697 { OPTION_F_DNS_HOST_NAME, "Failover DNS Hostname" },
698 { OPTION_F_DNS_ZONE_NAME, "Failover DNS Zone Name" },
699 { OPTION_F_DNS_FLAGS, "Failover DNS Flags" },
700 { OPTION_F_EXPIRATION_TIME, "Failover Expiration Time" },
701 { OPTION_F_MAX_UNACKED_BNDUPD, "Failover Maximum Number Unacked BNDUPD Messages" },
702 { OPTION_F_MCLT, "Failover Maximum Client Lead Time (MCLT)" },
703 { OPTION_F_PARTNER_LIFETIME, "Failover Partner Lifetime" },
704 { OPTION_F_PARTNER_LIFETIME_SENT,"Failover Partner Lifetime Sent" },
705 { OPTION_F_PARTNER_DOWN_TIME, "Failover Partner Down Time" },
706 { OPTION_F_PARTNER_RAW_CLT_TIME, "Failover Partner Raw Client Time" },
707 { OPTION_F_PROTOCOL_VERSION, "Failover Protocol Version" },
708 { OPTION_F_KEEPALIVE_TIME, "Failover Keepalive Time" },
709 { OPTION_F_RECONFIGURE_DATA, "Failover Reconfigure Data" },
710 { OPTION_F_RELATIONSHIP_NAME, "Failover Relationship Name" },
711 { OPTION_F_SERVER_FLAGS, "Failover Server Flags" },
712 { OPTION_F_SERVER_STATE, "Failover Server State" },
713 { OPTION_F_START_TIME_OF_STATE, "Failover Start Time of State" },
714 { OPTION_F_STATE_EXPIRATION_TIME,"Failover State Expiration Time" },
715 { OPTION_RELAY_PORT, "Relay Source Port" },
716 { OPTION_V6_SZTP_REDIRECT, "SZTP Redirect" },
717 { OPTION_S46_BIND_IPV6_PREFIX, "Softwire Source Binding Prefix Hint" },
718 { OPTION_IPv6_ADDRESS_ANDSF, "ANDSF IPv6 Address" },
719 { OPTION_V6_DNR, "Discovery of Network DNS Resolvers" },
720 { OPTION_MIP6_HA, "Mobile IPv6 Home Agent" },
721 { OPTION_MIP6_HOA, "Mobile IPv6 Home Address" },
722 { OPTION_NAI, "Network Access Identifier" },
723 { 0, NULL }
725 static value_string_ext opttype_vals_ext = VALUE_STRING_EXT_INIT(opttype_vals);
727 static const value_string infinity_val[] = {
728 { DHCPV6_LEASEDURATION_INFINITY, "infinity" },
729 { 0, NULL }
732 static const value_string statuscode_vals[] =
734 { 0, "Success" },
735 { 1, "UnspecFail" },
736 { 2, "NoAddrAvail" },
737 { 3, "NoBinding" },
738 { 4, "NotOnLink" },
739 { 5, "UseMulticast" },
740 { 6, "NoPrefixAvail" },
741 { 7, "UnknownQueryType" },
742 { 8, "MalformedQuery" },
743 { 9, "NotConfigured" },
744 {10, "NotAllowed" },
745 {11, "QueryTerminated" },
746 {12, "DataMissing" }, /* RFC 7653 */
747 {13, "CatchUpComplete" }, /* RFC 7653 */
748 {14, "NotSupported" }, /* RFC 7653 */
749 {15, "TLSConnectionRefused" }, /* RFC 7653 */
750 {0, NULL }
752 static value_string_ext statuscode_vals_ext = VALUE_STRING_EXT_INIT(statuscode_vals);
754 static const value_string duidtype_vals[] =
756 { DUID_LLT, "link-layer address plus time" },
757 { DUID_EN, "assigned by vendor based on Enterprise number" },
758 { DUID_LL, "link-layer address" },
759 { DUID_UUID, "Universally Unique IDentifier (UUID)" },
760 { 0, NULL }
763 #define NTP_SUBOPTION_SRV_ADDR 1
764 #define NTP_SUBOPTION_MC_ADDR 2
765 #define NTP_SUBOPTION_SRV_FQDN 3
767 static const value_string ntp_server_opttype_vals[] =
769 { NTP_SUBOPTION_SRV_ADDR, "NTP Server Address" },
770 { NTP_SUBOPTION_MC_ADDR, "NTP Multicast Address" },
771 { NTP_SUBOPTION_SRV_FQDN, "NTP Server FQDN" },
773 { 0, NULL }
777 static const true_false_string fqdn_n = {
778 "Server SHOULD NOT perform PTR RR updates",
779 "Server SHOULD perform PTR RR updates"
782 static const true_false_string fqdn_o = {
783 "Server HAS overridden client's S bit preference",
784 "Server HAS NOT overridden client's S bit preference"
787 static const true_false_string fqdn_s = {
788 "Server SHOULD perform AAAA RR updates",
789 "Server SHOULD NOT perform AAAA RR updates"
792 #define LQ_QUERY_ADDRESS 1
793 #define LQ_QUERY_CLIENTID 2
794 #define LQ_QUERY_RELAYID 3
795 #define LQ_QUERY_LINK_ADDRESS 4
796 #define LQ_QUERY_REMOTEID 5
798 static const value_string lq_query_vals[] = {
799 { LQ_QUERY_ADDRESS, "by-address" },
800 { LQ_QUERY_CLIENTID, "by-clientID" },
801 { LQ_QUERY_RELAYID, "by-relayID" },
802 { LQ_QUERY_LINK_ADDRESS, "by-linkAddress" },
803 { LQ_QUERY_REMOTEID, "by-remoteID" },
804 { 0, NULL },
807 /* CableLabs Common Vendor Specific Options */
808 #define CL_OPTION_ORO 0x0001 /* 1 */
809 #define CL_OPTION_DEVICE_TYPE 0x0002 /* 2 */
810 #define CL_OPTION_EMBEDDED_COMPONENT_LIST 0x0003 /* 3 */
811 #define CL_OPTION_DEVICE_SERIAL_NUMBER 0x0004 /* 4 */
812 #define CL_OPTION_HARDWARE_VERSION_NUMBER 0x0005 /* 5 */
813 #define CL_OPTION_SOFTWARE_VERSION_NUMBER 0x0006 /* 6 */
814 #define CL_OPTION_BOOT_ROM_VERSION 0x0007 /* 7 */
815 #define CL_OPTION_VENDOR_OUI 0x0008 /* 8 */
816 #define CL_OPTION_MODEL_NUMBER 0x0009 /* 9 */
817 #define CL_OPTION_VENDOR_NAME 0x000a /* 10 */
818 /* 11-32 are currently reserved */
819 #define CL_OPTION_TFTP_SERVERS 0x0020 /* 32 */
820 #define CL_OPTION_CONFIG_FILE_NAME 0x0021 /* 33 */
821 #define CL_OPTION_SYSLOG_SERVERS 0x0022 /* 34 */
822 #define CL_OPTION_TLV5 0x0023 /* 35 */
823 #define CL_OPTION_DEVICE_ID 0x0024 /* 36 */
824 #define CL_OPTION_RFC868_SERVERS 0x0025 /* 37 */
825 #define CL_OPTION_TIME_OFFSET 0x0026 /* 38 */
826 #define CL_OPTION_IP_PREF 0x0027 /* 39 */
827 #define CL_OPTION_CCAP_CORES 0x003D /* 61 */
829 /** CableLabs DOCSIS Project Vendor Specific Options */
830 #define CL_OPTION_DOCS_CMTS_CAP 0x0401 /* 1025 */
831 #define CL_CM_MAC_ADDR 0x0402 /* 1026 */
832 #define CL_EROUTER_CONTAINER_OPTION 0x403 /* 1027 */
834 /** CableLabs PacketCable Project Vendor Specific Options **/
835 #define CL_OPTION_CCC 0x087a /* 2170 */
836 #define CL_OPTION_CCCV6 0x087b /* 2171 */
837 #define CL_OPTION_CORRELATION_ID 0x087c /* 2172 */
839 /** CableLabs TLVs for DOCS_CMTS_CAP Vendor Option **/
840 #define CL_OPTION_DOCS_CMTS_TLV_VERS_NUM 0x01 /* 1 */
841 #define CL_OPTION_DOCS_DPOE_TLV_VERS_NUM 0x02 /* 2 */
843 static const value_string cl_vendor_subopt_values[] = {
844 /* 1 */ { CL_OPTION_ORO, "Option Request = " },
845 /* 2 */ { CL_OPTION_DEVICE_TYPE, "Device Type = " },
846 /* 3 */ { CL_OPTION_EMBEDDED_COMPONENT_LIST, "Embedded Components = " },
847 /* 4 */ { CL_OPTION_DEVICE_SERIAL_NUMBER, "Serial Number = " },
848 /* 5 */ { CL_OPTION_HARDWARE_VERSION_NUMBER, "Hardware Version = " },
849 /* 6 */ { CL_OPTION_SOFTWARE_VERSION_NUMBER, "Software Version = " },
850 /* 7 */ { CL_OPTION_BOOT_ROM_VERSION, "Boot ROM Version = " },
851 /* 8 */ { CL_OPTION_VENDOR_OUI, "Organization Unique Identifier = " },
852 /* 9 */ { CL_OPTION_MODEL_NUMBER, "Model Number = " },
853 /* 10 */ { CL_OPTION_VENDOR_NAME, "Vendor Name = " },
854 /* 32 */ { CL_OPTION_TFTP_SERVERS, "TFTP Server Addresses : " },
855 /* 33 */ { CL_OPTION_CONFIG_FILE_NAME, "Configuration File Name = " },
856 /* 34 */ { CL_OPTION_SYSLOG_SERVERS, "Syslog Servers : " },
857 /* 35 */ { CL_OPTION_TLV5, "TLV5 = " },
858 /* 36 */ { CL_OPTION_DEVICE_ID, "Device Identifier = " },
859 /* 37 */ { CL_OPTION_RFC868_SERVERS, "Time Protocol Servers : " },
860 /* 38 */ { CL_OPTION_TIME_OFFSET, "Time Offset = " },
861 /* 39 */ { CL_OPTION_IP_PREF, "IP preference : " },
862 /* 61 */ { CL_OPTION_CCAP_CORES, "CCAP-CORES : " },
863 /* 1025 */ { CL_OPTION_DOCS_CMTS_CAP, "CMTS Capabilities Option : " },
864 /* 1026 */ { CL_CM_MAC_ADDR, "CM MAC Address Option = " },
865 /* 1027 */ { CL_EROUTER_CONTAINER_OPTION, "eRouter Container Option : " },
866 /* 2170 */ { CL_OPTION_CCC, "CableLabs Client Configuration : " },
867 /* 2171 */ { CL_OPTION_CCCV6, "CableLabs Client Configuration IPv6 : " },
868 /* 2172 */ { CL_OPTION_CORRELATION_ID, "CableLabs Correlation ID = " },
869 { 0, NULL }
871 static value_string_ext cl_vendor_subopt_values_ext = VALUE_STRING_EXT_INIT(cl_vendor_subopt_values);
873 /* 17:2170: CL_OPTION_CCC */
874 #define PKT_CCC_PRI_DHCP 0x0001
875 #define PKT_CCC_SEC_DHCP 0x0002
877 static const value_string pkt_ccc_opt_vals[] = {
878 { PKT_CCC_PRI_DHCP, "TSP's Primary DHCP Server" },
879 { PKT_CCC_SEC_DHCP, "TSP's Secondary DHCP Server" },
880 { 0, NULL },
883 /* 17:2171: CL_OPTION_CCCV6 */
884 #define PKT_CCCV6_PRI_DSS 0x0001
885 #define PKT_CCCV6_SEC_DSS 0x0002
886 #define PKT_CCCV6_IETF_PROV_SRV 0x0003
887 #define PKT_CCCV6_IETF_AS_KRB 0x0004
888 #define PKT_CCCV6_IETF_AP_KRB 0x0005
889 #define PKT_CCCV6_KRB_REALM 0x0006
890 #define PKT_CCCV6_TGT_FLAG 0x0007
891 #define PKT_CCCV6_PROV_TIMER 0x0008
892 #define PKT_CCCV6_IETF_SEC_TKT 0x0009
893 /** 10 -255 Reserved for future extensions **/
895 static const value_string pkt_cccV6_opt_vals[] = {
896 { PKT_CCCV6_PRI_DSS, "TSP's Primary DHCPv6 Server Selector ID" },
897 { PKT_CCCV6_SEC_DSS, "TSP's Secondary DHCPv6 Server Selector ID " },
898 { PKT_CCCV6_IETF_PROV_SRV, "TSP's Provisioning Server" },
899 { PKT_CCCV6_IETF_AS_KRB, "TSP's AS-REQ/AS-REP Backoff and Retry" },
900 { PKT_CCCV6_IETF_AP_KRB, "TSP's AP-REQ/AP-REP Backoff and Retry" },
901 { PKT_CCCV6_KRB_REALM, "TSP's Kerberos Realm Name" },
902 { PKT_CCCV6_TGT_FLAG, "TSP's Ticket Granting Server Utilization" },
903 { PKT_CCCV6_PROV_TIMER, "TSP's Provisioning Timer Value" },
904 { PKT_CCCV6_IETF_SEC_TKT, "PacketCable Security Ticket Control" },
905 { 0, NULL }
907 static value_string_ext pkt_cccV6_opt_vals_ext = VALUE_STRING_EXT_INIT(pkt_cccV6_opt_vals);
909 static const value_string pkt_cccV6_prov_srv_type_vals[] = {
910 { 0, "FQDN" },
911 { 1, "IPv6" },
912 { 0, NULL },
915 #if 0
916 static const value_string sec_tcm_vals[] = {
917 { 1 << 0, "PacketCable Provisioning Server" },
918 { 1 << 1, "PacketCable Call Manager Servers" },
919 { 0, NULL },
921 #endif
923 static const value_string modem_capabilities_encoding [] = {
924 { 1, "Concatenation Support" },
925 { 2, "DOCSIS Version" },
926 { 3, "Fragmentation Support" },
927 { 4, "Payload Header Suppression Support" },
928 { 5, "IGMP Support" },
929 { 6, "Privacy Support" },
930 { 7, "Downstream SAID Support" },
931 { 8, "Upstream Service Flow Support" },
932 { 9, "Optional Filtering Support" },
933 { 10, "Transmit Pre-Equalizer Taps per Modulation Interval" },
934 { 11, "Number of Transmit Equalizer Taps" },
935 { 12, "DCC Support" },
936 { 13, "IP Filters Support" },
937 { 14, "LLC Filters Support" },
938 { 15, "Expanded Unicast SID Space" },
939 { 16, "Ranging Hold-Off Support" },
940 { 17, "L2VPN Capability" },
941 { 18, "L2VPN eSAFE Host Capability" },
942 { 19, "Downstream Unencrypted Traffic (DUT) Filtering" },
943 { 20, "Upstream Frequency Range Support" },
944 { 21, "Upstream Symbol Rate Support" },
945 { 22, "Selectable Active Code Mode 2 Support" },
946 { 23, "Code Hopping Mode 2 Support" },
947 { 24, "Multiple Transmit Channel Support" },
948 { 25, "5.12 Msps UpstreamTransmit Channel Support" },
949 { 26, "2.56 Msps Upstream Transmit Channel Support" },
950 { 27, "Total SID Cluster Support" },
951 { 28, "SID Clusters per Service Flow Support" },
952 { 29, "Multiple Receive Channel Support" },
953 { 30, "Total Downstream Service ID (DSID) Support" },
954 { 31, "Resequencing Downstream Service ID (DSID) Support" },
955 { 32, "Multicast Downstream Service ID (DSID) Support" },
956 { 33, "Multicast DSID Forwarding" },
957 { 34, "Frame Control Type Forwarding Capability" },
958 { 35, "DPV Capability" },
959 { 36, "Unsolicited Grant Service/Upstream Service Flow Support" },
960 { 37, "MAP and UCD Receipt Support" },
961 { 38, "Upstream Drop Classifier Support" },
962 { 39, "IPv6 Support" },
963 { 40, "Extended Upstream Transmit Power Capability" },
964 { 41, "Optional 802.1ad, 802.1ah, MPLS Classification Support" },
965 { 42, "D-ONU Capabilities Encoding" },
966 { 43, "Reserved" },
967 { 44, "Energy Management Capabilities" },
968 /* Added TLV5.45-62 from CL-SP-CANN-I18-180509 */
969 { 45, "C-DOCSIS Capability Encoding" },
970 { 46, "CM-STATUS-ACK" },
971 { 47, "Energy Management Preferences" },
972 { 48, "Extended Packet Length Support Capability" },
973 { 49, "Multiple Receive OFDM Channel Support" },
974 { 50, "Multiple Transmit OFDMA Channel Support" },
975 { 51, "Downstream OFDM Profile Support" },
976 { 52, "Downstream OFDM channel subcarrier QAM modulation support" },
977 { 53, "Upstream OFDM channel subcarrier QAM modulation support" },
978 { 54, "Downstream Lower Band Edge Support" },
979 { 55, "Downstream Upper Band Edge Support" },
980 { 56, "Upstream Upper Band Edge Support" },
981 { 57, "DOCSIS Time Protocol Support" },
982 { 58, "DOCSIS Time Protocol Performance Support" },
983 { 59, "Pmax" },
984 { 60, "Diplexer Downstream Lower Band Edge" },
985 { 61, "Diplexer Downstream Upper Band Edge" },
986 { 62, "Diplexer Upstream Upper Band Edge" },
987 { 0, NULL },
989 static value_string_ext modem_capabilities_encoding_ext = VALUE_STRING_EXT_INIT(modem_capabilities_encoding);
991 static const value_string eue_capabilities_encoding [] = {
992 { 1, "PacketCable Version" },
993 { 2, "Number Of Telephony Endpoints" },
994 { 3, "TGT Support" },
995 { 4, "HTTP Download File Access Method Support" },
996 { 5, "MTA-24 Event SYSLOG Notification Support" },
997 { 6, "NCS Service Flow Support" },
998 { 7, "Primary Line Support" },
999 { 8, "Vendor Specific TLV Type(s)" },
1000 { 9, "NVRAM Ticket/Ticket Information Storage Support" },
1001 { 10, "Provisioning Event Reporting Support" },
1002 { 11, "Supported CODEC(s)" },
1003 { 12, "Silence Suppression Support" },
1004 { 13, "Echo Cancellation Support" },
1005 { 14, "RSVP Support" },
1006 { 15, "UGS-AD Support" },
1007 { 16, "MTA's \"ifIndex\" starting number in \"ifTable\"" },
1008 { 17, "Provisioning Flow Logging Support" },
1009 { 18, "Supported Provisioning Flows" },
1010 { 19, "T38 Version Support" },
1011 { 20, "T38 Error Correction Support" },
1012 { 21, "RFC2833 DTMF Support" },
1013 { 22, "Voice Metrics Support" },
1014 { 23, "Device MIB Support" },
1015 { 24, "Multiple Grants Per Interval Support" },
1016 { 25, "V.152 Support" },
1017 { 26, "Certificate Bootstrapping Support" },
1018 { 38, "IP Address Provisioning Capability" },
1019 { 0, NULL },
1021 static value_string_ext eue_capabilities_encoding_ext = VALUE_STRING_EXT_INIT(eue_capabilities_encoding);
1023 static const value_string s46_opt_code_vals[] = {
1024 { 64, "DS-Lite" },
1025 { 88, "DHCPv4 over DHCPv6" },
1026 { 94, "MAP-E" },
1027 { 95, "MAP-T" },
1028 { 96, "Lightweight 4over6" },
1029 { 0, NULL },
1032 static const value_string failover_binding_status_vals[] = {
1033 { 0, "reserved" },
1034 { 1, "ACTIVE" },
1035 { 2, "EXPIRED" },
1036 { 3, "RELEASED" },
1037 { 4, "PENDING-FREE" },
1038 { 5, "FREE" },
1039 { 6, "FREE-BACKUP" },
1040 { 7, "ABANDONED" },
1041 { 8, "RESET" },
1042 { 0, NULL },
1045 static const value_string failover_server_state_vals[] = {
1046 { 0, "reserved" },
1047 { 1, "Startup state (1)" },
1048 { 2, "Normal state" },
1049 { 3, "Communications interrupted" },
1050 { 4, "Partner down" },
1051 { 5, "Synchronizing" },
1052 { 6, "Recovering bindings from partner" },
1053 { 7, "Waiting out MCLT after RECOVER" },
1054 { 8, "Interlock state prior to NORMAL" },
1055 { 9, "Comm. failed during resolution" },
1056 { 10, "Primary resolved its conflicts" },
1057 { 0, NULL },
1060 static int * const dhcpv6_failover_connect_flags_fields[] = {
1061 &hf_option_failover_connect_reserved_flag,
1062 &hf_option_failover_connect_f_flag,
1063 NULL
1066 static int * const dhcpv6_failover_dns_flags_fields[] = {
1067 &hf_option_failover_dns_reserved_flag,
1068 &hf_option_failover_dns_u_flag,
1069 &hf_option_failover_dns_s_flag,
1070 &hf_option_failover_dns_r_flag,
1071 &hf_option_failover_dns_f_flag,
1072 NULL
1075 static int * const dhcpv6_failover_server_flags_fields[] = {
1076 &hf_option_failover_server_reserved_flag,
1077 &hf_option_failover_server_a_flag,
1078 &hf_option_failover_server_s_flag,
1079 &hf_option_failover_server_c_flag,
1080 NULL
1083 typedef struct hopcount_info_t {
1084 uint8_t hopcount;
1085 proto_item *pi;
1086 bool relay_message_previously_detected;
1087 } hopcount_info;
1089 static int * const dhcpv6_s46_rule_flags_fields[] = {
1090 &hf_option_s46_rule_reserved_flag,
1091 &hf_option_s46_rule_fmr_flag,
1092 NULL
1097 * Service Parameters, defined in RFC9460. Now IANA maintains registry
1098 * for it, available at https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml.
1099 * The initial entries were defined in https://datatracker.ietf.org/doc/html/rfc9460#section-14.3.2,
1100 * but there are now more RFCs that added to that list. The IANA registry
1101 * is the ultimate, up to date source.
1103 * These are used in DNS, but also in DHCPv4 and DHCPv6 DNR options.
1104 * NOTE: Not all values are permitted in DHCP. The RFC9463 only mentions
1105 * alpn, port, and dohpath. ipv4hint and ipv6hint are explicitly forbidden
1106 * (there's dedicated field in the DHCP options for them).
1109 #define DNR_SVCPARAMS_KEY_MANDATORY 0 /* RFC 9460 */
1110 #define DNR_SVCPARAMS_KEY_ALPN 1 /* RFC 9460 */
1111 #define DNR_SVCPARAMS_KEY_NOALPN 2 /* RFC 9460 */
1112 #define DNR_SVCPARAMS_KEY_PORT 3 /* RFC 9460 */
1113 #define DNR_SVCPARAMS_KEY_IPV4HINT 4 /* RFC 9460 */
1114 #define DNR_SVCPARAMS_KEY_ECH 5 /* RFC 9460, but really waiting for draft-ietf-tls-svcb-ech */
1115 #define DNR_SVCPARAMS_KEY_IPV6HINT 6 /* RFC 9460 */
1116 #define DNR_SVCPARAMS_KEY_DOHPATH 7 /* RFC 9461 */
1117 #define DNR_SVCPARAMS_KEY_OHTTP 8 /* RFC 9540 */
1118 #define DNR_SVCPARAMS_KEY_RESERVED 65535
1121 * Service parameters Parameter Registry.
1123 static const value_string dnr_svcparams_key_vals[] = {
1124 { DNR_SVCPARAMS_KEY_MANDATORY, "mandatory" },
1125 { DNR_SVCPARAMS_KEY_ALPN, "alpn" },
1126 { DNR_SVCPARAMS_KEY_NOALPN, "no-default-alpn" },
1127 { DNR_SVCPARAMS_KEY_PORT, "port" },
1128 { DNR_SVCPARAMS_KEY_IPV4HINT, "ipv4hint" },
1129 { DNR_SVCPARAMS_KEY_ECH, "ech" },
1130 { DNR_SVCPARAMS_KEY_IPV6HINT, "ipv6hint" },
1131 { DNR_SVCPARAMS_KEY_DOHPATH, "dohpath" },
1132 { DNR_SVCPARAMS_KEY_OHTTP, "ohttp" },
1133 { DNR_SVCPARAMS_KEY_RESERVED, "key65535" },
1134 { 0, NULL }
1138 static void
1139 initialize_hopount_info(hopcount_info *hpi) {
1140 memset(hpi, 0, sizeof(hopcount_info));
1143 static void
1144 dissect_dhcpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1145 int off, int eoff, hopcount_info hpi);
1147 static int
1148 dissect_dhcpv6_s46_ipv6_prefix(tvbuff_t *tvb, int hf, int offset, int prefix_length, proto_tree *tree);
1151 static int
1152 dissect_packetcable_ccc_option(proto_tree *v_tree, proto_item *v_item, packet_info *pinfo, tvbuff_t *tvb, int optoff,
1153 int optend)
1155 /** THE ENCODING OF THIS SUBOPTION HAS CHANGED FROM DHCPv4
1156 the code and length fields have grown from a single octet to
1157 two octets each. **/
1158 int suboptoff = optoff;
1159 uint16_t subopt, subopt_len;
1160 proto_item *vti;
1161 proto_tree *pkt_s_tree;
1163 subopt = tvb_get_ntohs(tvb, optoff);
1164 suboptoff += 2;
1166 subopt_len = tvb_get_ntohs(tvb, suboptoff);
1167 suboptoff += 2;
1169 /* There must be at least five octets left to be a valid sub element */
1170 if (optend <= 0) {
1171 expert_add_info_format(pinfo, v_item, &ei_dhcpv6_no_suboption_len, "Sub element %d: no room left in option for suboption length", subopt);
1172 return (suboptoff - optoff);
1174 /* g_print("dissect packetcable ccc option subopt_len=%d optend=%d\n\n", subopt_len, optend); */
1176 vti = proto_tree_add_item(v_tree, hf_packetcable_ccc_suboption, tvb, optoff, 2, ENC_BIG_ENDIAN);
1177 pkt_s_tree = proto_item_add_subtree(vti, ett_dhcpv6_pkt_option);
1179 switch (subopt) {
1180 case PKT_CCC_PRI_DHCP: /* IPv4 address values */
1181 if (subopt_len == 4) {
1182 proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_pri_dhcp, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
1184 else {
1185 expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
1188 suboptoff += subopt_len;
1189 break;
1190 case PKT_CCC_SEC_DHCP:
1191 if (subopt_len == 4) {
1192 proto_tree_add_item(pkt_s_tree, hf_packetcable_ccc_sec_dhcp, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
1194 else {
1195 expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
1198 suboptoff += subopt_len;
1199 break;
1200 default:
1201 suboptoff += subopt_len;
1202 break;
1206 /** Return the number of bytes processed **/
1207 return (suboptoff - optoff);
1211 /** Dissect one or more domain names within an option's domain name field and verify conformance
1212 * with RFCs 8415, 3646, 4704, 2181, 1535, 1035, and 1034. Sufficiently detailed info is provided
1213 * as to the cause of each error.
1215 * TERMINOLOGY:
1216 * field An option's domain name field containing from 0-n domain names (DNs)
1217 * DN Decoded FQDN or a partial (relative) name.
1218 * label A DNS-encoded name consisting of length octet followed by a name of that many
1219 * octets. Bits 7 and 8 of the length octet are 0 thus the maximum length of a
1220 * name is 63 octets.
1221 * root "the null length of the root". An encoded root label only consists of its length,
1222 * [0] and decoded as a dot. The trailing dot of an FQDN should not be confused with
1223 * dots within a DN which are used to delineate its names.
1224 * TLD or tld A Top Level Domain name consisting of *two* encoded labels: name and root.
1225 * For example, [3org0] are decoded as [org.]
1226 * FQDN: Fully Qualified Domain Name: A "complete" or "absolute" domain name that consists
1227 * of *three* or more labels the last of which is root [0].
1228 * partial name One or more labels *not* terminated by root. Partial names consisting of two or
1229 * more names are referred to as "multi-part partially qualified Domain Names"
1230 * [RFC 1535 pg 4.]. They are also called "relative" names. "Relative names are either
1231 * taken relative to a well known origin, or to a list of domains used as a search
1232 * list." [RFC 1034 3.1]. A partial name must be the only DN in the field.
1234 * TODO: Revise DNS routines such as dissect_dns_query(), get_dns_name(), and expand_dns_name()
1235 * (a.) to be aware of relative/partial names
1236 * (b.) to detect protocol violations per keywords "MUST" "REQUIRED" and "SHALL"
1239 * This function assumes labels are encoded using ASCII. While RFC 1305 section 3.1
1240 * supposedly doesn't formally mandate any one encoding, from my understanding of it,
1241 * ASCII is "assumed" (and a de facto requirement for interoperability).
1242 * An expert info for invalid ASCII in domain name labels would be a useful enhancement.
1244 static void
1245 dhcpv6_domain(proto_tree *subtree, proto_item *v_item _U_, packet_info *pinfo, int hfindex,
1246 tvbuff_t *tvb, int dn_field_off, uint16_t dn_field_len)
1248 int final_field_off; /* Last offset of in DN field */
1249 uint8_t *label_str;
1250 uint8_t label_len;
1251 int remlen; /* The number of remaining octets in a domain field */
1252 uint8_t num_labels;
1253 int first_lab_off; /* Offset of the first label of a DN */
1254 wmem_strbuf_t *decoded_name_buf; /* Array used to construct an FQDN or partial name. */
1255 int total_label_ascii_len; /* Accumulated count of decoded label bytes, including separators. */
1256 int offset;
1257 bool fqdn_seen, inc;
1258 proto_item *exi;
1259 proto_tree *ex_subtree;
1261 /* Empty domain name
1262 * [RFC 4704 4.2.] "A client MAY also leave the Domain Name field empty if it desires the server
1263 * to provide a name." If the domain field is empty, dn_field_len = 0; however, if the field only
1264 * contains a root label(0), it consumes one octet so in that case dn_field_len = 1.
1265 * See [RFC 1034 3.1] for details.
1267 if (dn_field_len == 0) {
1268 proto_tree_add_uint_format(subtree, hf_empty_domain_name, tvb, dn_field_off-3, 2, dn_field_len,
1269 "Empty domain field: the client requests the server to provide a domain name");
1270 return;
1272 offset = dn_field_off;
1273 first_lab_off = dn_field_off;
1274 final_field_off = dn_field_off + dn_field_len - 1;
1275 remlen = dn_field_len;
1276 num_labels = 0;
1277 total_label_ascii_len = 0;
1278 decoded_name_buf = wmem_strbuf_new(pinfo->pool, NULL);
1279 fqdn_seen = false;
1280 inc = true;
1282 /* Decode one label of an FQDN or partial domain name per iteration. [RFC 1034 3.1] "labels are
1283 * separated by dots ('.'). Since a complete domain name ends with the root label, this leads to
1284 * a printed form which ends in a dot."
1286 while (remlen) {
1287 label_len = tvb_get_uint8(tvb, offset);
1288 if (label_len > 63) {
1290 * Bits 7 and 8 of the label length octet are zero, so the max length of a label is 63
1291 * octets. If greater, it is likely the first char of a non-DNS-encoded name.
1293 exi = proto_tree_add_uint_format(subtree, hf_dhcpv6_non_dns_encoded_name, tvb,
1294 offset, 1, label_len,
1295 "Label Length: %u\n"
1296 "This is not a DNS record encoded domain name. The value in the first octet of\n"
1297 "a label is the length of the name that follows and must be 63 octets or less.\n"
1298 "However, in this case it is %u which typically means the name is not DNS encoded.\n",
1299 label_len, label_len);
1300 ex_subtree = proto_item_add_subtree(exi, ett_clientfqdn_expert);
1302 if (num_labels) {
1303 proto_tree_add_string_format(ex_subtree, hf_dhcpv6_decoded_portion, tvb,
1304 first_lab_off, total_label_ascii_len, decoded_name_buf->str,
1305 "The decoded portion of this FQDN to this point is [%s]\n", decoded_name_buf->str);
1307 proto_tree_add_expert(ex_subtree, pinfo, &ei_dhcpv6_non_dns_encoded_name, tvb, offset, 1);
1308 return;
1311 if(total_label_ascii_len == 0)
1312 first_lab_off = offset;
1313 offset++;
1314 remlen--;
1316 if (label_len > remlen) {
1318 * FQDN len exceeds domain field len.
1320 col_append_str(pinfo->cinfo, COL_INFO, " [DOMAIN FIELD LEN EXCEEDED]");
1322 exi = proto_tree_add_uint_format(subtree, hf_dhcpv6_domain_field_len_exceeded, tvb,
1323 offset-1, 1, label_len,
1324 "ERROR: The length of this name, %u, exceeds the remaining length, %d, in the\n"
1325 "domain name field.\n", label_len, remlen);
1326 ex_subtree = proto_item_add_subtree(exi, ett_clientfqdn_expert);
1328 if (num_labels) {
1329 proto_tree_add_string_format(ex_subtree, hf_dhcpv6_decoded_portion, tvb,
1330 first_lab_off, total_label_ascii_len, decoded_name_buf->str,
1331 "The successfully decoded portion of this FQDN: [%s]\n", decoded_name_buf->str);
1333 proto_tree_add_expert(ex_subtree, pinfo, &ei_dhcpv6_domain_field_len_exceeded, tvb,
1334 dn_field_off, dn_field_len);
1335 return;
1338 if (total_label_ascii_len + label_len + 2 > 255) {
1340 * RFC 1034 Section 3.1: "To simplify implementations, the total number of octets that
1341 * represent a domain name (i.e., the sum of all label octets and label lengths) is
1342 * limited to 255."
1344 col_append_str(pinfo->cinfo, COL_INFO, " [FQDN > 255]");
1346 * Since label_len is valid (<=63 and the name has not been truncated (i.e., its length
1347 * is <= remlen), display this oversized FQDN.
1349 wmem_strbuf_append_c(decoded_name_buf, '.');
1350 total_label_ascii_len++;
1351 label_str = tvb_get_string_enc(pinfo->pool, tvb, offset, label_len, ENC_ASCII);
1352 wmem_strbuf_append(decoded_name_buf, label_str);
1353 offset += label_len;
1354 total_label_ascii_len += label_len;
1355 if (tvb_get_uint8(tvb, offset) == 0) {
1356 wmem_strbuf_append_c(decoded_name_buf, '.');
1357 total_label_ascii_len++;
1358 offset++;
1359 inc = false;
1361 exi = proto_tree_add_uint_format(subtree, hf_dhcpv6_encoded_fqdn_len_gt_255, tvb,
1362 first_lab_off, total_label_ascii_len-1, total_label_ascii_len,
1363 "FQDN: %s%s\n"
1364 "ERROR: The total length of DNS-encoded names of this FQDN, %d, exceeds 255,\n"
1365 "the maximum allowed.", decoded_name_buf->str, (inc ? "<incomplete>" : " "), total_label_ascii_len);
1366 ex_subtree = proto_item_add_subtree(exi, ett_clientfqdn_expert);
1367 proto_tree_add_expert(ex_subtree, pinfo, &ei_dhcpv6_encoded_fqdn_len_gt_255, tvb,
1368 first_lab_off, total_label_ascii_len-1);
1369 return;
1372 if (label_len==0) {
1373 wmem_strbuf_append_c(decoded_name_buf, '.');
1374 total_label_ascii_len++;
1376 if (num_labels == 0) {
1378 * This a standalone root label thus the client has request the resolver to return
1379 * the IP address of root.
1381 col_append_str(pinfo->cinfo, COL_INFO, " [ROOT-ONLY DOMAIN NAME]");
1382 exi = proto_tree_add_string(subtree, hf_dhcpv6_root_only_domain_name, tvb,
1383 offset-1, 1, "['.' (0)]");
1384 ex_subtree = proto_item_add_subtree(exi, ett_clientfqdn_expert);
1385 proto_tree_add_expert(ex_subtree, pinfo, &ei_dhcpv6_root_only_domain_name, tvb,
1386 offset-1, 1);
1387 return;
1389 else if (num_labels == 1) {
1391 * TLDs consist of one DNS encoded label and a root label(0) (e.g., [com.] is
1392 * encoded as [03 64 6F 6D 00]).
1394 exi = proto_tree_add_string_format(subtree, hf_dhcpv6_tld, tvb, first_lab_off, total_label_ascii_len+1,
1395 decoded_name_buf->str, "Top Level Domain name (TLD): %s", decoded_name_buf->str);
1396 ex_subtree = proto_item_add_subtree(exi, ett_clientfqdn_expert);
1397 proto_tree_add_expert(ex_subtree, pinfo, &ei_dhcpv6_tld_lookup, tvb, first_lab_off, total_label_ascii_len+1);
1399 num_labels = 0;
1400 total_label_ascii_len = 0;
1401 fqdn_seen = true;
1402 continue; /* This was only a COMMENT/WARNING so continue */
1405 /* This is a fully decoded FQDN. Add it to the tree with a trailing dot for root to
1406 * indicate that the domain name is in fact an FQDN and not a multi-part partially
1407 * qualified domain name.
1409 proto_tree_add_string(subtree, hfindex, tvb, first_lab_off, total_label_ascii_len+1, decoded_name_buf->str);
1410 num_labels = 0;
1411 total_label_ascii_len = 0;
1412 fqdn_seen = true;
1413 continue; /* Decode the next FQDN, if any */
1415 /**************** End of label_len==0 (root) ****************/
1417 /* If a DN's last offset equals final_field_off, this marks the end of a partial name. Due
1418 * to the fact that they are root-terminated, only one partial name or 'multi-part partially
1419 * qualified domain name' is permitted per option field; otherwise, the labels of a
1420 * subsequent DN would be appended to it.
1422 * If a client with a domain name suffix search list configured manually, via GPO, or
1423 * OPTION_DOMAIN_LIST response, appends each of the (rooted) list entries and queries the
1424 * DNS server for each. If a search list is unavailable, the client sends a partial name to
1425 * the server which will use its own search list. According to RFC 1535 Pg 4, "where a '.'
1426 * exists in a specified name it should be assumed to be a fully qualified domain name (FQDN)
1427 * and SHOULD be tried as a rooted name first." Some client implementations, most notably MS
1428 * Windows, do the opposite; the client issues several superfluous (silly-named) queries all
1429 * of which fail, followed by a successful rooted name query. See RFCs 1034 3.1 and 4704 4.2
1430 * for more info.
1432 if (offset + label_len - 1 == final_field_off) {
1433 label_str = tvb_get_string_enc(pinfo->pool, tvb, first_lab_off + 1, label_len, ENC_ASCII);
1434 wmem_strbuf_append(decoded_name_buf, label_str);
1435 total_label_ascii_len += label_len;
1436 num_labels++;
1438 if (fqdn_seen) {
1440 * An FQDN precedes this partial name. Partial names must be the only DN in the
1441 * domain field.
1443 col_append_str(pinfo->cinfo, COL_INFO, " [PROTOCOL VIOLATION]");
1445 exi = proto_tree_add_string_format(subtree, hf_dhcpv6_partial_name_preceded_by_fqdn,
1446 tvb, first_lab_off, label_len, decoded_name_buf->str,
1447 "Partial name: %s\n"
1448 "ERROR: A single or multi-part partial name must be the only name in "
1449 "the domain field", decoded_name_buf->str);
1450 ex_subtree = proto_item_add_subtree(exi, ett_clientfqdn_expert);
1451 proto_tree_add_expert(ex_subtree, pinfo, &ei_dhcpv6_partial_name_preceded_by_fqdn,
1452 tvb, first_lab_off, label_len);
1453 return;
1456 /* A conformant partial name
1458 if (num_labels==1) {
1459 proto_tree_add_string_format(subtree, hfindex, tvb, first_lab_off, total_label_ascii_len+1,
1460 decoded_name_buf->str, "Partial domain name: %s", decoded_name_buf->str);
1462 else {
1463 proto_tree_add_string_format(subtree, hfindex, tvb, first_lab_off, total_label_ascii_len+1,
1464 decoded_name_buf->str, "Multi-part partially qualified Domain Name: %s",
1465 decoded_name_buf->str);
1467 return;
1470 /* Add this name it to the array. Prepend it with a dot unless it's the first name of the DN.
1471 * Dots are only used to separate (delineate) the decoded names of a DN; however, an FQDN's
1472 * trailing root label (0) is decoded as a dot. This is handled above.
1474 if (num_labels) {
1475 wmem_strbuf_append_c(decoded_name_buf, '.');
1476 total_label_ascii_len++;
1478 label_str = tvb_get_string_enc(pinfo->pool, tvb, offset, label_len, ENC_ASCII);
1479 wmem_strbuf_append(decoded_name_buf, label_str);
1480 offset += label_len;
1481 remlen -= label_len;
1482 total_label_ascii_len += label_len;
1483 num_labels++;
1485 /* End of while() loop */
1489 static int
1490 dissect_packetcable_cccV6_option(proto_tree *v_tree, proto_item *v_item, packet_info *pinfo, tvbuff_t *tvb, int optoff,
1491 int optend)
1493 int suboptoff = optoff;
1494 uint16_t subopt, subopt_len;
1495 uint8_t type;
1496 proto_item *vti, *ti;
1497 proto_tree *pkt_s_tree;
1498 int i;
1500 subopt = tvb_get_ntohs(tvb, optoff);
1501 suboptoff += 2;
1503 subopt_len = tvb_get_ntohs(tvb, suboptoff);
1504 suboptoff += 2;
1506 /* There must be at least five octets left to be a valid sub element */
1507 if (optend <= 0) {
1508 expert_add_info_format(pinfo, v_item, &ei_dhcpv6_no_suboption_len, "Sub element %d: no room left in option for suboption length", subopt);
1509 return (suboptoff - optoff);
1512 vti = proto_tree_add_item(v_tree, hf_packetcable_cccV6_suboption, tvb, optoff, 2, ENC_BIG_ENDIAN);
1513 pkt_s_tree = proto_item_add_subtree(vti, ett_dhcpv6_pkt_option);
1515 switch (subopt) {
1516 case PKT_CCCV6_PRI_DSS:
1517 if (subopt_len < 35) {
1518 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_pri_dss, tvb, suboptoff, subopt_len, ENC_ASCII);
1519 } else {
1520 expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
1522 suboptoff += subopt_len;
1523 break;
1524 case PKT_CCCV6_SEC_DSS:
1525 if (subopt_len < 35) {
1526 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_dss, tvb, suboptoff, subopt_len, ENC_ASCII);
1527 } else {
1528 expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
1530 suboptoff += subopt_len;
1531 break;
1532 case PKT_CCCV6_IETF_PROV_SRV:
1533 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_prov_srv_type, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
1534 type = tvb_get_uint8(tvb, suboptoff);
1536 /** Type 0 is FQDN **/
1537 if (type == 0) {
1538 dhcpv6_domain(pkt_s_tree, vti, pinfo, hf_packetcable_cccV6_prov_srv_fqdn, tvb, suboptoff+1, subopt_len-1);
1540 /** Type 1 is IPv6 **/
1541 } else if (type == 1) {
1542 if ((subopt_len % 16) == 0) {
1543 for (i = 0; i < subopt_len/16; i++) {
1544 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_prov_srv_ipv6, tvb, suboptoff+1, 4, ENC_NA);
1545 suboptoff += 16;
1548 } else {
1549 expert_add_info_format(pinfo, vti, &ei_dhcpv6_invalid_type, "Invalid type: %u (%u byte%s)",
1550 type, subopt_len, plurality(subopt_len, "", "s"));
1552 suboptoff += subopt_len;
1553 break;
1554 case PKT_CCCV6_IETF_AS_KRB:
1555 if (subopt_len == 12) {
1556 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_as_krb_nominal_timeout, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
1557 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_as_krb_max_timeout, tvb, suboptoff+4, 4, ENC_BIG_ENDIAN);
1558 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_as_krb_max_retry_count, tvb, suboptoff+8, 4, ENC_BIG_ENDIAN);
1559 } else {
1560 proto_item_append_text(vti, "Bogus length: %d", subopt_len);
1562 suboptoff += subopt_len;
1563 break;
1564 case PKT_CCCV6_IETF_AP_KRB:
1565 if (subopt_len == 12) {
1566 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_ap_krb_nominal_timeout, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
1567 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_ap_krb_max_timeout, tvb, suboptoff+4, 4, ENC_BIG_ENDIAN);
1568 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_ap_krb_max_retry_count, tvb, suboptoff+8, 4, ENC_BIG_ENDIAN);
1569 } else {
1570 proto_item_append_text(vti, "Bogus length: %d", subopt_len);
1572 suboptoff += subopt_len;
1573 break;
1574 case PKT_CCCV6_KRB_REALM:
1575 if (subopt_len > 0) {
1576 dhcpv6_domain(pkt_s_tree, vti, pinfo, hf_packetcable_cccV6_krb_realm, tvb, suboptoff, subopt_len);
1578 suboptoff += subopt_len;
1579 break;
1580 case PKT_CCCV6_TGT_FLAG:
1581 if (subopt_len == 1) {
1582 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_tgt_flag, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
1583 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_tgt_flag_fetch, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
1585 else {
1586 expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
1588 suboptoff += subopt_len;
1589 break;
1590 case PKT_CCCV6_PROV_TIMER:
1591 if (subopt_len == 1) {
1592 ti = proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_prov_timer, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
1593 if (tvb_get_uint8(tvb, suboptoff) > 30)
1594 expert_add_info(pinfo, ti, &ei_dhcpv6_invalid_time_value);
1596 else {
1597 expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
1599 suboptoff += subopt_len;
1600 break;
1601 case PKT_CCCV6_IETF_SEC_TKT:
1602 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_tcm, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
1603 if (subopt_len == 2) {
1604 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_tcm_provisioning_server, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
1605 proto_tree_add_item(pkt_s_tree, hf_packetcable_cccV6_sec_tcm_call_manager_server, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
1606 } else {
1607 expert_add_info_format(pinfo, vti, &ei_dhcpv6_bogus_length, "Bogus length: %d", subopt_len);
1609 suboptoff += subopt_len;
1610 break;
1611 default:
1612 suboptoff += subopt_len;
1613 break;
1615 /** Return the number of bytes processed **/
1616 return (suboptoff - optoff);
1619 /* ToDo: review latest CL docs for updates */
1620 static int
1621 dissect_cablelabs_specific_opts(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1623 unsigned type,
1624 sub_value;
1625 proto_item *v_item;
1626 proto_item *ti;
1627 proto_item *ti2;
1628 proto_tree *subtree;
1629 proto_tree *subtree2;
1630 int tlv5_cap_index,
1631 tlv5_counter,
1632 tlv5_cap_len;
1633 int off = 0,
1634 len,
1635 sub_off, /** The offset for the sub-option */
1637 tlv_len, /* holds the number of elements in the tlv */
1638 field_len, /* holds the length of one occurrence of a field */
1639 opt_len, /* holds the length of the suboption */
1640 field_value;
1641 char *device_type = NULL;
1643 len = tvb_reported_length(tvb);
1645 /* Enterprise */
1646 v_item = proto_tree_add_item(tree, hf_vendoropts_enterprise, tvb, off, 4, ENC_BIG_ENDIAN);
1647 off += 4;
1648 len -= 4;
1650 if (len > 4) {
1651 while (off < len) {
1653 /* Type */
1654 type = tvb_get_ntohs(tvb, off);
1655 ti = proto_tree_add_item(tree, hf_cablelabs_opts, tvb, off, 2, ENC_BIG_ENDIAN);
1656 /* Length */
1657 tlv_len = tvb_get_ntohs(tvb, off+2);
1659 /* Values */
1660 sub_off = off + 4;
1662 switch (type) {
1663 /* String types */
1664 case CL_OPTION_DEVICE_TYPE:
1665 opt_len = tlv_len;
1666 field_len = tlv_len;
1668 device_type = tvb_get_string_enc(pinfo->pool, tvb, sub_off, field_len, ENC_ASCII);
1670 if ((device_type == NULL) || (strlen(device_type) == 0)) {
1671 proto_item_append_text(ti, "Packet does not contain Device Type.");
1672 } else {
1673 proto_item_append_text(ti, "\"%s\"", device_type);
1675 break;
1676 case CL_OPTION_DEVICE_SERIAL_NUMBER:
1677 case CL_OPTION_HARDWARE_VERSION_NUMBER:
1678 case CL_OPTION_SOFTWARE_VERSION_NUMBER:
1679 case CL_OPTION_BOOT_ROM_VERSION:
1680 case CL_OPTION_MODEL_NUMBER:
1681 case CL_OPTION_VENDOR_NAME:
1682 case CL_OPTION_CONFIG_FILE_NAME:
1683 case CL_OPTION_EMBEDDED_COMPONENT_LIST:
1684 opt_len = tlv_len;
1685 field_len = tlv_len;
1686 proto_item_append_text(ti, "\"%s\"",
1687 tvb_format_stringzpad(pinfo->pool, tvb, sub_off, field_len));
1688 break;
1689 case CL_OPTION_VENDOR_OUI:
1690 /* CableLabs specs treat 17.8 inconsistently
1691 * as either binary (3b) or string (6b) */
1692 opt_len = tlv_len;
1693 if (tlv_len == 3) {
1694 proto_item_append_text(ti, "%s",
1695 tvb_bytes_to_str_punct(pinfo->pool, tvb, sub_off, 3, ':'));
1696 } else if (tlv_len == 6) {
1697 proto_item_append_text(ti, "\"%s\"", tvb_format_stringzpad(pinfo->pool, tvb, sub_off, tlv_len));
1698 } else {
1699 expert_add_info_format(pinfo, ti, &ei_dhcpv6_bogus_length, "Suboption %d: suboption length isn't 3 or 6", type);
1701 break;
1702 case CL_OPTION_ORO:
1703 field_len = 2;
1704 opt_len = tlv_len;
1705 if (opt_len > 0) {
1706 for (i = 0; i < tlv_len; i += field_len) {
1707 sub_value = tvb_get_ntohs(tvb, sub_off);
1708 proto_item_append_text(ti, " %d", sub_value);
1709 sub_off += field_len;
1712 break;
1713 /* List of IPv6 Address */
1714 case CL_OPTION_TFTP_SERVERS:
1715 case CL_OPTION_SYSLOG_SERVERS:
1716 case CL_OPTION_RFC868_SERVERS:
1717 case CL_OPTION_CCAP_CORES:
1718 field_len = 16;
1719 opt_len = tlv_len;
1720 subtree = proto_item_add_subtree(ti, ett_dhcpv6_vendor_option);
1722 if ((tlv_len % field_len) == 0) {
1723 for (i = 0; i < tlv_len/field_len; i++) {
1724 ti = proto_tree_add_item(subtree, hf_cablelabs_ipv6_server, tvb, sub_off, 16, ENC_NA);
1725 proto_item_prepend_text(ti, " %d ", i + 1);
1726 sub_off += field_len;
1729 break;
1730 case CL_OPTION_DEVICE_ID:
1731 opt_len = tlv_len;
1732 field_len = tlv_len;
1733 if (tlv_len != 6) {
1734 expert_add_info_format(pinfo, ti, &ei_dhcpv6_bogus_length, "Bogus length: %d", tlv_len);
1736 else {
1737 proto_item_append_text(ti, "%s",
1738 tvb_bytes_to_str(pinfo->pool, tvb, sub_off, field_len));
1740 break;
1741 case CL_OPTION_TLV5:
1742 /* ToDo: review latest CL docs for updates */
1743 opt_len = tlv_len;
1746 tlv5_counter = 0;
1747 tlv5_cap_index = sub_off;
1749 subtree = proto_item_add_subtree(ti, ett_dhcpv6_tlv5_type);
1751 while (tlv5_counter < tlv_len) {
1752 /*Device type is not mandatory for CM (see par 10.2.5.2.3 "Obtain IPv6 Management Address and Other Configuration Parameters" in CM-SP-MULPIv3.1-114-180130*/
1753 if (device_type == NULL || !g_ascii_strncasecmp(device_type, "ecm", 3)) {
1754 ti2 = proto_tree_add_item(subtree, hf_modem_capabilities_encoding_type, tvb, tlv5_cap_index, 1, ENC_BIG_ENDIAN);
1755 } else if (!g_ascii_strncasecmp(device_type, "edva", 3)) {
1756 ti2 = proto_tree_add_item(subtree, hf_eue_capabilities_encoding_type, tvb, tlv5_cap_index, 1, ENC_BIG_ENDIAN);
1757 } else {
1758 break;
1761 tlv5_cap_index++;
1762 tlv5_counter++;
1764 /* Why make another subtree (subtree2) below?
1765 The addition of a subtree is not needed for the display.
1766 However, when parsing the PDML, each Type 'contains' it's Length and Value.
1768 subtree2 = proto_item_add_subtree(ti2, ett_dhcpv6_tlv5_type);
1770 proto_tree_add_item(subtree2, hf_capabilities_encoding_length, tvb, tlv5_cap_index, 1, ENC_BIG_ENDIAN);
1771 tlv5_cap_len = (uint8_t) tvb_get_uint8(tvb, tlv5_cap_index);
1773 tlv5_cap_index++;
1774 tlv5_counter += tlv5_cap_len;
1776 /* In cases where the TLV length is greater than 2, the value fields should be displayed
1777 according to the encoding of the values as described in the CL-SP-CANN-DHCP-Reg specification.
1778 Below, these values are simply displayed as hex.
1780 if (tlv5_cap_len > 2) {
1781 proto_tree_add_item(subtree2, hf_capabilities_encoding_bytes, tvb, tlv5_cap_index, tlv5_cap_len, ENC_NA);
1782 } else {
1783 proto_tree_add_item(subtree2, hf_capabilities_encoding_number, tvb, tlv5_cap_index, tlv5_cap_len, ENC_BIG_ENDIAN);
1786 tlv5_cap_index += tlv5_cap_len;
1787 tlv5_counter++;
1789 break;
1790 case CL_OPTION_TIME_OFFSET:
1791 opt_len = tlv_len;
1792 proto_item_append_text(ti, "%d", tvb_get_ntohl(tvb, sub_off));
1793 break;
1794 case CL_OPTION_IP_PREF:
1795 opt_len = tlv_len;
1796 field_value = tvb_get_uint8(tvb, sub_off);
1797 if (field_value == 1) {
1798 proto_item_append_text(ti, "%s", "IPv4");
1799 } else if (field_value == 2) {
1800 proto_item_append_text(ti, "%s", "IPv6");
1801 } else if (field_value == 6) {
1802 proto_item_append_text(ti, "%s", "Dual Stack");
1803 } else {
1804 proto_item_append_text(ti, "%s%d", "Invalid IP Preference value ", field_value);
1806 break;
1807 case CL_OPTION_DOCS_CMTS_CAP:
1808 opt_len = tlv_len;
1809 field_len = 0;
1810 subtree = proto_item_add_subtree(ti, ett_dhcpv6_vendor_option);
1812 /* tlv_len contains the total length of all the TLVs for this
1813 option */
1814 if (tlv_len > 0) {
1815 for (i = 0; field_len < opt_len; i++) {
1816 int tagLen = 0;
1817 int tag = 0;
1818 tag = tvb_get_uint8(tvb, sub_off);
1819 sub_off++;
1820 tagLen = tvb_get_uint8(tvb, sub_off);
1821 sub_off++;
1822 if ((tag == CL_OPTION_DOCS_CMTS_TLV_VERS_NUM) && (tagLen == 2)) {
1823 proto_tree_add_item(subtree, hf_cablelabs_docsis_version_number, tvb, sub_off,
1824 2, ENC_BIG_ENDIAN);
1825 sub_off += 2;
1827 else if ((tag == CL_OPTION_DOCS_DPOE_TLV_VERS_NUM) && (tagLen == 2)) {
1828 proto_tree_add_item(subtree, hf_cablelabs_dpoe_server_version_number, tvb, sub_off,
1829 2, ENC_BIG_ENDIAN);
1830 sub_off += 2;
1832 else
1833 sub_off += tagLen;
1835 field_len += tagLen + 2;
1838 else
1839 proto_item_append_text(ti, " (empty)");
1840 break;
1841 case CL_CM_MAC_ADDR:
1842 opt_len = tlv_len;
1843 if (tlv_len != 6) {
1844 expert_add_info_format(pinfo, ti, &ei_dhcpv6_bogus_length, "Bogus length: %d", tlv_len);
1846 else {
1847 /*proto_item_append_text(ti, "CM MAC Address Option = %s", */
1848 proto_item_append_text(ti, "%s", tvb_bytes_to_str_punct(pinfo->pool, tvb, sub_off, opt_len, ':'));
1849 /* tvb_bytes_to_str(pinfo->pool, tvb, sub_off, opt_len)); */
1851 break;
1852 case CL_EROUTER_CONTAINER_OPTION:
1853 opt_len = tlv_len;
1854 proto_item_append_text(ti, " %s (len=%d)",
1855 tvb_bytes_to_str(pinfo->pool, tvb, sub_off, opt_len), tlv_len);
1856 break;
1857 case CL_OPTION_CCC:
1858 opt_len = tlv_len;
1859 field_len = 0;
1860 subtree = proto_item_add_subtree(ti, ett_dhcpv6_vendor_option);
1861 proto_item_append_text(ti, " (%d bytes)", opt_len);
1862 while (field_len < opt_len) {
1863 sub_value = dissect_packetcable_ccc_option(subtree, ti, pinfo, tvb,
1864 sub_off, (opt_len - field_len));
1865 sub_off += sub_value;
1866 field_len += sub_value;
1868 break;
1869 case CL_OPTION_CCCV6:
1870 opt_len = tlv_len;
1871 field_len = 0;
1872 subtree = proto_item_add_subtree(ti, ett_dhcpv6_vendor_option);
1873 proto_item_append_text(ti, " (%d bytes)", opt_len);
1874 while (field_len < opt_len) {
1875 sub_value = dissect_packetcable_cccV6_option(subtree, ti, pinfo, tvb,
1876 sub_off, (opt_len - field_len));
1877 sub_off += sub_value;
1878 field_len += sub_value;
1880 break;
1881 case CL_OPTION_CORRELATION_ID:
1882 opt_len = tlv_len;
1883 if (tlv_len != 4) {
1884 proto_item_append_text(ti, "Bogus value length=%d",
1885 tlv_len);
1887 else {
1888 proto_item_append_text(ti, "%u", tvb_get_ntohl(tvb, sub_off));
1890 break;
1891 default:
1892 opt_len = tlv_len;
1893 break;
1895 off += (opt_len + 4);
1899 else {
1900 expert_add_info_format(pinfo, v_item, &ei_dhcpv6_bogus_length, "Bogus length: %d", len);
1902 return tvb_reported_length(tvb);
1905 static void
1906 cablelabs_fmt_docsis_version( char *result, uint32_t revision )
1908 snprintf( result, ITEM_LABEL_LENGTH, "%d.%02d", (uint8_t)(( revision & 0xFF00 ) >> 8), (uint8_t)(revision & 0xFF) );
1912 static void
1913 cablelabs_fmt_dpoe_server_version( char *result, uint32_t revision )
1915 snprintf( result, ITEM_LABEL_LENGTH, "%d.%02d", (uint8_t)(( revision & 0xFF00 ) >> 8), (uint8_t)(revision & 0xFF) );
1919 /* Returns the number of bytes consumed by this option. */
1920 static int
1921 // NOLINTNEXTLINE(misc-no-recursion)
1922 dhcpv6_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree,
1923 int off, int eoff, bool *at_end, int protocol, hopcount_info hpi, uint8_t msgtype)
1925 uint16_t opttype, hwtype, subopt_type;
1926 int temp_optlen, optlen, subopt_len; /* 16-bit values that need 16-bit rollover protection */
1927 proto_item *ti = NULL, *option_item;
1928 proto_tree *subtree;
1929 proto_tree *subtree_2;
1930 int i;
1931 uint16_t duidtype;
1932 uint32_t enterprise_no, temp_uint32;
1933 unsigned algorithm;
1935 /* option type and length must be present */
1936 if ((eoff - off) < 4) {
1937 *at_end = true;
1938 return 0;
1941 opttype = tvb_get_ntohs(tvb, off);
1942 optlen = tvb_get_ntohs(tvb, off + 2);
1944 /* all option data must be present */
1945 if ((eoff - off) < (4 + optlen)) {
1946 *at_end = true;
1947 return 0;
1950 /* Replace "Text item" option header with a filterable field which in turn eliminates the need
1951 * for the "Value:" raw data field. */
1952 option_item = proto_tree_add_string_format(bp_tree, hf_option_type_str, tvb, off, 4 + optlen,
1953 val_to_str_ext(opttype, &opttype_vals_ext, "DHCP option %u"),
1954 "%s", val_to_str_ext(opttype, &opttype_vals_ext, "DHCP option %u"));
1956 subtree = proto_item_add_subtree(option_item, ett_dhcpv6_option);
1958 proto_tree_add_item(subtree, hf_option_type_num, tvb, off, 2, ENC_BIG_ENDIAN);
1959 proto_tree_add_item(subtree, hf_option_length, tvb, off + 2, 2, ENC_BIG_ENDIAN);
1960 off += 4;
1962 increment_dissection_depth(pinfo);
1964 switch (opttype) {
1965 case OPTION_CLIENTID:
1966 if (optlen > 0) {
1967 col_append_fstr(pinfo->cinfo, COL_INFO, "CID: %s ", tvb_bytes_to_str(pinfo->pool, tvb, off, optlen));
1969 /* Fall through */
1970 case OPTION_SERVERID:
1971 case OPTION_RELAYID:
1972 if (optlen < 2) {
1973 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
1974 break;
1976 proto_tree_add_item(subtree, hf_duid_bytes, tvb, off, optlen, ENC_NA);
1977 duidtype = tvb_get_ntohs(tvb, off);
1978 proto_tree_add_item(subtree, hf_duid_type, tvb, off, 2, ENC_BIG_ENDIAN);
1980 switch (duidtype) {
1981 case DUID_LLT:
1983 nstime_t llt_time;
1985 if (optlen < 8) {
1986 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
1987 break;
1989 proto_tree_add_item(subtree, hf_duidllt_hwtype, tvb, off + 2, 2, ENC_BIG_ENDIAN);
1991 /* Packet specifies seconds since Jan 1 2000, so add 946684800U (30 years) to get back to epoch */
1992 llt_time.secs = tvb_get_ntohl(tvb, off + 4) + 946684800U;
1993 llt_time.nsecs = 0;
1995 proto_tree_add_time(subtree, hf_duidllt_time, tvb, off + 4, 4, &llt_time);
1996 if (optlen > 8) {
1997 hwtype = tvb_get_ntohs(tvb, off + 2);
1998 proto_tree_add_string(subtree, hf_duidllt_link_layer_addr, tvb, off + 8,
1999 optlen - 8, tvb_arphrdaddr_to_str(pinfo->pool, tvb, off+8, optlen-8, hwtype));
2000 if(DHCPV6_HW_IS_ETHER(hwtype, optlen-8)) {
2001 proto_tree_add_item(subtree, hf_duidllt_link_layer_addr_ether, tvb, off+8, optlen-8, ENC_NA);
2005 break;
2006 case DUID_EN:
2007 if (optlen < 6) {
2008 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
2009 break;
2011 proto_tree_add_item(subtree, hf_duiden_enterprise, tvb, off + 2, 4, ENC_BIG_ENDIAN);
2012 if (optlen > 6) {
2013 proto_tree_add_item(subtree, hf_duiden_identifier, tvb, off + 6, optlen - 6, ENC_NA);
2015 break;
2016 case DUID_LL:
2017 if (optlen < 4) {
2018 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
2019 break;
2021 proto_tree_add_item(subtree, hf_duidll_hwtype, tvb, off + 2, 2, ENC_BIG_ENDIAN);
2022 if (optlen > 4) {
2023 hwtype = tvb_get_ntohs(tvb, off + 2);
2024 proto_tree_add_string(subtree, hf_duidll_link_layer_addr, tvb, off + 4,
2025 optlen - 4, tvb_arphrdaddr_to_str(pinfo->pool, tvb, off+4, optlen-4, hwtype));
2026 if(DHCPV6_HW_IS_ETHER(hwtype, optlen-4)) {
2027 proto_tree_add_item(subtree, hf_duidll_link_layer_addr_ether, tvb, off+4, optlen-4, ENC_NA);
2030 break;
2031 case DUID_UUID:
2032 if (optlen != 18) {
2033 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DUID: malformed option");
2034 break;
2036 proto_tree_add_item(subtree, hf_duiduuid_bytes, tvb, off + 2, 16, ENC_NA);
2037 break;
2039 break;
2040 case OPTION_USER_CLASS:
2042 temp_optlen = 0;
2043 while (optlen > temp_optlen) {
2044 subopt_len = tvb_get_ntohs(tvb, off + temp_optlen);
2045 if (subopt_len > optlen - temp_optlen) {
2046 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "User Class: suboption too long");
2047 break;
2049 subtree_2 = proto_tree_add_subtree(subtree, tvb, off+temp_optlen, subopt_len, ett_dhcpv6_userclass_option, &ti, "User Class suboption");
2050 proto_tree_add_item(subtree_2, hf_option_userclass_length, tvb, off + temp_optlen, 2, ENC_BIG_ENDIAN);
2051 proto_tree_add_item(subtree_2, hf_option_userclass_opaque_data, tvb, off + temp_optlen + 2, subopt_len, ENC_NA);
2053 temp_optlen += subopt_len + 2;
2055 break;
2057 case OPTION_NTP_SERVER:
2058 if (optlen < 4) {
2059 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "NTP Server: malformed option");
2060 break;
2062 temp_optlen = 0;
2063 while (optlen > temp_optlen) {
2064 subopt_type = tvb_get_ntohs(tvb, off + temp_optlen);
2065 subopt_len = tvb_get_ntohs(tvb, off + 2 + temp_optlen);
2066 if (subopt_len > optlen - temp_optlen) {
2067 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "NTP Server: suboption too long");
2068 break;
2070 subtree_2 = proto_tree_add_subtree(subtree, tvb, off+temp_optlen, 4 + subopt_len, ett_dhcpv6_netserver_option, &ti,
2071 val_to_str(subopt_type, ntp_server_opttype_vals, "NTP Server suboption %u"));
2072 proto_tree_add_item(subtree_2, hf_option_ntpserver_type, tvb, off + temp_optlen, 2, ENC_BIG_ENDIAN);
2073 proto_tree_add_item(subtree_2, hf_option_ntpserver_length, tvb, off + temp_optlen + 2, 2, ENC_BIG_ENDIAN);
2074 temp_optlen += 4;
2075 switch (subopt_type) {
2076 case NTP_SUBOPTION_SRV_ADDR:
2077 proto_tree_add_item(subtree_2, hf_option_ntpserver_addr, tvb, off + temp_optlen, 16, ENC_NA);
2078 break;
2079 case NTP_SUBOPTION_MC_ADDR:
2080 proto_tree_add_item(subtree_2, hf_option_ntpserver_mc_addr, tvb, off + temp_optlen, 16, ENC_NA);
2081 break;
2082 case NTP_SUBOPTION_SRV_FQDN:
2083 /* RFC 5906: section 4.3: "Internationalized domain names are not allowed ..." */
2084 dhcpv6_domain(subtree_2, ti, pinfo, hf_option_ntpserver_fqdn, tvb, off + temp_optlen, subopt_len);
2085 break;
2088 temp_optlen += subopt_len;
2090 break;
2091 case OPTION_S46_RULE:
2093 uint8_t ipv4_pref_len, ipv6_pref_len;
2094 int ipv6_pref_len_bytes;
2096 if (optlen < 8) {
2097 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_RULE: malformed option");
2098 break;
2101 /* 0 1 2 3 4 5 6 7
2102 * +-+-+-+-+-+-+-+-+
2103 * |Reserved |F|
2104 * +-+-+-+-+-+-+-+-+
2106 proto_tree_add_bitmask(subtree, tvb, off, hf_option_s46_rule_flags, ett_dhcpv6_s46_rule_flags, dhcpv6_s46_rule_flags_fields, ENC_BIG_ENDIAN);
2107 proto_tree_add_item(subtree, hf_option_s46_rule_ea_len, tvb, off + 1, 1, ENC_BIG_ENDIAN);
2108 proto_tree_add_item(subtree, hf_option_s46_rule_ipv4_pref_len, tvb, off + 2, 1, ENC_BIG_ENDIAN);
2109 ipv4_pref_len = tvb_get_uint8(tvb, off + 2);
2111 if (ipv4_pref_len > 32) {
2112 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_RULE: malformed option");
2113 break;
2116 proto_tree_add_item(subtree, hf_option_s46_rule_ipv4_prefix, tvb, off + 3, 4, ENC_NA);
2117 proto_tree_add_item(subtree, hf_option_s46_rule_ipv6_pref_len, tvb, off + 7, 1, ENC_BIG_ENDIAN);
2118 ipv6_pref_len = tvb_get_uint8(tvb, off + 7);
2120 if (ipv6_pref_len > 128) {
2121 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_RULE: malformed option");
2122 break;
2125 ipv6_pref_len_bytes =
2126 dissect_dhcpv6_s46_ipv6_prefix(tvb, hf_option_s46_rule_ipv6_prefix, off + 8, ipv6_pref_len, subtree);
2128 temp_optlen = 8 + ipv6_pref_len_bytes;
2129 while ((optlen - temp_optlen) > 0) {
2130 temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
2131 off+temp_optlen, off + optlen, at_end, protocol, hpi, msgtype);
2132 if (*at_end) {
2133 /* Bad option - just skip to the end */
2134 temp_optlen = optlen;
2138 break;
2139 case OPTION_S46_BR:
2140 if (optlen != 16) {
2141 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_BR: malformed option");
2142 break;
2145 proto_tree_add_item(subtree, hf_option_s46_br_address, tvb, off, 16, ENC_NA);
2146 break;
2147 case OPTION_S46_DMR:
2149 uint8_t dmr_pref_len;
2151 if (optlen < 1 || optlen > 17) {
2152 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_DMR: malformed option");
2153 break;
2156 proto_tree_add_item(subtree, hf_option_s46_dmr_pref_len, tvb, off, 1, ENC_BIG_ENDIAN);
2157 dmr_pref_len = tvb_get_uint8(tvb, off);
2159 if (dmr_pref_len > 128) {
2160 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_DMR: malformed option");
2161 break;
2164 dissect_dhcpv6_s46_ipv6_prefix(tvb, hf_option_s46_dmr_prefix, off + 1, dmr_pref_len, subtree);
2166 break;
2167 case OPTION_S46_V4V6BIND:
2169 uint8_t ipv6_pref_len;
2170 int ipv6_pref_len_bytes;
2172 if (optlen < 5) {
2173 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_V4V6BIND: malformed option");
2174 break;
2177 proto_tree_add_item(subtree, hf_option_s46_v4v6bind_ipv4_address, tvb, off, 4, ENC_NA);
2178 proto_tree_add_item(subtree, hf_option_s46_v4v6bind_ipv6_pref_len, tvb, off + 4, 1, ENC_BIG_ENDIAN);
2179 ipv6_pref_len = tvb_get_uint8(tvb, off + 4);
2181 if (ipv6_pref_len > 128) {
2182 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_V4V6BIND: malformed option");
2183 break;
2186 ipv6_pref_len_bytes =
2187 dissect_dhcpv6_s46_ipv6_prefix(tvb, hf_option_s46_v4v6bind_ipv6_prefix, off + 5, ipv6_pref_len, subtree);
2189 temp_optlen = 5 + ipv6_pref_len_bytes;
2190 while ((optlen - temp_optlen) > 0) {
2191 temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
2192 off+temp_optlen, off + optlen, at_end, protocol, hpi, msgtype);
2193 if (*at_end) {
2194 /* Bad option - just skip to the end */
2195 temp_optlen = optlen;
2199 break;
2200 case OPTION_S46_PORTPARAMS:
2202 uint16_t psid;
2203 uint8_t offset, psid_len;
2205 if (optlen != 4) {
2206 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_PORTPARAMS: malformed option");
2207 break;
2210 proto_tree_add_item(subtree, hf_option_s46_portparam_offset, tvb, off, 1, ENC_BIG_ENDIAN);
2211 offset = tvb_get_uint8(tvb, off);
2213 if (offset > 15) {
2214 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_PORTPARAMS: malformed option");
2215 break;
2218 proto_tree_add_item(subtree, hf_option_s46_portparam_psid_len, tvb, off + 1, 1, ENC_BIG_ENDIAN);
2219 psid_len = tvb_get_uint8(tvb, off + 1);
2221 if (psid_len > 16) {
2222 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "S46_PORTPARAMS: malformed option");
2223 break;
2226 psid = tvb_get_ntohs(tvb, off + 2);
2227 proto_tree_add_uint(subtree, hf_option_s46_portparam_psid, tvb, off + 2, 2, psid >> (16 - psid_len));
2229 break;
2230 case OPTION_S46_CONT_MAPE:
2231 case OPTION_S46_CONT_MAPT:
2232 case OPTION_S46_CONT_LW:
2233 temp_optlen = 0;
2234 while ((optlen - temp_optlen) > 0) {
2235 temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
2236 off+temp_optlen, off + optlen, at_end, protocol, hpi, msgtype);
2237 if (*at_end) {
2238 /* Bad option - just skip to the end */
2239 temp_optlen = optlen;
2242 break;
2243 case OPTION_IA_NA:
2244 case OPTION_IA_PD:
2245 if (optlen < 12) {
2246 if (opttype == OPTION_IA_NA)
2247 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_NA: malformed option");
2248 else
2249 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_PD: malformed option");
2250 break;
2252 proto_tree_add_string(subtree, hf_iaid, tvb, off,
2253 4, tvb_arphrdaddr_to_str(pinfo->pool, tvb, off, 4, opttype)); /* XXX: IAID is opaque ? review ... */
2254 proto_tree_add_item(subtree, hf_iaid_t1, tvb, off+4, 4, ENC_BIG_ENDIAN);
2255 proto_tree_add_item(subtree, hf_iaid_t2, tvb, off+8, 4, ENC_BIG_ENDIAN);
2257 temp_optlen = 12;
2258 while ((optlen - temp_optlen) > 0) {
2259 temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
2260 off+temp_optlen, off + optlen, at_end, protocol, hpi, msgtype);
2261 if (*at_end) {
2262 /* Bad option - just skip to the end */
2263 temp_optlen = optlen;
2266 break;
2267 case OPTION_IA_TA:
2268 if (optlen < 4) {
2269 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_TA: malformed option");
2270 break;
2272 proto_tree_add_string(subtree, hf_iata, tvb, off,
2273 4, tvb_arphrdaddr_to_str(pinfo->pool, tvb, off, 4, opttype)); /* XXX: IAID is opaque ? review ... */
2274 temp_optlen = 4;
2275 while ((optlen - temp_optlen) > 0) {
2276 temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
2277 off+temp_optlen, off + optlen, at_end, protocol, hpi, msgtype);
2278 if (*at_end) {
2279 /* Bad option - just skip to the end */
2280 temp_optlen = optlen;
2283 break;
2284 case OPTION_IAADDR:
2286 if (optlen < 24) {
2287 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "IA_TA: malformed option");
2288 break;
2291 proto_tree_add_item(subtree, hf_iaaddr_ip, tvb, off, 16, ENC_NA);
2292 col_append_fstr(pinfo->cinfo, COL_INFO, "IAA: %s ", tvb_ip6_to_str(pinfo->pool, tvb, off));
2294 proto_tree_add_item(subtree, hf_iaaddr_pref_lifetime, tvb, off+16, 4, ENC_BIG_ENDIAN);
2295 proto_tree_add_item(subtree, hf_iaaddr_valid_lifetime, tvb, off+20, 4, ENC_BIG_ENDIAN);
2297 temp_optlen = 24;
2298 while ((optlen - temp_optlen) > 0) {
2299 temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
2300 off+temp_optlen, off + optlen, at_end, protocol, hpi, msgtype);
2301 if (*at_end) {
2302 /* Bad option - just skip to the end */
2303 temp_optlen = optlen;
2307 break;
2308 case OPTION_ORO:
2309 case OPTION_ERO:
2310 for (i = 0; i < optlen; i += 2) {
2311 proto_tree_add_item(subtree, hf_requested_option_code, tvb, off+i,
2312 2, ENC_BIG_ENDIAN);
2314 break;
2315 case OPTION_PREFERENCE:
2316 if (optlen != 1) {
2317 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "PREFERENCE: malformed option");
2318 break;
2320 proto_tree_add_item(subtree, hf_option_preference, tvb, off, 1, ENC_BIG_ENDIAN);
2321 break;
2322 case OPTION_ELAPSED_TIME:
2323 if (optlen != 2) {
2324 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "ELAPSED-TIME: malformed option");
2325 break;
2328 temp_optlen = tvb_get_ntohs(tvb, off);
2329 proto_tree_add_uint(subtree, hf_elapsed_time, tvb, off, 2, temp_optlen*10);
2330 break;
2331 case OPTION_RELAY_MSG:
2332 if (optlen == 0) {
2333 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "RELAY-MSG: malformed option");
2334 } else {
2335 /* here, we should dissect a full DHCP message */
2336 dissect_dhcpv6(tvb, pinfo, subtree, off, off + optlen, hpi);
2338 break;
2339 case OPTION_AUTH:
2340 if (optlen < 11) {
2341 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "AUTH: malformed option");
2342 break;
2345 proto_tree_add_item(subtree, hf_auth_protocol, tvb, off, 1, ENC_BIG_ENDIAN);
2346 proto_tree_add_item_ret_uint(subtree, hf_auth_algorithm, tvb, off+1, 1, ENC_BIG_ENDIAN, &algorithm);
2347 proto_tree_add_item(subtree, hf_auth_rdm, tvb, off+2, 1, ENC_BIG_ENDIAN);
2348 proto_tree_add_item(subtree, hf_auth_replay_detection, tvb, off+3, 8, ENC_NA);
2349 if (optlen > 11+20 && algorithm == 1) { // RFC 3315, HMAC-MD5 (16) + Key ID (4) => 20 bytes
2350 if (optlen-11-20 < 256) {
2351 proto_tree_add_item(subtree, hf_auth_realm, tvb, off+11, optlen-11-20, ENC_ASCII);
2352 } else {
2353 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DHCP realm: probably malformed option");
2355 proto_tree_add_item(subtree, hf_auth_key_id, tvb, off+optlen-16-4, 4, ENC_BIG_ENDIAN);
2356 proto_tree_add_item(subtree, hf_auth_md5_data, tvb, off+optlen-16, 16, ENC_NA);
2357 } else {
2358 proto_tree_add_item(subtree, hf_auth_info, tvb, off+11, optlen-11, ENC_NA);
2360 break;
2361 case OPTION_UNICAST:
2362 if (optlen != 16) {
2363 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "UNICAST: malformed option");
2364 break;
2366 proto_tree_add_item(subtree, hf_opt_unicast, tvb, off, 16, ENC_NA);
2367 break;
2368 case OPTION_STATUS_CODE:
2369 proto_tree_add_item(subtree, hf_opt_status_code, tvb, off, 2, ENC_BIG_ENDIAN);
2370 if (optlen > 2)
2371 proto_tree_add_item(subtree, hf_opt_status_msg, tvb, off+2, optlen - 2, ENC_ASCII);
2372 break;
2373 case OPTION_VENDOR_CLASS:
2374 if (optlen < 4) {
2375 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "VENDOR_CLASS: malformed option");
2376 break;
2378 proto_tree_add_item(subtree, hf_vendorclass_enterprise, tvb, off, 4, ENC_BIG_ENDIAN);
2379 if (optlen > 4)
2380 proto_tree_add_item(subtree, hf_vendorclass_data, tvb, off+6, optlen-6, ENC_ASCII);
2381 break;
2382 case OPTION_VENDOR_OPTS:
2384 if (optlen < 4) {
2385 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "VENDOR_OPTS: malformed option");
2386 break;
2389 tvbuff_t *opt_tvb;
2391 enterprise_no = tvb_get_ntohl(tvb, off);
2392 opt_tvb = tvb_new_subset_length(tvb, off, optlen);
2394 // Find a per-vendor dissector or fallback to the generic-enterprise-dissector.
2395 if (!dissector_try_uint_with_data(dhcpv6_enterprise_opts_dissector_table, enterprise_no, opt_tvb, pinfo, subtree, false, &msgtype)) {
2396 proto_tree_add_item(subtree, hf_vendoropts_enterprise, tvb, off, 4, ENC_BIG_ENDIAN);
2397 int optoffset = 0;
2399 while ((optlen - 4 - optoffset) > 0) {
2400 int olen = tvb_get_ntohs(tvb, off + optoffset + 6);
2401 subtree_2 = proto_tree_add_subtree(subtree, tvb, off + optoffset + 4,
2402 4 + olen, ett_dhcpv6_option_vsoption, NULL, "option");
2403 proto_tree_add_item(subtree_2, hf_vendoropts_enterprise_option_code, tvb, off + optoffset + 4, 2, ENC_BIG_ENDIAN);
2404 proto_tree_add_item(subtree_2, hf_vendoropts_enterprise_option_length, tvb, off + optoffset + 6, 2, ENC_BIG_ENDIAN);
2405 proto_tree_add_item(subtree_2, hf_vendoropts_enterprise_option_data, tvb, off + optoffset + 8, olen, ENC_NA);
2406 optoffset += (4 + olen);
2409 break;
2411 case OPTION_INTERFACE_ID:
2413 if (optlen == 0) {
2414 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "INTERFACE_ID: malformed option");
2415 break;
2418 if (cablelabs_interface_id) {
2419 int namelen = tvb_strnlen(tvb, off, optlen)+1;
2420 if (namelen == 0) {
2421 proto_tree_add_item(subtree, hf_cablelabs_interface_id, tvb, off, optlen, ENC_ASCII);
2422 } else {
2423 proto_tree_add_item(subtree, hf_cablelabs_interface_id, tvb, off, namelen-1, ENC_ASCII);
2425 temp_optlen = optlen - namelen;
2426 off += namelen;
2427 if (temp_optlen >= 6)
2428 proto_tree_add_string(subtree, hf_cablelabs_interface_id_link_address, tvb, off, temp_optlen, tvb_arphrdaddr_to_str(pinfo->pool, tvb, off, 6, ARPHRD_ETHER));
2430 } else {
2431 proto_tree_add_item(subtree, hf_interface_id, tvb, off, optlen, ENC_NA);
2434 break;
2435 case OPTION_RECONF_MSG:
2436 if (optlen != 1) {
2437 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "RECONF_MSG: malformed option");
2438 break;
2441 proto_tree_add_item(subtree, hf_reconf_msg, tvb, off, 1, ENC_BIG_ENDIAN);
2442 break;
2443 case OPTION_RECONF_ACCEPT:
2444 if (optlen)
2445 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "RECONF_ACCEPT: malformed option");
2446 break;
2447 case OPTION_SIP_SERVER_D:
2448 if (optlen > 0) {
2449 subtree_2 = proto_tree_add_subtree(subtree, tvb, off, optlen, ett_dhcpv6_sip_server_domain_search_list_option, &ti, "SIP Servers Domain Search List");
2450 dhcpv6_domain(subtree_2, ti, pinfo, hf_sip_server_domain_search_fqdn, tvb, off, optlen);
2452 break;
2453 case OPTION_SIP_SERVER_A:
2454 if (optlen % 16) {
2455 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "SIP servers address: malformed option");
2456 break;
2459 for (i = 0; i < optlen; i += 16)
2460 proto_tree_add_item(subtree, hf_sip_server_a, tvb, off + i, 16, ENC_NA);
2461 break;
2462 case OPTION_DNS_SERVERS:
2463 if (optlen % 16) {
2464 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DNS servers address: malformed option");
2465 break;
2468 for (i = 0; i < optlen; i += 16) {
2469 ti = proto_tree_add_item(subtree, hf_dns_servers, tvb, off + i, 16, ENC_NA);
2470 proto_item_prepend_text(ti, " %d ", i/16 + 1);
2472 break;
2474 case OPTION_DHCP4_O_DHCP6_SERVER:
2475 if (optlen % 16) {
2476 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "DHCP4_O_DHCP6_SERVER: malformed option");
2477 break;
2480 for (i = 0; i < optlen; i += 16) {
2481 ti = proto_tree_add_item(subtree, hf_dhcp4o6_servers, tvb, off + i, 16, ENC_NA);
2482 proto_item_prepend_text(ti, " %d ", i/16 + 1);
2484 break;
2486 case OPTION_DHCPV4_MSG:
2488 tvbuff_t *dhcpv4_tvb;
2490 dhcpv4_tvb = tvb_new_subset_length(tvb, off, optlen);
2491 call_dissector(dhcpv4_handle, dhcpv4_tvb, pinfo, subtree);
2493 /* the DHCP(v4) dissector overwrites COL_PROTOCOL. This is probably
2494 * good, because the DHCP(v4) message will be the main content of this
2495 * packet. But at least disambiguate it a little bit vs. "regular"
2496 * DHCP.
2498 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv4o6");
2499 col_prepend_fstr(pinfo->cinfo, COL_INFO, "%-12s ", val_to_str_ext(msgtype, &msgtype_vals_ext, "Message Type %u"));
2500 break;
2503 case OPTION_DOMAIN_LIST:
2504 if (optlen > 0) {
2505 subtree_2 = proto_tree_add_subtree(subtree, tvb, off, optlen, ett_dhcpv6_dns_domain_search_list_option, &ti,
2506 "Domain name suffix search list");
2507 dhcpv6_domain(subtree_2, ti, pinfo, hf_domain_search_list_entry, tvb, off, optlen);
2509 break;
2511 /* NIS...: RFC 3898 */
2512 case OPTION_NIS_SERVERS:
2513 if (optlen % 16) {
2514 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "NIS servers address: malformed option");
2515 break;
2517 for (i = 0; i < optlen; i += 16)
2518 proto_tree_add_item(subtree, hf_nis_servers, tvb, off + i, 16, ENC_NA);
2519 break;
2520 case OPTION_NISP_SERVERS:
2521 if (optlen % 16) {
2522 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "NISP servers address: malformed option");
2523 break;
2525 for (i = 0; i < optlen; i += 16)
2526 proto_tree_add_item(subtree, hf_nisp_servers, tvb, off + i, 16, ENC_NA);
2527 break;
2528 case OPTION_NIS_DOMAIN_NAME:
2529 if (optlen > 0) {
2530 subtree_2 = proto_tree_add_subtree(subtree, tvb, off, optlen, ett_dhcpv6_nis_domain_name_option, &ti, "nis-domain-name");
2531 dhcpv6_domain(subtree_2, ti, pinfo, hf_nis_fqdn, tvb, off, optlen);
2533 break;
2534 case OPTION_NISP_DOMAIN_NAME:
2535 if (optlen > 0) {
2536 subtree_2 = proto_tree_add_subtree(subtree, tvb, off, optlen, ett_dhcpv6_nisp_domain_name_option, &ti, "nisp-domain-name");
2537 dhcpv6_domain(subtree_2, ti, pinfo, hf_nisp_fqdn, tvb, off, optlen);
2539 break;
2541 case OPTION_SNTP_SERVERS:
2542 /* Deprecated as of RFC 5908 */
2543 if (optlen % 16) {
2544 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "SNTP servers address: malformed option");
2545 break;
2547 for (i = 0; i < optlen; i += 16){
2548 ti = proto_tree_add_item(subtree, hf_sntp_servers, tvb, off + i, 16, ENC_NA);
2549 proto_item_prepend_text(ti, " %d ", i/16 + 1);
2551 break;
2552 case OPTION_LIFETIME:
2553 if (optlen != 4) {
2554 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "LIFETIME: malformed option");
2555 break;
2557 proto_tree_add_item(subtree, hf_opt_lifetime, tvb, off, 4, ENC_BIG_ENDIAN);
2558 break;
2560 /* BCMCS...: RFC 4280 */
2561 case OPTION_BCMCS_SERVER_D:
2562 if (optlen > 0) {
2563 subtree_2 = proto_tree_add_subtree(subtree, tvb, off, optlen, ett_dhcpv6_bcmcs_servers_domain_search_list_option, &ti, "BCMCS Servers Domain Search List");
2564 dhcpv6_domain(subtree_2, ti, pinfo, hf_bcmcs_servers_fqdn, tvb, off, optlen);
2566 break;
2567 case OPTION_BCMCS_SERVER_A:
2568 if (optlen % 16) {
2569 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "BCMCS servers address: malformed option");
2570 break;
2572 for (i = 0; i < optlen; i += 16)
2573 proto_tree_add_item(subtree, hf_bcmcs_servers_a, tvb, off + i, 16, ENC_NA);
2574 break;
2576 case OPTION_REMOTE_ID:
2577 if (optlen < 4) {
2578 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "REMOTE_ID: malformed option");
2579 break;
2581 proto_tree_add_item(subtree, hf_remoteid_enterprise, tvb, off, 4, ENC_BIG_ENDIAN);
2582 off += 4;
2583 proto_tree_add_item(subtree, hf_remoteid_enterprise_id, tvb, off, optlen - 4, ENC_NA);
2584 break;
2585 case OPTION_SUBSCRIBER_ID:
2586 if (optlen == 0) {
2587 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "SUBSCRIBER_ID: malformed option");
2588 break;
2590 proto_tree_add_item(subtree, hf_subscriber_id, tvb, off, optlen, ENC_ASCII);
2591 break;
2592 case OPTION_CLIENT_FQDN:
2593 if (optlen < 1) {
2594 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "FQDN: malformed option");
2595 } else {
2596 uint8_t flags;
2597 proto_item *fi = NULL;
2598 proto_tree *flags_tree = NULL;
2599 char *flags_str= NULL, *suffix;
2600 bool is_client;
2601 proto_item *exi;
2602 proto_tree *ex_subtree;
2605 * A client MUST only include the OPTION_CLIENT_FQDN in SOLICIT, REQUEST, RENEW, or REBIND messages.
2606 * [RFC 4704 Section 5.]
2607 * Servers MUST only include a OPTION_CLIENT_FQDN in ADVERTISE and REPLY messages.
2608 * [RFC 4704 Section 6.]
2610 if (msgtype == SOLICIT || msgtype == REQUEST || msgtype == RENEW || msgtype == REBIND)
2611 is_client = true;
2612 else if (msgtype == ADVERTISE || msgtype == REPLY)
2613 is_client = false;
2614 else {
2615 exi = proto_tree_add_uint_format(subtree, hf_clientfqdn_bad_msgtype, tvb, off-4, 1,
2616 msgtype,
2617 "Only the following message types are permitted to use OPTION_CLIENT_FQDN:\n"
2618 "SOLICIT, REQUEST, RENEW, REBIND, ADVERTISE, and REPLY");
2619 ex_subtree = proto_item_add_subtree(exi, ett_clientfqdn_expert);
2620 proto_tree_add_expert(ex_subtree, pinfo, &ei_dhcpv6_clientfqdn_bad_msgtype, tvb, off-4, 1);
2621 break;
2624 * +-----+-+-+-+
2625 * | MBZ |N|O|S|
2626 * +-----+-+-+-+
2628 * [RFC4704 Section 4.1]
2629 * "The 'S' bit indicates whether the server SHOULD or SHOULD NOT perform the AAAA RR (FQDN-to-address)
2630 * DNS updates. A client sets the bit to 0 to indicate that the server SHOULD NOT perform the updates
2631 * and 1 to indicate that the server SHOULD perform the updates. The state of the bit in the reply from
2632 * the server indicates the action to be taken by the server; if it is 1 the server has taken
2633 * responsibility for AAAA RR updates for the FQDN.
2635 * The 'O' bit indicates whether the server has overridden the client's preference for the 'S' bit.
2636 * A client MUST set this bit to 0. A server MUST set this bit to 1 if the "S" bit in its reply to the
2637 * client does not match the 'S' bit received from the client.
2639 * The 'N' bit indicates whether the server SHOULD NOT perform any DNS updates. A client sets this bit to
2640 * 0 to request that the server SHOULD perform updates (the PTR RR and possibly the AAAA RR based on the
2641 * 'S' bit) 1 to request that the server SHOULD NOT perform any DNS updates. A server sets the 'N' bit to
2642 * indicate whether the server SHALL (0) or SHALL NOT (1) perform DNS updates. If the 'N' bit is 1, the
2643 * 'S' bit MUST be 0."
2645 flags = tvb_get_uint8(tvb, off);
2646 suffix = "]";
2648 if (is_client) {
2649 /*CLIENT*/
2650 if ((flags & 0x5)==0) flags_str = "[CLIENT wants to update its AAAA RRs and SERVER to update its PTR RRs";
2651 if ((flags & 0x5)==1) flags_str = "[CLIENT wants SERVER to update both its AAAA and PTR RRs";
2652 if ((flags & 0x5)==4) flags_str = "[CLIENT prefers that the server not perform *any* DNS updates";
2653 if ((flags & 0x5)==5) flags_str = "[ERROR: CLIENT prefers that the server not perform *any* DNS updates\n"
2654 " In which case the 'S' bit MUST be 0";
2655 /* The client MUST set this bit to 0 (in that it is meaningless). */
2657 else {
2658 /*SERVER*/
2659 if ((flags & 0x5)==0) flags_str = "[CLIENT SHALL update AAAA RRs; SERVER SHALL update PTR RRs";
2660 if ((flags & 0x5)==1) flags_str = "[SERVER SHALL update both AAAA and PTR RRs";
2661 if ((flags & 0x5)==4) flags_str = "[CLIENT SHALL update AAAA RRs; SERVER SHALL NOT perform any DNS updates";
2662 if ((flags & 0x5)==5) flags_str = "[ERROR: SERVER SHALL NOT perform *any* DNS updates in which case "
2663 " the 'S' bit MUST be 0";
2664 if ((flags & 0x2)==2
2665 && ((flags & 0x5)==0 || (flags & 0x5)==1))
2666 suffix = "]\n[Server has overridden the client's S bit]";
2668 fi = proto_tree_add_uint_format(subtree, hf_clientfqdn_flags, tvb, off, 1, flags,
2669 "Flags: 0x%02x %s%s", flags, flags_str, suffix);
2670 flags_tree = proto_item_add_subtree(fi, ett_clientfqdn_flags);
2672 if (is_client) {
2673 proto_tree_add_item(flags_tree, hf_clientfqdn_client_n, tvb, off, 1, ENC_BIG_ENDIAN);
2674 proto_tree_add_item(flags_tree, hf_clientfqdn_client_s, tvb, off, 1, ENC_BIG_ENDIAN);
2676 else {
2677 proto_tree_add_item(flags_tree, hf_clientfqdn_server_n, tvb, off, 1, ENC_BIG_ENDIAN);
2678 proto_tree_add_item(flags_tree, hf_clientfqdn_server_o, tvb, off, 1, ENC_BIG_ENDIAN);
2679 proto_tree_add_item(flags_tree, hf_clientfqdn_server_s, tvb, off, 1, ENC_BIG_ENDIAN);
2681 if ((flags & 0x5)==5)
2682 proto_tree_add_expert(subtree, pinfo, &ei_dhcpv6_s_bit_should_be_zero, tvb, off, 1);
2684 dhcpv6_domain(subtree, option_item, pinfo, hf_client_fqdn, tvb, off+1, optlen-1);
2686 break;
2687 case OPTION_PANA_AGENT:
2688 if (optlen % 16) {
2689 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "PANA agent address: malformed option");
2690 break;
2692 for (i = 0; i < optlen; i += 16)
2693 proto_tree_add_item(subtree, hf_pana_agent, tvb, off + i, 16, ENC_NA);
2694 break;
2695 case OPTION_TIME_ZONE:
2696 if (optlen > 0)
2697 proto_tree_add_item(subtree, hf_opt_timezone, tvb, off, optlen, ENC_ASCII);
2698 break;
2699 case OPTION_TZDB:
2700 if (optlen > 0)
2701 proto_tree_add_item(subtree, hf_opt_tzdb, tvb, off, optlen, ENC_ASCII);
2702 break;
2704 case OPTION_MUDURL:
2705 if (optlen > 0)
2706 proto_tree_add_item(subtree, hf_opt_mudurl, tvb, off, optlen, ENC_ASCII);
2707 break;
2709 case OPTION_LQ_QUERY:
2711 uint8_t query_type;
2712 if (optlen < 17) {
2713 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "LQ-QUERY: malformed option");
2714 break;
2716 query_type = tvb_get_uint8(tvb, off);
2717 ti = proto_tree_add_item(subtree, hf_lq_query, tvb, off, 1, ENC_BIG_ENDIAN);
2718 if ((protocol == proto_dhcpv6) &&
2719 ((query_type == LQ_QUERY_RELAYID) ||
2720 (query_type == LQ_QUERY_LINK_ADDRESS) ||
2721 (query_type == LQ_QUERY_REMOTEID))) {
2722 expert_add_info(pinfo, ti, &ei_dhcpv6_bulk_leasequery_bad_query_type);
2725 proto_tree_add_item(subtree, hf_lq_query_link_address, tvb, off+1, 16, ENC_NA);
2726 temp_optlen = 17;
2727 while ((optlen - temp_optlen) > 0) {
2728 temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
2729 off + temp_optlen,
2730 off + optlen, at_end, protocol, hpi, msgtype);
2731 if (*at_end) {
2732 /* Bad option - just skip to the end */
2733 temp_optlen = optlen;
2737 break;
2738 case OPTION_CLIENT_DATA:
2739 temp_optlen = 0;
2740 while ((optlen - temp_optlen) > 0) {
2741 temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
2742 off + temp_optlen,
2743 off + optlen, at_end, protocol, hpi, msgtype);
2744 if (*at_end) {
2745 /* Bad option - just skip to the end */
2746 temp_optlen = optlen;
2749 break;
2750 case OPTION_CLT_TIME:
2751 if (optlen != 4) {
2752 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "CLT_TIME: malformed option");
2753 break;
2756 proto_tree_add_item(subtree, hf_clt_time, tvb, off, 4, ENC_BIG_ENDIAN);
2757 break;
2758 case OPTION_LQ_RELAY_DATA:
2759 if (optlen < 16) {
2760 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "LQ_RELAY_DATA: malformed option");
2761 break;
2764 proto_tree_add_item(subtree, hf_lq_relay_data_peer_addr, tvb, off, 16, ENC_NA);
2765 proto_tree_add_item(subtree, hf_lq_relay_data_msg, tvb, off+16, optlen - 16, ENC_ASCII);
2766 break;
2767 case OPTION_LQ_CLIENT_LINK:
2768 if (optlen % 16) {
2769 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "LQ client links address: malformed option");
2770 break;
2772 for (i = 0; i < optlen; i += 16)
2773 proto_tree_add_item(subtree, hf_lq_client_link, tvb, off + i, 16, ENC_NA);
2774 break;
2775 case OPTION_CAPWAP_AC_V6:
2776 if (optlen % 16) {
2777 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "CAPWAP Access Controllers address: malformed option");
2778 break;
2780 for (i = 0; i < optlen; i += 16)
2781 proto_tree_add_item(subtree, hf_capwap_ac_v6, tvb, off + i, 16, ENC_NA);
2782 break;
2784 case OPTION_AFTR_NAME:
2785 dhcpv6_domain(subtree, option_item, pinfo, hf_aftr_name, tvb, off, optlen);
2786 break;
2787 case OPTION_IAPREFIX:
2788 if (optlen < 25) {
2789 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "IAPREFIX: malformed option");
2790 break;
2793 proto_tree_add_item(subtree, hf_iaprefix_pref_lifetime, tvb, off, 4, ENC_BIG_ENDIAN);
2794 proto_tree_add_item(subtree, hf_iaprefix_valid_lifetime, tvb, off+4, 4, ENC_BIG_ENDIAN);
2795 proto_tree_add_item(subtree, hf_iaprefix_pref_len, tvb, off+8, 1, ENC_BIG_ENDIAN);
2796 proto_tree_add_item(subtree, hf_iaprefix_pref_addr, tvb, off+9, 16, ENC_NA);
2797 temp_optlen = 25;
2798 while ((optlen - temp_optlen) > 0) {
2799 temp_optlen += dhcpv6_option(tvb, pinfo, subtree,
2800 off+temp_optlen, off + optlen, at_end, protocol, hpi, msgtype);
2801 if (*at_end) {
2802 /* Bad option - just skip to the end */
2803 temp_optlen = optlen;
2806 break;
2807 case OPTION_MIP6_HA:
2808 if (optlen != 16) {
2809 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "MIP6_HA: malformed option");
2810 break;
2812 proto_tree_add_item(subtree, hf_mip6_ha, tvb, off, 16, ENC_NA);
2813 break;
2814 case OPTION_MIP6_HOA:
2815 if (optlen != 16) {
2816 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "MIP6_HOA: malformed option");
2817 break;
2820 proto_tree_add_item(subtree, hf_mip6_hoa, tvb, off, 16, ENC_NA);
2821 break;
2822 case OPTION_NAI:
2823 if (optlen < 4) {
2824 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "NAI: malformed option");
2825 break;
2827 proto_tree_add_item(subtree, hf_nai, tvb, off, optlen - 2, ENC_ASCII);
2828 break;
2829 case OPTION_PD_EXCLUDE:
2830 if ((optlen < 2) || (optlen > 17)) {
2831 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "PD_EXCLUDE: malformed option");
2832 break;
2834 proto_tree_add_item(subtree, hf_pd_exclude_pref_len, tvb, off, 1, ENC_BIG_ENDIAN);
2835 proto_tree_add_item(subtree, hf_pd_exclude_subnet_id , tvb, off+1, optlen-1, ENC_NA);
2836 break;
2837 case OPTION_CAPTIVE_PORTAL:{
2838 proto_item *ti_cp;
2839 ti_cp = proto_tree_add_item(subtree, hf_option_captive_portal, tvb, off, optlen, ENC_ASCII);
2840 proto_item_set_url(ti_cp);
2841 break;
2843 case OPTION_S46_PRIORITY:
2844 temp_optlen = optlen;
2845 while (temp_optlen >= 2) {
2846 proto_tree_add_item(subtree, hf_option_s46_option_code, tvb, off, 2, ENC_BIG_ENDIAN);
2847 temp_optlen -= 2;
2848 off += 2;
2850 break;
2851 case OPTION_F_BINDING_STATUS:
2852 if (optlen != 1) {
2853 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2854 break;
2856 proto_tree_add_item(subtree, hf_option_failover_binding_status, tvb, off, 1, ENC_BIG_ENDIAN);
2857 break;
2858 case OPTION_F_CONNECT_FLAGS:
2859 if (optlen != 2) {
2860 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2861 break;
2863 proto_tree_add_bitmask(subtree, tvb, off, hf_option_failover_connect_flags, ett_dhcpv6_failover_connect_flags, dhcpv6_failover_connect_flags_fields, ENC_BIG_ENDIAN);
2864 break;
2865 case OPTION_F_DNS_HOST_NAME:
2867 const char *dns_name;
2868 int dns_name_len;
2870 get_dns_name(tvb, off, optlen, off, &dns_name, &dns_name_len);
2871 proto_tree_add_string(subtree, hf_option_failover_dns_hostname, tvb, off, optlen, format_text(pinfo->pool, dns_name, dns_name_len));
2872 break;
2874 case OPTION_F_DNS_ZONE_NAME:
2876 const char *dns_name;
2877 int dns_name_len;
2879 get_dns_name(tvb, off, optlen, off, &dns_name, &dns_name_len);
2880 proto_tree_add_string(subtree, hf_option_failover_dns_zonename, tvb, off, optlen, format_text(pinfo->pool, dns_name, dns_name_len));
2881 break;
2883 case OPTION_F_DNS_FLAGS:
2884 if (optlen != 2) {
2885 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2886 break;
2888 proto_tree_add_bitmask(subtree, tvb, off, hf_option_failover_dns_flags, ett_dhcpv6_failover_dns_flags, dhcpv6_failover_dns_flags_fields, ENC_BIG_ENDIAN);
2889 break;
2890 case OPTION_F_EXPIRATION_TIME:
2891 if (optlen != 4) {
2892 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2893 break;
2895 proto_tree_add_item(subtree, hf_option_failover_expiration_time, tvb, off, 4, ENC_BIG_ENDIAN);
2896 break;
2897 case OPTION_F_MAX_UNACKED_BNDUPD:
2898 if (optlen != 4) {
2899 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2900 break;
2902 proto_tree_add_item(subtree, hf_option_failover_max_unacked_bndupd, tvb, off, 4, ENC_BIG_ENDIAN);
2903 break;
2904 case OPTION_F_MCLT:
2905 if (optlen != 4) {
2906 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2907 break;
2909 proto_tree_add_item(subtree, hf_option_failover_mclt, tvb, off, 4, ENC_BIG_ENDIAN);
2910 break;
2911 case OPTION_F_PARTNER_LIFETIME:
2912 if (optlen != 4) {
2913 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2914 break;
2916 proto_tree_add_item(subtree, hf_option_failover_partner_lifetime, tvb, off, 4, ENC_BIG_ENDIAN);
2917 break;
2918 case OPTION_F_PARTNER_LIFETIME_SENT:
2919 if (optlen != 4) {
2920 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2921 break;
2923 proto_tree_add_item(subtree, hf_option_failover_partner_lifetime_sent, tvb, off, 4, ENC_BIG_ENDIAN);
2924 break;
2925 case OPTION_F_PARTNER_DOWN_TIME:
2926 if (optlen != 4) {
2927 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2928 break;
2930 proto_tree_add_item(subtree, hf_option_failover_partner_downtime, tvb, off, 4, ENC_BIG_ENDIAN);
2931 break;
2932 case OPTION_F_PARTNER_RAW_CLT_TIME:
2933 if (optlen != 4) {
2934 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2935 break;
2937 proto_tree_add_item(subtree, hf_option_failover_partner_raw_clt_time, tvb, off, 4, ENC_BIG_ENDIAN);
2938 break;
2939 case OPTION_F_PROTOCOL_VERSION:
2940 if (optlen != 4) {
2941 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2942 break;
2944 proto_tree_add_item(subtree, hf_option_failover_major_version, tvb, off, 2, ENC_BIG_ENDIAN);
2945 proto_tree_add_item(subtree, hf_option_failover_minor_version, tvb, off+2, 2, ENC_BIG_ENDIAN);
2946 break;
2947 case OPTION_F_KEEPALIVE_TIME:
2948 if (optlen != 4) {
2949 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2950 break;
2952 proto_tree_add_item(subtree, hf_option_failover_keepalive_time, tvb, off, 4, ENC_BIG_ENDIAN);
2953 break;
2954 case OPTION_F_RECONFIGURE_DATA:
2955 if (optlen < 4) {
2956 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2957 break;
2959 proto_tree_add_item(subtree, hf_option_failover_reconfigure_time, tvb, off, 4, ENC_BIG_ENDIAN);
2960 proto_tree_add_item(subtree, hf_option_failover_reconfigure_key, tvb, off+4, optlen-4, ENC_NA);
2961 break;
2962 case OPTION_F_RELATIONSHIP_NAME:
2963 proto_tree_add_item(subtree, hf_option_failover_relationship_name, tvb, off, optlen, ENC_UTF_8);
2964 break;
2965 case OPTION_F_SERVER_FLAGS:
2966 if (optlen != 1) {
2967 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2968 break;
2970 proto_tree_add_bitmask(subtree, tvb, off, hf_option_failover_server_flags, ett_dhcpv6_failover_server_flags, dhcpv6_failover_server_flags_fields, ENC_BIG_ENDIAN);
2971 break;
2972 case OPTION_F_SERVER_STATE:
2973 if (optlen != 1) {
2974 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2975 break;
2977 proto_tree_add_item(subtree, hf_option_failover_server_state, tvb, off, 1, ENC_BIG_ENDIAN);
2978 break;
2979 case OPTION_F_START_TIME_OF_STATE:
2980 if (optlen != 4) {
2981 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2982 break;
2984 proto_tree_add_item(subtree, hf_option_failover_start_time_of_state, tvb, off, 4, ENC_BIG_ENDIAN);
2985 break;
2986 case OPTION_F_STATE_EXPIRATION_TIME:
2987 if (optlen != 4) {
2988 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Failover: malformed option");
2989 break;
2991 proto_tree_add_item(subtree, hf_option_failover_state_expiration_time, tvb, off, 4, ENC_BIG_ENDIAN);
2992 break;
2993 case OPTION_RELAY_PORT:
2994 if (optlen != 2) {
2995 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Relay Port: malformed option");
2996 break;
2998 proto_tree_add_item(subtree, hf_option_relay_port, tvb, off, 2, ENC_BIG_ENDIAN);
2999 break;
3000 case OPTION_CLIENT_LINKLAYER_ADDR:
3001 if (optlen < 2) {
3002 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option, "Client link-layer address: malformed option");
3003 break;
3005 proto_tree_add_item_ret_uint(subtree, hf_client_link_layer_addr_hwtype, tvb, off, 2, ENC_BIG_ENDIAN, &temp_uint32);
3006 hwtype = temp_uint32 & 0xffff;
3007 if (optlen > 2) {
3008 proto_tree_add_string(subtree, hf_client_link_layer_addr, tvb, off+2, optlen-2,
3009 tvb_arphrdaddr_to_str(pinfo->pool, tvb, off+2, optlen-2, hwtype));
3010 if (DHCPV6_HW_IS_ETHER(hwtype, optlen-2)) {
3011 proto_tree_add_item(subtree, hf_client_link_layer_addr_ether, tvb, off+2, optlen-2, ENC_NA);
3014 break;
3015 case OPTION_V6_DNR: {
3016 // This option is pretty complex, with variable-length fields, FQDN, list of addresses, and service parameters
3017 // that have their own encoding, borrowed from DNS on-wire. Ugh. For option syntax, see RFC9463, Section 4.1.
3018 // The svcparams field is encoded according to RFC9460, Section 2.2. There is a registry of supported
3019 // service parameters, maintained by IANA (see https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml).
3020 // Initial (currently defined, as of Aug 2024) list of parmaters (that are usable in DHCPv6 DNR option) are:
3021 // alpn, port, dohpath.
3023 // This is a very active discussion area in the IETF, so more parameters are expected in the future.
3025 int adn_len = 0;
3026 int addrs_len = 0;
3027 // off is an offset from the beginning of a DHCPv6 packet. It is NOT zero when we start.
3028 int offset = 0; // offset within the DNR option. This starts at zero.
3029 uint32_t svcparams_key = 0;
3030 uint32_t svcparams_length = 0;
3031 uint32_t svcparams_alpn_length = 0;
3032 uint32_t svcparams_port = 0;
3034 proto_item *svcparams_ti = NULL;
3035 proto_tree *svcparams_tree = NULL;
3037 if (optlen < 6) {
3038 // At the very least svcpriority, an empty auth-domain-name, and empty address list is
3039 // necessary. The option would be still broken, but at least we could parse something.
3040 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option,
3041 "DNR v6 error: truncated option (shorter than 6 octets)");
3042 break;
3045 // Parsing service priority
3046 proto_tree_add_item(subtree, hf_dnr_svcpriority, tvb, off, 2, ENC_BIG_ENDIAN);
3047 offset += 2;
3049 // Parsing authentication-domain-name (len + FQDN field)
3050 proto_tree_add_item(subtree, hf_dnr_auth_domain_name_len, tvb, off+offset, 2, ENC_BIG_ENDIAN);
3051 adn_len = tvb_get_ntohs(tvb, off+offset);
3052 offset += 2;
3053 if (optlen < offset + adn_len) {
3054 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option,
3055 "DNR v6 error: truncated option (too long authentication-domain-name)");
3056 break;
3058 dhcpv6_domain(subtree, ti, pinfo, hf_dnr_auth_domain_name, tvb, off+offset, adn_len);
3059 offset += adn_len;
3061 // Parse Addresses list (length + actual list)
3062 if (optlen < offset + 2) {
3063 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option,
3064 "DNR v6 error: truncated option (Addr Length truncated)");
3065 break;
3067 addrs_len = tvb_get_ntohs(tvb, off+offset);
3068 proto_tree_add_item(subtree, hf_dnr_addrs_len, tvb, off+offset, 2, ENC_BIG_ENDIAN);
3069 offset += 2;
3071 if (addrs_len % 16) {
3072 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option,
3073 "v6 Discovery of Network Resolvers: invalid addrs_len %d (not divisible by 16)", addrs_len);
3074 break;
3076 if (optlen < offset + addrs_len) {
3077 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option,
3078 "DNR v6 error: truncated option (too long addrs_len or not enough octets with addresses)");
3079 break;
3082 for (i = 0; i < addrs_len; i += 16) {
3083 ti = proto_tree_add_item(subtree, hf_dnr_addrs, tvb, off + offset + i, 16, ENC_NA);
3084 proto_item_prepend_text(ti, " %d ", i/16 + 1);
3086 offset += addrs_len;
3088 // Parse the service parameters
3089 if (offset < optlen) {
3090 while (offset < optlen) {
3091 svcparams_ti = proto_tree_add_item(subtree, hf_dnr_svcparams, tvb, off + offset, -1, ENC_NA);
3092 svcparams_tree = proto_item_add_subtree(svcparams_ti, ett_dhcpv6_dnr_svcparams);
3094 proto_tree_add_item_ret_uint(svcparams_tree, hf_dnr_svcparams_key, tvb, off + offset, 2, ENC_BIG_ENDIAN, &svcparams_key);
3095 offset += 2;
3097 proto_tree_add_item_ret_uint(svcparams_tree, hf_dnr_svcparams_length, tvb, off + offset, 2, ENC_BIG_ENDIAN, &svcparams_length);
3098 offset += 2;
3100 proto_item_append_text(svcparams_ti, ": %s", val_to_str(svcparams_key, dnr_svcparams_key_vals, "key%u"));
3101 proto_item_set_len(svcparams_ti, svcparams_length + 4);
3103 switch(svcparams_key) {
3104 // There are other service parameters, but only ALPN and PORT use special encoding. Everything else
3105 // is a simple string encoding.
3106 case DNR_SVCPARAMS_KEY_ALPN:
3107 for (uint32_t svcparams_offset = 0; svcparams_offset < svcparams_length; ) {
3108 const uint8_t *alpn = 0;
3109 proto_tree_add_item_ret_uint(svcparams_tree, hf_dnr_svcparams_alpn_length, tvb, off+offset+svcparams_offset, 1, ENC_BIG_ENDIAN, &svcparams_alpn_length);
3110 proto_tree_add_item_ret_string(svcparams_tree, hf_dnr_svcparams_alpn, tvb, off+offset + 1 +svcparams_offset, svcparams_alpn_length, ENC_ASCII|ENC_NA, pinfo->pool, &alpn);
3111 proto_item_append_text(svcparams_ti, "%c%s", (svcparams_offset == 0 ? '=' : ','), alpn);
3112 svcparams_offset += 1 + svcparams_alpn_length;
3114 offset += svcparams_length;
3115 break;
3116 case DNR_SVCPARAMS_KEY_PORT:
3117 proto_tree_add_item_ret_uint(svcparams_tree, hf_dnr_svcparams_port, tvb, off+offset, 2, ENC_BIG_ENDIAN, &svcparams_port);
3118 proto_item_append_text(svcparams_ti, "=%u", svcparams_port);
3119 offset += 2;
3120 break;
3121 default:
3122 if (svcparams_length > 0) {
3123 proto_tree_add_item(svcparams_tree, hf_dnr_svcparams_value, tvb, off+offset, svcparams_length, ENC_NA);
3124 proto_item_append_text(svcparams_ti, "=%s", tvb_format_text(pinfo->pool, tvb, off+offset, svcparams_length));
3125 offset += svcparams_length;
3127 break;
3131 } else {
3132 expert_add_info_format(pinfo, option_item, &ei_dhcpv6_malformed_option,
3133 "DNR v6 error: truncated option (missing service parameters)");
3136 break;
3140 decrement_dissection_depth(pinfo);
3142 return 4 + optlen;
3146 /* May be called recursively via dhcpv6_option */
3147 static void
3148 // NOLINTNEXTLINE(misc-no-recursion)
3149 dissect_dhcpv6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3150 int off, int eoff, hopcount_info hpi)
3152 proto_tree *bp_tree = NULL;
3153 proto_item *ti;
3154 bool at_end;
3155 uint8_t msgtype;
3156 msgtype = tvb_get_uint8(tvb, off);
3158 col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str_ext(msgtype, &msgtype_vals_ext, "Message Type %u"));
3160 if (tree) {
3161 ti = proto_tree_add_item(tree, proto_dhcpv6, tvb, off, eoff - off, ENC_NA);
3162 bp_tree = proto_item_add_subtree(ti, ett_dhcpv6);
3166 if ((msgtype == RELAY_FORW) || (msgtype == RELAY_REPLY)) {
3167 const uint8_t previous_hopcount = hpi.hopcount;
3168 proto_item *previous_pi = hpi.pi;
3169 if (tree) {
3170 proto_tree_add_item(bp_tree, hf_dhcpv6_msgtype, tvb, off, 1, ENC_BIG_ENDIAN);
3171 hpi.pi = proto_tree_add_item(bp_tree, hf_dhcpv6_hopcount, tvb, off + 1, 1, ENC_BIG_ENDIAN);
3172 proto_tree_add_item(bp_tree, hf_dhcpv6_linkaddr, tvb, off + 2, 16, ENC_NA);
3173 proto_tree_add_item(bp_tree, hf_dhcpv6_peeraddr, tvb, off + 18, 16, ENC_NA);
3176 /* Check the hopcount not exceed the HOP_COUNT_LIMIT */
3177 hpi.hopcount = tvb_get_uint8(tvb, off + 1);
3178 if (hpi.hopcount > HOP_COUNT_LIMIT) {
3179 expert_add_info_format(pinfo, hpi.pi, &ei_dhcpv6_error_hopcount, "Hopcount (%d) exceeds the maximum limit HOP_COUNT_LIMIT (%d)", hpi.hopcount, HOP_COUNT_LIMIT);
3181 /* Check hopcount is correctly incremented by 1 */
3182 if (hpi.relay_message_previously_detected && hpi.hopcount != previous_hopcount - 1) {
3183 expert_add_info_format(pinfo, previous_pi, &ei_dhcpv6_error_hopcount, "hopcount is not correctly incremented by 1 (expected : %d, actual : %d)", hpi.hopcount + 1, previous_hopcount);
3185 hpi.relay_message_previously_detected = true;
3186 col_append_fstr(pinfo->cinfo, COL_INFO, "L: %s ", tvb_ip6_to_str(pinfo->pool, tvb, off + 2));
3187 off += 34;
3188 } else {
3189 /* Check the inner hopcount equals 0 */
3190 if (hpi.hopcount) {
3191 expert_add_info_format(pinfo, hpi.pi, &ei_dhcpv6_error_hopcount, "Hopcount of most inner message has to equal 0 instead of %d", hpi.hopcount);
3193 if (tree) {
3194 proto_tree_add_item(bp_tree, hf_dhcpv6_msgtype, tvb, off, 1, ENC_BIG_ENDIAN);
3195 proto_tree_add_item(bp_tree, hf_dhcpv6_xid, tvb, off + 1, 3, ENC_BIG_ENDIAN);
3197 col_append_fstr(pinfo->cinfo, COL_INFO, "XID: 0x%06x ", tvb_get_ntoh24(tvb, off + 1));
3198 off += 4;
3201 at_end = false;
3202 while ((off < eoff) && !at_end)
3203 off += dhcpv6_option(tvb, pinfo, bp_tree, off, eoff, &at_end, proto_dhcpv6, hpi, msgtype);
3206 static int
3207 dissect_dhcpv6_stream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3209 hopcount_info hpi;
3210 initialize_hopount_info(&hpi);
3211 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv6");
3212 col_clear(pinfo->cinfo, COL_INFO);
3213 dissect_dhcpv6(tvb, pinfo, tree, 0, tvb_reported_length(tvb), hpi);
3214 return tvb_captured_length(tvb);
3217 static unsigned
3218 get_dhcpv6_bulk_leasequery_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
3219 int offset, void *data _U_)
3221 return (tvb_get_ntohs(tvb, offset)+2);
3224 static int
3225 dissect_dhcpv6_bulk_leasequery_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3227 proto_item *ti;
3228 proto_tree *bulk_tree, *option_tree;
3229 int offset = 0, end;
3230 uint16_t size, trans_id;
3231 uint8_t msg_type;
3232 bool at_end = false;
3233 hopcount_info hpi;
3234 initialize_hopount_info(&hpi);
3236 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCPv6 BulkLease");
3237 col_clear(pinfo->cinfo, COL_INFO);
3239 ti = proto_tree_add_item(tree, proto_dhcpv6_bulk_leasequery, tvb, 0, -1, ENC_NA );
3240 bulk_tree = proto_item_add_subtree(ti, ett_dhcpv6_bulk_leasequery);
3242 size = tvb_get_ntohs(tvb, offset);
3243 proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_size, tvb, offset, 2, ENC_BIG_ENDIAN);
3244 offset += 2;
3246 msg_type = tvb_get_uint8( tvb, offset );
3247 ti = proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_msgtype, tvb, offset, 1, ENC_BIG_ENDIAN);
3248 if ((msg_type != LEASEQUERY) &&
3249 (msg_type != LEASEQUERY_REPLY) &&
3250 (msg_type != LEASEQUERY_DONE) &&
3251 (msg_type != LEASEQUERY_DATA))
3252 expert_add_info_format(pinfo, ti, &ei_dhcpv6_bulk_leasequery_bad_msg_type,
3253 "Message Type %d not allowed by DHCPv6 Bulk Leasequery", msg_type);
3255 offset += 1;
3256 proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
3257 offset += 1;
3259 trans_id = tvb_get_ntohs(tvb, offset);
3260 proto_tree_add_item(bulk_tree, hf_dhcpv6_bulk_leasequery_trans_id, tvb, offset, 2, ENC_BIG_ENDIAN);
3261 offset += 2;
3263 col_add_fstr(pinfo->cinfo, COL_INFO, "%s, Transaction ID: %5u",
3264 val_to_str_ext_const(msg_type, &msgtype_vals_ext, "Unknown"), trans_id);
3266 option_tree = proto_tree_add_subtree(bulk_tree, tvb, offset, -1, ett_dhcpv6_bulk_leasequery_options, NULL, "DHCPv6 Options");
3267 end = size + 2;
3268 while ((offset < end) && !at_end)
3269 offset += dhcpv6_option(tvb, pinfo, option_tree, offset,
3270 end, &at_end, proto_dhcpv6_bulk_leasequery, hpi, msg_type);
3272 return tvb_reported_length(tvb);
3275 static int
3276 dissect_dhcpv6_bulk_leasequery(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3278 tcp_dissect_pdus(tvb, pinfo, tree, dhcpv6_bulk_leasequery_desegment, 2,
3279 get_dhcpv6_bulk_leasequery_pdu_len, dissect_dhcpv6_bulk_leasequery_pdu, data);
3280 return tvb_reported_length(tvb);
3283 static int dissect_dhcpv6_s46_ipv6_prefix(tvbuff_t *tvb, int hf, int offset, int prefix_length, proto_tree *tree)
3286 int bytes_to_process;
3287 ws_in6_addr prefix;
3289 bytes_to_process = (((prefix_length + 7) & 0xf8) >> 3);
3291 memset(prefix.bytes, 0, sizeof prefix.bytes);
3292 if (bytes_to_process != 0) {
3293 tvb_memcpy(tvb, prefix.bytes, offset, bytes_to_process);
3295 proto_tree_add_ipv6(tree, hf, tvb, offset, bytes_to_process, &prefix);
3297 return bytes_to_process;
3300 void
3301 proto_register_dhcpv6(void)
3303 module_t *bulkquery_module;
3304 module_t *dhcpv6_module;
3306 static hf_register_info hf[] = {
3308 /* DHCPv6 header */
3309 { &hf_dhcpv6_msgtype,
3310 { "Message type", "dhcpv6.msgtype", FT_UINT8, BASE_DEC | BASE_EXT_STRING, &msgtype_vals_ext, 0x0, NULL, HFILL }},
3311 { &hf_dhcpv6_hopcount,
3312 { "Hopcount", "dhcpv6.hopcount", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
3313 { &hf_dhcpv6_xid,
3314 { "Transaction ID", "dhcpv6.xid", FT_UINT24, BASE_HEX, NULL, 0, NULL, HFILL}},
3315 { &hf_dhcpv6_linkaddr,
3316 { "Link address", "dhcpv6.linkaddr", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL}},
3317 { &hf_dhcpv6_peeraddr,
3318 { "Peer address", "dhcpv6.peeraddr", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL}},
3319 /* Generic option stuff */
3320 { &hf_option_type_num,
3321 { "Option", "dhcpv6.option.type", FT_UINT16, BASE_DEC | BASE_EXT_STRING, &opttype_vals_ext, 0x0, NULL, HFILL}},
3322 { &hf_option_length,
3323 { "Length", "dhcpv6.option.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
3324 { &hf_option_type_str,
3325 { "Option", "dhcpv6.option.type_str", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3327 /* OPTION_CLIENT_FQDN */
3328 { &hf_clientfqdn_bad_msgtype,
3329 { "Illegal Message Type", "dhcpv6.clientfqdn.bad_msgtype", FT_UINT8, BASE_HEX | BASE_EXT_STRING, &msgtype_vals_ext, 0x0, NULL, HFILL }},
3330 { &hf_clientfqdn_flags,
3331 { "Flags", "dhcpv6.client_fqdn_flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3332 /* Client's preferences */
3333 { &hf_clientfqdn_client_s,
3334 { "S bit", "dhcpv6.clientfqdn.client.s", FT_BOOLEAN, 8, TFS(&fqdn_s), 0x1,
3335 "Whether or not the client prefers to perform AAAA RR (FQDN-to-address) updates", HFILL}},
3336 { &hf_clientfqdn_client_n,
3337 { "N bit", "dhcpv6.clientfqdn.client.n", FT_BOOLEAN, 8, TFS(&fqdn_n), 0x4,
3338 "Whether or not the client prefers to perform PTR RR (address-to-FQDN) updates", HFILL}},
3339 /* Server's decision to reject or accept the client's preferences */
3340 { &hf_clientfqdn_server_s,
3341 { "S bit", "dhcpv6.clientfqdn.server.s", FT_BOOLEAN, 8, TFS(&fqdn_s), 0x1,
3342 "Whether or not the server SHALL perform AAAA RR (FQDN-to-address) updates", HFILL}},
3343 { &hf_clientfqdn_server_o,
3344 { "O bit", "dhcpv6.clientfqdn.server.o", FT_BOOLEAN, 8, TFS(&fqdn_o), 0x2,
3345 "Whether or not the server has overridden the client's S-bit preference", HFILL}},
3346 { &hf_clientfqdn_server_n,
3347 { "N bit", "dhcpv6.clientfqdn.server.n", FT_BOOLEAN, 8, TFS(&fqdn_n), 0x4,
3348 "Whether or not the server SHALL perform PTR RR (address-to-FQDN) updates", HFILL}},
3350 /* Headers used in dhcpv6_domain(). */
3351 { &hf_empty_domain_name,
3352 { "Empty domain name - field length", "dhcpv6.domain_field_len", FT_UINT16, BASE_DEC, NULL, 0,
3353 "Indicates that the client requests the server to provide an FQDN name", HFILL}},
3354 { &hf_dhcpv6_non_dns_encoded_name,
3355 { "Non-DNS encoded name. Label length exceeds 63", "dhcpv6.bogus_label_length",
3356 FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
3357 { &hf_dhcpv6_domain_field_len_exceeded,
3358 { "Remaining length in the domain name field exceeded", "dhcpv6.domain_field_len_exceeded", FT_UINT8, BASE_DEC,
3359 NULL, 0, NULL, HFILL }},
3360 { &hf_dhcpv6_decoded_portion,
3361 { "Portion successfully decoded", "dhcpv6.decoded_portion", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL}},
3362 { &hf_dhcpv6_encoded_fqdn_len_gt_255,
3363 { "DNS-encoded labels of FQDN exceed 255 octets", "dhcpv6.encoded_fqdn_gt_255", FT_UINT16, BASE_DEC, NULL, 0,
3364 "Encoded length is greater than 255 [RFC 1035 3.1.]", HFILL}},
3365 { &hf_dhcpv6_root_only_domain_name,
3366 { "Root only domain name", "dhcpv6.root_only_domain_name", FT_STRING, BASE_NONE, NULL, 0,
3367 "The root domain cannot be resolved", HFILL}},
3368 { &hf_dhcpv6_tld,
3369 { "Top Level Domain name", "dhcpv6.tld", FT_STRING, BASE_NONE, NULL, 0,
3370 "Likely to fail because most TLDs do not have an IP address", HFILL}},
3371 { &hf_dhcpv6_partial_name_preceded_by_fqdn,
3372 { "Partial name preceded by FQDN", "dhcpv6.partial_name_preceded_by_fqdn", FT_STRING, BASE_NONE, NULL, 0,
3373 "Partial domain names must be the only name in the domain field", HFILL}},
3375 { &hf_remoteid_enterprise,
3376 { "Enterprise ID", "dhcpv6.remoteid.enterprise", FT_UINT32, BASE_ENTERPRISES, STRINGS_ENTERPRISES, 0, "RemoteID Enterprise Number", HFILL }},
3377 { &hf_duid_bytes,
3378 { "DUID", "dhcpv6.duid.bytes", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3379 { &hf_duid_type,
3380 { "DUID Type", "dhcpv6.duid.type", FT_UINT16, BASE_DEC, VALS(duidtype_vals), 0x0, NULL, HFILL}},
3381 { &hf_duidllt_time,
3382 { "DUID Time", "dhcpv6.duidllt.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0, NULL, HFILL}},
3383 { &hf_duidllt_link_layer_addr,
3384 { "Link-layer address", "dhcpv6.duidllt.link_layer_addr", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3385 { &hf_duidllt_link_layer_addr_ether,
3386 { "Link-layer address (Ethernet)", "dhcpv6.duidllt.link_layer_addr_ether", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3387 { &hf_duidllt_hwtype,
3388 { "Hardware type", "dhcpv6.duidllt.hwtype", FT_UINT16, BASE_DEC, VALS(arp_hrd_vals), 0, "DUID LLT Hardware Type", HFILL }},
3389 { &hf_duidll_hwtype,
3390 { "Hardware type", "dhcpv6.duidll.hwtype", FT_UINT16, BASE_DEC, VALS(arp_hrd_vals), 0, "DUID LL Hardware Type", HFILL }},
3391 { &hf_duiden_enterprise,
3392 { "Enterprise ID", "dhcpv6.duiden.enterprise", FT_UINT32, BASE_ENTERPRISES, STRINGS_ENTERPRISES, 0, "DUID EN Enterprise Number", HFILL }},
3393 { &hf_duiden_identifier,
3394 { "Identifier", "dhcpv6.duiden.identifier", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3395 { &hf_duidll_link_layer_addr,
3396 { "Link-layer address", "dhcpv6.duidll.link_layer_addr", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3397 { &hf_duidll_link_layer_addr_ether,
3398 { "Link-layer address (Ethernet)", "dhcpv6.duidll.link_layer_addr_ether", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3399 { &hf_duiduuid_bytes,
3400 { "UUID", "dhcpv6.duiduuid.bytes", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3401 { &hf_iaid,
3402 { "IAID", "dhcpv6.iaid", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3403 { &hf_iaid_t1,
3404 { "T1", "dhcpv6.iaid.t1", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(infinity_val), 0, NULL, HFILL}},
3405 { &hf_iaid_t2,
3406 { "T2", "dhcpv6.iaid.t2", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(infinity_val), 0, NULL, HFILL}},
3407 { &hf_iata,
3408 { "IATA", "dhcpv6.iata", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3409 { &hf_iaaddr_ip,
3410 { "IPv6 address", "dhcpv6.iaaddr.ip", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3411 { &hf_iaaddr_pref_lifetime,
3412 { "Preferred lifetime", "dhcpv6.iaaddr.pref_lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(infinity_val), 0, NULL, HFILL}},
3413 { &hf_iaaddr_valid_lifetime,
3414 { "Valid lifetime", "dhcpv6.iaaddr.valid_lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(infinity_val), 0, NULL, HFILL}},
3415 { &hf_requested_option_code,
3416 { "Requested Option code", "dhcpv6.requested_option_code", FT_UINT16, BASE_DEC | BASE_EXT_STRING, &opttype_vals_ext, 0, NULL, HFILL }},
3417 { &hf_option_preference,
3418 { "Pref-value", "dhcpv6.option_preference", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
3419 { &hf_elapsed_time,
3420 { "Elapsed time", "dhcpv6.elapsed_time", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_milliseconds), 0, NULL, HFILL}},
3421 { &hf_auth_protocol,
3422 { "Protocol", "dhcpv6.auth.protocol", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
3423 { &hf_auth_algorithm,
3424 { "Algorithm", "dhcpv6.auth.algorithm", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
3425 { &hf_auth_rdm,
3426 { "RDM", "dhcpv6.auth.rdm", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL}},
3427 { &hf_auth_replay_detection,
3428 { "Replay Detection", "dhcpv6.auth.replay_detection", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3429 { &hf_auth_info,
3430 { "Authentication Information", "dhcpv6.auth.info", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3431 { &hf_auth_realm,
3432 { "DHCP realm", "dhcpv6.auth.realm", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3433 { &hf_auth_key_id,
3434 {"Key ID", "dhcpv6.auth.key_id", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
3435 { &hf_auth_md5_data,
3436 {"HMAC-MD5 data", "dhcpv6.auth.md5_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3437 { &hf_opt_unicast,
3438 { "IPv6 address", "dhcpv6.unicast", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3439 { &hf_opt_status_code,
3440 { "Status Code", "dhcpv6.status_code", FT_UINT16, BASE_DEC | BASE_EXT_STRING, &statuscode_vals_ext, 0, NULL, HFILL }},
3441 { &hf_opt_status_msg,
3442 { "Status Message", "dhcpv6.status_msg", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3443 { &hf_vendorclass_enterprise,
3444 { "Enterprise ID", "dhcpv6.vendorclass.enterprise", FT_UINT32, BASE_ENTERPRISES, STRINGS_ENTERPRISES, 0, "Vendor Class Enterprise Number", HFILL }},
3445 { &hf_vendorclass_data,
3446 { "vendor-class-data", "dhcpv6.vendorclass.data", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL }},
3447 { &hf_vendoropts_enterprise,
3448 { "Enterprise ID", "dhcpv6.vendoropts.enterprise", FT_UINT32, BASE_ENTERPRISES, STRINGS_ENTERPRISES, 0, "Vendor opts Enterprise Number", HFILL }},
3449 { &hf_vendoropts_enterprise_option_code,
3450 { "Option code", "dhcpv6.vendoropts.enterprise.option_code", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
3451 { &hf_vendoropts_enterprise_option_length,
3452 { "Option length", "dhcpv6.vendoropts.enterprise.option_length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
3453 { &hf_vendoropts_enterprise_option_data,
3454 { "Option data", "dhcpv6.vendoropts.enterprise.option_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3455 { &hf_interface_id,
3456 { "Interface-ID", "dhcpv6.interface_id", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
3457 { &hf_reconf_msg,
3458 { "Reconfigure message type", "dhcpv6.reconf_msg", FT_UINT8, BASE_DEC | BASE_EXT_STRING, &msgtype_vals_ext, 0, NULL, HFILL }},
3459 { &hf_sip_server_domain_search_fqdn,
3460 { "SIP Server Domain Search FQDN", "dhcpv6.sip_server_domain_search_fqdn", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3461 { &hf_sip_server_a,
3462 { "SIP server address", "dhcpv6.sip_server_a", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3463 { &hf_dns_servers,
3464 { "DNS server address", "dhcpv6.dns_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3465 { &hf_dhcp4o6_servers,
3466 { "DHCP4o6 server address", "dhcpv6.dhcp4o6_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3467 { &hf_domain_search_list_entry,
3468 { "List entry", "dhcpv6.search_list_entry", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3469 { &hf_nis_servers,
3470 { "NIS server address", "dhcpv6.nis_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3471 { &hf_nisp_servers,
3472 { "NISP server address", "dhcpv6.nisp_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3473 { &hf_nis_fqdn,
3474 { "NIS FQDN", "dhcpv6.nis_fqdn", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3475 { &hf_nisp_fqdn,
3476 { "NISP FQDN", "dhcpv6.nisp_fqdn", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3477 { &hf_sntp_servers,
3478 { "SNTP server address", "dhcpv6.sntp_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3479 { &hf_opt_lifetime,
3480 { "Lifetime", "dhcpv6.lifetime", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
3481 { &hf_bcmcs_servers_fqdn,
3482 { "BCMCS server FQDN", "dhcpv6.bcmcs_server_fqdn", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3483 { &hf_bcmcs_servers_a,
3484 { "BCMCS server address", "dhcpv6.bcmcs_server_a", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3485 { &hf_remoteid_enterprise_id,
3486 { "Remote-ID", "dhcpv6.remoteid_enterprise_id", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3487 { &hf_subscriber_id,
3488 { "Subscriber-ID", "dhcpv6.subscriber_id", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3489 { &hf_client_fqdn,
3490 { "Client Domain Name", "dhcpv6.client_domain", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3491 { &hf_pana_agent,
3492 { "PANA agents address", "dhcpv6.pana_agent", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3493 { &hf_opt_timezone,
3494 { "Time-zone", "dhcpv6.timezone", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3495 { &hf_opt_tzdb,
3496 { "TZ-database", "dhcpv6.tzdb", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3497 { &hf_lq_query,
3498 { "Query-type", "dhcpv6.lq_query", FT_UINT8, BASE_DEC, VALS(lq_query_vals), 0, NULL, HFILL }},
3499 { &hf_lq_query_link_address,
3500 { "Link address", "dhcpv6.lq_query_link_address", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3501 { &hf_clt_time,
3502 { "Clt_time", "dhcpv6.clt_time", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL}},
3503 { &hf_lq_relay_data_peer_addr,
3504 { "Peer address", "dhcpv6.lq_relay_data_peer_addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3505 { &hf_lq_relay_data_msg,
3506 { "DHCPv6 relay message", "dhcpv6.lq_relay_data_msg", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3507 { &hf_lq_client_link,
3508 { "LQ client links address", "dhcpv6.lq_client_link", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3509 { &hf_capwap_ac_v6,
3510 { "CAPWAP Access Controllers address", "dhcpv6.capwap_ac_v6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3511 { &hf_aftr_name,
3512 { "DS-Lite AFTR Name", "dhcpv6.aftr_name", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3513 { &hf_iaprefix_pref_lifetime,
3514 { "Preferred lifetime", "dhcpv6.iaprefix.pref_lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(infinity_val), 0, NULL, HFILL}},
3515 { &hf_iaprefix_valid_lifetime,
3516 { "Valid lifetime", "dhcpv6.iaprefix.valid_lifetime", FT_UINT32, BASE_DEC|BASE_SPECIAL_VALS, VALS(infinity_val), 0, NULL, HFILL}},
3517 { &hf_iaprefix_pref_len,
3518 { "Prefix length", "dhcpv6.iaprefix.pref_len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
3519 { &hf_iaprefix_pref_addr,
3520 { "Prefix address", "dhcpv6.iaprefix.pref_addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3521 { &hf_mip6_ha,
3522 { "Home Agent", "dhcpv6.mip6_home_agent", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3523 { &hf_mip6_hoa,
3524 { "Home Address", "dhcpv6.mip6_home_address", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3525 { &hf_nai,
3526 { "NAI", "dhcpv6.nai", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3527 { &hf_pd_exclude_pref_len,
3528 { "Prefix length", "dhcpv6.pd_exclude.pref_len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
3529 { &hf_pd_exclude_subnet_id,
3530 { "IPv6 subnet ID", "dhcpv6.pd_exclude.subnet_id", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
3531 { &hf_option_userclass_length,
3532 { "Length", "dhcpv6.userclass.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
3533 { &hf_option_userclass_opaque_data,
3534 { "Suboption", "dhcpv6.userclass.opaque_data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL}},
3535 { &hf_option_ntpserver_type,
3536 { "Suboption", "dhcpv6.ntpserver.option.type", FT_UINT16, BASE_DEC, VALS(ntp_server_opttype_vals), 0x0, NULL, HFILL}},
3537 { &hf_option_ntpserver_length,
3538 { "Length", "dhcpv6.ntpserver.option.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
3539 { &hf_option_ntpserver_addr,
3540 { "NTP Server Address", "dhcpv6.ntpserver.addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3541 { &hf_option_ntpserver_mc_addr,
3542 { "NTP Multicast Address", "dhcpv6.ntpserver.mc_addr", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3543 { &hf_option_captive_portal,
3544 { "Captive Portal", "dhcpv6.captive_portal", FT_STRING, BASE_NONE, NULL, 0x0, "The contact URI for the captive portal that the user should connect to", HFILL }},
3545 { &hf_option_s46_option_code,
3546 { "S46 Option code", "dhcpv6.option_code", FT_UINT16, BASE_HEX, VALS(s46_opt_code_vals), 0x0, NULL, HFILL }},
3547 { &hf_option_failover_binding_status,
3548 { "Failover Binding Status", "dhcpv6.failover.binding_status", FT_UINT8, BASE_DEC, VALS(failover_binding_status_vals), 0x0, NULL, HFILL }},
3549 { &hf_option_failover_connect_flags,
3550 { "Flags", "dhcpv6.failover.connect.flags", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
3551 { &hf_option_failover_connect_reserved_flag,
3552 { "Reserved", "dhcpv6.failover.connect.flags.reserved", FT_BOOLEAN, 16, NULL, 0xfffe, NULL, HFILL }},
3553 { &hf_option_failover_connect_f_flag,
3554 { "Fixed PD Length (F)", "dhcpv6.failover.connect.flags.f", FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL }},
3555 { &hf_option_failover_dns_hostname,
3556 { "DNS Hostname", "dhcpv6.failover.dns_hostname", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3557 { &hf_option_failover_dns_zonename,
3558 { "DNS Zone Name", "dhcpv6.failover.dns_zonename", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3559 { &hf_option_failover_dns_flags,
3560 { "Flags", "dhcpv6.failover.dns.flags", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
3561 { &hf_option_failover_dns_reserved_flag,
3562 { "Reserved", "dhcpv6.failover.dns.flags.reserved", FT_BOOLEAN, 16, NULL, 0xfff0, NULL, HFILL }},
3563 { &hf_option_failover_dns_u_flag,
3564 { "Using Requested FQDN (U)", "dhcpv6.failover.dns.flags.u", FT_BOOLEAN, 16, NULL, 0x0008, NULL, HFILL }},
3565 { &hf_option_failover_dns_s_flag,
3566 { "Synthesized Name (S)", "dhcpv6.failover.dns.flags.s", FT_BOOLEAN, 16, NULL, 0x0004, NULL, HFILL }},
3567 { &hf_option_failover_dns_r_flag,
3568 { "Rev Uptodate (R)", "dhcpv6.failover.dns.flags.r", FT_BOOLEAN, 16, NULL, 0x0002, NULL, HFILL }},
3569 { &hf_option_failover_dns_f_flag,
3570 { "Fwd Uptodate (F)", "dhcpv6.failover.dns.flags.f", FT_BOOLEAN, 16, NULL, 0x0001, NULL, HFILL }},
3571 { &hf_option_failover_expiration_time,
3572 { "Expiration Time", "dhcpv6.failover.expiration_time", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3573 { &hf_option_failover_max_unacked_bndupd,
3574 { "Max number of unacked BNDUPD messages", "dhcpv6.failover.max_unacked_bndupd", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3575 { &hf_option_failover_mclt,
3576 { "Maximum Client Lead Time (MCLT)", "dhcpv6.failover.mclt", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3577 { &hf_option_failover_partner_lifetime,
3578 { "Partner Lifetime", "dhcpv6.failover.partner_lifetime", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3579 { &hf_option_failover_partner_lifetime_sent,
3580 { "Partner Lifetime Sent", "dhcpv6.failover.partner_lifetime_sent", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3581 { &hf_option_failover_partner_downtime,
3582 { "Partner Down Time", "dhcpv6.failover.partner_down_time", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3583 { &hf_option_failover_partner_raw_clt_time,
3584 { "Partner Raw Client Time", "dhcpv6.failover.partner_raw_clt_time", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3585 { &hf_option_failover_major_version,
3586 { "Protocol Major Version", "dhcpv6.failover.protocol.major_version", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
3587 { &hf_option_failover_minor_version,
3588 { "Protocol Minor Version", "dhcpv6.failover.protocol.minor_version", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
3589 { &hf_option_failover_keepalive_time,
3590 { "Keepalive Time", "dhcpv6.failover.keepalive_time", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3591 { &hf_option_failover_reconfigure_time,
3592 { "Reconfigure Time", "dhcpv6.failover.reconfigure_time", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3593 { &hf_option_failover_reconfigure_key,
3594 { "Reconfigure Key", "dhcpv6.failover.reconfigure_key", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
3595 { &hf_option_failover_relationship_name,
3596 { "Relationship Name", "dhcpv6.failover.relationship_name", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3597 { &hf_option_failover_server_flags,
3598 { "Flags", "dhcpv6.failover.server.flags", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
3599 { &hf_option_failover_server_reserved_flag,
3600 { "Reserved", "dhcpv6.failover.server.flags.reserved", FT_BOOLEAN, 8, NULL, 0xf8, NULL, HFILL }},
3601 { &hf_option_failover_server_a_flag,
3602 { "Ack Startup (A)", "dhcpv6.failover.server.flags.a", FT_BOOLEAN, 8, NULL, 0x04, NULL, HFILL }},
3603 { &hf_option_failover_server_s_flag,
3604 { "Startup (S)", "dhcpv6.failover.server.flags.s", FT_BOOLEAN, 8, NULL, 0x02, NULL, HFILL }},
3605 { &hf_option_failover_server_c_flag,
3606 { "Communicated (C)", "dhcpv6.failover.server.flags.c", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
3607 { &hf_option_failover_server_state,
3608 { "Server State", "dhcpv6.failover.server_state", FT_UINT8, BASE_DEC, VALS(failover_server_state_vals), 0, NULL, HFILL }},
3609 { &hf_option_failover_start_time_of_state,
3610 { "Start Time of State", "dhcpv6.failover.start_time_of_state", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3611 { &hf_option_failover_state_expiration_time,
3612 { "State Expiration Time", "dhcpv6.failover.state_expiration_time", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3613 { &hf_option_relay_port,
3614 { "Downstream Source Port", "dhcpv6.relay_port", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3615 { &hf_option_ntpserver_fqdn,
3616 { "NTP Server FQDN", "dhcpv6.ntpserver.fqdn", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3617 { &hf_packetcable_ccc_suboption,
3618 { "Sub element", "dhcpv6.packetcable.ccc.suboption", FT_UINT16, BASE_DEC, VALS(pkt_ccc_opt_vals), 0, NULL, HFILL }},
3619 { &hf_packetcable_ccc_pri_dhcp,
3620 { "Primary DHCP", "dhcpv6.packetcable.ccc.pri_dhcp", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }},
3621 { &hf_packetcable_ccc_sec_dhcp,
3622 { "Secondary DHCP", "dhcpv6.packetcable.ccc.sec_dhcp", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }},
3623 { &hf_packetcable_cccV6_suboption,
3624 { "Sub element", "dhcpv6.packetcable.cccV6.suboption", FT_UINT16, BASE_DEC | BASE_EXT_STRING, &pkt_cccV6_opt_vals_ext, 0, NULL, HFILL }},
3625 { &hf_modem_capabilities_encoding_type,
3626 { "Type", "dhcpv6.docsis.cccV6.tlv5.suboption", FT_UINT16, BASE_DEC | BASE_EXT_STRING, &modem_capabilities_encoding_ext, 0, NULL, HFILL }},
3627 { &hf_eue_capabilities_encoding_type,
3628 { "Type", "dhcpv6.packetcable.cccV6.tlv5.suboption", FT_UINT16, BASE_DEC | BASE_EXT_STRING, &eue_capabilities_encoding_ext, 0, NULL, HFILL }},
3629 { &hf_capabilities_encoding_length,
3630 { "Length", "dhcpv6.cccV6.tlv5.suboption.length", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
3631 { &hf_capabilities_encoding_bytes,
3632 { "Value", "dhcpv6.cccV6.tlv5.suboption.value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3633 { &hf_capabilities_encoding_number,
3634 { "Value", "dhcpv6.cccV6.tlv5.suboption.value_number", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
3635 { &hf_packetcable_cccV6_pri_dss,
3636 { "Primary SSID", "dhcpv6.packetcable.cccV6.pri_dss", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL }},
3637 { &hf_packetcable_cccV6_sec_dss,
3638 { "Secondary SSID", "dhcpv6.packetcable.cccV6.sec_dss", FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL }},
3639 { &hf_packetcable_cccV6_prov_srv_type,
3640 { "Type", "dhcpv6.packetcable.cccV6.prov_srv.type", FT_UINT8, BASE_DEC, VALS(pkt_cccV6_prov_srv_type_vals), 0, NULL, HFILL }},
3641 { &hf_packetcable_cccV6_prov_srv_fqdn,
3642 { "FQDN", "dhcpv6.packetcable.cccV6.prov_srv.fqdn", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3643 { &hf_packetcable_cccV6_prov_srv_ipv6,
3644 { "IPv6 address", "dhcpv6.packetcable.cccV6.prov_srv.ipv6", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }},
3645 { &hf_packetcable_cccV6_as_krb_nominal_timeout,
3646 { "Nominal Timeout", "dhcpv6.packetcable.cccV6.as_krb.nominal_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3647 { &hf_packetcable_cccV6_as_krb_max_timeout,
3648 { "Maximum Timeout", "dhcpv6.packetcable.cccV6.as_krb.max_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3649 { &hf_packetcable_cccV6_as_krb_max_retry_count,
3650 { "Maximum Retry Count", "dhcpv6.packetcable.cccV6.as_krb.max_retry_count", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3651 { &hf_packetcable_cccV6_ap_krb_nominal_timeout,
3652 { "Nominal Timeout", "dhcpv6.packetcable.cccV6.ap_krb.nominal_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3653 { &hf_packetcable_cccV6_ap_krb_max_timeout,
3654 { "Maximum Timeout", "dhcpv6.packetcable.cccV6.ap_krb.max_timeout", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3655 { &hf_packetcable_cccV6_ap_krb_max_retry_count,
3656 { "Maximum Retry Count", "dhcpv6.packetcable.cccV6.ap_krb.max_retry_count", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
3657 { &hf_packetcable_cccV6_krb_realm,
3658 { "KRB Realm", "dhcpv6.packetcable.cccV6.krb_realm", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3659 { &hf_packetcable_cccV6_tgt_flag,
3660 { "TGT Flags", "dhcpv6.packetcable.cccV6.tgt_flag", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
3661 { &hf_packetcable_cccV6_tgt_flag_fetch,
3662 { "Fetch TGT", "dhcpv6.packetcable.cccV6.tgt_flag.fetch", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
3663 { &hf_packetcable_cccV6_prov_timer,
3664 { "Provisioning timer", "dhcpv6.packetcable.cccV6.prov_timer", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
3665 { &hf_packetcable_cccV6_sec_tcm,
3666 { "SEC TCM Flags", "dhcpv6.packetcable.cccV6.sec_tcm", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
3667 { &hf_packetcable_cccV6_sec_tcm_provisioning_server,
3668 { "Provisioning Server", "dhcpv6.packetcable.cccV6.sec_tcm.provisioning_server", FT_BOOLEAN, 16, TFS(&tfs_on_off), 0x0001, NULL, HFILL }},
3669 { &hf_packetcable_cccV6_sec_tcm_call_manager_server,
3670 { "Call Manager Servers", "dhcpv6.packetcable.cccV6.tgt_flag.call_manager_server", FT_BOOLEAN, 16, TFS(&tfs_on_off), 0x0002, NULL, HFILL }},
3671 { &hf_cablelabs_opts,
3672 { "Suboption", "dhcpv6.cablelabs.opt", FT_UINT16, BASE_DEC | BASE_EXT_STRING, &cl_vendor_subopt_values_ext, 0, NULL, HFILL }},
3673 { &hf_cablelabs_ipv6_server,
3674 { "IPv6 address", "dhcpv6.cablelabs.ipv6_server", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3675 { &hf_cablelabs_docsis_version_number,
3676 { "DOCSIS Version Number", "dhcpv6.cablelabs.docsis_version_number", FT_UINT16, BASE_CUSTOM, CF_FUNC(cablelabs_fmt_docsis_version), 0x0, NULL, HFILL}},
3677 { &hf_cablelabs_dpoe_server_version_number,
3678 { "DPoE Server Version Number", "dhcpv6.cablelabs.dpoe_server_version_number", FT_UINT16, BASE_CUSTOM, CF_FUNC(cablelabs_fmt_dpoe_server_version), 0x0, NULL, HFILL}},
3679 { &hf_cablelabs_interface_id,
3680 { "Interface-ID", "dhcpv6.cablelabs.interface_id", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3681 { &hf_cablelabs_interface_id_link_address,
3682 { "Link Address", "dhcpv6.cablelabs.interface_id_link_address", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3683 { &hf_option_s46_rule_flags,
3684 { "Flags", "dhcpv6.s46_rule.flags", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
3685 { &hf_option_s46_rule_reserved_flag,
3686 { "Reserved", "dhcpv6.s46_rule.flags.reserved", FT_BOOLEAN, 8, NULL, 0xfe, NULL, HFILL }},
3687 { &hf_option_s46_rule_fmr_flag,
3688 { "Forwarding Mapping Rule", "dhcpv6.s46_rule.flags.fmr", FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL }},
3689 { &hf_option_s46_rule_ea_len,
3690 { "EA-bit length", "dhcpv6.s46_rule.ea_len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
3691 { &hf_option_s46_rule_ipv4_pref_len,
3692 { "IPv4 prefix length", "dhcpv6.s46_rule.ipv4_pref_len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
3693 { &hf_option_s46_rule_ipv4_prefix,
3694 { "IPv4 prefix", "dhcpv6.s46_rule.ipv4_prefix", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }},
3695 { &hf_option_s46_rule_ipv6_pref_len,
3696 { "IPv6 prefix length", "dhcpv6.s46_rule.ipv6_prefix_len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
3697 { &hf_option_s46_rule_ipv6_prefix,
3698 { "IPv6 prefix", "dhcpv6.s46_rule.ipv6_prefix", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }},
3699 { &hf_option_s46_br_address,
3700 { "BR address", "dhcpv6.s46_br.address", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }},
3701 { &hf_option_s46_dmr_pref_len,
3702 { "IPv6 prefix length", "dhcpv6.s46_dmr.dmr_pref_len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
3703 { &hf_option_s46_dmr_prefix,
3704 { "IPv6 prefix", "dhcpv6.s46_dmr.dmr_prefix", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }},
3705 { &hf_option_s46_v4v6bind_ipv4_address,
3706 { "IPv4 Address", "dhcpv6.s46_v4v6bind.ipv4_address", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }},
3707 { &hf_option_s46_v4v6bind_ipv6_pref_len,
3708 { "IPv6 prefix length", "dhcpv6.s46_v4v6bind.ipv6_pref_len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
3709 { &hf_option_s46_v4v6bind_ipv6_prefix,
3710 { "IPv6 prefix", "dhcpv6.s46_v4v6bind.ipv6_prefix", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }},
3711 { &hf_option_s46_portparam_offset,
3712 { "Offset", "dhcpv6.s46_portparam.offset", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
3713 { &hf_option_s46_portparam_psid_len,
3714 { "PSID length", "dhcpv6.s46_portparam.psid_len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
3715 { &hf_option_s46_portparam_psid,
3716 { "PSID", "dhcpv6.s46_portparam.psid", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
3717 { &hf_opt_mudurl,
3718 { "MUDURL", "dhcpv6.mudurl", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }},
3719 { &hf_client_link_layer_addr,
3720 { "Link-layer address", "dhcpv6.client_link_layer_addr", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3721 { &hf_client_link_layer_addr_ether,
3722 { "Link-layer address (Ethernet)", "dhcpv6.client_link_layer_addr_ether", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}},
3723 { &hf_client_link_layer_addr_hwtype,
3724 { "Hardware type", "dhcpv6.client_link_layer_addr_hwtype", FT_UINT16, BASE_DEC, VALS(arp_hrd_vals), 0, NULL, HFILL }},
3725 { &hf_dnr_svcpriority,
3726 {"DNR service priority", "dhcpv6.dnr.svcpriority", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL}},
3727 { &hf_dnr_auth_domain_name_len,
3728 {"DNR authentication domain name length", "dhcpv6.dnr.adn_len", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL}},
3729 { &hf_dnr_auth_domain_name,
3730 {"DNR authentication domain name", "dhcpv6.dnr.adn", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL}},
3731 { &hf_dnr_addrs_len,
3732 {"DNR addresses list length", "dhcpv6.dnr.addrs.len", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL}},
3733 { &hf_dnr_addrs,
3734 {"DNR address", "dhcpv6.dnr.addrs", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL}},
3735 { &hf_dnr_svcparams,
3736 {"DNR service parameters", "dhcpv6.dnr.svcparams", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL}},
3737 { &hf_dnr_svcparams_key,
3738 { "SvcParamKey", "dhcpv6.dnr.svcparams.key", FT_UINT16, BASE_DEC, VALS(dnr_svcparams_key_vals), 0x0, NULL, HFILL }},
3739 { &hf_dnr_svcparams_length,
3740 { "SvcParamValue length", "dhcpv6.dnr.svcparams.value.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3741 { &hf_dnr_svcparams_value,
3742 { "SvcParamValue", "dhcpv6.dnr.svcparams.value", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3743 { &hf_dnr_svcparams_mandatory_key,
3744 { "Mandatory key", "dhcpv6.dnr.svcparams.mandatory.key", FT_UINT16, BASE_DEC, VALS(dnr_svcparams_key_vals), 0x0, "Mandatory keys in this RR", HFILL }},
3745 { &hf_dnr_svcparams_alpn_length,
3746 { "ALPN length", "dhcpv6.dnr.svcparams.alpn.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3747 { &hf_dnr_svcparams_alpn,
3748 { "ALPN", "dhcpv6.dnr.svcparams.alpn", FT_STRING, BASE_NONE, NULL, 0x0, "Additional supported protocols", HFILL }},
3749 { &hf_dnr_svcparams_port,
3750 { "Port", "dhcpv6.dnr.svcparams.port", FT_UINT16, BASE_DEC, NULL, 0x0, "Port for alternative endpoint", HFILL }},
3751 { &hf_dnr_svcparams_ipv4hint_ip, { "IP", "dhcpv6.dnr.svcparams.ipv4hint.ip", FT_IPv4, BASE_NONE, NULL, 0x0, "IPv4 address hints", HFILL }},
3752 { &hf_dnr_svcparams_ipv6hint_ip, { "IP", "dhcpv6.dnr.svcparams.ipv6hint.ip", FT_IPv6, BASE_NONE, NULL, 0x0, "IPv6 address hints", HFILL }},
3753 { &hf_dnr_svcparams_dohpath, { "DoH path", "dhcpv6.dnr.svcparams.dohpath", FT_STRING, BASE_NONE, NULL, 0x0, "DoH URI template", HFILL}},
3754 { &hf_dnr_svcparams_odohconfig, { "ODoHConfig", "dhcpv6.dnr.svcparams.odohconfig", FT_BYTES, BASE_NONE, NULL, 0x0, "Oblivious DoH keys", HFILL }}
3757 static int *ett[] = {
3758 &ett_dhcpv6,
3759 &ett_dhcpv6_option,
3760 &ett_dhcpv6_option_vsoption,
3761 &ett_dhcpv6_vendor_option,
3762 &ett_dhcpv6_pkt_option,
3763 &ett_dhcpv6_userclass_option,
3764 &ett_dhcpv6_netserver_option,
3765 &ett_dhcpv6_tlv5_type,
3766 &ett_dhcpv6_sip_server_domain_search_list_option,
3767 &ett_dhcpv6_dns_domain_search_list_option,
3768 &ett_dhcpv6_nis_domain_name_option,
3769 &ett_dhcpv6_nisp_domain_name_option,
3770 &ett_dhcpv6_bcmcs_servers_domain_search_list_option,
3771 &ett_dhcpv6_s46_rule_flags,
3772 &ett_dhcpv6_failover_connect_flags,
3773 &ett_dhcpv6_failover_dns_flags,
3774 &ett_dhcpv6_failover_server_flags,
3775 &ett_clientfqdn_flags,
3776 &ett_clientfqdn_expert,
3777 &ett_dhcpv6_dnr_svcparams
3780 static ei_register_info ei[] = {
3781 { &ei_dhcpv6_bogus_length, { "dhcpv6.bogus_length", PI_MALFORMED, PI_ERROR, "Bogus length", EXPFILL }},
3782 { &ei_dhcpv6_malformed_option, { "dhcpv6.malformed_option", PI_MALFORMED, PI_ERROR, "Malformed option", EXPFILL }},
3783 { &ei_dhcpv6_no_suboption_len, { "dhcpv6.no_suboption_len", PI_PROTOCOL, PI_WARN,
3784 "no room left in option for suboption length", EXPFILL }},
3785 { &ei_dhcpv6_invalid_time_value, { "dhcpv6.invalid_time_value", PI_PROTOCOL, PI_WARN, "Invalid time value", EXPFILL }},
3786 { &ei_dhcpv6_invalid_type, { "dhcpv6.invalid_type", PI_PROTOCOL, PI_WARN, "Invalid type", EXPFILL }},
3787 { &ei_dhcpv6_error_hopcount, { "dhcpv6.error_hopcount", PI_PROTOCOL, PI_WARN, "Detected error on hop-count", EXPFILL }},
3788 { &ei_dhcpv6_clientfqdn_bad_msgtype, { "dhcpv6.bad_msgtype", PI_PROTOCOL, PI_ERROR,
3789 "This message type is not permitted to use OPTION_CLIENT_FQDN", EXPFILL }},
3790 { &ei_dhcpv6_s_bit_should_be_zero, { "dhcpv6.s_bit_should_be_zero", PI_PROTOCOL, PI_ERROR,
3791 "ERROR: When the N-bit is set, the S-bit must be reset", EXPFILL }},
3793 * FQDN-related errors in dhcpv6_domain() */
3794 { &ei_dhcpv6_non_dns_encoded_name, { "dhcpv6.expert.name_not_dns_encoded", PI_PROTOCOL, PI_ERROR,
3795 "ERROR: This name is not a DNS record encoded", EXPFILL }},
3796 { &ei_dhcpv6_domain_field_len_exceeded, { "dhcpv6.expert.domain_field_length_exceeded", PI_MALFORMED, PI_ERROR,
3797 "ERROR: FQDN exceeds length of the domain name field", EXPFILL }},
3798 { &ei_dhcpv6_encoded_fqdn_len_gt_255, { "dhcpv6.expert.encoded_fqdn_gt_255", PI_MALFORMED, PI_ERROR,
3799 "ERROR: FQDN's *encoded* length exceeds 255 octets [RFC 1035 3.1.]", EXPFILL }},
3800 { &ei_dhcpv6_root_only_domain_name, { "dhcpv6.expert.root_only_domain_name", PI_PROTOCOL, PI_ERROR,
3801 "ERROR: A root-only domain name cannot be resolved.", EXPFILL }},
3802 { &ei_dhcpv6_tld_lookup, { "dhcpv6.expert.tld_lookup", PI_COMMENTS_GROUP, PI_WARN,
3803 "WARNING: TLDs are rarely resolvable", EXPFILL }},
3804 { &ei_dhcpv6_partial_name_preceded_by_fqdn, { "dhcpv6.expert.partial_name_preceded_by_fqdn", PI_PROTOCOL, PI_ERROR,
3805 "ERROR: Partial name is preceded by an FQDN", EXPFILL }},
3808 static hf_register_info bulk_leasequery_hf[] = {
3809 { &hf_dhcpv6_bulk_leasequery_size,
3810 { "Message size", "dhcpv6.bulk_leasequery.size", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3811 { &hf_dhcpv6_bulk_leasequery_msgtype,
3812 { "Message type", "dhcpv6.bulk_leasequery.msgtype", FT_UINT8, BASE_DEC | BASE_EXT_STRING, &msgtype_vals_ext, 0x0, NULL, HFILL }},
3813 { &hf_dhcpv6_bulk_leasequery_reserved,
3814 { "Reserved", "dhcpv6.bulk_leasequery.reserved", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3815 { &hf_dhcpv6_bulk_leasequery_trans_id,
3816 { "Transaction ID", "dhcpv6.bulk_leasequery.trans_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3819 static int *ett_bulk_leasequery[] = {
3820 &ett_dhcpv6_bulk_leasequery,
3821 &ett_dhcpv6_bulk_leasequery_options
3824 static ei_register_info ei_bulk_leasequery[] = {
3825 { &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 }},
3826 { &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 }},
3829 expert_module_t *expert_dhcpv6;
3830 expert_module_t *expert_dhcpv6_bulk_leasequery;
3832 proto_dhcpv6 = proto_register_protocol("DHCPv6", "DHCPv6", "dhcpv6");
3833 proto_register_field_array(proto_dhcpv6, hf, array_length(hf));
3834 proto_register_subtree_array(ett, array_length(ett));
3836 expert_dhcpv6 = expert_register_protocol(proto_dhcpv6);
3837 expert_register_field_array(expert_dhcpv6, ei, array_length(ei));
3839 proto_dhcpv6_bulk_leasequery = proto_register_protocol("DHCPv6 Bulk Leasequery", "DHCPv6 Bulk Leasequery", "dhcpv6.bulk_leasequery");
3840 register_dissector("dhcpv6.bulk_leasequery", dissect_dhcpv6_bulk_leasequery,
3841 proto_dhcpv6_bulk_leasequery);
3842 proto_register_field_array(proto_dhcpv6_bulk_leasequery, bulk_leasequery_hf, array_length(bulk_leasequery_hf));
3843 proto_register_subtree_array(ett_bulk_leasequery, array_length(ett_bulk_leasequery));
3845 expert_dhcpv6_bulk_leasequery = expert_register_protocol(proto_dhcpv6_bulk_leasequery);
3846 expert_register_field_array(expert_dhcpv6_bulk_leasequery, ei_bulk_leasequery, array_length(ei_bulk_leasequery));
3848 /* Allow other dissectors to find this one by name. */
3849 dhcpv6_handle = register_dissector("dhcpv6", dissect_dhcpv6_stream, proto_dhcpv6);
3851 dhcpv6_module = prefs_register_protocol(proto_dhcpv6, NULL);
3852 prefs_register_bool_preference(dhcpv6_module, "cablelabs_interface_id",
3853 "Dissect Option 18 (Interface-Id) as CableLab option",
3854 "Whether Option 18 is dissected as CableLab or RFC 3315",
3855 &cablelabs_interface_id);
3857 bulkquery_module = prefs_register_protocol(proto_dhcpv6_bulk_leasequery, NULL);
3858 prefs_register_bool_preference(bulkquery_module, "desegment",
3859 "Desegment all Bulk Leasequery messages spanning multiple TCP segments",
3860 "Whether the Bulk Leasequery dissector should desegment all messages spanning multiple TCP segments",
3861 &dhcpv6_bulk_leasequery_desegment);
3863 dhcpv6_enterprise_opts_dissector_table = register_dissector_table("dhcpv6.enterprise_opts", "DHCPv6 Enterprise OPTs", proto_dhcpv6, FT_UINT32, BASE_DEC);
3865 proto_dhcpv6_cablelabs = proto_register_protocol("DHCPv6 Cablelabs", "DHCPv6(cablelabs)", "dhcpv6_cablelabs");
3866 dhcpv6_cablelabs_handle = register_dissector("dhcpv6_cablelabs", dissect_cablelabs_specific_opts, proto_dhcpv6_cablelabs);
3867 dissector_add_uint("dhcpv6.enterprise_opts", VENDOR_CABLELABS, dhcpv6_cablelabs_handle);
3870 void
3871 proto_reg_handoff_dhcpv6(void)
3873 dissector_add_uint_range_with_preference("udp.port", UDP_PORT_DHCPV6_RANGE, dhcpv6_handle);
3875 dissector_add_uint_with_preference("tcp.port", TCP_PORT_DHCPV6_UPSTREAM, find_dissector("dhcpv6.bulk_leasequery"));
3877 dhcpv4_handle = find_dissector_add_dependency("dhcp", proto_dhcpv6);
3881 * Editor modelines
3883 * Local Variables:
3884 * c-basic-offset: 4
3885 * tab-width: 8
3886 * indent-tabs-mode: nil
3887 * End:
3889 * ex: set shiftwidth=4 tabstop=8 expandtab:
3890 * :indentSize=4:tabSize=8:noTabs=true: