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