Coverage Report

Created: 2026-06-30 07:22

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