Convert a bunch of time_to_str functions to wmem
[metze/wireshark/wip.git] / epan / dissectors / packet-bootp.c
1 /* packet-bootp.c
2  * Routines for BOOTP/DHCP packet disassembly
3  *
4  * Copyright 1998, Gilbert Ramirez <gram@alumni.rice.edu>
5  * Copyright 2004, Thomas Anders <thomas.anders [AT] blue-cable.de>
6  *
7  * Added option field filters
8  * Copyright 2011, Michael Mann
9  *
10  * Added option  77 : RFC 3004 - The User Class Option for DHCP
11  * Added option 117 : RFC 2937 - The Name Service Search Option for DHCP
12  * Added option 119 : RFC 3397 - Dynamic Host Configuration Protocol (DHCP) Domain Search Option
13  *                    RFC 3396 - Encoding Long Options in the Dynamic Host Configuration Protocol (DHCPv4)
14  * Improved opt 120 : Add support of RFC 3396 - Encoding Long Options in the Dynamic Host Configuration Protocol (DHCPv4)
15  *                    Add support compression according to the encoding in Section 4.1.4 of RFC 1035 - DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION
16  *
17  *
18  * Copyright 2012, Jerome LAFORGE <jerome.laforge [AT] gmail.com>
19  *
20  * The information used comes from:
21  * RFC  951: Bootstrap Protocol
22  * RFC 1035: Domain Names - Implementation And Specification
23  * RFC 1497: BOOTP extensions
24  * RFC 1542: Clarifications and Extensions for the Bootstrap Protocol
25  * RFC 2131: Dynamic Host Configuration Protocol
26  * RFC 2132: DHCP Options and BOOTP Vendor Extensions
27  * RFC 2241: DHCP Options for Novell Directory Services
28  * RFC 2242: NetWare/IP Domain Name and Information
29  * RFC 2489: Procedure for Defining New DHCP Options
30  * RFC 2610: DHCP Options for Service Location Protocol
31  * RFC 2685: Virtual Private Networks Identifier
32  * RFC 2937: The Name Service Search Option for DHCP
33  * RFC 3004: The User Class Option for DHCP
34  * RFC 3046: DHCP Relay Agent Information Option
35  * RFC 3118: Authentication for DHCP Messages
36  * RFC 3203: DHCP reconfigure extension
37  * RFC 3315: Dynamic Host Configuration Protocol for IPv6 (DHCPv6)
38  * RFC 3396: Encoding Long Options in the Dynamic Host Configuration Protocol (DHCPv4)
39  * RFC 3397: Dynamic Host Configuration Protocol (DHCP) Domain Search Option
40  * RFC 3495: DHCP Option (122) for CableLabs Client Configuration
41  * RFC 3594: PacketCable Security Ticket Control Sub-Option (122.9)
42  * RFC 3442: Classless Static Route Option for DHCP version 4
43  * RFC 3825: Dynamic Host Configuration Protocol Option for Coordinate-based Location Configuration Information
44  * RFC 3925: Vendor-Identifying Vendor Options for Dynamic Host Configuration Protocol version 4 (DHCPv4)
45  * RFC 3942: Reclassifying DHCPv4 Options
46  * RFC 4243: Vendor-Specific Information Suboption for the Dynamic Host Configuration Protocol (DHCP) Relay Agent Option
47  * RFC 4361: Node-specific Client Identifiers for Dynamic Host Configuration Protocol Version Four (DHCPv4)
48  * RFC 4388: Dynamic Host Configuration Protocol (DHCP) Leasequery
49  * RFC 4578: Dynamic Host Configuration Protocol (DHCP) Options for PXE
50  * RFC 4776: Dynamic Host Configuration Protocol (DHCPv4 and DHCPv6) Option for Civic Addresses Configuration Information
51  * RFC 5223: Discovering Location-to-Service Translation (LoST) Servers Using the Dynamic Host Configuration Protocol (DHCP)
52  * RFC 5417: CAPWAP Access Controller DHCP Option
53  * RFC 5969: IPv6 Rapid Deployment on IPv4 Infrastructures (6rd)
54  * RFC 6607: Virtual Subnet Selection Options for DHCPv4 and DHCPv6
55  * draft-ietf-dhc-fqdn-option-07.txt
56  * TFTP Server Address Option for DHCPv4 [draft-raj-dhc-tftp-addr-option-06.txt: http://tools.ietf.org/html/draft-raj-dhc-tftp-addr-option-06]
57  * BOOTP and DHCP Parameters
58  *     http://www.iana.org/assignments/bootp-dhcp-parameters
59  * DOCSIS(TM) 2.0 Radio Frequency Interface Specification
60  *     http://www.cablelabs.com/specifications/CM-SP-RFI2.0-I11-060602.pdf
61  * DOCSIS(TM) 3.0 MAC and Upper Layer Protocols Interface Specification
62  *     http://www.cablelabs.com/specifications/CM-SP-MULPIv3.0-I20-121113.pdf
63  * PacketCable(TM) 1.0 MTA Device Provisioning Specification
64  *     http://www.cablelabs.com/packetcable/downloads/specs/PKT-SP-PROV-I11-050812.pdf
65  *     http://www.cablelabs.com/specifications/archives/PKT-SP-PROV-I05-021127.pdf (superseded by above)
66  * PacketCable(TM) 1.5 MTA Device Provisioning Specification
67  *     http://www.cablelabs.com/packetcable/downloads/specs/PKT-SP-PROV1.5-I02-050812.pdf
68  * PacketCable(TM) 2.0 EUE Device Provisioning Specification
69  *     http://www.cablelabs.com/specifications/PKT-SP-EUE-DATA-I03-090528.pdf
70  * Business Services over DOCSIS(R) Layer 2 Virtual Private Networks
71  *     http://www.cablelabs.com/specifications/CM-SP-L2VPN-I09-100611.pdf
72  * CableHome(TM) 1.1 Specification
73  *     http://www.cablelabs.com/projects/cablehome/downloads/specs/CH-SP-CH1.1-I11-060407.pdf
74  * Broadband Forum TR-111
75  *     http://www.broadband-forum.org/technical/download/TR-111.pdf
76  *
77  * Wireshark - Network traffic analyzer
78  * By Gerald Combs <gerald@wireshark.org>
79  * Copyright 1998 Gerald Combs
80  *
81  * This program is free software; you can redistribute it and/or
82  * modify it under the terms of the GNU General Public License
83  * as published by the Free Software Foundation; either version 2
84  * of the License, or (at your option) any later version.
85  *
86  * This program is distributed in the hope that it will be useful,
87  * but WITHOUT ANY WARRANTY; without even the implied warranty of
88  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
89  * GNU General Public License for more details.
90  *
91  * You should have received a copy of the GNU General Public License
92  * along with this program; if not, write to the Free Software
93  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
94  */
95
96 /*
97  * Some of the development of the BOOTP/DHCP protocol decoder was sponsored by
98  * Cable Television Laboratories, Inc. ("CableLabs") based upon proprietary
99  * CableLabs' specifications. Your license and use of this protocol decoder
100  * does not mean that you are licensed to use the CableLabs'
101  * specifications.  If you have questions about this protocol, contact
102  * jf.mule [AT] cablelabs.com or c.stuart [AT] cablelabs.com for additional
103  * information.
104  */
105
106
107 #include "config.h"
108
109 #include <stdio.h>
110 #include <stdlib.h>
111 #include <string.h>
112
113 #include <glib.h>
114
115 #include <epan/packet.h>
116 #include <epan/exceptions.h>
117 #include "packet-arp.h"
118 #include "packet-dns.h"                         /* for get_dns_name() */
119 #include <epan/addr_resolv.h>
120 #include <epan/prefs.h>
121 #include <epan/tap.h>
122 #include <epan/arptypes.h>
123 #include <epan/sminmpec.h>
124 #include <epan/expert.h>
125 #include <epan/uat.h>
126 #include <epan/wmem/wmem.h>
127
128 void proto_register_bootp(void);
129 void proto_reg_handoff_bootp(void);
130
131 static int bootp_dhcp_tap = -1;
132 static int proto_bootp = -1;
133 static int hf_bootp_type = -1;
134 static int hf_bootp_hw_type = -1;
135 static int hf_bootp_hw_len = -1;
136 static int hf_bootp_hops = -1;
137 static int hf_bootp_id = -1;
138 static int hf_bootp_secs = -1;
139 static int hf_bootp_flags = -1;
140 static int hf_bootp_flags_broadcast = -1;
141 static int hf_bootp_flags_reserved = -1;
142 static int hf_bootp_ip_client = -1;
143 static int hf_bootp_ip_your = -1;
144 static int hf_bootp_ip_server = -1;
145 static int hf_bootp_ip_relay = -1;
146 static int hf_bootp_hw_addr = -1;
147 static int hf_bootp_hw_addr_padding = -1;
148 static int hf_bootp_hw_ether_addr = -1;
149 static int hf_bootp_server = -1;
150 static int hf_bootp_file = -1;
151 static int hf_bootp_cookie = -1;
152 static int hf_bootp_dhcp = -1;
153 static int hf_bootp_fqdn_s = -1;
154 static int hf_bootp_fqdn_o = -1;
155 static int hf_bootp_fqdn_e = -1;
156 static int hf_bootp_fqdn_n = -1;
157 static int hf_bootp_fqdn_mbz = -1;
158 static int hf_bootp_fqdn_rcode1 = -1;
159 static int hf_bootp_fqdn_rcode2 = -1;
160 static int hf_bootp_fqdn_name = -1;
161 static int hf_bootp_fqdn_asciiname = -1;
162 static int hf_bootp_pkt_mta_cap_len = -1;
163 static int hf_bootp_docsis_cm_cap_type = -1;
164 static int hf_bootp_docsis_cm_cap_len = -1;
165 static int hf_bootp_client_identifier_uuid = -1;
166 static int hf_bootp_client_identifier_duid_llt_hw_type = -1;
167 static int hf_bootp_client_identifier_duid_ll_hw_type = -1;
168 static int hf_bootp_option_type = -1;
169 static int hf_bootp_option_length = -1;
170 static int hf_bootp_option_value = -1;
171 static int hf_bootp_option_value_8 = -1;
172 static int hf_bootp_option_value_16 = -1;
173 static int hf_bootp_option_value_u32 = -1;
174 static int hf_bootp_option_value_i32 = -1;
175 static int hf_bootp_option_value_stringz = -1;
176 static int hf_bootp_option_value_ip_address = -1;
177 static int hf_bootp_option_value_boolean = -1;
178 static int hf_bootp_suboption_length = -1;
179
180 static int hf_bootp_option_padding = -1;                                /* 0 */
181 static int hf_bootp_option_subnet_mask = -1;                            /* 1 */
182 static int hf_bootp_option_time_offset = -1;                            /* 2 */
183 static int hf_bootp_option_router = -1;                                 /* 3 */
184 static int hf_bootp_option_time_server = -1;                            /* 4 */
185 static int hf_bootp_option_name_server = -1;                            /* 5 */
186 static int hf_bootp_option_domain_name_server = -1;                     /* 6 */
187 static int hf_bootp_option_log_server = -1;                             /* 7 */
188 static int hf_bootp_option_quotes_server = -1;                          /* 8 */
189 static int hf_bootp_option_lpr_server = -1;                             /* 9 */
190 static int hf_bootp_option_impress_server = -1;                         /* 10 */
191 static int hf_bootp_option_resource_location_server = -1;               /* 11 */
192 static int hf_bootp_option_hostname = -1;                               /* 12 */
193 static int hf_bootp_option_boot_file_size = -1;                         /* 13 */
194 static int hf_bootp_option_merit_dump_file = -1;                        /* 14 */
195 static int hf_bootp_option_domain_name = -1;                            /* 15 */
196 static int hf_bootp_option_swap_server = -1;                            /* 16 */
197 static int hf_bootp_option_root_path = -1;                              /* 17 */
198 static int hf_bootp_option_extension_path = -1;                         /* 18 */
199 static int hf_bootp_option_ip_forwarding = -1;                          /* 19 */
200 static int hf_bootp_option_non_local_source_routing = -1;               /* 20 */
201 static int hf_bootp_option_policy_filter_ip = -1;                       /* 21 - IP address */
202 static int hf_bootp_option_policy_filter_subnet_mask = -1;              /* 21 - Subnet mask */
203 static int hf_bootp_option_max_datagram_reassembly_size = -1;           /* 22 */
204 static int hf_bootp_option_default_ip_ttl = -1;                         /* 23 */
205 static int hf_bootp_option_path_mtu_aging_timeout = -1;                 /* 24 */
206 static int hf_bootp_option_path_mtu_plateau_table_item = -1;            /* 25 */
207 static int hf_bootp_option_interface_mtu = -1;                          /* 26 */
208 static int hf_bootp_option_all_subnets_are_local = -1;                  /* 27 */
209 static int hf_bootp_option_broadcast_address = -1;                      /* 28 */
210 static int hf_bootp_option_perform_mask_discovery = -1;                 /* 29 */
211 static int hf_bootp_option_mask_supplier = -1;                          /* 30 */
212 static int hf_bootp_option_perform_router_discover = -1;                /* 31 */
213 static int hf_bootp_option_router_solicitation_address = -1;            /* 32 */
214 static int hf_bootp_option_static_route_ip = -1;                        /* 33 - Destination IP */
215 static int hf_bootp_option_static_route_router = -1;                    /* 33 - Router */
216 static int hf_bootp_option_trailer_encapsulation = -1;                  /* 34 */
217 static int hf_bootp_option_arp_cache_timeout = -1;                      /* 35 */
218 static int hf_bootp_option_ethernet_encapsulation = -1;                 /* 36 */
219 static int hf_bootp_option_tcp_default_ttl = -1;                        /* 37 */
220 static int hf_bootp_option_tcp_keepalive_interval = -1;                 /* 38 */
221 static int hf_bootp_option_tcp_keepalive_garbage = -1;                  /* 39 */
222 static int hf_bootp_option_nis_domain = -1;                             /* 40 */
223 static int hf_bootp_option_nis_server = -1;                             /* 41 */
224 static int hf_bootp_option_ntp_server = -1;                             /* 42 */
225
226 static int hf_bootp_option43_value = -1;                                /* 43 suboption value */
227 static int hf_bootp_option43_value_8 = -1;                              /* 43 suboption value */
228 static int hf_bootp_option43_value_32 = -1;                             /* 43 suboption value */
229 static int hf_bootp_option43_value_stringz = -1;                        /* 43 suboption value */
230 static int hf_bootp_option43_value_ip_address = -1;                     /* 43 suboption value */
231
232 static int hf_bootp_option43_pxeclient_suboption = -1;                  /* 43 suboption */
233 static int hf_bootp_option43_pxeclient_padding = -1;                    /* 43:0 PXE  */
234 static int hf_bootp_option43_pxeclient_mtftp_ip = -1;                   /* 43:1 PXE  */
235 static int hf_bootp_option43_pxeclient_mtftp_client_port = -1;          /* 43:2 PXE  */
236 static int hf_bootp_option43_pxeclient_mtftp_server_port = -1;          /* 43:3 PXE  */
237 static int hf_bootp_option43_pxeclient_mtftp_timeout = -1;              /* 43:4 PXE  */
238 static int hf_bootp_option43_pxeclient_mtftp_delay = -1;                /* 43:5 PXE  */
239 static int hf_bootp_option43_pxeclient_discovery_control = -1;          /* 43:6 PXE  */
240 static int hf_bootp_option43_pxeclient_multicast_address = -1;          /* 43:7 PXE  */
241 static int hf_bootp_option43_pxeclient_boot_servers = -1;               /* 43:8 PXE  */
242 static int hf_bootp_option43_pxeclient_boot_menu = -1;                  /* 43:9 PXE  */
243 static int hf_bootp_option43_pxeclient_menu_prompt = -1;                /* 43:10 PXE  */
244 static int hf_bootp_option43_pxeclient_multicast_address_alloc = -1;    /* 43:11 PXE  */
245 static int hf_bootp_option43_pxeclient_credential_types = -1;           /* 43:12 PXE  */
246 static int hf_bootp_option43_pxeclient_boot_item = -1;                  /* 43:71 PXE  */
247 static int hf_bootp_option43_pxeclient_end = -1;                        /* 43:255 PXE */
248
249 static int hf_bootp_option43_cl_suboption = -1;                         /* 43 suboption */
250 static int hf_bootp_option43_cl_padding = -1;                           /* 43:0 CL  */
251 static int hf_bootp_option43_cl_suboption_request_list = -1;            /* 43:1 CL  */
252 static int hf_bootp_option43_cl_device_type = -1;                       /* 43:2 CL  */
253 static int hf_bootp_option43_cl_esafe_type = -1;                        /* 43:3 CL  */
254 static int hf_bootp_option43_cl_serial_number = -1;                     /* 43:4 CL  */
255 static int hf_bootp_option43_cl_hardware_version = -1;                  /* 43:5 CL  */
256 static int hf_bootp_option43_cl_software_version = -1;                  /* 43:6 CL  */
257 static int hf_bootp_option43_cl_boot_rom_version = -1;                  /* 43:7 CL  */
258 static int hf_bootp_option43_cl_oui_bytes = -1;                         /* 43:8 CL  */
259 static int hf_bootp_option43_cl_oui_string = -1;                        /* 43:8 CL  */
260 static int hf_bootp_option43_cl_model_number = -1;                      /* 43:9 CL  */
261 static int hf_bootp_option43_cl_vendor_name10 = -1;                     /* 43:10 CL  */
262 static int hf_bootp_option43_cl_address_realm = -1;                     /* 43:11 CL  */
263 static int hf_bootp_option43_cl_cm_ps_system_desc = -1;                 /* 43:12 CL  */
264 static int hf_bootp_option43_cl_cm_ps_firmware_revision = -1;           /* 43:13 CL  */
265 static int hf_bootp_option43_cl_firewall_policy_file_version = -1;      /* 43:14 CL  */
266 static int hf_bootp_option43_cl_esafe_config_file_devices = -1;         /* 43:15 CL  */
267 static int hf_bootp_option43_cl_video_security_tape = -1;               /* 43:18 CL  */
268 static int hf_bootp_option43_cl_mta_mac_address = -1;                   /* 43:31 CL  */
269 static int hf_bootp_option43_cl_correlation_ID = -1;                    /* 43:32 CL  */
270 static int hf_bootp_option43_cl_vendor_name51 = -1;                     /* 43:51 CL  */
271 static int hf_bootp_option43_cl_cablecard_capability = -1;              /* 43:52 CL  */
272 static int hf_bootp_option43_cl_device_id_ca = -1;                      /* 43:53 CL  */
273 static int hf_bootp_option43_cl_device_id_x509 = -1;                    /* 43:54 CL  */
274 static int hf_bootp_option43_cl_end = -1;                               /* 43:255 CL */
275
276 static int hf_bootp_option43_alcatel_suboption = -1;                    /* 43 suboption */
277 static int hf_bootp_option43_alcatel_padding = -1;                      /* 43:0 Alcatel  */
278 static int hf_bootp_option43_alcatel_vlan_id = -1;                      /* 43:58 Alcatel  */
279 static int hf_bootp_option43_alcatel_tftp1 = -1;                        /* 43:64 Alcatel  */
280 static int hf_bootp_option43_alcatel_tftp2 = -1;                        /* 43:65 Alcatel  */
281 static int hf_bootp_option43_alcatel_app_type = -1;                     /* 43:66 Alcatel  */
282 static int hf_bootp_option43_alcatel_sip_url = -1;                      /* 43:67 Alcatel  */
283 static int hf_bootp_option43_alcatel_end = -1;                          /* 43:255 Alcatel */
284
285 static int hf_bootp_option43_arubaap_controllerip = -1;                 /* 43: ArubaAP*/
286 static int hf_bootp_option43_arubaiap = -1;                             /* 43: ArubaIAP*/
287 static int hf_bootp_option43_arubaiap_nameorg = -1;                     /* 43: ArubaIAP: Name Organisation*/
288 static int hf_bootp_option43_arubaiap_ampip = -1;                       /* 43: ArubaIAP: AMP IP Address*/
289 static int hf_bootp_option43_arubaiap_password = -1;                    /* 43 :ArubaIAP: Passwod*/
290
291 static int hf_bootp_option_netbios_over_tcpip_name_server = -1;         /* 44 */
292 static int hf_bootp_option_netbios_over_tcpip_dd_name_server = -1;      /* 45 */
293 static int hf_bootp_option_netbios_over_tcpip_node_type = -1;           /* 46 */
294 static int hf_bootp_option_netbios_over_tcpip_scope = -1;               /* 47 */
295 static int hf_bootp_option_xwindows_system_font_server = -1;            /* 48 */
296 static int hf_bootp_option_xwindows_system_display_manager = -1;        /* 49 */
297 static int hf_bootp_option_requested_ip_address = -1;                   /* 50 */
298 static int hf_bootp_option_ip_address_lease_time = -1;                  /* 51 */
299 static int hf_bootp_option_option_overload = -1;                        /* 52 */
300 static int hf_bootp_option_dhcp = -1;                                   /* 53 */
301 static int hf_bootp_option_dhcp_server_id = -1;                         /* 54 */
302 static int hf_bootp_option_parameter_request_list_item = -1;            /* 55 */
303 static int hf_bootp_option_message = -1;                                /* 56 */
304 static int hf_bootp_option_dhcp_max_message_size = -1;                  /* 57 */
305 static int hf_bootp_option_renewal_time_value = -1;                     /* 58 */
306 static int hf_bootp_option_rebinding_time_value = -1;                   /* 59 */
307 static int hf_bootp_option_vendor_class_id = -1;                        /* 60 */
308
309 static int hf_bootp_option_novell_netware_ip_domain = -1;               /* 62 */
310
311 static int hf_bootp_option63_suboption = -1;                            /* 63 suboption */
312 static int hf_bootp_option63_value = -1;                                /* 63 suboption value */
313 static int hf_bootp_option63_value_8 = -1;                              /* 63 suboption value */
314 static int hf_bootp_option63_value_ip_address = -1;                     /* 63 suboption value */
315 static int hf_bootp_option63_value_boolean = -1;                        /* 63 suboption value */
316 static int hf_bootp_option63_broadcast = -1;                            /* 63:5 */
317 static int hf_bootp_option63_preferred_dss_server = -1;                 /* 63:6 */
318 static int hf_bootp_option63_nearest_nwip_server = -1;                  /* 63:7 */
319 static int hf_bootp_option63_autoretries = -1;                          /* 63:8 */
320 static int hf_bootp_option63_autoretry_delay = -1;                      /* 63:9 */
321 static int hf_bootp_option63_support_netware_v1_1 = -1;                 /* 63:10 */
322 static int hf_bootp_option63_primary_dss = -1;                          /* 63:11 */
323
324 static int hf_bootp_option_nis_plus_domain = -1;                        /* 64 */
325 static int hf_bootp_option_nis_plus_server = -1;                        /* 65 */
326 static int hf_bootp_option_tftp_server_name = -1;                       /* 66 */
327 static int hf_bootp_option_bootfile_name = -1;                          /* 67 */
328 static int hf_bootp_option_mobile_ip_home_agent = -1;                   /* 68 */
329 static int hf_bootp_option_smtp_server = -1;                            /* 69 */
330 static int hf_bootp_option_pop3_server = -1;                            /* 70 */
331 static int hf_bootp_option_nntp_server = -1;                            /* 71 */
332 static int hf_bootp_option_default_www_server = -1;                     /* 72 */
333 static int hf_bootp_option_default_finger_server = -1;                  /* 73 */
334 static int hf_bootp_option_default_irc_server = -1;                     /* 74 */
335 static int hf_bootp_option_streettalk_server = -1;                      /* 75 */
336 static int hf_bootp_option_streettalk_da_server = -1;                   /* 76 */
337 static int hf_bootp_option77_user_class = -1;                           /* 77 User Class instance */
338 static int hf_bootp_option77_user_class_length = -1;                    /* 77 length of User Class instance */
339 static int hf_bootp_option77_user_class_data = -1;                      /* 77 data of User Class instance */
340 static int hf_bootp_option_slp_directory_agent_value = -1;              /* 78 */
341 static int hf_bootp_option_slp_directory_agent_slpda_address = -1;      /* 78 */
342 static int hf_bootp_option_slp_service_scope_value = -1;                /* 79 */
343 static int hf_bootp_option_slp_service_scope_string = -1;               /* 79 */
344
345 static int hf_bootp_option82_suboption = -1;                            /* 82 suboption */
346 static int hf_bootp_option82_value = -1;                                /* 82 suboption value */
347 static int hf_bootp_option82_value_8 = -1;                              /* 82 suboption value */
348 static int hf_bootp_option82_value_32 = -1;                             /* 82 suboption value */
349 static int hf_bootp_option82_value_ip_address = -1;                     /* 82 suboption value */
350 static int hf_bootp_option82_value_stringz = -1;                        /* 82 suboption value */
351 static int hf_bootp_option82_padding = -1;                              /* 82:0 */
352 static int hf_bootp_option82_agent_circuit_id = -1;                     /* 82:1 */
353 static int hf_bootp_option82_agent_remote_id = -1;                      /* 82:2 */
354 static int hf_bootp_option82_reserved = -1;                             /* 82:3 */
355 static int hf_bootp_option82_docsis_device_class = -1;                  /* 82:4 */
356 static int hf_bootp_option82_link_selection = -1;                       /* 82:5 */
357 static int hf_bootp_option82_subscriber_id = -1;                        /* 82:6 */
358 static int hf_bootp_option82_radius_attributes = -1;                    /* 82:7 */
359 static int hf_bootp_option82_authentication = -1;                       /* 82:8 */
360 static int hf_bootp_option82_vi = -1;                                   /* 82:9 */
361                                                                         /* 82:9 suboptions */
362 static int hf_bootp_option82_vi_enterprise = -1;
363 static int hf_bootp_option82_vi_data_length = -1;
364 static int hf_bootp_option82_vi_cl_option = -1;
365 static int hf_bootp_option82_vi_cl_length = -1;
366 static int hf_bootp_option82_vi_cl_tag = -1;
367 static int hf_bootp_option82_vi_cl_tag_length = -1;
368 static int hf_bootp_option82_vi_cl_docsis_version = -1;
369                                                                         /* 82:9 suboptions end */
370 static int hf_bootp_option82_flags = -1;                                /* 82:10 */
371 static int hf_bootp_option82_server_id_override = -1;                   /* 82:11 */
372 static int hf_bootp_option82_link_selection_cisco = -1;                 /* 82:150 */
373 static int hf_bootp_option82_vrf_name_vpn_id = -1;                      /* 82:151 */
374                                                                         /* 82:151 suboptions */
375 static int hf_bootp_option82_vrf_name_global = -1;
376 static int hf_bootp_option82_vrf_name = -1;
377 static int hf_bootp_option82_vrf_name_vpn_id_oui = -1;
378 static int hf_bootp_option82_vrf_name_vpn_id_index = -1;
379                                                                         /* 82:151 suboptions end */
380 static int hf_bootp_option82_server_id_override_cisco = -1;             /* 82:152 */
381
382 static int hf_bootp_option_novell_dss_string = -1;                      /* 85 */
383 static int hf_bootp_option_novell_dss_ip = -1;                          /* 85 */
384 static int hf_bootp_option_novell_ds_tree_name = -1;                    /* 86 */
385 static int hf_bootp_option_novell_ds_context = -1;                      /* 87 */
386 static int hf_bootp_option_dhcp_authentication_protocol = -1;           /* 90 */
387 static int hf_bootp_option_dhcp_authentication_alg_delay = -1;          /* 90 */
388 static int hf_bootp_option_dhcp_authentication_algorithm = -1;          /* 90 */
389 static int hf_bootp_option_dhcp_authentication_rdm = -1;                /* 90 */
390 static int hf_bootp_option_dhcp_authentication_rdm_replay_detection = -1;   /* 90 */
391 static int hf_bootp_option_dhcp_authentication_rdm_rdv = -1;            /* 90 */
392 static int hf_bootp_option_dhcp_authentication_secret_id = -1;          /* 90 */
393 static int hf_bootp_option_dhcp_authentication_hmac_md5_hash = -1;      /* 90 */
394 static int hf_bootp_option_dhcp_authentication_information = -1;        /* 90 */
395 static int hf_bootp_option_client_last_transaction_time = -1;           /* 91 */
396 static int hf_bootp_option_associated_ip_option = -1;                   /* 92 */
397 static int hf_bootp_option_client_system_architecture = -1;             /* 93 */
398 static int hf_bootp_option_client_network_id_major_ver = -1;            /* 94 */
399 static int hf_bootp_option_client_network_id_minor_ver = -1;            /* 94 */
400 static int hf_bootp_option_civic_location_what = -1;                    /* 99 */
401 static int hf_bootp_option_civic_location_country = -1;                 /* 99 */
402 static int hf_bootp_option_civic_location_ca_type = -1;                 /* 99 */
403 static int hf_bootp_option_civic_location_ca_length = -1;               /* 99 */
404 static int hf_bootp_option_civic_location_ca_value = -1;                /* 99 */
405 static int hf_bootp_option_netinfo_parent_server_address = -1;          /* 112 */
406 static int hf_bootp_option_netinfo_parent_server_tag = -1;              /* 113 */
407 static int hf_bootp_option_dhcp_auto_configuration = -1;                /* 116 */
408 static int hf_bootp_option_dhcp_name_service_search_option = -1;                /* 117 */
409 static int hf_bootp_option_dhcp_dns_domain_search_list_rfc_3396_detected = -1;  /* 119 */
410 static int hf_bootp_option_dhcp_dns_domain_search_list_refer_last_option = -1;  /* 119 */
411 static int hf_bootp_option_dhcp_dns_domain_search_list_fqdn = -1;               /* 119 */
412 static int hf_bootp_option_sip_server_rfc_3396_detected = -1;                   /* 120 */
413 static int hf_bootp_option_sip_server_refer_last_option = -1;                   /* 120 */
414 static int hf_bootp_option_sip_server_enc = -1;                         /* 120 */
415 static int hf_bootp_option_sip_server_name = -1;                                /* 120 */
416 static int hf_bootp_option_sip_server_address = -1;                             /* 120 */
417 static int hf_bootp_option_sip_server_address_stringz = -1;             /* 120 */
418 static int hf_bootp_option_cl_dss_id_option = -1;                       /* 123 CL */
419 static int hf_bootp_option_cl_dss_id_len = -1;                          /* 123 CL */
420 static int hf_bootp_option_cl_dss_id = -1;                              /* 123 CL */
421 static int hf_bootp_option_vi_class_cl_address_mode = -1;               /* 124 */
422 static int hf_bootp_option_vi_class_enterprise = -1;                    /* 124 */
423 static int hf_bootp_option_vi_class_data_length = -1;                   /* 124 */
424 static int hf_bootp_option_vi_class_data = -1;                          /* 124 */
425
426 static int hf_bootp_option125_enterprise = -1;
427 static int hf_bootp_option125_value = -1;                               /* 125 suboption value */
428 static int hf_bootp_option125_value_8 = -1;                             /* 125 suboption value */
429 static int hf_bootp_option125_value_16 = -1;                            /* 125 suboption value */
430 static int hf_bootp_option125_value_ip_address = -1;                    /* 125 suboption value */
431 static int hf_bootp_option125_value_stringz = -1;                       /* 125 suboption value */
432 static int hf_bootp_option125_tr111_suboption = -1;                     /* 125 suboption */
433 static int hf_bootp_option125_tr111_device_manufacturer_oui = -1;       /* 125:TR-111 1 */
434 static int hf_bootp_option125_tr111_device_serial_number = -1;          /* 125:TR-111 2 */
435 static int hf_bootp_option125_tr111_device_product_class = -1;          /* 125:TR-111 3 */
436 static int hf_bootp_option125_tr111_gateway_manufacturer_oui = -1;      /* 125:TR-111 4 */
437 static int hf_bootp_option125_tr111_gateway_serial_number = -1;         /* 125:TR-111 5 */
438 static int hf_bootp_option125_tr111_gateway_product_class = -1;         /* 125:TR-111 6 */
439 static int hf_bootp_option125_cl_suboption = -1;                        /* 125 suboption */
440 static int hf_bootp_option125_cl_option_request = -1;                   /* 125:CL 1 */
441 static int hf_bootp_option125_cl_tftp_server_addresses = -1;            /* 125:CL 2 */
442 static int hf_bootp_option125_cl_erouter_container_option = -1;         /* 125:CL 3 */
443 static int hf_bootp_option125_cl_mib_environment_indicator_option = -1; /* 125:CL 4 */
444 static int hf_bootp_option125_cl_modem_capabilities = -1;               /* 125:CL 5 */
445
446 static int hf_bootp_option_subnet_selection_option = -1;                /* 118 */
447 static int hf_bootp_option_lost_server_domain_name = -1;                /* 137 */
448 static int hf_bootp_option_capwap_access_controller = -1;               /* 138 */
449 static int hf_bootp_option_tftp_server_address = -1;                    /* 150 */
450 static int hf_bootp_option_6RD_ipv4_mask_len = -1;                      /* 212 */
451 static int hf_bootp_option_6RD_prefix_len = -1;                         /* 212 */
452 static int hf_bootp_option_6RD_prefix = -1;                             /* 212 */
453 static int hf_bootp_option_6RD_border_relay_ip = -1;                    /* 212 */
454 static int hf_bootp_option_private_proxy_autodiscovery = -1;            /* 252 */
455 static int hf_bootp_option_end = -1;                                    /* 255 */
456 static int hf_bootp_option_end_overload = -1;                           /* 255 (with overload)*/
457 static int hf_bootp_vendor_unknown_suboption = -1;
458 static int hf_bootp_suboption_data = -1;
459
460
461
462 static gint ett_bootp = -1;
463 static gint ett_bootp_flags = -1;
464 static gint ett_bootp_option = -1;
465 static gint ett_bootp_option43_suboption = -1;
466 static gint ett_bootp_option63_suboption = -1;
467 static gint ett_bootp_option77_instance = -1;
468 static gint ett_bootp_option82_suboption = -1;
469 static gint ett_bootp_option82_suboption9 = -1;
470 static gint ett_bootp_option125_suboption = -1;
471 static gint ett_bootp_option125_tr111_suboption = -1;
472 static gint ett_bootp_option125_cl_suboption = -1;
473 static gint ett_bootp_fqdn = -1;
474
475 static expert_field ei_bootp_bad_length = EI_INIT;
476 static expert_field ei_bootp_missing_subopt_length = EI_INIT;
477 static expert_field ei_bootp_missing_subopt_value = EI_INIT;
478 static expert_field ei_bootp_mal_duid = EI_INIT;
479 static expert_field hf_bootp_opt_overload_file_end_missing = EI_INIT;
480 static expert_field hf_bootp_opt_overload_sname_end_missing = EI_INIT;
481 static expert_field hf_bootp_subopt_unknown_type = EI_INIT;
482 static expert_field ei_bootp_option77_user_class_malformed = EI_INIT;
483 static expert_field ei_bootp_option_civic_location_bad_cattype = EI_INIT;
484 static expert_field ei_bootp_option_dhcp_name_service_invalid = EI_INIT;
485 static expert_field ei_bootp_option_sip_server_address_encoding = EI_INIT;
486 static expert_field ei_bootp_option_classless_static_route = EI_INIT;
487 static expert_field ei_bootp_option125_enterprise_malformed = EI_INIT;
488 static expert_field ei_bootp_option_6RD_malformed = EI_INIT;
489 static expert_field ei_bootp_option82_vi_cl_tag_unknown = EI_INIT;
490 static expert_field ei_bootp_suboption_invalid = EI_INIT;
491 static expert_field ei_bootp_secs_le = EI_INIT;
492 static expert_field ei_bootp_end_option_missing = EI_INIT;
493
494 static dissector_handle_t bootp_handle;
495
496 /* RFC2937 The Name Service Search Option for DHCP */
497 #define RFC2937_LOCAL_NAMING_INFORMATION                           0
498 #define RFC2937_DOMAIN_NAME_SERVER_OPTION                          6
499 #define RFC2937_NETWORK_INFORMATION_SERVERS_OPTION                41
500 #define RFC2937_NETBIOS_OVER_TCP_IP_NAME_SERVER_OPTION            44
501 #define RFC2937_NETWORK_INFORMATION_SERVICE_PLUS_SERVERS_OPTION   65
502
503 /* RFC3825decoder error codes of the conversion function */
504 #define RFC3825_NOERROR                           0
505 #define RFC3825_LATITUDE_OUTOFRANGE               1
506 #define RFC3825_LATITUDE_UNCERTAINTY_OUTOFRANGE   2
507 #define RFC3825_LONGITUDE_OUTOFRANGE              3
508 #define RFC3825_LONGITUDE_UNCERTAINTY_OUTOFRANGE  4
509 #define RFC3825_ALTITUDE_OUTOFRANGE               5
510 #define RFC3825_ALTITUDE_UNCERTAINTY_OUTOFRANGE   6
511 #define RFC3825_ALTITUDE_TYPE_OUTOFRANGE          7
512 #define RFC3825_DATUM_TYPE_OUTOFRANGE             8
513
514 #define DUID_LLT                1
515 #define DUID_EN                 2
516 #define DUID_LL                 3
517
518 struct rfc3825_location_fixpoint_t {
519
520         gint64 latitude;        /* latitude in degrees, allowed range from -90deg to 90deg.
521                                    Fixpoint A(8,25) with 34 bits */
522         guint8 latitude_res;    /* the resolution of the latitude in bits, allowed range is from 0 to 34.
523                                    6 bits. */
524         gint64 longitude;       /* longitude in degrees, range from -180deg to 180deg.
525                                    Fixpoint A(8,25) with 34 bits */
526         guint8 longitude_res;   /* the resolution of the longitude in bits, allowed range is from 0 to 34.
527                                    6 bits. */
528         gint32 altitude;        /* the altitude, 30 bits.
529                                    Depending on alt_type this are meters or floors, no range limit.
530                                    altitude_type==1: A(13,8) with 22 bits
531                                    altitude_type==2: A(13,8) with 22 bits */
532         guint8 altitude_res;    /* the resolution of the altitude in bits, allowed range is from 0 to 30.
533                                    6 bits.
534                                    altitude_type==1: any value between 0 and 30
535                                    altitude_type==2: either 0 (floor unknown) or 30 */
536         guint8 altitude_type;   /* the type of the altitude, 4 bits. allowed values are:
537                                    0: unknown
538                                    1: altitude in meters
539                                    2: altitude in floors */
540         guint8 datum_type;      /* the map datum used for the coordinates. 8 bits.
541                                    All values are allowed although currently only the
542                                    following ones are defined:
543                                    1: WGS84
544                                    2: NAD83/NAVD88
545                                    3: NAD83/MLLW */
546 };
547
548 /* The rfc3825_location_decimal_t structure holds the location parameters
549  * in decimal (floating point) format.
550  */
551 struct rfc3825_location_decimal_t {
552
553         double latitude;        /* latitude in degrees, allowed range from -90deg to 90deg */
554         double latitude_res;    /* the uncertainty of the latitude in grad, "0.01" means +-0.01deg
555                                    from the altitude. During conversion this will be rounded to
556                                    next smaller value which can be represented in fixpoint arithmetic */
557         double longitude;       /* longitude in degrees, range from -180deg to 180deg */
558         double longitude_res;   /* the uncertainty of the longitude in grad, "0.01" means +-0.01deg
559                                    from the longitude. During conversion this will be rounded to
560                                    next smaller value which can be represented in fixpoint arithmetic */
561         double altitude;        /* the altitude, depending on alt_type this are meters or floors, no range limit */
562         double altitude_res;    /* the uncertainty of the altitude in either:
563                                    - altitude-type=meters: "10" means 10 meters which means +-10 meters from the altitude
564                                    - altitude-type=floors: either 0 (unknown) or 30 (exact) */
565         int altitude_type;      /* the type of the altitude, allowed values are
566                                    0: unknown
567                                    1: altitude in meters
568                                    2: altitude in floors */
569         int datum_type;          /* the map datum used for the coordinates.
570                                     All values are allowed although currently only the
571                                     following ones are defined:
572                                     1: WGS84
573                                     2: NAD83/NAVD88
574                                     3: NAD83/MLLW */
575 };
576
577 /* For managing split options with RFC 3396 */
578 struct rfc3396_for_option_t {
579         unsigned int total_number_of_block;
580         unsigned int index_current_block;
581         tvbuff_t* tvb_composite;
582 };
583
584 /* The RFC 3397 allows to cut long option (RFC 3396). */
585 struct rfc3396_for_option_t rfc3396_dns_domain_search_list;
586
587 /* The RFC 3361 allows to cut long option (RFC 3396). */
588 struct rfc3396_for_option_t rfc3396_sip_server;
589
590 enum {
591         RFC_3361_ENC_FQDN,
592         RFC_3361_ENC_IPADDR
593 };
594
595 /* converts fixpoint presentation into decimal presentation
596    also converts values which are out of range to allow decoding of received data */
597 static int rfc3825_fixpoint_to_decimal(struct rfc3825_location_fixpoint_t *fixpoint, struct rfc3825_location_decimal_t *decimal);
598
599 /* decodes the LCI string received from DHCP into the fixpoint values */
600 static void rfc3825_lci_to_fixpoint(const unsigned char lci[16], struct rfc3825_location_fixpoint_t *fixpoint);
601
602
603 /* Map Datum Types used for the coordinates (RFC 3825) */
604 static const value_string map_datum_type_values[] = {
605         { 1,    "WGS 84" },
606         { 2,    "NAD83 (NAVD88)" },
607         { 3,    "NAD83 (MLLW)" },
608         { 0,    NULL }
609 };
610
611
612 /* Altitude Types used for the coordinates (RFC 3825) */
613 static const value_string altitude_type_values[] = {
614         { 1,    "Meters" },
615         { 2,    "Floors" },
616         { 0,    NULL }
617 };
618
619 /* AutoConfigure (RFC 2563) */
620 static const value_string dhcp_autoconfig[] = {
621         { 0,    "DoNotAutoConfigure"},
622         { 1,    "AutoConfigure"},
623         { 0,    NULL }
624 };
625
626 /* Error Types for RFC 3825 coordinate location decoding */
627 static const value_string rfc3825_error_types[] = {
628         { 1,    "Latitude is out of range [-90,90]"},
629         { 2,    "Latitude Uncertainty is out of range [0,90]"},
630         { 3,    "Longitude is out of range [-180,180]"},
631         { 4,    "Longitude Uncertainty is out of range [0,180]"},
632         { 5,    "Altitude is out of range [-(2^21),(2^21)-1]"},
633         { 6,    "Altitude Uncertainty is out of range [0,2^20]"},
634         { 7,    "Altitude Type is out of range [0,2]"},
635         { 8,    "Datum is out of range [1,3]"},
636         { 0,    NULL }
637 };
638
639
640
641 /* Civic Address What field (RFC 4776) */
642 static const value_string civic_address_what_values[] = {
643         { 0,    "Location of the DHCP server" },
644         { 1,    "Location of the network element believed to be closest to the client" },
645         { 2,    "Location of the client"},
646         { 0, NULL}
647 };
648
649 /* Civic Address Type field (RFC 4119, RFC 4776, RFC 5139) */
650 static const value_string civic_address_type_values[] = {
651         {   0,  "Language" },
652         {   1,  "A1" },
653         {   2,  "A2" },
654         {   3,  "A3" },
655         {   4,  "A4" },
656         {   5,  "A5" },
657         {   6,  "A6" },
658         {  16,  "PRD (Leading street direction)" },
659         {  17,  "POD (Trailing street suffix)" },
660         {  18,  "STS (Street suffix)" },
661         {  19,  "HNO (House number)" },
662         {  20,  "HNS (House number suffix)" },
663         {  21,  "LMK (Landmark or vanity address)" },
664         {  22,  "LOC (Additional location information)" },
665         {  23,  "NAM" },
666         {  24,  "PC (Postal/ZIP code)" },
667         {  25,  "BLD (Building)" },
668         {  26,  "UNIT" },
669         {  27,  "FLR (Floor)" },
670         {  28,  "ROOM" },
671         {  29,  "PLC (Place-type)" },
672         {  30,  "PCN (Postal community name)" },
673         {  31,  "POBOX" },
674         {  32,  "ADDCODE (Additional Code)" },
675         {  33,  "SEAT" },
676         {  34,  "RD (Primary road or street)" },
677         {  35,  "RDSEC (Road section)" },
678         {  36,  "RDBR (Road branch)" },
679         {  37,  "RDSUBBR (Road sub-branch)" },
680         {  38,  "PRM (Road pre-modifier)" },
681         {  39,  "POM (Road post-modifier" },
682         { 128,  "Script" },
683         { 0, NULL }
684 };
685
686 static const value_string cablelab_ipaddr_mode_vals[] = {
687         { 1, "IPv4" },
688         { 2, "IPv6" },
689         { 0, NULL }
690 };
691
692 static const value_string duidtype_vals[] =
693 {
694         { DUID_LLT,     "link-layer address plus time" },
695         { DUID_EN,      "assigned by vendor based on Enterprise number" },
696         { DUID_LL,      "link-layer address" },
697         { 0, NULL }
698 };
699
700 static gboolean novell_string = FALSE;
701
702 #define UDP_PORT_BOOTPS  67
703 #define UDP_PORT_BOOTPC  68
704
705 #define BOOTP_BC        0x8000
706 #define BOOTP_MBZ       0x7FFF
707
708 /* FQDN stuff */
709 #define F_FQDN_S        0x01
710 #define F_FQDN_O        0x02
711 #define F_FQDN_E        0x04
712 #define F_FQDN_N        0x08
713 #define F_FQDN_MBZ      0xf0
714
715 static const true_false_string tfs_fqdn_s = {
716         "Server",
717         "Client"
718 };
719
720 static const true_false_string tfs_fqdn_o = {
721         "Override",
722         "No override"
723 };
724
725 static const true_false_string tfs_fqdn_e = {
726         "Binary encoding",
727         "ASCII encoding"
728 };
729
730 static const true_false_string tfs_fqdn_n = {
731         "No server updates",
732         "Some server updates"
733 };
734
735 enum field_type {
736         special,
737         none,
738         presence,
739         ipv4,                   /* single IPv4 address */
740         ipv4_list,              /* list of IPv4 addresses */
741         string,
742         bytes,
743         opaque,
744         val_boolean,
745         val_u_byte,
746         val_u_short,
747         val_u_short_list,
748         val_u_le_short,
749         val_u_long,
750         time_in_s_secs,         /* Signed */
751         time_in_u_secs,         /* Unsigned (not micro) */
752         fqdn,
753         ipv4_or_fqdn
754 };
755
756 struct opt_info {
757         const char      *text;
758         enum field_type ftype;
759         int* phf;
760 };
761
762 static const true_false_string flag_set_broadcast = {
763         "Broadcast",
764         "Unicast"
765 };
766
767 #define BOOTP_MAX_NO_CHAR 64
768
769 /* PacketCable/DOCSIS definitions */
770 #define PACKETCABLE_MTA_CAP10 "pktc1.0:"
771 #define PACKETCABLE_MTA_CAP15 "pktc1.5:"
772 #define PACKETCABLE_MTA_CAP20 "pktc2.0:"
773 #define PACKETCABLE_CM_CAP11  "docsis1.1:"
774 #define PACKETCABLE_CM_CAP20  "docsis2.0:"
775 #define PACKETCABLE_CM_CAP30  "docsis3.0:"
776
777 #define PACKETCABLE_CCC_I05      1
778 #define PACKETCABLE_CCC_DRAFT5   2
779 #define PACKETCABLE_CCC_RFC_3495 3
780
781 static const enum_val_t pkt_ccc_protocol_versions[] = {
782         { "ccc_i05",     "PKT-SP-PROV-I05-021127", PACKETCABLE_CCC_I05 },
783         { "ccc_draft_5", "IETF Draft 5",           PACKETCABLE_CCC_DRAFT5 },
784         { "rfc_3495",    "RFC 3495",               PACKETCABLE_CCC_RFC_3495 },
785         { NULL, NULL, 0 }
786 };
787
788 static gint pkt_ccc_protocol_version = PACKETCABLE_CCC_RFC_3495;
789 static guint pkt_ccc_option = 122;
790
791
792 static int dissect_vendor_pxeclient_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
793                                               tvbuff_t *tvb, int optoff, int optend);
794 static int dissect_vendor_cablelabs_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
795                                               tvbuff_t *tvb, int optoff, int optend);
796 static int dissect_vendor_alcatel_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
797                                             tvbuff_t *tvb, int optoff, int optend);
798 static int dissect_netware_ip_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
799                                             tvbuff_t *tvb, int optoff, int optend);
800 static int dissect_vendor_tr111_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
801                                             tvbuff_t *tvb, int optoff, int optend);
802 static int bootp_dhcp_decode_agent_info(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
803                                             tvbuff_t *tvb, int optoff, int optend);
804 static void dissect_packetcable_mta_cap(proto_tree *v_tree, tvbuff_t *tvb,
805                                         int voff, int len);
806 static void dissect_docsis_cm_cap(proto_tree *v_tree, tvbuff_t *tvb,
807                                   int voff, int len, gboolean opt125);
808 static int dissect_packetcable_i05_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
809                                        tvbuff_t *tvb, int optoff, int optend);
810 static int dissect_packetcable_ietf_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
811                                         tvbuff_t *tvb, int optoff, int optend, int revision);
812 static int dissect_vendor_cl_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
813                                             tvbuff_t *tvb, int optoff, int optend);
814 static int dissect_vendor_generic_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
815                                             tvbuff_t *tvb, int optoff, int optend);
816
817 #define OPT53_DISCOVER "Discover"
818 /* http://www.iana.org/assignments/bootp-dhcp-parameters */
819 static const value_string opt53_text[] = {
820         {  1,   OPT53_DISCOVER },
821         {  2,   "Offer" },
822         {  3,   "Request" },
823         {  4,   "Decline" },
824         {  5,   "ACK" },
825         {  6,   "NAK" },
826         {  7,   "Release" },
827         {  8,   "Inform" },
828         {  9,   "Force Renew" },
829         { 10,   "Lease query" },                /* RFC4388 */
830         { 11,   "Lease Unassigned" },           /* RFC4388 */
831         { 12,   "Lease Unknown" },              /* RFC4388 */
832         { 13,   "Lease Active" },               /* RFC4388 */
833         /* draft-ietf-dhc-leasequery-09.txt
834         { 13,   "Lease query" },                        */
835         { 14,   "Lease known" },
836         { 15,   "Lease unknown" },
837         { 16,   "Lease active" },
838         { 17,   "Unimplemented" },
839
840         { 0,    NULL }
841 };
842
843 /* DHCP Authentication protocols */
844 #define AUTHEN_PROTO_CONFIG_TOKEN       0
845 #define AUTHEN_PROTO_DELAYED_AUTHEN     1
846
847 /* DHCP Authentication algorithms for delayed authentication */
848 #define AUTHEN_DELAYED_ALGO_HMAC_MD5    1
849
850 /* DHCP Authentication Replay Detection Methods */
851 #define AUTHEN_RDM_MONOTONIC_COUNTER    0x00
852
853 /* DHCP Option Overload (option code 52) */
854 #define OPT_OVERLOAD_FILE               1
855 #define OPT_OVERLOAD_SNAME              2
856 #define OPT_OVERLOAD_BOTH               3
857
858 /* Server name and boot file offsets and lengths */
859 #define SERVER_NAME_OFFSET              44
860 #define SERVER_NAME_LEN                 64
861 #define FILE_NAME_OFFSET                108
862 #define FILE_NAME_LEN                   128
863 #define VENDOR_INFO_OFFSET              236
864
865 static const value_string bootp_nbnt_vals[] = {
866         {0x1,   "B-node" },
867         {0x2,   "P-node" },
868         {0x4,   "M-node" },
869         {0x8,   "H-node" },
870         {0,     NULL     }
871 };
872
873 static const value_string bootp_client_arch[] = {
874         { 0x0000, "IA x86 PC" },
875         { 0x0001, "NEC/PC98" },
876         { 0x0002, "IA64 PC" },
877         { 0x0003, "DEC Alpha" },
878         { 0x0004, "ArcX86" },
879         { 0x0005, "Intel Lean Client" },
880         { 0x0006, "EFI IA32" },
881         { 0x0007, "EFI BC" },
882         { 0x0008, "EFI Xscale" },
883         { 0x0009, "EFI x86-64" },
884         { 0,      NULL }
885 };
886
887 static const value_string opt_overload_vals[] = {
888         { OPT_OVERLOAD_FILE,  "Boot file name holds options",                },
889         { OPT_OVERLOAD_SNAME, "Server host name holds options",              },
890         { OPT_OVERLOAD_BOTH,  "Boot file and server host names hold options" },
891         { 0,                  NULL                                           } };
892
893 static const value_string slpda_vals[] = {
894         {0x00,   "Dynamic Discovery" },
895         {0x01,   "Static Discovery" },
896         {0x80,   "Backwards compatibility" },
897         {0,     NULL     } };
898
899 static const value_string slp_scope_vals[] = {
900         {0x00,   "Preferred Scope" },
901         {0x01,   "Mandatory Scope" },
902         {0,     NULL     } };
903
904 static const value_string authen_protocol_vals[] = {
905         {AUTHEN_PROTO_CONFIG_TOKEN,   "configuration token" },
906         {AUTHEN_PROTO_DELAYED_AUTHEN, "delayed authentication" },
907         {0,                           NULL     } };
908
909 static const value_string authen_da_algo_vals[] = {
910         {AUTHEN_DELAYED_ALGO_HMAC_MD5, "HMAC_MD5" },
911         {0,                            NULL     } };
912
913 static const value_string authen_rdm_vals[] = {
914         {AUTHEN_RDM_MONOTONIC_COUNTER, "Monotonically-increasing counter" },
915         {0,                            NULL     } };
916
917 static const value_string cl_dss_id_type_vals[] = {
918         {1, "Primary DSS_ID" },
919         {2, "Secondary DSS_ID" },
920         {0, NULL }
921 };
922
923 static const value_string sip_server_enc_vals[] = {
924         {0, "Fully Qualified Domain Name" },
925         {1, "IPv4 Address" },
926         {0, NULL }
927 };
928 /* bootp options administration */
929 #define BOOTP_OPT_NUM   256
930
931 /* Re-define structure.  Values to be updated by bootp_init_protocol */
932 static struct opt_info bootp_opt[BOOTP_OPT_NUM];
933
934 static struct opt_info default_bootp_opt[BOOTP_OPT_NUM] = {
935 /*   0 */ { "Padding",                                  none, &hf_bootp_option_padding },
936 /*   1 */ { "Subnet Mask",                              ipv4, &hf_bootp_option_subnet_mask },
937 /*   2 */ { "Time Offset",                              time_in_s_secs, &hf_bootp_option_time_offset },
938 /*   3 */ { "Router",                                   ipv4_list, &hf_bootp_option_router },
939 /*   4 */ { "Time Server",                              ipv4_list, &hf_bootp_option_time_server },
940 /*   5 */ { "Name Server",                              ipv4_list, &hf_bootp_option_name_server },
941 /*   6 */ { "Domain Name Server",                       ipv4_list, &hf_bootp_option_domain_name_server },
942 /*   7 */ { "Log Server",                               ipv4_list, &hf_bootp_option_log_server },
943 /*   8 */ { "Quotes Server",                            ipv4_list, &hf_bootp_option_quotes_server },
944 /*   9 */ { "LPR Server",                               ipv4_list, &hf_bootp_option_lpr_server },
945 /*  10 */ { "Impress Server",                           ipv4_list, &hf_bootp_option_impress_server },
946 /*  11 */ { "Resource Location Server",                 ipv4_list, &hf_bootp_option_resource_location_server },
947 /*  12 */ { "Host Name",                                string, &hf_bootp_option_hostname },
948 /*  13 */ { "Boot File Size",                           val_u_short, &hf_bootp_option_boot_file_size },
949 /*  14 */ { "Merit Dump File",                          string, &hf_bootp_option_merit_dump_file },
950 /*  15 */ { "Domain Name",                              string, &hf_bootp_option_domain_name },
951 /*  16 */ { "Swap Server",                              ipv4, &hf_bootp_option_swap_server },
952 /*  17 */ { "Root Path",                                string, &hf_bootp_option_root_path },
953 /*  18 */ { "Extensions Path",                          string, &hf_bootp_option_extension_path },
954 /*  19 */ { "IP Forwarding",                            val_boolean, &hf_bootp_option_ip_forwarding },
955 /*  20 */ { "Non-Local Source Routing",                 val_boolean, &hf_bootp_option_non_local_source_routing },
956 /*  21 */ { "Policy Filter",                            special, NULL },
957 /*  22 */ { "Maximum Datagram Reassembly Size",         val_u_short, &hf_bootp_option_max_datagram_reassembly_size },
958 /*  23 */ { "Default IP Time-to-Live",                  val_u_byte, &hf_bootp_option_default_ip_ttl },
959 /*  24 */ { "Path MTU Aging Timeout",                   time_in_u_secs, &hf_bootp_option_path_mtu_aging_timeout },
960 /*  25 */ { "Path MTU Plateau Table",                   val_u_short_list, &hf_bootp_option_path_mtu_plateau_table_item },
961 /*  26 */ { "Interface MTU",                            val_u_short, &hf_bootp_option_interface_mtu },
962 /*  27 */ { "All Subnets are Local",                    val_boolean, &hf_bootp_option_all_subnets_are_local },
963 /*  28 */ { "Broadcast Address",                        ipv4, &hf_bootp_option_broadcast_address },
964 /*  29 */ { "Perform Mask Discovery",                   val_boolean, &hf_bootp_option_perform_mask_discovery },
965 /*  30 */ { "Mask Supplier",                            val_boolean, &hf_bootp_option_mask_supplier },
966 /*  31 */ { "Perform Router Discover",                  val_boolean, &hf_bootp_option_perform_router_discover },
967 /*  32 */ { "Router Solicitation Address",              ipv4, &hf_bootp_option_router_solicitation_address },
968 /*  33 */ { "Static Route",                             special, NULL },
969 /*  34 */ { "Trailer Encapsulation",                    val_boolean, &hf_bootp_option_trailer_encapsulation },
970 /*  35 */ { "ARP Cache Timeout",                        time_in_u_secs, &hf_bootp_option_arp_cache_timeout },
971 /*  36 */ { "Ethernet Encapsulation",                   val_boolean, &hf_bootp_option_ethernet_encapsulation },
972 /*  37 */ { "TCP Default TTL",                          val_u_byte, &hf_bootp_option_tcp_default_ttl },
973 /*  38 */ { "TCP Keepalive Interval",                   time_in_u_secs, &hf_bootp_option_tcp_keepalive_interval },
974 /*  39 */ { "TCP Keepalive Garbage",                    val_boolean, &hf_bootp_option_tcp_keepalive_garbage },
975 /*  40 */ { "Network Information Service Domain",       string, &hf_bootp_option_nis_domain },
976 /*  41 */ { "Network Information Service Servers",      ipv4_list, &hf_bootp_option_nis_server },
977 /*  42 */ { "Network Time Protocol Servers",            ipv4_list, &hf_bootp_option_ntp_server },
978 /*  43 */ { "Vendor-Specific Information",              special, NULL },
979 /*  44 */ { "NetBIOS over TCP/IP Name Server",          ipv4_list, &hf_bootp_option_netbios_over_tcpip_name_server },
980 /*  45 */ { "NetBIOS over TCP/IP Datagram Distribution Name Server", ipv4_list, &hf_bootp_option_netbios_over_tcpip_dd_name_server },
981 /*  46 */ { "NetBIOS over TCP/IP Node Type",            val_u_byte, &hf_bootp_option_netbios_over_tcpip_node_type },
982 /*  47 */ { "NetBIOS over TCP/IP Scope",                string, &hf_bootp_option_netbios_over_tcpip_scope },
983 /*  48 */ { "X Window System Font Server",              ipv4_list, &hf_bootp_option_xwindows_system_font_server },
984 /*  49 */ { "X Window System Display Manager",          ipv4_list, &hf_bootp_option_xwindows_system_display_manager },
985 /*  50 */ { "Requested IP Address",                     ipv4, &hf_bootp_option_requested_ip_address },
986 /*  51 */ { "IP Address Lease Time",                    time_in_u_secs, &hf_bootp_option_ip_address_lease_time },
987 /*  52 */ { "Option Overload",                          special, &hf_bootp_option_option_overload },
988 /*  53 */ { "DHCP Message Type",                        val_u_byte, &hf_bootp_option_dhcp },
989 /*  54 */ { "DHCP Server Identifier",                   ipv4, &hf_bootp_option_dhcp_server_id },
990 /*  55 */ { "Parameter Request List",                   special, &hf_bootp_option_parameter_request_list_item },
991 /*  56 */ { "Message",                                  string, &hf_bootp_option_message },
992 /*  57 */ { "Maximum DHCP Message Size",                val_u_short, &hf_bootp_option_dhcp_max_message_size },
993 /*  58 */ { "Renewal Time Value",                       time_in_u_secs, &hf_bootp_option_renewal_time_value },
994 /*  59 */ { "Rebinding Time Value",                     time_in_u_secs, &hf_bootp_option_rebinding_time_value },
995 /*  60 */ { "Vendor class identifier",                  special, NULL },
996 /*  61 */ { "Client identifier",                        special, NULL },
997 /*  62 */ { "Novell/Netware IP domain",                 string, &hf_bootp_option_novell_netware_ip_domain },
998 /*  63 */ { "Novell Options",                           special, NULL },
999 /*  64 */ { "Network Information Service+ Domain",      string, &hf_bootp_option_nis_plus_domain },
1000 /*  65 */ { "Network Information Service+ Servers",     ipv4_list, &hf_bootp_option_nis_plus_server },
1001 /*  66 */ { "TFTP Server Name",                         string, &hf_bootp_option_tftp_server_name },
1002 /*  67 */ { "Bootfile name",                            string, &hf_bootp_option_bootfile_name },
1003 /*  68 */ { "Mobile IP Home Agent",                     ipv4_list, &hf_bootp_option_mobile_ip_home_agent  },
1004 /*  69 */ { "SMTP Server",                              ipv4_list, &hf_bootp_option_smtp_server },
1005 /*  70 */ { "POP3 Server",                              ipv4_list, &hf_bootp_option_pop3_server },
1006 /*  71 */ { "NNTP Server",                              ipv4_list, &hf_bootp_option_nntp_server },
1007 /*  72 */ { "Default WWW Server",                       ipv4_list, &hf_bootp_option_default_www_server },
1008 /*  73 */ { "Default Finger Server",                    ipv4_list, &hf_bootp_option_default_finger_server },
1009 /*  74 */ { "Default IRC Server",                       ipv4_list, &hf_bootp_option_default_irc_server },
1010 /*  75 */ { "StreetTalk Server",                        ipv4_list, &hf_bootp_option_streettalk_server },
1011 /*  76 */ { "StreetTalk Directory Assistance Server",   ipv4_list, &hf_bootp_option_streettalk_da_server },
1012 /*  77 */ { "User Class Information",                   special, NULL },
1013 /*  78 */ { "Directory Agent Information",              special, NULL },
1014 /*  79 */ { "Service Location Agent Scope",             special, NULL },
1015 /*  80 */ { "Rapid commit",                             opaque, NULL },
1016 /*  81 */ { "Client Fully Qualified Domain Name",       special, NULL},
1017 /*  82 */ { "Agent Information Option",                 special, NULL},
1018 /*  83 */ { "iSNS [TODO:RFC4174]",                      opaque, NULL },
1019 /*  84 */ { "Removed/Unassigned",                       opaque, NULL },
1020 /*  85 */ { "Novell Directory Services Servers",        special, NULL},
1021 /*  86 */ { "Novell Directory Services Tree Name",      string, &hf_bootp_option_novell_ds_tree_name },
1022 /*  87 */ { "Novell Directory Services Context",        string, &hf_bootp_option_novell_ds_context },
1023 /*  88 */ { "BCMCS Controller Domain Name [TODO:RFC4280]",      opaque, NULL },
1024 /*  89 */ { "BCMCS Controller IPv4 address [TODO:RFC4280]",     opaque, NULL },
1025 /*  90 */ { "Authentication",                           special, NULL},
1026 /*  91 */ { "Client last transaction time",             time_in_u_secs, &hf_bootp_option_client_last_transaction_time },
1027 /*  92 */ { "Associated IP option",                     ipv4_list, &hf_bootp_option_associated_ip_option },
1028 /*  93 */ { "Client System Architecture",               val_u_short, &hf_bootp_option_client_system_architecture },
1029 /*  94 */ { "Client Network Device Interface",          special, NULL},
1030 /*  95 */ { "LDAP [TODO:RFC3679]",                      opaque, NULL },
1031 /*  96 */ { "Removed/Unassigned",                       opaque, NULL },
1032 /*  97 */ { "UUID/GUID-based Client Identifier",        special, NULL},
1033 /*  98 */ { "Open Group's User Authentication [TODO:RFC2485]",  opaque, NULL },
1034 /*  99 */ { "Civic Addresses Configuration",            special, NULL},
1035 /* 100 */ { "PCode [TODO:RFC4833]",                     opaque, NULL },
1036 /* 101 */ { "TCode [TODO:RFC4833]",                     opaque, NULL },
1037 /* 102 */ { "Removed/unassigned",                       opaque, NULL },
1038 /* 103 */ { "Removed/unassigned",                       opaque, NULL },
1039 /* 104 */ { "Removed/unassigned",                       opaque, NULL },
1040 /* 105 */ { "Removed/unassigned",                       opaque, NULL },
1041 /* 106 */ { "Removed/unassigned",                       opaque, NULL },
1042 /* 107 */ { "Removed/unassigned",                       opaque, NULL },
1043 /* 108 */ { "Removed/Unassigned",                       opaque, NULL },
1044 /* 109 */ { "Unassigned",                               opaque, NULL },
1045 /* 110 */ { "Removed/Unassigned",                       opaque, NULL },
1046 /* 111 */ { "Unassigned",                               opaque, NULL },
1047 /* 112 */ { "NetInfo Parent Server Address",            ipv4_list, &hf_bootp_option_netinfo_parent_server_address },
1048 /* 113 */ { "NetInfo Parent Server Tag",                string, &hf_bootp_option_netinfo_parent_server_tag },
1049 /* 114 */ { "URL [TODO:RFC3679]",                       opaque, NULL },
1050 /* 115 */ { "Removed/Unassigned",                       opaque, NULL },
1051 /* 116 */ { "DHCP Auto-Configuration",                  val_u_byte, &hf_bootp_option_dhcp_auto_configuration },
1052 /* 117 */ { "Name Service Search",                      special, NULL },
1053 /* 118 */ { "Subnet Selection Option",                  ipv4_list, &hf_bootp_option_subnet_selection_option },
1054 /* 119 */ { "Domain Search",                            special, NULL },
1055 /* 120 */ { "SIP Servers",              special, NULL },
1056 /* 121 */ { "Classless Static Route",                   special, NULL},
1057 /* 122 */ { "CableLabs Client Configuration [TODO:RFC3495]",    opaque, NULL },
1058 /* 123 */ { "Coordinate-based Location Configuration",  special, NULL},
1059 /* 124 */ { "V-I Vendor Class",                         special, NULL},
1060 /* 125 */ { "V-I Vendor-specific Information",          special, NULL},
1061 /* 126 */ { "Removed/Unassigned",                       opaque, NULL },
1062 /* 127 */ { "Removed/Unassigned",                       opaque, NULL },
1063 /* 128 */ { "DOCSIS full security server IP [TODO]",    opaque, NULL },
1064 /* 129 */ { "PXE - undefined (vendor specific)",        opaque, NULL },
1065 /* 130 */ { "PXE - undefined (vendor specific)",        opaque, NULL },
1066 /* 131 */ { "PXE - undefined (vendor specific)",        opaque, NULL },
1067 /* 132 */ { "PXE - undefined (vendor specific)",        opaque, NULL },
1068 /* 133 */ { "PXE - undefined (vendor specific)",        opaque, NULL },
1069 /* 134 */ { "PXE - undefined (vendor specific)",        opaque, NULL },
1070 /* 135 */ { "PXE - undefined (vendor specific)",        opaque, NULL },
1071 /* 136 */ { "OPTION_PANA_AGENT [TODO:RFC5192]",         opaque, NULL },
1072 /* 137 */ { "LoST Server Domain Name",                  string, &hf_bootp_option_lost_server_domain_name },
1073 /* 138 */ { "CAPWAP Access Controllers",                ipv4_list, &hf_bootp_option_capwap_access_controller },
1074 /* 139 */ { "IPv4 Address-MoS",                         opaque, NULL },
1075 /* 140 */ { "IPv4 FQDN-MoS",                            opaque, NULL },
1076 /* 141 */ { "SIP UA Configuration Domains",             opaque, NULL },
1077 /* 142 */ { "Unassigned",                               opaque, NULL },
1078 /* 143 */ { "Unassigned",                               opaque, NULL },
1079 /* 144 */ { "Unassigned",                               opaque, NULL },
1080 /* 145 */ { "Unassigned",                               opaque, NULL },
1081 /* 146 */ { "Unassigned",                               opaque, NULL },
1082 /* 147 */ { "Unassigned",                               opaque, NULL },
1083 /* 148 */ { "Unassigned",                               opaque, NULL },
1084 /* 149 */ { "Unassigned",                               opaque, NULL },
1085 /* 150 */ { "TFTP Server Address",                      ipv4_list, &hf_bootp_option_tftp_server_address },
1086 /* 151 */ { "Unassigned",                               opaque, NULL },
1087 /* 152 */ { "Unassigned",                               opaque, NULL },
1088 /* 153 */ { "Unassigned",                               opaque, NULL },
1089 /* 154 */ { "Unassigned",                               opaque, NULL },
1090 /* 155 */ { "Unassigned",                               opaque, NULL },
1091 /* 156 */ { "Unassigned",                               opaque, NULL },
1092 /* 157 */ { "Unassigned",                               opaque, NULL },
1093 /* 158 */ { "Unassigned",                               opaque, NULL },
1094 /* 159 */ { "Unassigned",                               opaque, NULL },
1095 /* 160 */ { "Unassigned",                               opaque, NULL },
1096 /* 161 */ { "Unassigned",                               opaque, NULL },
1097 /* 162 */ { "Unassigned",                               opaque, NULL },
1098 /* 163 */ { "Unassigned",                               opaque, NULL },
1099 /* 164 */ { "Unassigned",                               opaque, NULL },
1100 /* 165 */ { "Unassigned",                               opaque, NULL },
1101 /* 166 */ { "Unassigned",                               opaque, NULL },
1102 /* 167 */ { "Unassigned",                               opaque, NULL },
1103 /* 168 */ { "Unassigned",                               opaque, NULL },
1104 /* 169 */ { "Unassigned",                               opaque, NULL },
1105 /* 170 */ { "Unassigned",                               opaque, NULL },
1106 /* 171 */ { "Unassigned",                               opaque, NULL },
1107 /* 172 */ { "Unassigned",                               opaque, NULL },
1108 /* 173 */ { "Unassigned",                               opaque, NULL },
1109 /* 174 */ { "Unassigned",                               opaque, NULL },
1110 /* 175 */ { "Etherboot",                                opaque, NULL },
1111 /* 176 */ { "IP Telephone",                             opaque, NULL },
1112 /* 177 */ { "Etherboot",                                opaque, NULL },
1113 /* 178 */ { "Unassigned",                               opaque, NULL },
1114 /* 179 */ { "Unassigned",                               opaque, NULL },
1115 /* 180 */ { "Unassigned",                               opaque, NULL },
1116 /* 181 */ { "Unassigned",                               opaque, NULL },
1117 /* 182 */ { "Unassigned",                               opaque, NULL },
1118 /* 183 */ { "Unassigned",                               opaque, NULL },
1119 /* 184 */ { "Unassigned",                               opaque, NULL },
1120 /* 185 */ { "Unassigned",                               opaque, NULL },
1121 /* 186 */ { "Unassigned",                               opaque, NULL },
1122 /* 187 */ { "Unassigned",                               opaque, NULL },
1123 /* 188 */ { "Unassigned",                               opaque, NULL },
1124 /* 189 */ { "Unassigned",                               opaque, NULL },
1125 /* 190 */ { "Unassigned",                               opaque, NULL },
1126 /* 191 */ { "Unassigned",                               opaque, NULL },
1127 /* 192 */ { "Unassigned",                               opaque, NULL },
1128 /* 193 */ { "Unassigned",                               opaque, NULL },
1129 /* 194 */ { "Unassigned",                               opaque, NULL },
1130 /* 195 */ { "Unassigned",                               opaque, NULL },
1131 /* 196 */ { "Unassigned",                               opaque, NULL },
1132 /* 197 */ { "Unassigned",                               opaque, NULL },
1133 /* 198 */ { "Unassigned",                               opaque, NULL },
1134 /* 199 */ { "Unassigned",                               opaque, NULL },
1135 /* 200 */ { "Unassigned",                               opaque, NULL },
1136 /* 201 */ { "Unassigned",                               opaque, NULL },
1137 /* 202 */ { "Unassigned",                               opaque, NULL },
1138 /* 203 */ { "Unassigned",                               opaque, NULL },
1139 /* 204 */ { "Unassigned",                               opaque, NULL },
1140 /* 205 */ { "Unassigned",                               opaque, NULL },
1141 /* 206 */ { "Unassigned",                               opaque, NULL },
1142 /* 207 */ { "Unassigned",                               opaque, NULL },
1143 /* 208 */ { "PXELINUX Magic",                           opaque, NULL },
1144 /* 209 */ { "Configuration file",                       opaque, NULL },
1145 /* 210 */ { "Authentication",                           special, NULL}, /* Path Prefix rfc5071 */
1146 /* 211 */ { "Reboot Time",                              opaque, NULL },
1147 /* 212 */ { "6RD",                                      opaque, NULL },
1148 /* 213 */ { "V4 Access Domain",                         opaque, NULL },
1149 /* 214 */ { "Unassigned",                               opaque, NULL },
1150 /* 215 */ { "Unassigned",                               opaque, NULL },
1151 /* 216 */ { "Unassigned",                               opaque, NULL },
1152 /* 217 */ { "Unassigned",                               opaque, NULL },
1153 /* 218 */ { "Unassigned",                               opaque, NULL },
1154 /* 219 */ { "Unassigned",                               opaque, NULL },
1155 /* 220 */ { "Subnet Allocation",                        opaque, NULL },
1156 /* 221 */ { "Virtual Subnet Selection",                 opaque, NULL },
1157 /* 222 */ { "Unassigned",                               opaque, NULL },
1158 /* 223 */ { "Unassigned",                               opaque, NULL },
1159 /* 224 */ { "Private",                                  opaque, NULL },
1160 /* 225 */ { "Private",                                  opaque, NULL },
1161 /* 226 */ { "Private",                                  opaque, NULL },
1162 /* 227 */ { "Private",                                  opaque, NULL },
1163 /* 228 */ { "Private",                                  opaque, NULL },
1164 /* 229 */ { "Private",                                  opaque, NULL },
1165 /* 230 */ { "Private",                                  opaque, NULL },
1166 /* 231 */ { "Private",                                  opaque, NULL },
1167 /* 232 */ { "Private",                                  opaque, NULL },
1168 /* 233 */ { "Private",                                  opaque, NULL },
1169 /* 234 */ { "Private",                                  opaque, NULL },
1170 /* 235 */ { "Private",                                  opaque, NULL },
1171 /* 236 */ { "Private",                                  opaque, NULL },
1172 /* 237 */ { "Private",                                  opaque, NULL },
1173 /* 238 */ { "Private",                                  opaque, NULL },
1174 /* 239 */ { "Private",                                  opaque, NULL },
1175 /* 240 */ { "Private",                                  opaque, NULL },
1176 /* 241 */ { "Private",                                  opaque, NULL },
1177 /* 242 */ { "Private",                                  opaque, NULL },
1178 /* 243 */ { "Private",                                  opaque, NULL },
1179 /* 244 */ { "Private",                                  opaque, NULL },
1180 /* 245 */ { "Private",                                  opaque, NULL },
1181 /* 246 */ { "Private",                                  opaque, NULL },
1182 /* 247 */ { "Private",                                  opaque, NULL },
1183 /* 248 */ { "Private",                                  opaque, NULL },
1184 /* 249 */ { "Private/Classless Static Route (Microsoft)",       special, NULL},
1185 /* 250 */ { "Private",                                  opaque, NULL },
1186 /* 251 */ { "Private",                                  opaque, NULL },
1187 /* 252 */ { "Private/Proxy autodiscovery",                      string, &hf_bootp_option_private_proxy_autodiscovery },
1188 /* 253 */ { "Private",                                  opaque, NULL },
1189 /* 254 */ { "Private",                                  opaque, NULL },
1190 /* 255 */ { "End",                                      opaque, NULL }
1191 };
1192
1193 /*-------------------------------------
1194  * UAT for BOOTP
1195  *-------------------------------------
1196  */
1197 /* UAT entry structure. */
1198 typedef struct {
1199         guint  opt;
1200         gchar *text;
1201         enum field_type ftype;
1202
1203 } uat_bootp_record_t;
1204
1205 static uat_bootp_record_t *uat_bootp_records = NULL;
1206 static uat_t *bootp_uat = NULL;
1207 static guint num_bootp_records_uat = 0;
1208
1209 static void* uat_bootp_record_copy_cb(void* n, const void* o, size_t siz _U_) {
1210         uat_bootp_record_t* new_record = (uat_bootp_record_t *)n;
1211         const uat_bootp_record_t* old_record = (const uat_bootp_record_t *)o;
1212
1213         if (old_record->text) {
1214                 new_record->text = g_strdup(old_record->text);
1215         } else {
1216                 new_record->text = NULL;
1217         }
1218
1219         return new_record;
1220 }
1221
1222 static void uat_bootp_record_update_cb(void* r, const char** err) {
1223         uat_bootp_record_t* rec = (uat_bootp_record_t *)r;
1224
1225         if ((rec->opt == 0) || (rec->opt >=BOOTP_OPT_NUM-1))
1226                 *err = g_strdup_printf("Option must be between 1 and %d", BOOTP_OPT_NUM-2);
1227 }
1228
1229 static void uat_bootp_record_free_cb(void*r) {
1230         uat_bootp_record_t* rec = (uat_bootp_record_t *)r;
1231
1232         if (rec->text) g_free(rec->text);
1233 }
1234
1235 UAT_DEC_CB_DEF(uat_bootp_records, opt, uat_bootp_record_t)
1236 UAT_CSTRING_CB_DEF(uat_bootp_records, text, uat_bootp_record_t)
1237 UAT_VS_DEF(uat_bootp_records, ftype, uat_bootp_record_t, enum field_type, special, "string")
1238
1239
1240 static struct opt_info* bootp_get_opt(unsigned int idx)
1241 {
1242         if(idx>=BOOTP_OPT_NUM)
1243                 return NULL;
1244
1245         return &bootp_opt[idx];
1246 }
1247
1248 static const char *
1249 bootp_get_opt_text(unsigned int idx)
1250 {
1251         if(idx>=BOOTP_OPT_NUM)
1252                 return "unknown";
1253         return bootp_opt[idx].text;
1254 }
1255
1256 struct basic_types_hfs {
1257         gint* bytes;
1258         gint* ipv4;
1259         gint* ipv4_list;
1260         gint* string;
1261         gint* val_boolean;
1262         gint* val_u_byte;
1263         gint* val_u_short;
1264         gint* val_u_short_list;
1265         gint* val_u_long;
1266         gint* time_in_s_secs;
1267         gint* time_in_u_secs;
1268 };
1269
1270 /* Handle "basic" datatypes adding to a tree */
1271 static int
1272 bootp_handle_basic_types(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1273                          enum field_type ftype, int offset, int total_len,
1274                          gint *hf, struct basic_types_hfs* hf_default)
1275 {
1276         int     i, left;
1277         gint32  time_s_secs;
1278         guint32 time_u_secs;
1279         int     consumed = 0;
1280
1281         switch (ftype) {
1282         case bytes:
1283                 if (hf != NULL)
1284                         proto_tree_add_item(tree, *hf, tvb, offset, total_len, ENC_BIG_ENDIAN);
1285                 else if (hf_default->bytes != NULL)
1286                         proto_tree_add_item(tree, *hf_default->bytes, tvb, offset, total_len, ENC_BIG_ENDIAN);
1287                 consumed = total_len;
1288                 break;
1289
1290         case ipv4:
1291                 if (total_len != 4) {
1292                         expert_add_info_format(pinfo, item, &ei_bootp_bad_length, "length isn't 4");
1293                         break;
1294                 }
1295
1296                 if (hf != NULL)
1297                         proto_tree_add_item(tree, *hf, tvb, offset, 4, ENC_BIG_ENDIAN);
1298                 else if (hf_default->ipv4 != NULL)
1299                         proto_tree_add_item(tree, *hf_default->ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
1300                 consumed = 4;
1301                 break;
1302
1303         case ipv4_list:
1304                 for (i = offset, left = total_len; left > 0; i += 4, left -= 4) {
1305                         if (left < 4) {
1306                                 expert_add_info_format(pinfo, item, &ei_bootp_bad_length, "Option length isn't a multiple of 4");
1307                                 break;
1308                         }
1309
1310                         if (hf != NULL)
1311                                 proto_tree_add_item(tree, *hf, tvb, i, 4, ENC_BIG_ENDIAN);
1312                         else if (hf_default->ipv4_list != NULL)
1313                                 proto_tree_add_item(tree, *hf_default->ipv4_list, tvb, i, 4, ENC_BIG_ENDIAN);
1314                         consumed += 4;
1315                 }
1316
1317                 break;
1318
1319         case string:
1320                 if (hf != NULL)
1321                         proto_tree_add_item(tree, *hf, tvb, offset, total_len, ENC_BIG_ENDIAN);
1322                 else if (hf_default->string != NULL)
1323                         proto_tree_add_item(tree, *hf_default->string, tvb, offset, total_len, ENC_BIG_ENDIAN);
1324                 consumed = total_len;
1325                 break;
1326
1327         case val_boolean:
1328                 if (total_len != 1) {
1329                         expert_add_info_format(pinfo, item, &ei_bootp_bad_length, "length isn't 1");
1330                         break;
1331                 }
1332
1333                 if (hf != NULL)
1334                         proto_tree_add_item(tree, *hf, tvb, offset, 1, ENC_BIG_ENDIAN);
1335                 else if (hf_default->val_boolean != NULL)
1336                         proto_tree_add_item(tree, *hf_default->val_boolean, tvb, offset, 1, ENC_BIG_ENDIAN);
1337                 consumed = 1;
1338                 break;
1339
1340         case val_u_byte:
1341                 if (total_len != 1) {
1342                         expert_add_info_format(pinfo, item, &ei_bootp_bad_length, "length isn't 1");
1343                         break;
1344                 }
1345
1346                 if (hf != NULL)
1347                         proto_tree_add_item(tree, *hf, tvb, offset, 1, ENC_BIG_ENDIAN);
1348                 else if (hf_default->val_u_byte != NULL)
1349                         proto_tree_add_item(tree, *hf_default->val_u_byte, tvb, offset, 1, ENC_BIG_ENDIAN);
1350                 consumed = 1;
1351                 break;
1352
1353         case val_u_short:
1354                 if (total_len != 2) {
1355                         expert_add_info_format(pinfo, item, &ei_bootp_bad_length, "length isn't 2");
1356                         break;
1357                 }
1358
1359                 if (hf != NULL)
1360                         proto_tree_add_item(tree, *hf, tvb, offset, 2, ENC_BIG_ENDIAN);
1361                 else if (hf_default->val_u_short != NULL)
1362                         proto_tree_add_item(tree, *hf_default->val_u_short, tvb, offset, 2, ENC_BIG_ENDIAN);
1363                 consumed = 2;
1364                 break;
1365
1366         case val_u_le_short:
1367                 if (total_len != 2) {
1368                         expert_add_info_format(pinfo, item, &ei_bootp_bad_length, "length isn't 2");
1369                         break;
1370                 }
1371
1372                 if (hf != NULL)
1373                         proto_tree_add_item(tree, *hf, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1374                 else if (hf_default->val_u_short != NULL)
1375                         proto_tree_add_item(tree, *hf_default->val_u_short, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1376                 consumed = 2;
1377                 break;
1378
1379         case val_u_short_list:
1380                 for (i = offset, left = total_len; left > 0; i += 2, left -= 2) {
1381                         if (left < 2) {
1382                                 expert_add_info_format(pinfo, item, &ei_bootp_bad_length, "Option length isn't a multiple of 2");
1383                                 break;
1384                         }
1385
1386                         if (hf != NULL)
1387                                 proto_tree_add_item(tree, *hf, tvb, i, 2, ENC_BIG_ENDIAN);
1388                         else if (hf_default->val_u_short_list != NULL)
1389                                 proto_tree_add_item(tree, *hf_default->val_u_short_list, tvb, i, 2, ENC_BIG_ENDIAN);
1390                         consumed += 2;
1391                 }
1392                 break;
1393
1394         case val_u_long:
1395                 if (total_len != 4) {
1396                         expert_add_info_format(pinfo, item, &ei_bootp_bad_length, "length isn't 4");
1397                         break;
1398                 }
1399
1400                 if (hf != NULL)
1401                         proto_tree_add_item(tree, *hf, tvb, offset, 4, ENC_BIG_ENDIAN);
1402                 else if (hf_default->val_u_long != NULL)
1403                         proto_tree_add_item(tree, *hf_default->val_u_long, tvb, offset, 4, ENC_BIG_ENDIAN);
1404                 consumed = 4;
1405                 break;
1406
1407         case time_in_s_secs:
1408                 if (total_len != 4) {
1409                         expert_add_info_format(pinfo, item, &ei_bootp_bad_length, "length isn't 4");
1410                         break;
1411                 }
1412
1413                 if (hf != NULL) {
1414                         time_s_secs = (gint32) tvb_get_ntohl(tvb, offset);
1415                         proto_tree_add_int_format_value(tree, *hf,
1416                                 tvb, offset, 4, time_s_secs, "(%ds) %s", time_s_secs, time_secs_to_str(wmem_packet_scope(), time_s_secs));
1417                 }
1418                 else if (hf_default->time_in_s_secs != NULL)
1419                         proto_tree_add_item(tree, *hf_default->time_in_s_secs, tvb, offset, 4, ENC_BIG_ENDIAN);
1420
1421                 consumed = 4;
1422                 break;
1423
1424         case time_in_u_secs:
1425                 if (total_len != 4) {
1426                         expert_add_info_format(pinfo, item, &ei_bootp_bad_length, "length isn't 4");
1427                         break;
1428                 }
1429
1430                 if (hf != NULL) {
1431                         time_u_secs = tvb_get_ntohl(tvb, offset);
1432                         proto_tree_add_uint_format_value(tree, *hf,
1433                                 tvb, offset, 4, time_u_secs, "(%us) %s", time_u_secs,
1434                                 ((time_u_secs == 0xffffffff) ? "infinity" : time_secs_to_ep_str_unsigned(time_u_secs)));
1435                 }
1436                 else if (hf_default->time_in_u_secs != NULL)
1437                         proto_tree_add_item(tree, *hf_default->time_in_u_secs, tvb, offset, 4, ENC_BIG_ENDIAN);
1438                 consumed = 4;
1439                 break;
1440         default:
1441                 /* Ignore other field_types */
1442                 break;
1443    }
1444
1445    return consumed;
1446 }
1447
1448 /* Returns the number of bytes consumed by this option. */
1449 static int
1450 bootp_option(tvbuff_t *tvb, packet_info *pinfo, proto_tree *bp_tree, proto_item *bp_item, int voff,
1451              int eoff, gboolean first_pass, gboolean *at_end, const char **dhcp_type_p,
1452              const guint8 **vendor_class_id_p, guint8 *overload_p)
1453 {
1454         struct opt_info *opt;
1455         enum field_type  ftype;
1456         guchar           code = tvb_get_guint8(tvb, voff);
1457         int              optlen;
1458         guchar           byte;
1459         int              i, consumed, basictype_consumed;
1460         int              optoff, optleft, optend;
1461         proto_tree      *v_tree;
1462         proto_item      *vti, *ti;
1463         guint8           protocol;
1464         guint8           algorithm;
1465         guint8           rdm;
1466         guint8           fqdn_flags;
1467         int              o52voff, o52eoff;
1468         gboolean         o52at_end;
1469         guint8           s_option;
1470         guint8           s_len;
1471         const guchar    *dns_name;
1472         gboolean         option_handled = TRUE;
1473
1474         struct basic_types_hfs default_hfs = {
1475                 &hf_bootp_option_value,
1476                 &hf_bootp_option_value_ip_address,
1477                 &hf_bootp_option_value_ip_address,
1478                 &hf_bootp_option_value_stringz,
1479                 &hf_bootp_option_value_boolean,
1480                 &hf_bootp_option_value_8,
1481                 &hf_bootp_option_value_16,
1482                 &hf_bootp_option_value_16,
1483                 &hf_bootp_option_value_u32,
1484                 &hf_bootp_option_value_i32,
1485                 &hf_bootp_option_value_u32
1486         };
1487
1488         /* Options whose length isn't "optlen + 2". */
1489         switch (code) {
1490
1491         case 0:         /* Padding */
1492                 /* check how much padding we have */
1493                 for (i = voff + 1; i < eoff; i++ ) {
1494                         if (tvb_get_guint8(tvb, i) != 0) {
1495                                 break;
1496                         }
1497                 }
1498                 i = i - voff;
1499                 if (!first_pass) {
1500                         if (bp_tree != NULL) {
1501                                 vti = proto_tree_add_uint_format_value(bp_tree, hf_bootp_option_type,
1502                                                 tvb, voff, 1, 0, "(0) Padding");
1503                                 v_tree = proto_item_add_subtree(vti, ett_bootp_option);
1504                                 proto_tree_add_item(v_tree, hf_bootp_option_padding, tvb, voff, i, ENC_NA);
1505                         }
1506                 }
1507                 consumed = i;
1508                 return consumed;
1509
1510         case 255:       /* End Option */
1511                 if (!first_pass) {
1512                         if (bp_tree != NULL) {
1513                                 vti = proto_tree_add_uint_format_value(bp_tree, hf_bootp_option_type,
1514                                                 tvb, voff, 1, 0, "(255) End");
1515                                 v_tree = proto_item_add_subtree(vti, ett_bootp_option);
1516                                 if (*overload_p)
1517                                         proto_tree_add_item(v_tree, hf_bootp_option_end_overload, tvb, voff, 1, ENC_BIG_ENDIAN);
1518                                 else
1519                                         proto_tree_add_item(v_tree, hf_bootp_option_end, tvb, voff, 1, ENC_BIG_ENDIAN);
1520                         }
1521                 }
1522                 *at_end = TRUE;
1523                 consumed = 1;
1524                 return consumed;
1525         }
1526
1527         /*
1528          * Get the length of the option, and the number of bytes it
1529          * consumes (the length doesn't include the option code or
1530          * length bytes).
1531          *
1532          * On the first pass, check first whether we have the length
1533          * byte, so that we don't throw an exception; if we throw an
1534          * exception in the first pass, which is only checking for options
1535          * whose values we need in order to properly dissect the packet
1536          * on the second pass, we won't actually dissect the options, so
1537          * you won't be able to see which option had the problem.
1538          */
1539         if (first_pass) {
1540                 if (!tvb_bytes_exist(tvb, voff+1, 1)) {
1541                         /*
1542                          * We don't have the length byte; just return 1
1543                          * as the number of bytes we consumed, to count
1544                          * the code byte.
1545                          */
1546                         return 1;
1547                 }
1548         }
1549         optlen = tvb_get_guint8(tvb, voff+1);
1550         consumed = optlen + 2;
1551
1552         /*
1553          * In the first pass, we don't put anything into the protocol
1554          * tree; we just check for some options we have to look at
1555          * in order to properly process the packet:
1556          *
1557          *      52 (Overload) - we need this to properly dissect the
1558          *         file and sname fields
1559          *
1560          *      53 (DHCP message type) - if this is present, this is DHCP
1561          *
1562          *      60 (Vendor class identifier) - we need this in order to
1563          *         interpret the vendor-specific info
1564          *
1565          * We also check, before fetching anything, to make sure we
1566          * have the entire item we're fetching, so that we don't throw
1567          * an exception.
1568          */
1569         if (first_pass) {
1570                 if (tvb_bytes_exist(tvb, voff+2, consumed-2)) {
1571                         switch (code) {
1572
1573                         case 52:
1574                                 *overload_p = tvb_get_guint8(tvb, voff+2);
1575                                 break;
1576
1577                         case 53:
1578                                 *dhcp_type_p =
1579                                     val_to_str(tvb_get_guint8(tvb, voff+2),
1580                                         opt53_text,
1581                                         "Unknown Message Type (0x%02x)");
1582                                 break;
1583
1584                         case 60:
1585                                 *vendor_class_id_p =
1586                                     tvb_get_ptr(tvb, voff+2, consumed-2);
1587                                 break;
1588                         case 119:
1589                                 rfc3396_dns_domain_search_list.total_number_of_block++;
1590                                 break;
1591                         case 120:
1592                                 rfc3396_sip_server.total_number_of_block++;
1593                                 break;
1594                         }
1595                 }
1596
1597                 /*
1598                  * We don't do anything else here.
1599                  */
1600                 return consumed;
1601         }
1602
1603         /* Normal cases */
1604         opt = bootp_get_opt(code);
1605         if (opt == NULL)
1606         {
1607                 /* THIS SHOULD NEVER HAPPEN!!! */
1608                 return consumed;
1609         }
1610
1611         /* function type may be overridden and that shouldn't be a 'saved' change */
1612         ftype = opt->ftype;
1613
1614         optoff = voff+2;
1615
1616         vti = proto_tree_add_uint_format_value(bp_tree, hf_bootp_option_type,
1617                 tvb, voff, consumed, code, "(%d) %s", code, opt->text);
1618         v_tree = proto_item_add_subtree(vti, ett_bootp_option);
1619         proto_tree_add_item(v_tree, hf_bootp_option_length, tvb, voff+1, 1, ENC_BIG_ENDIAN);
1620
1621         ti = proto_tree_add_item(v_tree, hf_bootp_option_value, tvb, voff+2, optlen, ENC_NA);
1622         PROTO_ITEM_SET_HIDDEN(ti);
1623
1624         /* Special cases */
1625         switch (code) {
1626
1627         case 21:        /* Policy Filter */
1628                 for (i = optoff, optleft = optlen;
1629                         optleft > 0; i += 8, optleft -= 8) {
1630                         if (optleft < 8) {
1631                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "Option length isn't a multiple of 8");
1632                                 break;
1633                         }
1634
1635                         proto_tree_add_item(v_tree, hf_bootp_option_policy_filter_ip, tvb, i, 4, ENC_BIG_ENDIAN);
1636                         proto_tree_add_item(v_tree, hf_bootp_option_policy_filter_subnet_mask, tvb, i+4, 4, ENC_BIG_ENDIAN);
1637                 }
1638                 break;
1639
1640         case 33:        /* Static Route */
1641                 for (i = optoff, optleft = optlen;
1642                         optleft > 0; i += 8, optleft -= 8) {
1643                         if (optleft < 8) {
1644                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "Option length isn't a multiple of 8");
1645                                 break;
1646                         }
1647
1648                         proto_tree_add_item(v_tree, hf_bootp_option_static_route_ip, tvb, i, 4, ENC_BIG_ENDIAN);
1649                         proto_tree_add_item(v_tree, hf_bootp_option_static_route_router, tvb, i+4, 4, ENC_BIG_ENDIAN);
1650                 }
1651                 break;
1652
1653         case 43:        /* Vendor-Specific Info */
1654                 s_option = tvb_get_guint8(tvb, optoff);
1655
1656                 /* PXE protocol 2.1 as described in the Intel specs */
1657                 if (*vendor_class_id_p != NULL &&
1658                     strncmp((const gchar*)*vendor_class_id_p, "PXEClient", strlen("PXEClient")) == 0) {
1659                         proto_item_append_text(vti, " (PXEClient)");
1660                         v_tree = proto_item_add_subtree(vti, ett_bootp_option);
1661
1662                         optend = optoff + optlen;
1663                         while (optoff < optend) {
1664                                 optoff = dissect_vendor_pxeclient_suboption(pinfo, vti, v_tree,
1665                                         tvb, optoff, optend);
1666                         }
1667                 } else if (*vendor_class_id_p != NULL &&
1668                            ((strncmp((const gchar*)*vendor_class_id_p, "pktc", strlen("pktc")) == 0) ||
1669                             (strncmp((const gchar*)*vendor_class_id_p, "docsis", strlen("docsis")) == 0) ||
1670                             (strncmp((const gchar*)*vendor_class_id_p, "OpenCable2.0", strlen("OpenCable2.0")) == 0) ||
1671                             (strncmp((const gchar*)*vendor_class_id_p, "CableHome", strlen("CableHome")) == 0))) {
1672                         /* CableLabs standard - see www.cablelabs.com/projects */
1673                         proto_item_append_text(vti, " (CableLabs)");
1674
1675                         optend = optoff + optlen;
1676                         while (optoff < optend) {
1677                                 optoff = dissect_vendor_cablelabs_suboption(pinfo, vti, v_tree,
1678                                         tvb, optoff, optend);
1679                         }
1680                 } else if (*vendor_class_id_p != NULL &&
1681                            ((strncmp((const gchar*)*vendor_class_id_p, "ArubaAP", strlen("ArubaAP")) == 0) )) {
1682                         /* Aruba AP */
1683                         proto_item_append_text(vti, " (Aruba AP)");
1684                         proto_tree_add_item(v_tree, hf_bootp_option43_arubaap_controllerip, tvb, optoff, optlen, ENC_ASCII|ENC_NA);
1685                 } else if (*vendor_class_id_p != NULL &&
1686                            ((strncmp((const gchar*)*vendor_class_id_p, "ArubaInstantAP", strlen("ArubaInstantAP")) == 0) )) {
1687                         gint32 nameorglen, ampiplen;
1688                         /* Aruba  Instant AP */
1689                         proto_item_append_text(vti, " (Aruba Instant AP)");
1690                         vti = proto_tree_add_item(v_tree, hf_bootp_option43_arubaiap, tvb, optoff, optlen, ENC_ASCII|ENC_NA);
1691                         v_tree = proto_item_add_subtree(vti, ett_bootp_option43_suboption);
1692                         nameorglen = tvb_find_guint8(tvb, optoff, optlen, ',') - optoff;
1693                         proto_tree_add_item(v_tree, hf_bootp_option43_arubaiap_nameorg, tvb, optoff, nameorglen, ENC_ASCII|ENC_NA);
1694                         ampiplen = tvb_find_guint8(tvb, optoff+nameorglen+1, optlen-nameorglen-1, ',') - (optoff+nameorglen+1);
1695                         proto_tree_add_item(v_tree, hf_bootp_option43_arubaiap_ampip, tvb, optoff+nameorglen+1, ampiplen, ENC_ASCII|ENC_NA);
1696                         proto_tree_add_item(v_tree, hf_bootp_option43_arubaiap_password, tvb, optoff+nameorglen+1+ampiplen+1, optlen-(nameorglen+1+ampiplen+1), ENC_ASCII|ENC_NA);
1697                 } else if (s_option==58 || s_option==64 || s_option==65
1698                         || s_option==66 || s_option==67) {
1699                         /* Note that this is a rather weak (permissive) heuristic, */
1700                         /* but since it comes last, I guess this is OK. */
1701                         /* Add any stronger (less permissive) heuristics before this! */
1702                         /* Alcatel-Lucent DHCP Extensions */
1703                         proto_item_append_text(vti, " (Alcatel-Lucent)");
1704                         optend = optoff + optlen;
1705                         while (optoff < optend) {
1706                                 optoff = dissect_vendor_alcatel_suboption(pinfo, vti, v_tree,
1707                                         tvb, optoff, optend);
1708                         }
1709                 } else {
1710                         /* Default Vendor-Specific Info.. display in bytes */
1711                         proto_tree_add_item(v_tree, hf_bootp_option43_value, tvb, optoff, optlen, ENC_NA);
1712                 }
1713                 break;
1714
1715         case 52:        /* Option Overload */
1716                 if (optlen < 1) {
1717                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't >= 1");
1718                         break;
1719                 }
1720
1721                 byte = tvb_get_guint8(tvb, optoff);
1722                 proto_tree_add_item(v_tree, *opt->phf, tvb, optoff, 1, ENC_BIG_ENDIAN);
1723
1724                 /* Just in case we find an option 52 in sname or file */
1725                 if (voff > VENDOR_INFO_OFFSET && byte >= 1 && byte <= 3) {
1726                         if (byte & OPT_OVERLOAD_FILE) {
1727                                 proto_item *oti;
1728                                 oti = proto_tree_add_text (bp_tree, tvb,
1729                                         FILE_NAME_OFFSET, FILE_NAME_LEN,
1730                                         "Boot file name option overload");
1731                                 o52voff = FILE_NAME_OFFSET;
1732                                 o52eoff = FILE_NAME_OFFSET + FILE_NAME_LEN;
1733                                 o52at_end = FALSE;
1734                                 rfc3396_dns_domain_search_list.index_current_block = 0;
1735                                 rfc3396_sip_server.index_current_block = 0;
1736                                 while (o52voff < o52eoff && !o52at_end) {
1737                                         o52voff += bootp_option(tvb, pinfo, bp_tree, bp_item, o52voff,
1738                                                 o52eoff, FALSE, &o52at_end,
1739                                                 dhcp_type_p, vendor_class_id_p,
1740                                                 overload_p);
1741                                 }
1742                                 if (!o52at_end)
1743                                 {
1744                                         expert_add_info(pinfo, oti, &hf_bootp_opt_overload_file_end_missing);
1745                                 }
1746                         }
1747                         if (byte & OPT_OVERLOAD_SNAME) {
1748                                 proto_item *oti;
1749                                 oti = proto_tree_add_text (bp_tree, tvb,
1750                                         SERVER_NAME_OFFSET, SERVER_NAME_LEN,
1751                                         "Server host name option overload");
1752                                 o52voff = SERVER_NAME_OFFSET;
1753                                 o52eoff = SERVER_NAME_OFFSET + SERVER_NAME_LEN;
1754                                 o52at_end = FALSE;
1755                                 rfc3396_dns_domain_search_list.index_current_block = 0;
1756                                 rfc3396_sip_server.index_current_block = 0;
1757                                 while (o52voff < o52eoff && !o52at_end) {
1758                                         o52voff += bootp_option(tvb, pinfo, bp_tree, bp_item, o52voff,
1759                                                 o52eoff, FALSE, &o52at_end,
1760                                                 dhcp_type_p, vendor_class_id_p,
1761                                                 overload_p);
1762                                 }
1763                                 if (!o52at_end)
1764                                 {
1765                                         expert_add_info(pinfo, oti, &hf_bootp_opt_overload_sname_end_missing);
1766                                 }
1767                         }
1768                         /* The final end option is not in overload */
1769                         *overload_p = 0;
1770                 }
1771                 break;
1772
1773         case 53:
1774                 /* Show the message type name on the Message Type option, and in the protocol root */
1775                 proto_item_append_text(vti, " (%s)", val_to_str(tvb_get_guint8(tvb, voff+2),
1776                                        opt53_text,
1777                                        "Unknown Message Type (0x%02x)"));
1778                 proto_item_append_text(bp_item, " (%s)", val_to_str(tvb_get_guint8(tvb, voff+2),
1779                                        opt53_text,
1780                                        "Unknown Message Type (0x%02x)"));
1781                 break;
1782
1783         case 55:        /* Parameter Request List */
1784                 for (i = 0; i < optlen; i++) {
1785                         byte = tvb_get_guint8(tvb, optoff+i);
1786                         proto_tree_add_uint_format_value(v_tree, hf_bootp_option_parameter_request_list_item,
1787                                         tvb, optoff+i, 1, byte, "(%d) %s", byte, bootp_get_opt_text(byte));
1788                 }
1789                 break;
1790
1791         case 60:        /* Vendor class identifier */
1792                 /*
1793                  * XXX - RFC 2132 says this is a string of octets;
1794                  * should we check for non-printables?
1795                  */
1796
1797                 proto_tree_add_item(v_tree, hf_bootp_option_vendor_class_id, tvb, optoff, consumed-2, ENC_ASCII|ENC_NA);
1798                 if ((tvb_memeql(tvb, optoff, (const guint8*)PACKETCABLE_MTA_CAP10,
1799                                       (int)strlen(PACKETCABLE_MTA_CAP10)) == 0)
1800                     ||
1801                     (tvb_memeql(tvb, optoff, (const guint8*)PACKETCABLE_MTA_CAP15,
1802                                       (int)strlen(PACKETCABLE_MTA_CAP15)) == 0)
1803                         ||
1804                         (tvb_memeql(tvb, optoff, (const guint8*)PACKETCABLE_MTA_CAP20,
1805                                       (int)strlen(PACKETCABLE_MTA_CAP20)) == 0))
1806                 {
1807                         dissect_packetcable_mta_cap(v_tree, tvb, optoff, optlen);
1808                 } else
1809                         if ((tvb_memeql(tvb, optoff, (const guint8*)PACKETCABLE_CM_CAP11,
1810                                 (int)strlen(PACKETCABLE_CM_CAP11)) == 0)
1811                         ||
1812                         (tvb_memeql(tvb, optoff, (const guint8*)PACKETCABLE_CM_CAP20,
1813                                 (int)strlen(PACKETCABLE_CM_CAP20)) == 0 ))
1814                 {
1815                         dissect_docsis_cm_cap(v_tree, tvb, optoff, optlen, FALSE);
1816                 } else
1817                         if (tvb_memeql(tvb, optoff, (const guint8*)PACKETCABLE_CM_CAP30,
1818                                 (int)strlen(PACKETCABLE_CM_CAP30)) == 0 )
1819                 {
1820                         proto_tree_add_text(v_tree, tvb, optoff, optlen,
1821                                 "vendor-class-data: \"%s\"", tvb_format_stringzpad(tvb, optoff, optlen));
1822                 }
1823                 break;
1824
1825         case 61:        /* Client Identifier */
1826                 if (optlen > 0)
1827                         byte = tvb_get_guint8(tvb, optoff);
1828                 else
1829                         byte = 0;
1830
1831                 /* We *MAY* use hwtype/hwaddr. If we have 7 bytes, I'll
1832                    guess that the first is the hwtype, and the last 6
1833                    are the hw addr */
1834                 /* See http://www.iana.org/assignments/arp-parameters */
1835                 /* RFC2132 9.14 Client-identifier has the following to say:
1836                    A hardware type of 0 (zero) should be used when the value
1837                    field contains an identifier other than a hardware address
1838                    (e.g. a fully qualified domain name). */
1839
1840                 if (optlen == 7 && byte > 0 && byte < 48) {
1841                         proto_tree_add_item(v_tree,
1842                                         hf_bootp_hw_type, tvb, optoff, 1,
1843                                         ENC_NA);
1844
1845                         if (byte == ARPHRD_ETHER || byte == ARPHRD_IEEE802)
1846                                 proto_tree_add_item(v_tree,
1847                                         hf_bootp_hw_ether_addr, tvb, optoff+1, 6,
1848                                         ENC_NA);
1849                         else
1850                                 proto_tree_add_text(v_tree, tvb, optoff+1, 6,
1851                                         "Client hardware address: %s",
1852                                         tvb_arphrdaddr_to_str(tvb, optoff+1, 6, byte));
1853                 } else if (optlen == 17 && byte == 0) {
1854                         /* Identifier is a UUID */
1855                         proto_tree_add_item(v_tree, hf_bootp_client_identifier_uuid,
1856                                             tvb, optoff + 1, 16, ENC_LITTLE_ENDIAN);
1857                 /* From RFC 4631 paragraph 6.1 DHCPv4 Client Behavior:
1858                         To send an RFC 3315-style binding identifier in a DHCPv4 'client
1859                         identifier' option, the type of the 'client identifier' option is set
1860                         to 255. */
1861                 } else if (byte == 255) {
1862                         guint16 duidtype;
1863                         guint16 hwtype;
1864                         guint8  *buf;
1865                         int     enterprise;
1866
1867                         /*      The type field is immediately followed by the IAID, which is
1868                                 an opaque 32-bit quantity       */
1869                         proto_tree_add_text(v_tree, tvb, optoff+1, 4,
1870                                 "IAID: %s",
1871                                 tvb_arphrdaddr_to_str(tvb, optoff+1, 4, byte));
1872                         optoff = optoff + 5;
1873                         duidtype = tvb_get_ntohs(tvb, optoff);
1874                         proto_tree_add_text(v_tree, tvb, optoff, 2,
1875                                             "DUID type: %s (%u)",
1876                                             val_to_str_const(duidtype, duidtype_vals, "Unknown"),
1877                                             duidtype);
1878                         switch (duidtype) {
1879                         case DUID_LLT:
1880                                 if (optlen < 8) {
1881                                         expert_add_info(pinfo, vti, &ei_bootp_mal_duid);
1882                                         break;
1883                                 }
1884                                 hwtype=tvb_get_ntohs(tvb, optoff + 2);
1885                                 proto_tree_add_item(v_tree, hf_bootp_client_identifier_duid_llt_hw_type,
1886                                                 tvb, optoff + 2, 2, ENC_BIG_ENDIAN);
1887
1888                                 /* XXX seconds since Jan 1 2000 */
1889                                 proto_tree_add_text(v_tree, tvb, optoff + 4, 4,
1890                                         "Time: %u", tvb_get_ntohl(tvb, optoff + 4));
1891                                 if (optlen > 8) {
1892                                         proto_tree_add_text(v_tree, tvb, optoff + 8,
1893                                                 optlen - 13, "Link-layer address: %s",
1894                                                 tvb_arphrdaddr_to_str(tvb, optoff+8, optlen-13, hwtype));
1895                                 }
1896                                 break;
1897                         case DUID_EN:
1898                                 if (optlen < 6) {
1899                                         expert_add_info(pinfo, vti, &ei_bootp_mal_duid);
1900                                         break;
1901                                 }
1902                                 enterprise = tvb_get_ntohl(tvb, optoff+2);
1903                                 proto_tree_add_text(v_tree, tvb, optoff + 2, 4,
1904                                             "Enterprise-number: %s (%u)",
1905                                             val_to_str_ext_const( enterprise, &sminmpec_values_ext, "Unknown"),
1906                                             enterprise);
1907                                 if (optlen > 6) {
1908                                                 buf = tvb_bytes_to_ep_str(tvb, optoff + 6, optlen - 11);
1909                                         proto_tree_add_text(v_tree, tvb, optoff + 6,
1910                                                 optlen - 11, "identifier: %s", buf);
1911                                 }
1912                                 break;
1913                         case DUID_LL:
1914                                 if (optlen < 4) {
1915                                         expert_add_info(pinfo, vti, &ei_bootp_mal_duid);
1916                                         break;
1917                                 }
1918                                 hwtype=tvb_get_ntohs(tvb, optoff + 2);
1919                                 proto_tree_add_item(v_tree, hf_bootp_client_identifier_duid_ll_hw_type,
1920                                                 tvb, optoff + 2, 2, ENC_BIG_ENDIAN);
1921
1922                                 if (optlen > 4) {
1923                                         proto_tree_add_text(v_tree, tvb, optoff + 4,
1924                                                 optlen - 9, "Link-layer address: %s",
1925                                                 tvb_arphrdaddr_to_str(tvb, optoff+4, optlen-9, hwtype));
1926                                 }
1927                                 break;
1928                         }
1929                 } else {
1930                         /* otherwise, it's opaque data */
1931                 }
1932                 break;
1933         case 77: {      /* User Class Information RFC 3004 */
1934                 guchar user_class_instance_index;
1935                 proto_item *vtix;
1936                 proto_tree *o77_v_tree;
1937                 if (optlen < 2) {
1938                         expert_add_info_format(pinfo, v_tree, &ei_bootp_bad_length, "length isn't >= 2");
1939                         break;
1940                 }
1941                 optleft = optlen;
1942                 for (user_class_instance_index = 0, i = 0, byte = tvb_get_guint8(tvb, optoff); i < optlen; byte = tvb_get_guint8(tvb, optoff + i), user_class_instance_index++) {
1943                         /* Create subtree for instance of User Class. */
1944                         vtix = proto_tree_add_uint_format_value(v_tree, hf_bootp_option77_user_class,
1945                                         tvb, optoff + i, byte + 1, user_class_instance_index, "[%d]", user_class_instance_index);
1946                         o77_v_tree = proto_item_add_subtree(vtix, ett_bootp_option77_instance);
1947
1948                         /* Add length for instance of User Class. */
1949                         proto_tree_add_item(o77_v_tree, hf_bootp_option77_user_class_length,
1950                                         tvb, optoff + i, 1, ENC_BIG_ENDIAN);
1951
1952                         if (byte == 0) {
1953                                 expert_add_info_format(pinfo, vtix, &ei_bootp_bad_length, "UC_Len_%u isn't >= 1 (UC_Len_%u = 0)", user_class_instance_index, user_class_instance_index);
1954                                 break;
1955                         }
1956                         optleft -= byte + 1;
1957                         if (optleft < 0) {
1958                                 expert_add_info(pinfo, vtix, &ei_bootp_option77_user_class_malformed);
1959                                 break;
1960                         }
1961
1962                         /* Add data for instance of User Class. */
1963                         proto_tree_add_item(o77_v_tree, hf_bootp_option77_user_class_data,
1964                                         tvb, optoff + i + 1, byte, ENC_NA);
1965
1966                         /* Slide to next instance of User Class if any. */
1967                         i += byte + 1;
1968                 }
1969                 break;
1970         }
1971         case 97:        /* Client Identifier (UUID) */
1972                 if (optlen > 0)
1973                         byte = tvb_get_guint8(tvb, optoff);
1974                 else
1975                         byte = 0;
1976
1977                 /* We *MAY* use hwtype/hwaddr. If we have 7 bytes, I'll
1978                    guess that the first is the hwtype, and the last 6
1979                    are the hw addr */
1980                 /* See http://www.iana.org/assignments/arp-parameters */
1981                 /* RFC2132 9.14 Client-identifier has the following to say:
1982                    A hardware type of 0 (zero) should be used when the value
1983                    field contains an identifier other than a hardware address
1984                    (e.g. a fully qualified domain name). */
1985
1986                 if (optlen == 7 && byte > 0 && byte < 48) {
1987                         proto_tree_add_item(v_tree,
1988                                         hf_bootp_hw_type, tvb, optoff, 1,
1989                                         ENC_NA);
1990                         if (byte == ARPHRD_ETHER || byte == ARPHRD_IEEE802)
1991                                 proto_tree_add_item(v_tree,
1992                                         hf_bootp_hw_ether_addr, tvb, optoff+1, 6,
1993                                         ENC_NA);
1994                         else
1995                                 proto_tree_add_text(v_tree, tvb, optoff+1, 6,
1996                                         "Client hardware address: %s",
1997                                         tvb_arphrdaddr_to_str(tvb, optoff+1, 6, byte));
1998                 } else if (optlen == 17 && byte == 0) {
1999                         /* Identifier is a UUID */
2000                         proto_tree_add_item(v_tree, hf_bootp_client_identifier_uuid,
2001                                             tvb, optoff + 1, 16, ENC_LITTLE_ENDIAN);
2002                 } else {
2003                         /* otherwise, it's opaque data */
2004                 }
2005                 break;
2006
2007         case 63:        /* NetWare/IP options (RFC 2242) */
2008
2009                 optend = optoff + optlen;
2010                 while (optoff < optend)
2011                         optoff = dissect_netware_ip_suboption(pinfo, vti, v_tree, tvb, optoff, optend);
2012                 break;
2013
2014         case 78:        /* SLP Directory Agent Option RFC2610 Added by Greg Morris (gmorris@novell.com)*/
2015                 if (optlen < 1) {
2016                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't >= 1");
2017                         break;
2018                 }
2019                 optleft = optlen;
2020                 byte = tvb_get_guint8(tvb, optoff);
2021                 proto_tree_add_item(v_tree, hf_bootp_option_slp_directory_agent_value, tvb, optoff, 1, ENC_BIG_ENDIAN);
2022
2023                 optoff++;
2024                 optleft--;
2025                 if (byte == 0x80) {
2026                         if (optleft == 0)
2027                                 break;
2028                         optoff++;
2029                         optleft--;
2030                 }
2031                 for (i = optoff; optleft > 0; i += 4, optleft -= 4) {
2032                         if (optleft < 4) {
2033                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "Option length isn't a multiple of 4");
2034                                 break;
2035                         }
2036
2037                         proto_tree_add_item(v_tree, hf_bootp_option_slp_directory_agent_slpda_address, tvb, i, 4, ENC_BIG_ENDIAN);
2038                 }
2039                 break;
2040
2041         case 79:        /* SLP Service Scope Option RFC2610 Added by Greg Morris (gmorris@novell.com)*/
2042                 proto_tree_add_item(v_tree, hf_bootp_option_slp_service_scope_value, tvb, optoff, 1, ENC_BIG_ENDIAN);
2043
2044                 optoff++;
2045                 optleft = optlen - 1;
2046                 proto_tree_add_item(v_tree, hf_bootp_option_slp_service_scope_string, tvb, optoff, optleft, ENC_ASCII|ENC_NA);
2047                 break;
2048
2049         case 81:        /* Client Fully Qualified Domain Name */
2050                 if (optlen < 3) {
2051                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't >= 3");
2052                         break;
2053                 }
2054                 fqdn_flags = tvb_get_guint8(tvb, optoff);
2055                 proto_tree_add_text(v_tree, tvb, optoff, 1, "Flags: 0x%02x", fqdn_flags);
2056                 proto_tree_add_item(v_tree, hf_bootp_fqdn_mbz, tvb, optoff, 1, ENC_BIG_ENDIAN);
2057                 proto_tree_add_item(v_tree, hf_bootp_fqdn_n, tvb, optoff, 1, ENC_BIG_ENDIAN);
2058                 proto_tree_add_item(v_tree, hf_bootp_fqdn_e, tvb, optoff, 1, ENC_BIG_ENDIAN);
2059                 proto_tree_add_item(v_tree, hf_bootp_fqdn_o, tvb, optoff, 1, ENC_BIG_ENDIAN);
2060                 proto_tree_add_item(v_tree, hf_bootp_fqdn_s, tvb, optoff, 1, ENC_BIG_ENDIAN);
2061                 /* XXX: use code from packet-dns for return code decoding */
2062                 proto_tree_add_item(v_tree, hf_bootp_fqdn_rcode1, tvb, optoff+1, 1, ENC_BIG_ENDIAN);
2063                 /* XXX: use code from packet-dns for return code decoding */
2064                 proto_tree_add_item(v_tree, hf_bootp_fqdn_rcode2, tvb, optoff+2, 1, ENC_BIG_ENDIAN);
2065                 if (optlen > 3) {
2066                         if (fqdn_flags & F_FQDN_E) {
2067                                 get_dns_name(tvb, optoff+3, optlen-3, optoff+3, &dns_name);
2068                                 proto_tree_add_string(v_tree, hf_bootp_fqdn_name,
2069                                     tvb, optoff+3, optlen-3, dns_name);
2070                         } else {
2071                                 proto_tree_add_item(v_tree, hf_bootp_fqdn_asciiname,
2072                                     tvb, optoff+3, optlen-3, ENC_ASCII|ENC_NA);
2073                         }
2074                 }
2075                 break;
2076
2077         case 82:        /* Relay Agent Information Option */
2078                 optend = optoff + optlen;
2079                 while (optoff < optend)
2080                         optoff = bootp_dhcp_decode_agent_info(pinfo, vti, v_tree, tvb, optoff, optend);
2081                 break;
2082
2083         case 85:        /* Novell Servers (RFC 2241) */
2084                 /* Option 85 can be sent as a string */
2085                 /* Added by Greg Morris (gmorris[AT]novell.com) */
2086                 if (novell_string) {
2087                         proto_tree_add_item(v_tree, hf_bootp_option_novell_dss_string, tvb, optoff, optlen, ENC_ASCII|ENC_NA);
2088                 } else{
2089                         /* IP addresses */
2090                         for (i = optoff, optleft = optlen; optleft > 0;
2091                                 i += 4, optleft -= 4) {
2092                                 if (optleft < 4) {
2093                                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "Option length isn't a multiple of 4");
2094                                         break;
2095                                 }
2096
2097                                 proto_tree_add_item(v_tree, hf_bootp_option_novell_dss_ip, tvb, i, 4, ENC_BIG_ENDIAN);
2098                         }
2099                 }
2100                 break;
2101
2102         case 94: {      /* Client network interface identifier */
2103                 guint8 id_type;
2104
2105                 id_type = tvb_get_guint8(tvb, optoff);
2106
2107                 if (id_type == 0x01) {
2108                         proto_tree_add_item(v_tree, hf_bootp_option_client_network_id_major_ver,
2109                                                                 tvb, optoff + 1, 1, ENC_LITTLE_ENDIAN);
2110                         proto_tree_add_item(v_tree, hf_bootp_option_client_network_id_minor_ver,
2111                                                                 tvb, optoff + 2, 1, ENC_LITTLE_ENDIAN);
2112                 }
2113
2114                 break;
2115         }
2116
2117         case 90:        /* DHCP Authentication */
2118         case 210:       /* Was this used for authentication at one time? */
2119                 if (optlen < 11) {
2120                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't >= 11");
2121                         break;
2122                 }
2123                 optleft = optlen;
2124                 protocol = tvb_get_guint8(tvb, optoff);
2125
2126                 proto_tree_add_item(v_tree, hf_bootp_option_dhcp_authentication_protocol, tvb, optoff, 1, ENC_BIG_ENDIAN);
2127                 optoff++;
2128                 optleft--;
2129
2130                 algorithm = tvb_get_guint8(tvb, optoff);
2131                 switch (protocol) {
2132
2133                 case AUTHEN_PROTO_DELAYED_AUTHEN:
2134                         proto_tree_add_item(v_tree, hf_bootp_option_dhcp_authentication_alg_delay, tvb, optoff, 1, ENC_BIG_ENDIAN);
2135                         break;
2136
2137                 default:
2138                         proto_tree_add_item(v_tree, hf_bootp_option_dhcp_authentication_algorithm, tvb, optoff, 1, ENC_BIG_ENDIAN);
2139                         break;
2140                 }
2141                 optoff++;
2142                 optleft--;
2143
2144                 rdm = tvb_get_guint8(tvb, optoff);
2145                 proto_tree_add_item(v_tree, hf_bootp_option_dhcp_authentication_rdm, tvb, optoff, 1, ENC_BIG_ENDIAN);
2146                 optoff++;
2147                 optleft--;
2148
2149                 switch (rdm) {
2150
2151                 case AUTHEN_RDM_MONOTONIC_COUNTER:
2152                         proto_tree_add_item(v_tree, hf_bootp_option_dhcp_authentication_rdm_replay_detection, tvb, optoff, 8, ENC_BIG_ENDIAN);
2153                         break;
2154
2155                 default:
2156                         proto_tree_add_item(v_tree, hf_bootp_option_dhcp_authentication_rdm_rdv, tvb, optoff, 8, ENC_ASCII|ENC_NA);
2157                         break;
2158                 }
2159                 optoff += 8;
2160                 optleft -= 8;
2161
2162                 switch (protocol) {
2163
2164                 case AUTHEN_PROTO_DELAYED_AUTHEN:
2165                         switch (algorithm) {
2166
2167                         case AUTHEN_DELAYED_ALGO_HMAC_MD5:
2168                                 if (*dhcp_type_p && !strcmp(*dhcp_type_p, OPT53_DISCOVER)) {
2169                                         /* Discover has no Secret ID nor HMAC MD5 Hash */
2170                                         break;
2171                                 } else {
2172                                         if (optlen < 31) {
2173                                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't >= 31");
2174                                                 break;
2175                                         }
2176
2177                                         proto_tree_add_item(v_tree, hf_bootp_option_dhcp_authentication_secret_id, tvb, optoff, 4, ENC_BIG_ENDIAN);
2178                                         optoff += 4;
2179                                         /*optleft -= 4;*/
2180                                         proto_tree_add_item(v_tree, hf_bootp_option_dhcp_authentication_hmac_md5_hash, tvb, optoff, 16, ENC_ASCII|ENC_NA);
2181                                         break;
2182                                 }
2183
2184                         default:
2185                                 if (optleft == 0)
2186                                         break;
2187
2188                                 proto_tree_add_item(v_tree, hf_bootp_option_dhcp_authentication_information, tvb, optoff, optleft, ENC_ASCII|ENC_NA);
2189                                 break;
2190                         }
2191                         break;
2192
2193                 default:
2194                         if (optleft == 0)
2195                                 break;
2196
2197                         proto_tree_add_item(v_tree, hf_bootp_option_dhcp_authentication_information, tvb, optoff, optleft, ENC_ASCII|ENC_NA);
2198                         break;
2199                 }
2200                 break;
2201
2202         case 99: /* civic location (RFC 4776) */
2203
2204                 optleft = optlen;
2205                 if (optleft >= 3)
2206                 {
2207                         proto_tree_add_item(v_tree, hf_bootp_option_civic_location_what, tvb, optoff, 1, ENC_BIG_ENDIAN);
2208                         proto_tree_add_item(v_tree, hf_bootp_option_civic_location_country, tvb, optoff+1, 2, ENC_ASCII|ENC_NA);
2209                         optleft = optleft - 3;
2210                         optoff = optoff + 3;
2211
2212                         while (optleft >= 2)
2213                         {
2214                                 int calength = tvb_get_guint8(tvb, optoff+1);
2215                                 proto_tree_add_item(v_tree, hf_bootp_option_civic_location_ca_type, tvb, optoff, 1, ENC_BIG_ENDIAN);
2216                                 proto_tree_add_item(v_tree, hf_bootp_option_civic_location_ca_length, tvb, optoff+1, 1, ENC_BIG_ENDIAN);
2217
2218                                 optoff += 2;
2219                                 optleft -= 2;
2220
2221                                 if (calength == 0)
2222                                         continue;
2223
2224                                 if (optleft >= calength)
2225                                 {
2226                                         proto_tree_add_item(v_tree, hf_bootp_option_civic_location_ca_value, tvb, optoff, calength, ENC_ASCII|ENC_NA);
2227
2228                                         optoff = optoff + calength;
2229                                         optleft = optleft - calength;
2230                                 }
2231                                 else
2232                                 {
2233                                         optleft = 0;
2234                                         expert_add_info(pinfo, vti, &ei_bootp_option_civic_location_bad_cattype);
2235                                 }
2236                         }
2237                 }
2238                 break;
2239
2240         case 117:   /* The Name Service Search Option for DHCP (RFC 2937) */
2241                 if (optlen < 2) {
2242                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't >= 2");
2243                 } else if (optlen & 1) {
2244                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length (%u) isn't even number", optlen);
2245                 } else {
2246                         guint16 ns;
2247                         for (i = 0, ns = tvb_get_ntohs(tvb, optoff); i < optlen; i += 2, ns = tvb_get_ntohs(tvb, optoff + i)) {
2248                                 switch (ns) {
2249                                 case RFC2937_LOCAL_NAMING_INFORMATION:
2250                                         proto_tree_add_string(v_tree, hf_bootp_option_dhcp_name_service_search_option, tvb, optoff + i, 2, "Local naming information (e.g., an /etc/hosts file on a UNIX machine) (0)");
2251                                         break;
2252                                 case RFC2937_DOMAIN_NAME_SERVER_OPTION:
2253                                         proto_tree_add_string(v_tree, hf_bootp_option_dhcp_name_service_search_option, tvb, optoff + i, 2, "Domain Name Server Option (6)");
2254                                         break;
2255                                 case RFC2937_NETWORK_INFORMATION_SERVERS_OPTION:
2256                                         proto_tree_add_string(v_tree, hf_bootp_option_dhcp_name_service_search_option, tvb, optoff + i, 2, "Network Information Servers Option (41)");
2257                                         break;
2258                                 case RFC2937_NETBIOS_OVER_TCP_IP_NAME_SERVER_OPTION:
2259                                         proto_tree_add_string(v_tree, hf_bootp_option_dhcp_name_service_search_option, tvb, optoff + i, 2, "NetBIOS over TCP/IP Name Server Option (44)");
2260                                         break;
2261                                 case RFC2937_NETWORK_INFORMATION_SERVICE_PLUS_SERVERS_OPTION:
2262                                         proto_tree_add_string(v_tree, hf_bootp_option_dhcp_name_service_search_option, tvb, optoff + i, 2, "Network Information Service+ Servers Option (65)");
2263                                         break;
2264                                 default:
2265                                         expert_add_info_format(pinfo, vti, &ei_bootp_option_dhcp_name_service_invalid,
2266                                                                 "Invalid Name Service (%u). RFC 2937 defines only 0, 6, 41, 44, and 65 as possible values.", ns);
2267                                         break;
2268                                 }
2269                         }
2270                 }
2271                 break;
2272
2273         case 119: { /* Dynamic Host Configuration Protocol (DHCP) Domain Search Option (RFC 3397) */
2274                     /* Encoding Long Options in the Dynamic Host Configuration Protocol (DHCPv4) (RFC 3396) */
2275                     /* Domain Names - Implementation And Specification (RFC 1035) */
2276                 char tmpChar[BOOTP_MAX_NO_CHAR];
2277                 rfc3396_dns_domain_search_list.index_current_block++;
2278                 if (rfc3396_dns_domain_search_list.total_number_of_block > 1) {
2279                         g_snprintf(tmpChar, BOOTP_MAX_NO_CHAR, "%u/%u", rfc3396_dns_domain_search_list.index_current_block, rfc3396_dns_domain_search_list.total_number_of_block);
2280                         proto_tree_add_string(v_tree, hf_bootp_option_dhcp_dns_domain_search_list_rfc_3396_detected, tvb, optoff, optlen, tmpChar);
2281                         if (rfc3396_dns_domain_search_list.index_current_block != rfc3396_dns_domain_search_list.total_number_of_block) {
2282                                 g_snprintf(tmpChar, BOOTP_MAX_NO_CHAR, "%u/%u", rfc3396_dns_domain_search_list.total_number_of_block, rfc3396_dns_domain_search_list.total_number_of_block);
2283                                 proto_tree_add_string(v_tree, hf_bootp_option_dhcp_dns_domain_search_list_refer_last_option, tvb, optoff, optlen, tmpChar);
2284                         }
2285                 }
2286
2287                 if (rfc3396_dns_domain_search_list.tvb_composite == NULL && optlen) {
2288                         /* We use composite tvb for managing RFC 3396 */
2289                         rfc3396_dns_domain_search_list.tvb_composite = tvb_new_composite();
2290                 }
2291
2292                 /* Concatenate the block before being interpreted for managing RFC 3396 */
2293                 if (optlen)
2294                         tvb_composite_append(rfc3396_dns_domain_search_list.tvb_composite, tvb_new_subset_length(tvb, optoff, optlen));
2295
2296                 if (rfc3396_dns_domain_search_list.index_current_block == rfc3396_dns_domain_search_list.total_number_of_block
2297                     && rfc3396_dns_domain_search_list.tvb_composite) {
2298                         /* Here, we are into the last (or unique) option 119. */
2299                         /* We will display the information about fqdn */
2300                         unsigned int consumedx = 0;
2301                         unsigned int offset = 0;
2302                         tvb_composite_finalize(rfc3396_dns_domain_search_list.tvb_composite);
2303
2304                         while (offset < tvb_length(rfc3396_dns_domain_search_list.tvb_composite)) {
2305                                 /* use the get_dns_name method that manages all techniques of RFC 1035 (compression pointer and so on) */
2306                                 consumedx = get_dns_name(rfc3396_dns_domain_search_list.tvb_composite, offset, tvb_length(rfc3396_dns_domain_search_list.tvb_composite), 0, &dns_name);
2307                                 if (rfc3396_dns_domain_search_list.total_number_of_block == 1) {
2308                                         /* RFC 3396 is not used, so we can easily link the fqdn with v_tree. */
2309                                         proto_tree_add_string(v_tree, hf_bootp_option_dhcp_dns_domain_search_list_fqdn, tvb, optoff + offset, consumedx, dns_name);
2310                                 } else {
2311                                         /* RFC 3396 is used, so the option is split into several option 119. We don't link fqdn with v_tree. */
2312                                         proto_tree_add_string(v_tree, hf_bootp_option_dhcp_dns_domain_search_list_fqdn, tvb, 0, 0, dns_name);
2313                                 }
2314                                 offset += consumedx;
2315                         }
2316                         rfc3396_dns_domain_search_list.tvb_composite = NULL;
2317                 }
2318                 break;
2319         }
2320         case 120: { /* SIP Servers (RFC 3361) */
2321                     /* Encoding Long Options in the Dynamic Host Configuration Protocol (DHCPv4) (RFC 3396) */
2322                     /* Domain Names - Implementation And Specification (RFC 1035) */
2323                 char tmpChar[BOOTP_MAX_NO_CHAR];
2324                 rfc3396_sip_server.index_current_block++;
2325                 if (rfc3396_sip_server.total_number_of_block > 1) {
2326                         g_snprintf(tmpChar, BOOTP_MAX_NO_CHAR, "%u/%u", rfc3396_sip_server.index_current_block, rfc3396_sip_server.total_number_of_block);
2327                         proto_tree_add_string(v_tree, hf_bootp_option_sip_server_rfc_3396_detected, tvb, optoff, optlen, tmpChar);
2328                         if (rfc3396_sip_server.index_current_block != rfc3396_sip_server.total_number_of_block) {
2329                                 g_snprintf(tmpChar, BOOTP_MAX_NO_CHAR, "%u/%u", rfc3396_sip_server.total_number_of_block, rfc3396_sip_server.total_number_of_block);
2330                                 proto_tree_add_string(v_tree, hf_bootp_option_sip_server_refer_last_option, tvb, optoff, optlen, tmpChar);
2331                         }
2332                 }
2333
2334                 if (rfc3396_sip_server.tvb_composite == NULL && optlen) {
2335                         /* We use composite tvb for managing RFC 3396 */
2336                         rfc3396_sip_server.tvb_composite = tvb_new_composite();
2337                 }
2338
2339                 /* Concatenate the block before being interpreted for managing RFC 3396 */
2340                 if (optlen)
2341                         tvb_composite_append(rfc3396_sip_server.tvb_composite, tvb_new_subset_length(tvb, optoff, optlen));
2342
2343                 if (rfc3396_sip_server.index_current_block == rfc3396_sip_server.total_number_of_block
2344                     && rfc3396_sip_server.tvb_composite) {
2345                         /* Here, we are into the last (or unique) option 120. */
2346                         /* We will display the information about SIP server */
2347                         guint8 enc;
2348                         unsigned int offset = 1; /* ignore enc */
2349                         tvb_composite_finalize(rfc3396_sip_server.tvb_composite);
2350
2351                         enc = tvb_get_guint8(rfc3396_sip_server.tvb_composite, 0);
2352                         if (rfc3396_sip_server.total_number_of_block == 1) {
2353                                 /* RFC 3396 is not used, so we can easily link the fqdn with v_tree. */
2354                                 proto_tree_add_uint(v_tree, hf_bootp_option_sip_server_enc, tvb, optoff, 1, enc);
2355                         } else {
2356                                 /* RFC 3396 is used, so the option is split into several option 120. We don't link fqdn with v_tree. */
2357                                 proto_tree_add_uint(v_tree, hf_bootp_option_sip_server_enc, tvb, 0, 0, enc);
2358                         }
2359
2360                         switch (enc) {
2361                         case RFC_3361_ENC_FQDN: {
2362                                 unsigned int consumedx = 0;
2363                                 if (tvb_length(rfc3396_sip_server.tvb_composite) < 3) {
2364                                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't >= 3 (len = %u)", tvb_length(rfc3396_sip_server.tvb_composite));
2365                                         break;
2366                                 }
2367
2368                                 while (offset < tvb_length(rfc3396_sip_server.tvb_composite)) {
2369                                         /* use the get_dns_name method that manages all techniques of RFC 1035 (compression pointer and so on) */
2370                                         consumedx = get_dns_name(rfc3396_sip_server.tvb_composite, offset, tvb_length(rfc3396_sip_server.tvb_composite), 1 /* ignore enc */, &dns_name);
2371
2372                                         if (rfc3396_sip_server.total_number_of_block == 1) {
2373                                                 /* RFC 3396 is not used, so we can easily link the fqdn with v_tree. */
2374                                                 proto_tree_add_string(v_tree, hf_bootp_option_sip_server_name, tvb, optoff + offset, consumedx, dns_name);
2375                                         } else {
2376                                                 /* RFC 3396 is used, so the option is split into several option 120. We don't link fqdn with v_tree. */
2377                                                 proto_tree_add_string(v_tree, hf_bootp_option_sip_server_name, tvb, 0, 0, dns_name);
2378                                         }
2379                                         offset += consumedx;
2380                                 }
2381                                 rfc3396_sip_server.tvb_composite = NULL;
2382                                 break;
2383                         }
2384                         case RFC_3361_ENC_IPADDR:
2385                                 if (tvb_length(rfc3396_sip_server.tvb_composite) < 5) {
2386                                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't >= 5 (len = %u)", tvb_length(rfc3396_sip_server.tvb_composite));
2387                                         break;
2388                                 }
2389                                 /* x % 2^n == x & (2^n - 1) note : (assuming x is a positive integer) */
2390                                 if ((tvb_length(rfc3396_sip_server.tvb_composite) - 1) & 3) {
2391                                         if (rfc3396_sip_server.total_number_of_block == 1)
2392                                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't a multiple of 4 plus 1 (len = %u).", tvb_length(rfc3396_sip_server.tvb_composite));
2393                                         else
2394                                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length,
2395                                                         "length isn't a multiple of 4 plus 1 (len = %u). For your information with RFC 3396, the length is the length sum of all options 120 into this BOOTP packet.",
2396                                                         tvb_length(rfc3396_sip_server.tvb_composite));
2397                                         break;
2398                                 }
2399                                 while (offset < tvb_length(rfc3396_sip_server.tvb_composite)) {
2400                                         if (rfc3396_sip_server.total_number_of_block == 1) {
2401                                                 /* RFC 3396 is not used, so we can easily link the fqdn with v_tree. */
2402                                                 proto_tree_add_item(v_tree, hf_bootp_option_sip_server_address, rfc3396_sip_server.tvb_composite, offset, 4, ENC_BIG_ENDIAN);
2403                                         } else {
2404                                                 /* RFC 3396 is used, so the option is split into several option 120. We don't link fqdn with v_tree. */
2405                                                 /* Since we don't use the "numbered argument" as described by README.developer, we have to repeat the arguments :( */
2406                                                 g_snprintf(tmpChar, BOOTP_MAX_NO_CHAR, "%u.%u.%u.%u (%u.%u.%u.%u)",
2407                                                            tvb_get_guint8(rfc3396_sip_server.tvb_composite, offset),
2408                                                            tvb_get_guint8(rfc3396_sip_server.tvb_composite, offset + 1),
2409                                                            tvb_get_guint8(rfc3396_sip_server.tvb_composite, offset + 2),
2410                                                            tvb_get_guint8(rfc3396_sip_server.tvb_composite, offset + 3),
2411                                                            tvb_get_guint8(rfc3396_sip_server.tvb_composite, offset),
2412                                                            tvb_get_guint8(rfc3396_sip_server.tvb_composite, offset + 1),
2413                                                            tvb_get_guint8(rfc3396_sip_server.tvb_composite, offset + 2),
2414                                                            tvb_get_guint8(rfc3396_sip_server.tvb_composite, offset + 3)
2415                                                            );
2416                                                 proto_tree_add_string(v_tree, hf_bootp_option_sip_server_address_stringz, tvb, 0, 0, tmpChar);
2417                                         }
2418                                         offset += 4;
2419                                 }
2420                                 break;
2421                         default:
2422                                 expert_add_info_format(pinfo, vti, &ei_bootp_option_sip_server_address_encoding, "RFC 3361 defines only 0 and 1 for Encoding byte (Encoding = %u).", enc);
2423                                 break;
2424                         }
2425                 }
2426                 break;
2427         }
2428         case 121:       /* Classless Static Route */
2429         case 249: {     /* Classless Static Route (Microsoft) */
2430                 int mask_width, significant_octets;
2431                 optend = optoff + optlen;
2432                 /* minimum length is 5 bytes */
2433                 if (optlen < 5) {
2434                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't >= 5");
2435                         break;
2436                 }
2437                 while (optoff < optend) {
2438                         mask_width = tvb_get_guint8(tvb, optoff);
2439                         /* mask_width <= 32 */
2440                         if (mask_width > 32) {
2441                                 expert_add_info_format(pinfo, vti, &ei_bootp_option_classless_static_route, "Mask width (%d) > 32", mask_width);
2442                                 break;
2443                         }
2444                         significant_octets = (mask_width + 7) / 8;
2445                         vti = proto_tree_add_text(v_tree, tvb, optoff,
2446                                 1 + significant_octets + 4,
2447                                 "Subnet/MaskWidth-Router: ");
2448                         optoff++;
2449                         /* significant octets + router(4) */
2450                         if (optend < optoff + significant_octets + 4) {
2451                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "Remaining length (%d) < %d bytes", optend - optoff, significant_octets + 4);
2452                                 break;
2453                         }
2454                         if(mask_width == 0)
2455                                 proto_item_append_text(vti, "default");
2456                         else {
2457                                 for(i = 0 ; i < significant_octets ; i++) {
2458                                         if (i > 0)
2459                                                 proto_item_append_text(vti, ".");
2460                                         byte = tvb_get_guint8(tvb, optoff++);
2461                                         proto_item_append_text(vti, "%d", byte);
2462                                 }
2463                                 for(i = significant_octets ; i < 4 ; i++)
2464                                         proto_item_append_text(vti, ".0");
2465                                 proto_item_append_text(vti, "/%d", mask_width);
2466                         }
2467                         proto_item_append_text(vti, "-%s", tvb_ip_to_str(tvb, optoff));
2468                         optoff += 4;
2469                 }
2470                 break;
2471         }
2472
2473         case 123: /* coordinate based location RFC 3825 or CableLabs DSS_ID  */
2474                 if (optlen == 16) {
2475                         int c;
2476                         unsigned char lci[16];
2477                         struct rfc3825_location_fixpoint_t location_fp;
2478                         struct rfc3825_location_decimal_t location;
2479
2480                         for (c=0; c < 16;c++)
2481                                 lci[c] = (unsigned char) tvb_get_guint8(tvb, optoff + c);
2482
2483                         /* convert lci encoding into fixpoint location */
2484                         rfc3825_lci_to_fixpoint(lci, &location_fp);
2485
2486                         /* convert location from decimal to fixpoint */
2487                         i = rfc3825_fixpoint_to_decimal(&location_fp, &location);
2488
2489                         if (i != RFC3825_NOERROR) {
2490                                 proto_tree_add_text(v_tree, tvb, optoff, optlen, "Error: %s", val_to_str_const(i, rfc3825_error_types, "Unknown"));
2491                         } else {
2492                                 proto_tree_add_text(v_tree, tvb, optoff, 5, "Latitude: %15.10f", location.latitude);
2493                                 proto_tree_add_text(v_tree, tvb, optoff+5, 5, "Longitude: %15.10f", location.longitude);
2494                                 proto_tree_add_text(v_tree, tvb, optoff, 1, "Latitude resolution: %15.10f", location.latitude_res);
2495                                 proto_tree_add_text(v_tree, tvb, optoff+5, 1, "Longitude resolution: %15.10f", location.longitude_res);
2496                                 proto_tree_add_text(v_tree, tvb, optoff+12, 4, "Altitude: %15.10f", location.altitude);
2497                                 proto_tree_add_text(v_tree, tvb, optoff+10, 2, "Altitude resolution: %15.10f", location.altitude_res);
2498                                 proto_tree_add_text(v_tree, tvb, optoff+10, 1, "Altitude type: %s (%d)", val_to_str_const(location.altitude_type, altitude_type_values, "Unknown"), location.altitude_type);
2499                                 proto_tree_add_text(v_tree, tvb, optoff+15, 1, "Map Datum: %s (%d)", val_to_str_const(location.datum_type, map_datum_type_values, "Unknown"), location.datum_type);
2500                         }
2501                 } else if (optlen < 69) { /* CableLabs DSS_ID */
2502
2503                         proto_tree_add_item(v_tree, hf_bootp_option_cl_dss_id_option, tvb, optoff, 1, ENC_BIG_ENDIAN);
2504                         proto_tree_add_item(v_tree, hf_bootp_option_cl_dss_id_len, tvb, optoff+1, 1, ENC_BIG_ENDIAN);
2505                         s_len = tvb_get_guint8(tvb, optoff+1);
2506                         proto_tree_add_item(v_tree, hf_bootp_option_cl_dss_id, tvb, optoff+2, s_len, ENC_ASCII|ENC_NA);
2507
2508                         if (optlen > s_len+2) { /* Second DSS_ID*/
2509
2510                                 proto_tree_add_item(v_tree, hf_bootp_option_cl_dss_id_option, tvb, optoff+2+s_len, 1, ENC_BIG_ENDIAN);
2511                                 proto_tree_add_item(v_tree, hf_bootp_option_cl_dss_id_len, tvb, optoff+1+2+s_len, 1, ENC_BIG_ENDIAN);
2512                                 s_len = tvb_get_guint8(tvb, optoff+1+2+s_len);
2513                                 proto_tree_add_item(v_tree, hf_bootp_option_cl_dss_id, tvb, optoff+2+2+s_len, s_len, ENC_ASCII|ENC_NA);
2514                         }
2515                 } else {
2516                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "Invalid length of DHCP option!");
2517                 }
2518                 break;
2519
2520         case 124: {     /* V-I Vendor Class */
2521                 int data_len;
2522
2523                 if (optlen == 1) {
2524                         /* CableLab specific */
2525                         proto_tree_add_item(v_tree, hf_bootp_option_vi_class_cl_address_mode, tvb, optoff, optlen, ENC_BIG_ENDIAN);
2526                         break;
2527                 }
2528
2529                 optleft = optlen;
2530
2531                 while (optleft > 0) {
2532
2533                         if (optleft < 5) {
2534                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length < 5");
2535                                 break;
2536                         }
2537
2538                         proto_tree_add_item(v_tree, hf_bootp_option_vi_class_enterprise, tvb, optoff, 4, ENC_BIG_ENDIAN);
2539                         proto_tree_add_item(v_tree, hf_bootp_option_vi_class_data_length, tvb, optoff, 1, ENC_BIG_ENDIAN);
2540                         data_len = tvb_get_guint8(tvb, optoff + 4);
2541
2542                         optoff += 5;
2543                         optleft -= 5;
2544
2545                         proto_tree_add_item(v_tree, hf_bootp_option_vi_class_data, tvb, optoff, data_len, ENC_ASCII|ENC_NA);
2546
2547                         /* look for next enterprise number */
2548                         optoff += data_len;
2549                         optleft -= data_len;
2550                 }
2551                 break;
2552         }
2553
2554         case 125: {     /* V-I Vendor-specific Information */
2555                 int enterprise = 0;
2556                 int s_end = 0;
2557                 int s_option_len = 0;
2558                 proto_tree *e_tree = 0;
2559
2560                 optend = optoff + optlen;
2561                 optleft = optlen;
2562
2563                 while (optleft > 0) {
2564
2565                         if (optleft < 5) {
2566                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length < 5");
2567                                 break;
2568                         }
2569
2570                         enterprise = tvb_get_ntohl(tvb, optoff);
2571                         vti = proto_tree_add_item(v_tree, hf_bootp_option125_enterprise, tvb, optoff, 4, ENC_BIG_ENDIAN);
2572
2573                         s_option_len = tvb_get_guint8(tvb, optoff + 4);
2574
2575                         optoff += 5;
2576                         optleft -= 5;
2577
2578                         /* Handle DSL Forum TR-111 Option 125 */
2579                         switch (enterprise) {
2580
2581                         case 3561: /* ADSL Forum */
2582                                 s_end = optoff + s_option_len;
2583                                 if ( s_end > optend ) {
2584                                         expert_add_info_format(pinfo, vti, &ei_bootp_option125_enterprise_malformed, "no room left in option for enterprise %u data", enterprise);
2585                                         break;
2586                                 }
2587
2588                                 e_tree = proto_item_add_subtree(vti, ett_bootp_option);
2589                                 while (optoff < s_end) {
2590
2591                                 optoff = dissect_vendor_tr111_suboption(pinfo, vti, e_tree, tvb, optoff, s_end);
2592                         }
2593                         break;
2594
2595                         case 4491: /* CableLab */
2596                                 s_end = optoff + s_option_len;
2597                                 if ( s_end > optend ) {
2598                                         expert_add_info_format(pinfo, vti, &ei_bootp_option125_enterprise_malformed, "no room left in option for enterprise %u data", enterprise);
2599                                         break;
2600                                 }
2601
2602                                 e_tree = proto_item_add_subtree(vti, ett_bootp_option);
2603                                 while (optoff < s_end) {
2604                                         optoff = dissect_vendor_cl_suboption(pinfo, vti, e_tree, tvb, optoff, s_end);
2605                         }
2606                         break;
2607
2608                         default:
2609                                 s_end = optoff + s_option_len;
2610                                 if ( s_end > optend ) {
2611                                         expert_add_info_format(pinfo, vti, &ei_bootp_option125_enterprise_malformed, "no room left in option for enterprise %u data", enterprise);
2612                                         break;
2613                                 }
2614
2615                                 e_tree = proto_item_add_subtree(vti, ett_bootp_option);
2616                                 while (optoff < s_end) {
2617
2618                                 optoff = dissect_vendor_generic_suboption(pinfo, vti, e_tree, tvb, optoff, s_end);
2619                         }
2620                         break;
2621                         }
2622
2623                         optleft -= s_option_len;
2624                 }
2625                 break;
2626         }
2627
2628         case 212: {     /* 6RD option (RFC 5969) */
2629                 if (optlen < 22) {
2630                         expert_add_info(pinfo, vti, &ei_bootp_option_6RD_malformed);
2631                         break;
2632                 }
2633
2634                 proto_tree_add_item(v_tree, hf_bootp_option_6RD_ipv4_mask_len, tvb, optoff, 1, ENC_BIG_ENDIAN);
2635                 proto_tree_add_item(v_tree, hf_bootp_option_6RD_prefix_len, tvb, optoff+1, 1, ENC_BIG_ENDIAN);
2636                 proto_tree_add_item(v_tree, hf_bootp_option_6RD_prefix, tvb, optoff+2, 16, ENC_NA);
2637                 proto_tree_add_item(v_tree, hf_bootp_option_6RD_border_relay_ip, tvb, optoff+18, 4, ENC_BIG_ENDIAN);
2638
2639                 /* More Border Relay IPv4 addresses included */
2640                 if (optlen > 22) {
2641                         optoff += 22;
2642                         for (i = optoff, optleft = optlen - 22; optleft > 0; i += 4, optleft -= 4) {
2643                                 if (optleft < 4) {
2644                                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "Option length isn't a multiple of 4");
2645                                         break;
2646                                 }
2647
2648                                 proto_tree_add_item(v_tree, hf_bootp_option_6RD_border_relay_ip, tvb, i, 4, ENC_BIG_ENDIAN);
2649                         }
2650                 }
2651                 break;
2652         }
2653
2654         default:        /* not special */
2655                 /* The PacketCable CCC option number can vary.  If this is a CCC option,
2656                    handle it as a special.
2657                  */
2658                 if (code == pkt_ccc_option) {
2659                         ftype = special;
2660                         proto_item_append_text(vti,
2661                                 "CableLabs Client Configuration (%d bytes)",
2662                                 optlen);
2663                         optend = optoff + optlen;
2664                         while (optoff < optend) {
2665                                 switch (pkt_ccc_protocol_version) {
2666
2667                                 case PACKETCABLE_CCC_I05:
2668                                         optoff = dissect_packetcable_i05_ccc(pinfo, vti, v_tree, tvb, optoff, optend);
2669                                         break;
2670                                 case PACKETCABLE_CCC_DRAFT5:
2671                                 case PACKETCABLE_CCC_RFC_3495:
2672                                         optoff = dissect_packetcable_ietf_ccc(pinfo, vti, v_tree, tvb, optoff, optend, pkt_ccc_protocol_version);
2673                                         break;
2674                                 default: /* XXX Should we do something here? */
2675                                         break;
2676                                 }
2677                         }
2678                 } else {
2679                         option_handled = FALSE;
2680                 }
2681
2682                 break;
2683         }
2684
2685         basictype_consumed = bootp_handle_basic_types(pinfo, v_tree, vti, tvb, ftype,
2686                                                       optoff, optlen, opt->phf, &default_hfs);
2687
2688         if ((basictype_consumed == 0) && (option_handled == FALSE) &&
2689             (opt->phf == NULL) && (optlen > 0)) {
2690                 proto_tree_add_item(v_tree, hf_bootp_option_value, tvb, voff+2, optlen, ENC_NA);
2691         }
2692
2693         return consumed;
2694 }
2695
2696 static const value_string option82_suboption_vals[] = {
2697         {  0, "Padding" },
2698         {  1, "Agent Circuit ID" },
2699         {  2, "Agent Remote ID" },
2700         {  3, "Reserved" },
2701         {  4, "DOCSIS Device Class" },
2702         {  5, "Link selection" },
2703         {  6, "Subscriber ID" },
2704         {  7, "RADIUS Attributes" },
2705         {  8, "Authentication" },
2706         {  9, "Vendor-Specific Information" },
2707         { 10, "Flags" },
2708         { 11, "Server ID Override" },
2709         { 150, "Link selection (Cisco proprietary)" },
2710         { 151, "VRF name/VPN ID" },
2711         { 152, "Server ID Override (Cisco proprietary)" },
2712         { 0, NULL }
2713 };
2714
2715 static int
2716 bootp_dhcp_decode_agent_info(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree, tvbuff_t *tvb, int optoff,
2717                              int optend)
2718 {
2719         int         suboptoff = optoff;
2720         guint8      subopt, idx, vs_opt, vs_len;
2721         int         subopt_len, subopt_end, datalen;
2722         guint32     enterprise;
2723         proto_item *vti, *ti;
2724         proto_tree *o82_v_tree, *o82_sub_tree;
2725         guint8      tag, tag_len;
2726
2727         struct basic_types_hfs default_hfs = {
2728                 &hf_bootp_option82_value,
2729                 &hf_bootp_option82_value_ip_address,
2730                 &hf_bootp_option82_value_ip_address,
2731                 &hf_bootp_option82_value_stringz,
2732                 NULL,
2733                 &hf_bootp_option82_value_8,
2734                 NULL,
2735                 NULL,
2736                 &hf_bootp_option82_value_32,
2737                 NULL,
2738                 NULL
2739         };
2740
2741         struct opt82_info {
2742                 int id;
2743                 struct opt_info info;
2744         };
2745         static struct opt82_info o82_opt[]= {
2746                 {0, {"nop", bytes, &hf_bootp_option82_padding}},        /* dummy */
2747                 {1, {"Agent Circuit ID", bytes, &hf_bootp_option82_agent_circuit_id}}, /* [RFC3046] */
2748                 {2, {"Agent Remote ID", bytes, &hf_bootp_option82_agent_remote_id}}, /* [RFC3046] */
2749                 {3, {"Reserved", bytes, &hf_bootp_option82_reserved}},
2750                 {4, {"DOCSIS Device Class", val_u_long, &hf_bootp_option82_docsis_device_class}}, /* [RFC3256] */
2751                 {5, {"Link selection", ipv4, &hf_bootp_option82_link_selection}}, /* [RFC3527] */
2752                 {6, {"Subscriber ID", string, &hf_bootp_option82_subscriber_id}},  /* [RFC3993] */ /***** CHECK STRING TYPE */
2753                 {7, {"RADIUS Attributes", bytes, &hf_bootp_option82_radius_attributes}}, /* [RFC4014] */
2754                 {8, {"Authentication", bytes, &hf_bootp_option82_authentication}}, /* [RFC4030] */
2755                 {9, {"Vendor-Specific Information", special, &hf_bootp_option82_vi}}, /* [RFC 4243] */
2756                 {10, {"Flags", val_u_byte, &hf_bootp_option82_flags}}, /* [RFC5010] */
2757                 {11, {"Server ID Override", ipv4, &hf_bootp_option82_server_id_override}}, /* [RFC 5107] */
2758                 {150, {"Link selection (Cisco proprietary)", ipv4, &hf_bootp_option82_link_selection_cisco}}, /* [RFC3527] */
2759                 {151, {"VRF name/VPN ID", special, &hf_bootp_option82_vrf_name_vpn_id}}, /* [RFC2685] */
2760                 {152, {"Server ID Override (Cisco proprietary)", ipv4, &hf_bootp_option82_server_id_override_cisco}} /* [RFC 5107] */
2761         };
2762
2763         subopt = tvb_get_guint8(tvb, optoff);
2764         suboptoff++;
2765
2766         if (suboptoff >= optend) {
2767                 expert_add_info_format(pinfo, v_ti, &ei_bootp_missing_subopt_length,
2768                                                                         "Suboption %d: no room left in option for suboption length", subopt);
2769                 return (optend);
2770         }
2771
2772         subopt_len = tvb_get_guint8(tvb, suboptoff);
2773         vti = proto_tree_add_uint_format_value(v_tree, hf_bootp_option82_suboption,
2774                 tvb, optoff, subopt_len+2, subopt, "(%d) %s", subopt, val_to_str_const(subopt, option82_suboption_vals, "Unknown"));
2775
2776         o82_v_tree = proto_item_add_subtree(vti, ett_bootp_option82_suboption);
2777         proto_tree_add_item(o82_v_tree, hf_bootp_suboption_length, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
2778         suboptoff++;
2779
2780         subopt_end = suboptoff+subopt_len;
2781         if (subopt_end > optend) {
2782                 expert_add_info_format(pinfo, vti, &ei_bootp_missing_subopt_value,
2783                                                 "Suboption %d: no room left in option for suboption value", subopt);
2784                 return (optend);
2785         }
2786
2787         for (idx = 0; idx < array_length(o82_opt); idx++) {
2788                 if (o82_opt[idx].id == subopt) {
2789                         break;
2790                 }
2791         }
2792
2793         ti = proto_tree_add_item(o82_v_tree, hf_bootp_option82_value, tvb, suboptoff, subopt_len, ENC_NA);
2794
2795         if ( (idx >= 1 ) && (idx < array_length(o82_opt)) ) {
2796                 PROTO_ITEM_SET_HIDDEN(ti);
2797                 if (o82_opt[idx].info.ftype == special) {
2798                         switch(subopt)
2799                         {
2800                         case 9:
2801                                 while (suboptoff < subopt_end) {
2802                                         enterprise = tvb_get_ntohl(tvb, suboptoff);
2803                                         vti = proto_tree_add_item(o82_v_tree, hf_bootp_option82_vi_enterprise, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
2804                                         suboptoff += 4;
2805
2806                                         o82_sub_tree = proto_item_add_subtree(vti, ett_bootp_option82_suboption9);
2807                                         datalen = tvb_get_guint8(tvb, suboptoff);
2808                                         proto_tree_add_item(o82_sub_tree, hf_bootp_option82_vi_data_length, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
2809                                         suboptoff++;
2810
2811                                         switch (enterprise) {
2812                                         case 4491: /* CableLab */
2813                                                 vs_opt = tvb_get_guint8(tvb, suboptoff);
2814                                                 proto_tree_add_item(o82_sub_tree, hf_bootp_option82_vi_cl_option, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
2815                                                 suboptoff++;
2816                                                 vs_len = tvb_get_guint8(tvb, suboptoff);
2817                                                 proto_tree_add_item(o82_sub_tree, hf_bootp_option82_vi_cl_length, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
2818                                                 suboptoff++;
2819
2820                                                 switch (vs_opt) {
2821
2822                                                 case 1:
2823                                                         if (vs_len == 4) {
2824                                                                 tag = tvb_get_guint8(tvb, suboptoff);
2825                                                                 proto_tree_add_item(o82_sub_tree, hf_bootp_option82_vi_cl_tag, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
2826                                                                 tag_len = tvb_get_guint8(tvb, suboptoff+1);
2827                                                                 proto_tree_add_item(o82_sub_tree, hf_bootp_option82_vi_cl_tag_length, tvb, suboptoff+1, 1, ENC_BIG_ENDIAN);
2828                                                                 suboptoff+=2;
2829                                                                 if (tag == 1) {
2830                                                                         proto_tree_add_uint_format_value(o82_sub_tree, hf_bootp_option82_vi_cl_docsis_version,
2831                                                                                           tvb, suboptoff, 2, 0, "%d.%d",
2832                                                                                           tvb_get_guint8(tvb, suboptoff), tvb_get_guint8(tvb, suboptoff+1));
2833                                                                         suboptoff+=2;
2834                                                                 } else {
2835                                                                         expert_add_info_format(pinfo, vti, &ei_bootp_option82_vi_cl_tag_unknown, "Unknown tag %d (%d bytes)", tag, tag_len);
2836                                                                         suboptoff += tag_len;
2837                                                                 }
2838                                                         } else {
2839                                                                 suboptoff += vs_len;
2840                                                         }
2841                                                         break;
2842
2843                                                 default:
2844                                                         expert_add_info_format(pinfo, vti, &ei_bootp_suboption_invalid, "Invalid suboption %d (%d bytes)", vs_opt, vs_len);
2845                                                         suboptoff += vs_len;
2846                                                         break;
2847                                                 }
2848                                                 break;
2849                                         default:
2850                                                 proto_tree_add_item(o82_v_tree, hf_bootp_option82_value, tvb, suboptoff, datalen, ENC_NA);
2851                                                 suboptoff += datalen;
2852                                                 break;
2853                                         }
2854                                 }
2855                                 break;
2856                         case 151:
2857                                 if (subopt_len == 1) {
2858                                         proto_tree_add_item(o82_v_tree, hf_bootp_option82_vrf_name_global, tvb, suboptoff, 1, ENC_NA);
2859                                 }
2860                                 else if (subopt_len != 7) {
2861                                         proto_tree_add_item(o82_v_tree, hf_bootp_option82_vrf_name, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
2862                                 } else {
2863                                         proto_tree_add_item(o82_v_tree, hf_bootp_option82_vrf_name_vpn_id_oui, tvb, suboptoff, 3, ENC_BIG_ENDIAN);
2864                                         proto_tree_add_item(o82_v_tree, hf_bootp_option82_vrf_name_vpn_id_index, tvb, suboptoff+3, 4, ENC_BIG_ENDIAN);
2865                                 }
2866                                 break;
2867                         default:
2868                                 if (o82_opt[idx].info.phf != NULL)
2869                                         proto_tree_add_item(o82_v_tree, *o82_opt[idx].info.phf, tvb, suboptoff, subopt_len, ENC_BIG_ENDIAN);
2870                                 else
2871                                         proto_tree_add_item(o82_v_tree, hf_bootp_option82_value, tvb, suboptoff, subopt_len, ENC_NA);
2872                                 break;
2873                         }
2874                 }
2875                 else {
2876                         if (bootp_handle_basic_types(pinfo, o82_v_tree, vti, tvb, o82_opt[idx].info.ftype,
2877                                                      suboptoff, subopt_len, o82_opt[idx].info.phf, &default_hfs) == 0) {
2878                                 expert_add_info_format(pinfo, vti, &hf_bootp_subopt_unknown_type, "ERROR, please report: Unknown subopt type handler %d", subopt);
2879                         }
2880                 }
2881         }
2882
2883         optoff += (subopt_len + 2);
2884         return optoff;
2885 }
2886
2887 static const value_string option43_pxeclient_suboption_vals[] = {
2888         {  0, "Padding" },
2889         {  1, "PXE mtftp IP" },
2890         {  2, "PXE mtftp client port" },
2891         {  3, "PXE mtftp server port" },
2892         {  4, "PXE mtftp timeout" },
2893         {  5, "PXE mtftp delay" },
2894         {  6, "PXE discovery control" },
2895         {  7, "PXE multicast address" },
2896         {  8, "PXE boot servers" },
2897         {  9, "PXE boot menu" },
2898         { 10, "PXE menu prompt" },
2899         { 11, "PXE multicast address alloc", },
2900         { 12, "PXE credential types" },
2901         { 71, "PXE boot item" },
2902         { 255, "PXE End" },
2903         { 0, NULL}
2904 };
2905
2906 static int
2907 dissect_vendor_pxeclient_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
2908                                    tvbuff_t *tvb, int optoff, int optend)
2909 {
2910         int         suboptoff = optoff;
2911         guint8      subopt;
2912         guint8      subopt_len;
2913         proto_tree *o43pxeclient_v_tree;
2914         proto_item *vti, *ti;
2915
2916         struct basic_types_hfs default_hfs = {
2917                 NULL,
2918                 &hf_bootp_option43_value_ip_address,
2919                 &hf_bootp_option43_value_ip_address,
2920                 NULL,
2921                 NULL,
2922                 &hf_bootp_option43_value_8,
2923                 NULL,
2924                 NULL,
2925                 NULL,
2926                 NULL,
2927                 NULL
2928         };
2929
2930         static struct opt_info o43pxeclient_opt[]= {
2931                 /* 0 */ {"nop", special, &hf_bootp_option43_pxeclient_padding}, /* dummy */
2932                 /* 1 */ {"PXE mtftp IP", ipv4_list, &hf_bootp_option43_pxeclient_mtftp_ip},
2933                 /* 2 */ {"PXE mtftp client port", val_u_le_short, &hf_bootp_option43_pxeclient_mtftp_client_port},
2934                 /* 3 */ {"PXE mtftp server port",val_u_le_short, &hf_bootp_option43_pxeclient_mtftp_server_port},
2935                 /* 4 */ {"PXE mtftp timeout", val_u_byte, &hf_bootp_option43_pxeclient_mtftp_timeout},
2936                 /* 5 */ {"PXE mtftp delay", val_u_byte, &hf_bootp_option43_pxeclient_mtftp_delay},
2937                 /* 6 */ {"PXE discovery control", val_u_byte, &hf_bootp_option43_pxeclient_discovery_control},
2938                         /*
2939                          * Correct: b0 (lsb): disable broadcast discovery
2940                          *      b1: disable multicast discovery
2941                          *      b2: only use/accept servers in boot servers
2942                          *      b3: download bootfile without prompt/menu/disc
2943                          */
2944                 /* 7 */ {"PXE multicast address", ipv4_list, &hf_bootp_option43_pxeclient_multicast_address},
2945                 /* 8 */ {"PXE boot servers", special, &hf_bootp_option43_pxeclient_boot_servers},
2946                 /* 9 */ {"PXE boot menu", special, &hf_bootp_option43_pxeclient_boot_menu},
2947                 /* 10 */ {"PXE menu prompt", special, &hf_bootp_option43_pxeclient_menu_prompt},
2948                 /* 11 */ {"PXE multicast address alloc", special, &hf_bootp_option43_pxeclient_multicast_address_alloc},
2949                 /* 12 */ {"PXE credential types", special, &hf_bootp_option43_pxeclient_credential_types}
2950                 /* 71 {"PXE boot item", bytes, &hf_bootp_option43_pxeclient_boot_item}, */
2951                 /* 255 {"PXE end options", special, &hf_bootp_option43_pxeclient_end} */
2952         };
2953
2954         subopt = tvb_get_guint8(tvb, optoff);
2955         suboptoff++;
2956
2957         if (subopt == 0) {
2958                 proto_tree_add_item(v_tree, hf_bootp_option43_pxeclient_padding, tvb, optoff, 1, ENC_BIG_ENDIAN);
2959                 return (suboptoff);
2960         } else if (subopt == 255) {     /* End Option */
2961                 proto_tree_add_item(v_tree, hf_bootp_option43_pxeclient_end, tvb, optoff, 1, ENC_BIG_ENDIAN);
2962                 /* Make sure we skip any junk left this option */
2963                 return (optend);
2964         }
2965
2966         if (suboptoff >= optend) {
2967                 expert_add_info_format(pinfo, v_ti, &ei_bootp_missing_subopt_length,
2968                                                                         "Suboption %d: no room left in option for suboption length", subopt);
2969                 return (optend);
2970         }
2971
2972         subopt_len = tvb_get_guint8(tvb, suboptoff);
2973         vti = proto_tree_add_uint_format_value(v_tree, hf_bootp_option43_pxeclient_suboption,
2974                                 tvb, optoff, subopt_len+2, subopt, "(%d) %s",
2975                                 subopt, val_to_str_const(subopt, option43_pxeclient_suboption_vals, "Unknown"));
2976
2977         o43pxeclient_v_tree = proto_item_add_subtree(vti, ett_bootp_option43_suboption);
2978         proto_tree_add_item(o43pxeclient_v_tree, hf_bootp_suboption_length, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
2979         suboptoff++;
2980
2981         ti = proto_tree_add_item(o43pxeclient_v_tree, hf_bootp_option43_value, tvb, suboptoff, subopt_len, ENC_NA);
2982         PROTO_ITEM_SET_HIDDEN(ti);
2983
2984         if ( subopt == 71 ) {   /* 71 {"PXE boot item", special} */
2985                 /* case special */
2986                 /* I may need to decode that properly one day */
2987                 proto_tree_add_item(o43pxeclient_v_tree, hf_bootp_option43_pxeclient_boot_item, tvb, suboptoff, subopt_len, ENC_NA);
2988         } else if ((subopt < 1) || (subopt >= array_length(o43pxeclient_opt))) {
2989                 expert_add_info_format(pinfo, vti, &ei_bootp_suboption_invalid, "Unknown suboption %d (%d bytes)", subopt, subopt_len);
2990         } else if (o43pxeclient_opt[subopt].ftype == special) {
2991                 /* I may need to decode that properly one day */
2992                 if (o43pxeclient_opt[subopt].phf != NULL)
2993                         proto_tree_add_item(o43pxeclient_v_tree, *o43pxeclient_opt[subopt].phf, tvb, suboptoff, subopt_len, ENC_BIG_ENDIAN);
2994                 else
2995                         proto_tree_add_item(o43pxeclient_v_tree, hf_bootp_option43_value, tvb, suboptoff, subopt_len, ENC_NA);
2996         } else {
2997                 if (bootp_handle_basic_types(pinfo, o43pxeclient_v_tree, vti, tvb, o43pxeclient_opt[subopt].ftype,
2998                                                         suboptoff, subopt_len, o43pxeclient_opt[subopt].phf, &default_hfs) == 0)
2999                 {
3000                         expert_add_info_format(pinfo, vti, &hf_bootp_subopt_unknown_type, "ERROR, please report: Unknown subopt type handler %d", subopt);
3001                 }
3002         }
3003
3004         optoff += (subopt_len + 2);
3005         return optoff;
3006 }
3007
3008 /* RFC3825Decoder: http://www.enum.at/rfc3825encoder.529.0.html */
3009 static void
3010 rfc3825_lci_to_fixpoint(const unsigned char lci[16], struct rfc3825_location_fixpoint_t *fixpoint)
3011 {
3012         fixpoint->latitude_res = (lci[0]>>2) & 0x3F; /* make sure that right-shift does not copy sign bit */
3013         if (lci[0] & 2) { /* LSB<<1 contains the sign of the latitude */
3014                 /* Latitude is negative, expand two's complement */
3015                 fixpoint->latitude = (((gint64)lci[0] & 3)<<32) | ((gint64)lci[1]<<24) |
3016                                            ((gint64)lci[2]<<16) | ((gint64)lci[3]<<8)  |
3017                                             (gint64)lci[4]      | ((gint64)0x3FFFFFFF<<34);
3018
3019         } else {
3020                 /* Latitude is positive */
3021                 fixpoint->latitude = (((gint64)lci[0] & 3)<<32) | ((gint64)lci[1]<<24) |
3022                                            ((gint64)lci[2]<<16) | ((gint64)lci[3]<<8)  |
3023                                             (gint64)lci[4];
3024         }
3025         fixpoint->longitude_res = (lci[5]>>2) & 0x3F;  /* make sure that right-shift does not copy sign bit */
3026         if (lci[5] & 2) { /* LSB<<1 contains the sign of the latitude */
3027                 /* Longitude is negative, expand two's complement */
3028                 fixpoint->longitude = (((gint64)lci[5] & 3)<<32) | ((gint64)lci[6]<<24) |
3029                                             ((gint64)lci[7]<<16) | ((gint64)lci[8]<<8)  |
3030                                              (gint64)lci[9]      | ((gint64)0x3FFFFFFF<<34);
3031
3032         } else {
3033                 /* Longitude is positive */
3034                 fixpoint->longitude = (((gint64)lci[5] & 3)<<32) | ((gint64)lci[6]<<24) |
3035                                             ((gint64)lci[7]<<16) | ((gint64)lci[8]<<8)  |
3036                                              (gint64)lci[9];
3037         }
3038         fixpoint->altitude_type = (lci[10]>>4) & 0x0F;  /* make sure that right-shift does not copy sign bit */
3039         fixpoint->altitude_res  = ((lci[10] & 0x0F) << 2) | ((lci[11]>>6) & 0x03);
3040         if (lci[11] & 0x20) { /* LSB<<1 contains the sign of the latitude */
3041                 /* Altitude is negative, expand two's complement */
3042                 fixpoint->altitude = (((gint32)lci[11] & 0x3F)<<24) | ((gint32)lci[12]<<16) |
3043                                      ((gint32)lci[13]<<8) | ((gint32)lci[14]) |
3044                                       ((gint32)0x03<<30);
3045
3046         } else {
3047                 /* Altitude is positive */
3048                 fixpoint->altitude = (((gint32)lci[11] & 0x3F)<<24) | ((gint32)lci[12]<<16) |
3049                                      ((gint32)lci[13]<<8) | ((gint32)lci[14]);
3050         }
3051
3052         fixpoint->datum_type = lci[15];
3053
3054 }
3055
3056 /* RFC3825Decoder: http://www.enum.at/rfc3825encoder.529.0.html */
3057 static int
3058 rfc3825_fixpoint_to_decimal(struct rfc3825_location_fixpoint_t *fixpoint, struct rfc3825_location_decimal_t *decimal)
3059 {
3060         /* Latitude */
3061         decimal->latitude = (double) fixpoint->latitude / (1 << 25);
3062         if ((decimal->latitude > 90) || (decimal->latitude < -90)) {
3063                 return RFC3825_LATITUDE_OUTOFRANGE;
3064         }
3065
3066         /* Latitude Uncertainty */
3067         if (fixpoint->latitude_res > 34) {
3068                 return RFC3825_LATITUDE_UNCERTAINTY_OUTOFRANGE;
3069         }
3070         if (fixpoint->latitude_res > 8 ) {
3071                 decimal->latitude_res = (double) 1  / (G_GUINT64_CONSTANT(1) << (fixpoint->latitude_res - 8));
3072         } else {
3073                 decimal->latitude_res = (double) (G_GUINT64_CONSTANT(1) << (8 - fixpoint->latitude_res));
3074         }
3075
3076         /* Longitude */
3077         decimal->longitude = (double) fixpoint->longitude / (1 << 25);
3078         if ((decimal->longitude > 180) || (decimal->longitude < -180)) {
3079                 return RFC3825_LONGITUDE_OUTOFRANGE;
3080         }
3081
3082         /* Longitude Uncertainty */
3083         if (fixpoint->longitude_res > 34) {
3084                 return RFC3825_LONGITUDE_UNCERTAINTY_OUTOFRANGE;
3085         }
3086         if (fixpoint->longitude_res > 8 ) {
3087                 decimal->longitude_res = (double) 1 / (G_GUINT64_CONSTANT(1) << (fixpoint->longitude_res - 8));
3088         } else {
3089                 decimal->longitude_res = (double) (G_GUINT64_CONSTANT(1) << (8 - fixpoint->longitude_res));
3090         }
3091
3092         /* Altitude Type */
3093         decimal->altitude_type = fixpoint->altitude_type;
3094         decimal->altitude = 0;
3095         decimal->altitude_res = 0;
3096
3097         if (decimal->altitude_type == 0) { /* Unknown */
3098         } else if (decimal->altitude_type == 1) { /* Meters */
3099                 /* Altitude */
3100                 decimal->altitude = (double) fixpoint->altitude / (1 << 8);
3101                 if ((decimal->altitude > ((gint32) 1<<21)-1) || (decimal->altitude < ((gint32) -(1<<21))))
3102                         return RFC3825_ALTITUDE_OUTOFRANGE;
3103
3104                 /* Altitude Uncertainty */
3105                 if (fixpoint->altitude_res > 30) {
3106                         return RFC3825_ALTITUDE_UNCERTAINTY_OUTOFRANGE;
3107                 }
3108                 if (fixpoint->altitude_res > 21 ) {
3109                         decimal->altitude_res = (double) 1 / (G_GUINT64_CONSTANT(1) << (fixpoint->altitude_res - 21));
3110                 } else {
3111                         decimal->altitude_res = (double) (G_GUINT64_CONSTANT(1) << (21 - fixpoint->altitude_res));
3112                 }
3113         } else if (decimal->altitude_type == 2) { /* Floors */
3114                 /* Altitude */
3115                 if ((fixpoint->altitude_res != 30) && (fixpoint->altitude_res != 0)) {
3116                         return RFC3825_ALTITUDE_UNCERTAINTY_OUTOFRANGE;
3117                 }
3118                 decimal->altitude = (double) fixpoint->altitude / (1 << 8);
3119         } else { /* invalid type */
3120                 return RFC3825_ALTITUDE_TYPE_OUTOFRANGE;
3121         }
3122
3123         /* Datum Type */
3124         decimal->datum_type = 0;
3125         if ((fixpoint->datum_type > 3) || (fixpoint->datum_type < 1)) {
3126                 return RFC3825_DATUM_TYPE_OUTOFRANGE;
3127         }
3128         decimal->datum_type = fixpoint->datum_type;
3129
3130         return RFC3825_NOERROR;
3131 }
3132
3133 static const value_string option43_cl_suboption_vals[] = {
3134         {  0, "Padding" },
3135         {  1, "Suboption Request List" },
3136         {  2, "Device Type" },
3137         {  3, "eSAFE Types" },
3138         {  4, "Serial Number" },
3139         {  5, "Hardware Version" },
3140         {  6, "Software Version" },
3141         {  7, "Boot ROM version" },
3142         {  8, "Organizationally Unique Identifier" },
3143         {  9, "Model Number" },
3144         { 10, "Vendor Name" },
3145         { 11, "Address Realm" },
3146         { 12, "CM/PS System Description" },
3147         { 13, "CM/PS Firmware Revision" },
3148         { 14, "Firewall Policy File Version" },
3149         { 15, "eSafe Config File Devices" },
3150         { 18, "Video Security Type" },
3151         { 31, "MTA MAC Address" },
3152         { 32, "Correlation ID" },
3153         { 51, "Vendor Name" },
3154         { 52, "CableCARD Capability" },
3155         { 53, "Device Identification (CA)" },
3156         { 54, "Device Identification (X.509)" },
3157         { 255, "CL End" },
3158         { 0, NULL}
3159 };
3160
3161 static const value_string cablehome_subopt11_vals[] = {
3162         { 1, "PS WAN-Man" },
3163         { 2, "PS WAN-Data" },
3164         { 0, NULL }
3165 };
3166
3167 static int
3168 dissect_vendor_cablelabs_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
3169                                    tvbuff_t *tvb, int optoff, int optend)
3170 {
3171         int         suboptoff = optoff;
3172         guint8      subopt;
3173         guint8      subopt_len;
3174         proto_tree *o43cl_v_tree;
3175         proto_item *vti;
3176
3177         struct basic_types_hfs default_hfs = {
3178                 &hf_bootp_option43_value,
3179                 NULL,
3180                 NULL,
3181                 &hf_bootp_option43_value_stringz,
3182                 NULL,
3183                 &hf_bootp_option43_value_8,
3184                 NULL,
3185                 NULL,
3186                 &hf_bootp_option43_value_32,
3187                 NULL,
3188                 NULL
3189         };
3190
3191         static struct opt_info o43cablelabs_opt[]= {
3192                 /*  0 */ {"nop", special, &hf_bootp_option43_cl_padding},       /* dummy */
3193                 /*  1 */ {"Suboption Request List", string, &hf_bootp_option43_cl_suboption_request_list},
3194                 /*  2 */ {"Device Type", string, &hf_bootp_option43_cl_device_type},
3195                 /*  3 */ {"eSAFE Types", string, &hf_bootp_option43_cl_esafe_type},
3196                 /*  4 */ {"Serial Number", string, &hf_bootp_option43_cl_serial_number},
3197                 /*  5 */ {"Hardware Version", string, &hf_bootp_option43_cl_hardware_version},
3198                 /*  6 */ {"Software Version", string, &hf_bootp_option43_cl_software_version},
3199                 /*  7 */ {"Boot ROM version", string, &hf_bootp_option43_cl_boot_rom_version},
3200                 /*  8 */ {"Organizationally Unique Identifier", special, &hf_bootp_option43_cl_oui_bytes},
3201                 /*  9 */ {"Model Number", string, &hf_bootp_option43_cl_model_number},
3202                 /* 10 */ {"Vendor Name", string, &hf_bootp_option43_cl_vendor_name10},
3203                 /* *** 11-30: CableHome *** */
3204                 /* 11 */ {"Address Realm", val_u_byte, &hf_bootp_option43_cl_address_realm},
3205                 /* 12 */ {"CM/PS System Description", string, &hf_bootp_option43_cl_cm_ps_system_desc},
3206                 /* 13 */ {"CM/PS Firmware Revision", string, &hf_bootp_option43_cl_cm_ps_firmware_revision},
3207                 /* 14 */ {"Firewall Policy File Version", string, &hf_bootp_option43_cl_firewall_policy_file_version},
3208                 /* 15 */ {"eSafe Config File Devices", string, &hf_bootp_option43_cl_esafe_config_file_devices},
3209                 /* 16 */ {"Unassigned (CableHome)", special, NULL},
3210                 /* 17 */ {"Unassigned (CableHome)", special, NULL},
3211                 /* 18 */ {"Video Security Type", string, &hf_bootp_option43_cl_video_security_tape},
3212                 /* 19 */ {"Unassigned (CableHome)", special, NULL},
3213                 /* 20 */ {"Unassigned (CableHome)", special, NULL},
3214                 /* 21 */ {"Unassigned (CableHome)", special, NULL},
3215                 /* 22 */ {"Unassigned (CableHome)", special, NULL},
3216                 /* 23 */ {"Unassigned (CableHome)", special, NULL},
3217                 /* 24 */ {"Unassigned (CableHome)", special, NULL},
3218                 /* 25 */ {"Unassigned (CableHome)", special, NULL},
3219                 /* 26 */ {"Unassigned (CableHome)", special, NULL},
3220                 /* 27 */ {"Unassigned (CableHome)", special, NULL},
3221                 /* 28 */ {"Unassigned (CableHome)", special, NULL},
3222                 /* 29 */ {"Unassigned (CableHome)", special, NULL},
3223                 /* 30 */ {"Unassigned (CableHome)", special, NULL},
3224                 /* *** 31-50: PacketCable *** */
3225                 /* 31 */ {"MTA MAC Address", special, &hf_bootp_option43_cl_mta_mac_address},
3226                 /* 32 */ {"Correlation ID", val_u_long, &hf_bootp_option43_cl_correlation_ID},
3227                 /* 33 */ {"Unassigned (PacketCable)", special, NULL},
3228                 /* 34 */ {"Unassigned (PacketCable)", special, NULL},
3229                 /* 35 */ {"Unassigned (PacketCable)", special, NULL},
3230                 /* 36 */ {"Unassigned (PacketCable)", special, NULL},
3231                 /* 37 */ {"Unassigned (PacketCable)", special, NULL},
3232                 /* 38 */ {"Unassigned (PacketCable)", special, NULL},
3233                 /* 39 */ {"Unassigned (PacketCable)", special, NULL},
3234                 /* 40 */ {"Unassigned (PacketCable)", special, NULL},
3235                 /* 41 */ {"Unassigned (PacketCable)", special, NULL},
3236                 /* 42 */ {"Unassigned (PacketCable)", special, NULL},
3237                 /* 43 */ {"Unassigned (PacketCable)", special, NULL},
3238                 /* 44 */ {"Unassigned (PacketCable)", special, NULL},
3239                 /* 45 */ {"Unassigned (PacketCable)", special, NULL},
3240                 /* 46 */ {"Unassigned (PacketCable)", special, NULL},
3241                 /* 47 */ {"Unassigned (PacketCable)", special, NULL},
3242                 /* 48 */ {"Unassigned (PacketCable)", special, NULL},
3243                 /* 49 */ {"Unassigned (PacketCable)", special, NULL},
3244                 /* 50 */ {"Unassigned (PacketCable)", special, NULL},
3245                 /* *** 51-127: CableLabs *** */
3246                 /* 51 */ {"Vendor Name", string, &hf_bootp_option43_cl_vendor_name51},
3247                 /* 52 */ {"CableCARD Capability", special, &hf_bootp_option43_cl_cablecard_capability},
3248                 /* 53 */ {"Device Identification (CA)", special, &hf_bootp_option43_cl_device_id_ca},
3249                 /* 54 */ {"Device Identification (X.509)", string, &hf_bootp_option43_cl_device_id_x509},
3250                 /* 55 */ {"Unassigned (CableLabs)", special, NULL},
3251                 /* *** 128-254: Vendors *** */
3252                 /* 128-254 {"Unassigned (Vendors)", special, NULL}, */
3253                 /* 255 {"end options", special, &hf_bootp_option43_cl_end} */
3254         };
3255
3256         subopt = tvb_get_guint8(tvb, optoff);
3257         suboptoff++;
3258
3259         if (subopt == 0) {
3260                 proto_tree_add_item(v_tree, hf_bootp_option43_cl_padding, tvb, optoff, 1, ENC_BIG_ENDIAN);
3261                 return (suboptoff);
3262         } else if (subopt == 255) {     /* End Option */
3263                 proto_tree_add_item(v_tree, hf_bootp_option43_cl_end, tvb, optoff, 1, ENC_BIG_ENDIAN);
3264                 /* Make sure we skip any junk left this option */
3265                 return (optend);
3266         }
3267
3268         if (suboptoff >= optend) {
3269                 expert_add_info_format(pinfo, v_ti, &ei_bootp_missing_subopt_length,
3270                                                                         "Suboption %d: no room left in option for suboption length", subopt);
3271                 return (optend);
3272         }
3273
3274         subopt_len = tvb_get_guint8(tvb, suboptoff);
3275         vti = proto_tree_add_uint_format_value(v_tree, hf_bootp_option43_cl_suboption,
3276                                 tvb, optoff, subopt_len+2, subopt, "(%d) %s",
3277                                 subopt, val_to_str_const(subopt, option43_cl_suboption_vals, "Unknown"));
3278
3279         o43cl_v_tree = proto_item_add_subtree(vti, ett_bootp_option43_suboption);
3280         proto_tree_add_item(o43cl_v_tree, hf_bootp_suboption_length, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
3281         suboptoff++;
3282
3283         if (suboptoff+subopt_len > optend) {
3284                 expert_add_info_format(pinfo, vti, &ei_bootp_missing_subopt_value,
3285                                                 "Suboption %d: no room left in option for suboption value", subopt);
3286                 return (optend);
3287         }
3288
3289         if ( (subopt < 1 ) || (subopt >= array_length(o43cablelabs_opt)) ) {
3290                 proto_tree_add_item(o43cl_v_tree, hf_bootp_option43_value, tvb, suboptoff, subopt_len, ENC_NA);
3291         } else if (o43cablelabs_opt[subopt].ftype == special) {
3292                 switch(subopt)
3293                 {
3294                 case 8:/* OUI */
3295                         /* CableLabs specs treat 43.8 inconsistently
3296                          * as either binary (3b) or string (6b) */
3297                         if (subopt_len == 3) {
3298                                 proto_tree_add_bytes_format_value(o43cl_v_tree, hf_bootp_option43_cl_oui_bytes, tvb, suboptoff, subopt_len, NULL,
3299                                         "%02x:%02x:%02x", tvb_get_guint8(tvb, suboptoff), tvb_get_guint8(tvb, suboptoff+1), tvb_get_guint8(tvb, suboptoff+2));
3300                         } else if (subopt_len == 6) {
3301                                 proto_tree_add_item(o43cl_v_tree, hf_bootp_option43_cl_oui_string, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
3302                         } else {
3303                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't 3 or 6");
3304                         }
3305                         break;
3306                 case 31: /* MTA MAC address */
3307                         if (subopt_len != 6) {
3308                                 expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't 6");
3309                                 break;
3310                         }
3311
3312                         proto_tree_add_item(o43cl_v_tree, hf_bootp_option43_cl_mta_mac_address, tvb, suboptoff, 6, ENC_NA);
3313                         break;
3314                 default:
3315                         if (o43cablelabs_opt[subopt].phf != NULL)
3316                                 proto_tree_add_item(o43cl_v_tree, *o43cablelabs_opt[subopt].phf, tvb, suboptoff, subopt_len, ENC_BIG_ENDIAN);
3317                         else
3318                                 proto_tree_add_item(o43cl_v_tree, hf_bootp_option43_value, tvb, suboptoff, subopt_len, ENC_NA);
3319                 }
3320         }
3321         else {
3322                 if (bootp_handle_basic_types(pinfo, o43cl_v_tree, vti, tvb, o43cablelabs_opt[subopt].ftype,
3323                                                         suboptoff, subopt_len, o43cablelabs_opt[subopt].phf, &default_hfs) == 0) {
3324                         expert_add_info_format(pinfo, vti, &hf_bootp_subopt_unknown_type, "ERROR, please report: Unknown subopt type handler %d", subopt);
3325                 }
3326         }
3327
3328         optoff += (subopt_len + 2);
3329         return optoff;
3330 }
3331
3332
3333 static int
3334 dissect_vendor_generic_suboption(packet_info *pinfo _U_, proto_item *v_ti _U_, proto_tree *v_tree,
3335                                  tvbuff_t *tvb, int optoff, int optend _U_)
3336 {
3337         int         suboptoff = optoff;
3338         guint8      subopt_len;
3339         proto_item *item;
3340         proto_tree *sub_tree;
3341
3342         item = proto_tree_add_item(v_tree, hf_bootp_vendor_unknown_suboption, tvb, optoff, 1, ENC_BIG_ENDIAN);
3343         suboptoff+=1;
3344
3345         sub_tree = proto_item_add_subtree(item, ett_bootp_option125_suboption);
3346         subopt_len = tvb_get_guint8(tvb,suboptoff);
3347         proto_tree_add_item(sub_tree, hf_bootp_suboption_length, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
3348         suboptoff++;
3349         proto_tree_add_item(sub_tree, hf_bootp_suboption_data, tvb, suboptoff, subopt_len, ENC_NA);
3350         suboptoff+= subopt_len;
3351
3352         return suboptoff;
3353
3354 }
3355 static const value_string option43_alcatel_suboption_vals[] = {
3356         {  0, "Padding" },
3357         { 58, "Voice VLAN ID" },
3358         { 64, "Spatial Redundancy TFTP1" },
3359         { 65, "Spatial Redundancy TFTP2" },
3360         { 66, "Application Type" },
3361         { 67, "SIP URL" },
3362         { 255, "Alcatel-Lucent End" },
3363         { 0, NULL}
3364 };
3365
3366 static const value_string option43_alcatel_app_type_vals[] = {
3367         { 0, "NOE" },
3368         { 1, "SIP" },
3369         { 0, NULL}
3370 };
3371
3372 static int
3373 dissect_vendor_alcatel_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
3374                                  tvbuff_t *tvb, int optoff, int optend)
3375 {
3376         int         suboptoff = optoff;
3377         guint8      subopt;
3378         guint8      subopt_len;
3379         proto_item *vti;
3380         proto_tree *o43alcatel_v_tree;
3381
3382         subopt = tvb_get_guint8(tvb, optoff);
3383         suboptoff++;
3384
3385         if (subopt == 0) {
3386                 proto_tree_add_item(v_tree, hf_bootp_option43_alcatel_padding, tvb, optoff, 1, ENC_BIG_ENDIAN);
3387                 return (suboptoff);
3388         } else if (subopt == 255) {     /* End Option */
3389                 proto_tree_add_item(v_tree, hf_bootp_option43_alcatel_end, tvb, optoff, 1, ENC_BIG_ENDIAN);
3390                 /* Make sure we skip any junk left this option */
3391                 return (optend);
3392         }
3393
3394         if (suboptoff >= optend) {
3395                 expert_add_info_format(pinfo, v_ti, &ei_bootp_missing_subopt_length,
3396                                                                         "Suboption %d: no room left in option for suboption length", subopt);
3397                 return (optend);
3398         }
3399
3400         subopt_len = tvb_get_guint8(tvb, suboptoff);
3401         vti = proto_tree_add_uint_format_value(v_tree, hf_bootp_option43_alcatel_suboption,
3402                                 tvb, optoff, subopt_len+2, subopt, "(%d) %s",
3403                                 subopt, val_to_str_const(subopt, option43_alcatel_suboption_vals, "Unknown"));
3404
3405         o43alcatel_v_tree = proto_item_add_subtree(vti, ett_bootp_option43_suboption);
3406         proto_tree_add_item(o43alcatel_v_tree, hf_bootp_suboption_length, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
3407         suboptoff++;
3408
3409         if (suboptoff+subopt_len > optend) {
3410                 expert_add_info_format(pinfo, vti, &ei_bootp_missing_subopt_value,
3411                                                 "Suboption %d: no room left in option for suboption value", subopt);
3412                 return (optend);
3413         }
3414
3415         switch (subopt)
3416         {
3417         case 58: /* 0x3A - Alcatel-Lucent AVA VLAN Id */
3418                 if (subopt_len != 2) {
3419                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't 2");
3420                         return (optend);
3421                 }
3422
3423                 proto_tree_add_item(o43alcatel_v_tree, hf_bootp_option43_alcatel_vlan_id, tvb, suboptoff, 2, ENC_BIG_ENDIAN);
3424                 break;
3425         case 64: /* 0x40 - Alcatel-Lucent TFTP1 */
3426                 if (subopt_len != 4) {
3427                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't 4");
3428                         return (optend);
3429                 }
3430
3431                 proto_tree_add_item(o43alcatel_v_tree, hf_bootp_option43_alcatel_tftp1, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
3432                 break;
3433         case 65: /* 0x41 - Alcatel-Lucent TFTP2 */
3434                 if (subopt_len != 4) {
3435                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't 4");
3436                         return (optend);
3437                 }
3438
3439                 proto_tree_add_item(o43alcatel_v_tree, hf_bootp_option43_alcatel_tftp2, tvb, suboptoff, 4, ENC_BIG_ENDIAN);
3440                 break;
3441         case 66: /* 0x42 - Alcatel-Lucent APPLICATION TYPE */
3442                 if (subopt_len != 1) {
3443                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't 1");
3444                         return (optend);
3445                 }
3446                 proto_tree_add_item(o43alcatel_v_tree, hf_bootp_option43_alcatel_app_type, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
3447                 break;
3448         case 67: /* 0x43 - Alcatel-Lucent SIP URL */
3449                 proto_tree_add_item(o43alcatel_v_tree, hf_bootp_option43_alcatel_sip_url, tvb, suboptoff, subopt_len, ENC_ASCII|ENC_NA);
3450                 break;
3451         default:
3452                 expert_add_info_format(pinfo, vti, &hf_bootp_subopt_unknown_type, "ERROR, please report: Unknown subopt type handler %d", subopt);
3453                 return optend;
3454         }
3455
3456         optoff += (subopt_len + 2);
3457         return optoff;
3458 }
3459
3460 static const value_string option63_suboption_vals[] = {
3461         { 1, "NWIP does not exist on subnet" },
3462         { 2, "NWIP exists in options area" },
3463         { 3, "NWIP exists in sname/file" },
3464         { 4, "NWIP exists, but too big" },
3465         { 5, "Broadcast for nearest Netware server" },
3466         { 6, "Preferred DSS server" },
3467         { 7, "Nearest NWIP server" },
3468         { 8, "Autoretries" },
3469         { 9, "Autoretry delay, secs" },
3470         { 10, "Support NetWare/IP v1.1" },
3471         { 11, "Primary DSS" },
3472         { 0, NULL }
3473 };
3474
3475 static int
3476 dissect_netware_ip_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
3477                              tvbuff_t *tvb, int optoff, int optend)
3478 {
3479         int         suboptoff = optoff;
3480         guint8      subopt, subopt_len;
3481         proto_tree *o63_v_tree;
3482         proto_item *vti, *ti;
3483
3484         struct basic_types_hfs default_hfs = {
3485                 NULL,
3486                 &hf_bootp_option63_value_ip_address,
3487                 &hf_bootp_option63_value_ip_address,
3488                 NULL,
3489                 &hf_bootp_option63_value_boolean,
3490                 &hf_bootp_option63_value_8,
3491                 NULL,
3492                 NULL,
3493                 NULL,
3494                 NULL,
3495                 NULL
3496         };
3497
3498         static struct opt_info o63_opt[]= {
3499                 /* 0 */ {"",none,NULL},
3500                 /* 1 */ {"NWIP does not exist on subnet",presence,NULL},
3501                 /* 2 */ {"NWIP exists in options area",presence,NULL},
3502                 /* 3 */ {"NWIP exists in sname/file",presence,NULL},
3503                 /* 4 */ {"NWIP exists, but too big",presence,NULL},
3504                 /* 5 */ {"Broadcast for nearest Netware server",val_boolean, &hf_bootp_option63_broadcast},
3505                 /* 6 */ {"Preferred DSS server",ipv4_list,&hf_bootp_option63_preferred_dss_server},
3506                 /* 7 */ {"Nearest NWIP server",ipv4_list,&hf_bootp_option63_nearest_nwip_server},
3507                 /* 8 */ {"Autoretries",val_u_byte,&hf_bootp_option63_autoretries},
3508                 /* 9 */ {"Autoretry delay, secs",val_u_byte,&hf_bootp_option63_autoretry_delay},
3509                 /* 10*/ {"Support NetWare/IP v1.1",val_boolean,&hf_bootp_option63_support_netware_v1_1},
3510                 /* 11*/ {"Primary DSS",ipv4,&hf_bootp_option63_primary_dss}
3511         };
3512
3513         subopt = tvb_get_guint8(tvb, optoff);
3514         suboptoff++;
3515
3516         if (suboptoff >= optend) {
3517                 expert_add_info_format(pinfo, v_ti, &ei_bootp_missing_subopt_length,
3518                                                                         "Suboption %d: no room left in option for suboption length", subopt);
3519                 return (optend);
3520         }
3521
3522         subopt_len = tvb_get_guint8(tvb, suboptoff);
3523         vti = proto_tree_add_uint_format_value(v_tree, hf_bootp_option63_suboption,
3524                                 tvb, optoff, subopt_len+2, subopt, "(%d) %s",
3525                                 subopt, val_to_str_const(subopt, option63_suboption_vals, "Unknown"));
3526
3527         o63_v_tree = proto_item_add_subtree(vti, ett_bootp_option63_suboption);
3528         proto_tree_add_item(o63_v_tree, hf_bootp_suboption_length, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
3529         suboptoff++;
3530
3531         ti = proto_tree_add_item(o63_v_tree, hf_bootp_option63_value, tvb, suboptoff, subopt_len, ENC_NA);
3532         PROTO_ITEM_SET_HIDDEN(ti);
3533
3534         if (subopt < array_length(o63_opt)) {
3535                 if (bootp_handle_basic_types(pinfo, o63_v_tree, vti, tvb, o63_opt[subopt].ftype,
3536                                                         suboptoff, subopt_len, o63_opt[subopt].phf, &default_hfs) == 0) {
3537                         switch(o63_opt[subopt].ftype)
3538                         {
3539                         case presence:
3540                                 if (subopt_len != 0) {
3541                                         expert_add_info_format(pinfo, vti, &ei_bootp_bad_length, "length isn't 0");
3542                                 }
3543                                 break;
3544                         default:
3545                                 if (o63_opt[subopt].phf == NULL)
3546                                         proto_tree_add_item(o63_v_tree, hf_bootp_option63_value, tvb, suboptoff, subopt_len, ENC_NA);
3547                                 break;
3548                         }
3549                 }
3550         }
3551         optoff += (subopt_len + 2);
3552         return optoff;
3553 }
3554
3555 static const value_string option125_tr111_suboption_vals[] = {
3556         { 1, "DeviceManufacturerOUI" },
3557         { 2, "DeviceSerialNumber" },
3558         { 3, "DeviceProductClass" },
3559         { 4, "GatewayManufacturerOUI" },
3560         { 5, "GatewaySerialNumber" },
3561         { 6, "GatewayProductClass" },
3562         { 0, NULL }
3563 };
3564
3565 static int
3566 dissect_vendor_tr111_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
3567                                tvbuff_t *tvb, int optoff, int optend)
3568 {
3569         int         suboptoff = optoff;
3570         proto_tree *o125_v_tree;
3571         proto_item *vti, *ti;
3572         guint8      subopt, subopt_len;
3573
3574         struct basic_types_hfs default_hfs = {
3575                 NULL,
3576                 NULL,
3577                 NULL,
3578                 &hf_bootp_option125_value_stringz,
3579                 NULL,
3580                 NULL,
3581                 NULL,
3582                 NULL,
3583                 NULL,
3584                 NULL,
3585                 NULL
3586         };
3587
3588         /* Reference: TR-111 DHCP Option 125 Sub-Option Data Fields
3589            Page 10.
3590         */
3591
3592         static struct opt_info o125_tr111_opt[]= {
3593                 /* 0 */ {"nop", special, NULL}, /* dummy */
3594                 /* 1 */ {"DeviceManufacturerOUI", string, &hf_bootp_option125_tr111_device_manufacturer_oui},
3595                 /* 2 */ {"DeviceSerialNumber", string, &hf_bootp_option125_tr111_device_serial_number},
3596                 /* 3 */ {"DeviceProductClass", string, &hf_bootp_option125_tr111_device_product_class},
3597                 /* 4 */ {"GatewayManufacturerOUI", string, &hf_bootp_option125_tr111_gateway_manufacturer_oui},
3598                 /* 5 */ {"GatewaySerialNumber", string, &hf_bootp_option125_tr111_gateway_serial_number},
3599                 /* 6 */ {"GatewayProductClass", string, &hf_bootp_option125_tr111_gateway_product_class},
3600         };
3601
3602         subopt = tvb_get_guint8(tvb, optoff);
3603         suboptoff++;
3604
3605         if (suboptoff >= optend) {
3606                 expert_add_info_format(pinfo, v_ti, &ei_bootp_missing_subopt_length,
3607                                                                         "Suboption %d: no room left in option for suboption length", subopt);
3608                 return (optend);
3609         }
3610
3611         subopt_len = tvb_get_guint8(tvb, suboptoff);
3612         vti = proto_tree_add_uint_format_value(v_tree, hf_bootp_option125_tr111_suboption,
3613                                 tvb, optoff, subopt_len+2, subopt, "(%d) %s",
3614                                 subopt, val_to_str_const(subopt, option125_tr111_suboption_vals, "Unknown"));
3615
3616         o125_v_tree = proto_item_add_subtree(vti, ett_bootp_option125_tr111_suboption);
3617         proto_tree_add_item(o125_v_tree, hf_bootp_suboption_length, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
3618         suboptoff++;
3619
3620         if (suboptoff+subopt_len > optend) {
3621                 expert_add_info_format(pinfo, vti, &ei_bootp_missing_subopt_value,
3622                                                 "Suboption %d: no room left in option for suboption value", subopt);
3623                 return (optend);
3624         }
3625
3626         ti = proto_tree_add_item(v_tree, hf_bootp_option125_value, tvb, suboptoff, subopt_len, ENC_NA);
3627         PROTO_ITEM_SET_HIDDEN(ti);
3628
3629         if (subopt < array_length(o125_tr111_opt)) {
3630                 if (bootp_handle_basic_types(pinfo, o125_v_tree, vti, tvb, o125_tr111_opt[subopt].ftype,
3631                                                         suboptoff, subopt_len, o125_tr111_opt[subopt].phf, &default_hfs) == 0) {
3632                         if (o125_tr111_opt[subopt].ftype == special) {
3633                                 if (o125_tr111_opt[subopt].phf != NULL)
3634                                    proto_tree_add_item(v_tree, *o125_tr111_opt[subopt].phf, tvb, suboptoff, subopt_len, ENC_BIG_ENDIAN);
3635                                 else
3636                                    proto_tree_add_item(v_tree, hf_bootp_option125_value, tvb, suboptoff, subopt_len, ENC_NA);
3637                         } else if (o125_tr111_opt[subopt].phf == NULL)
3638                                 proto_tree_add_item(v_tree, hf_bootp_option125_value, tvb, suboptoff, subopt_len, ENC_NA);
3639                 }
3640         }
3641
3642         optoff += (subopt_len + 2);
3643         return optoff;
3644 }
3645
3646 static const value_string option125_cl_suboption_vals[] = {
3647         { 1, "Option Request" },
3648         { 2, "TFTP Server Addresses" },
3649         { 3, "eRouter Container Option" },
3650         { 4, "MIB Environment Indicator Option" },
3651         { 5, "Modem Capabilities" },
3652         { 0, NULL }
3653 };
3654
3655 static const value_string pkt_mib_env_ind_opt_vals[] = {
3656         { 0x00, "Reserved" },
3657         { 0x01, "CableLabs" },
3658         { 0x02, "IETF" },
3659         { 0x03, "EuroCableLabs" },
3660         { 0, NULL }
3661 };
3662
3663 static int
3664 dissect_vendor_cl_suboption(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
3665                             tvbuff_t *tvb, int optoff, int optend)
3666 {
3667         int         suboptoff = optoff;
3668         guint8      subopt, subopt_len;
3669         proto_tree *o125_v_tree;
3670         proto_item *vti;
3671
3672         struct basic_types_hfs default_hfs = {
3673                 &hf_bootp_option125_value,
3674                 &hf_bootp_option125_value_ip_address,
3675                 &hf_bootp_option125_value_ip_address,
3676                 &hf_bootp_option125_value_stringz,
3677                 NULL,
3678                 &hf_bootp_option125_value_8,
3679                 &hf_bootp_option125_value_16,
3680                 NULL,
3681                 NULL,
3682                 NULL,
3683                 NULL
3684         };
3685
3686         static struct opt_info o125_cl_opt[]= {
3687                 /* 0 */ {"nop", special, NULL}, /* dummy */
3688                 /* 1 */ {"Option Request = ", val_u_byte, &hf_bootp_option125_cl_option_request},
3689                 /* 2 */ {"TFTP Server Addresses : ", ipv4_list, &hf_bootp_option125_cl_tftp_server_addresses},
3690                 /* 3 */ {"eRouter Container Option : ", bytes, &hf_bootp_option125_cl_erouter_container_option},
3691                 /* 4 */ {"MIB Environment Indicator Option = ", val_u_byte, &hf_bootp_option125_cl_mib_environment_indicator_option},
3692                 /* 5 */ {"Modem Capabilities : ", special, &hf_bootp_option125_cl_modem_capabilities},
3693         };
3694
3695         subopt = tvb_get_guint8(tvb, optoff);
3696         suboptoff++;
3697
3698         if (suboptoff >= optend) {
3699                 expert_add_info_format(pinfo, v_ti, &ei_bootp_missing_subopt_length,
3700                                                                         "Suboption %d: no room left in option for suboption length", subopt);
3701                 return (optend);
3702         }
3703
3704         subopt_len = tvb_get_guint8(tvb, suboptoff);
3705         vti = proto_tree_add_uint_format_value(v_tree, hf_bootp_option125_cl_suboption,
3706                                 tvb, optoff, subopt_len+2, subopt, "(%d) %s",
3707                                 subopt, val_to_str_const(subopt, option125_cl_suboption_vals, "Unknown"));
3708
3709         o125_v_tree = proto_item_add_subtree(vti, ett_bootp_option125_cl_suboption);
3710         proto_tree_add_item(o125_v_tree, hf_bootp_suboption_length, tvb, suboptoff, 1, ENC_BIG_ENDIAN);
3711         suboptoff++;
3712
3713         if (suboptoff+subopt_len > optend) {
3714                 expert_add_info_format(pinfo, vti, &ei_bootp_missing_subopt_value,
3715                                                 "Suboption %d: no room left in option for suboption value", subopt);
3716                 return (optend);
3717         }
3718
3719         if (subopt < array_length(o125_cl_opt)) {
3720                 if (bootp_handle_basic_types(pinfo, o125_v_tree, vti, tvb, o125_cl_opt[subopt].ftype,
3721                                                         suboptoff, subopt_len, o125_cl_opt[subopt].phf, &default_hfs) == 0) {
3722
3723                         switch(o125_cl_opt[subopt].ftype) {
3724                         case special:
3725                                 if (o125_cl_opt[subopt].phf != NULL)
3726                                    proto_tree_add_item(o125_v_tree, *o125_cl_opt[subopt].phf, tvb, suboptoff, subopt_len, ENC_BIG_ENDIAN);
3727                                 else
3728                                    proto_tree_add_item(o125_v_tree, hf_bootp_option125_value, tvb, suboptoff, subopt_len, ENC_NA);
3729
3730                                         dissect_docsis_cm_cap(o125_v_tree, tvb, optoff, subopt_len+2, TRUE);
3731                                 break;
3732                         default:
3733                                 if (o125_cl_opt[subopt].phf == NULL)
3734                                    proto_tree_add_item(o125_v_tree, hf_bootp_option125_value, tvb, suboptoff, subopt_len, ENC_NA);
3735                                 break;
3736                         }
3737                 }
3738         }
3739
3740         optoff += (subopt_len + 2);
3741         return optoff;
3742 }
3743
3744 /* PacketCable Multimedia Terminal Adapter device capabilities (option 60).
3745    Ref: PKT-SP-I05-021127 sections 8.2 and 10 */
3746
3747 #define PKT_MDC_TLV_OFF 10
3748
3749
3750 /* These are ASCII-encoded hexadecimal digits.  We use the raw hex equivalent for
3751    convenience. */
3752 #define PKT_MDC_VERSION                 0x3031  /* "01" */
3753 #define PKT_MDC_TEL_END                 0x3032  /* "02" */
3754 #define PKT_MDC_TGT                     0x3033  /* "03" */
3755 #define PKT_MDC_HTTP_ACC                0x3034  /* "04" */
3756 #define PKT_MDC_SYSLOG                  0x3035  /* "05" */
3757 #define PKT_MDC_NCS                     0x3036  /* "06" */
3758 #define PKT_MDC_PRI_LINE                0x3037  /* "07" */
3759 #define PKT_MDC_VENDOR_TLV              0x3038  /* "08" */
3760 #define PKT_MDC_NVRAM_STOR              0x3039  /* "09" */
3761 #define PKT_MDC_PROV_REP                0x3041  /* "0A" */
3762 #define PKT_MDC_PROV_REP_LC             0x3061  /* "0a" */
3763 #define PKT_MDC_SUPP_CODECS             0x3042  /* "0B" */
3764 #define PKT_MDC_SUPP_CODECS_LC          0x3062  /* "0b" */
3765 #define PKT_MDC_SILENCE                 0x3043  /* "0C" */
3766 #define PKT_MDC_SILENCE_LC              0x3063  /* "0c" */
3767 #define PKT_MDC_ECHO_CANCEL             0x3044  /* "0D" */
3768 #define PKT_MDC_ECHO_CANCEL_LC          0x3064  /* "0d" */
3769 #define PKT_MDC_RSVP                    0x3045  /* "0E" */
3770 #define PKT_MDC_RSVP_LC                 0x3065  /* "0e" */
3771 #define PKT_MDC_UGS_AD                  0x3046  /* "0F" */
3772 #define PKT_MDC_UGS_AD_LC               0x3066  /* "0f" */
3773 #define PKT_MDC_IF_INDEX                0x3130  /* "10" */
3774 #define PKT_MDC_FLOW_LOG                0x3131  /* "11" */
3775 #define PKT_MDC_PROV_FLOWS              0x3132  /* "12" */
3776 /* PacketCable 1.5: */
3777 #define PKT_MDC_T38_VERSION             0x3133  /* "13" */
3778 #define PKT_MDC_T38_EC                  0x3134  /* "14" */
3779 #define PKT_MDC_RFC2833_DTMF            0x3135  /* "15" */
3780 #define PKT_MDC_VOICE_METRICS           0x3136  /* "16" */
3781 #define PKT_MDC_MIBS                    0x3137  /* "17" */
3782 #define PKT_MDC_MGPI                    0x3138  /* "18" */
3783 #define PKT_MDC_V152                    0x3139  /* "19" */
3784 #define PKT_MDC_CBS                     0x3141  /* "1A" */
3785 #define PKT_MDC_CBS_LC                  0x3161  /* "1a" */
3786
3787 static const value_string pkt_mdc_type_vals[] = {
3788         { PKT_MDC_VERSION,              "PacketCable Version" },
3789         { PKT_MDC_TEL_END,              "Number Of Telephony Endpoints" },
3790         { PKT_MDC_TGT,                  "TGT Support" },
3791         { PKT_MDC_HTTP_ACC,             "HTTP Download File Access Method Support" },
3792         { PKT_MDC_SYSLOG,               "MTA-24 Event SYSLOG Notification Support" },
3793         { PKT_MDC_NCS,                  "NCS Service Flow Support" },
3794         { PKT_MDC_PRI_LINE,             "Primary Line Support" },
3795         { PKT_MDC_VENDOR_TLV,           "Vendor Specific TLV Type(s)" },
3796         { PKT_MDC_NVRAM_STOR,           "NVRAM Ticket/Session Keys Storage Support" },
3797         { PKT_MDC_PROV_REP,             "Provisioning Event Reporting Support" },
3798         { PKT_MDC_PROV_REP_LC,          "Provisioning Event Reporting Support" },
3799         { PKT_MDC_SUPP_CODECS,          "Supported CODEC(s)" },
3800         { PKT_MDC_SUPP_CODECS_LC,       "Supported CODEC(s)" },
3801         { PKT_MDC_SILENCE,              "Silence Suppression Support" },
3802         { PKT_MDC_SILENCE_LC,           "Silence Suppression Support" },
3803         { PKT_MDC_ECHO_CANCEL,          "Echo Cancellation Support" },
3804         { PKT_MDC_ECHO_CANCEL_LC,       "Echo Cancellation Support" },
3805         { PKT_MDC_RSVP,                 "RSVP Support/ Reserved" },
3806         { PKT_MDC_RSVP_LC,              "RSVP Support/ Reserved" },
3807         { PKT_MDC_UGS_AD,               "UGS-AD Support" },
3808         { PKT_MDC_UGS_AD_LC,            "UGS-AD Support" },
3809         { PKT_MDC_IF_INDEX,             "MTA's \"ifIndex\" starting number in \"ifTable\"" },
3810         { PKT_MDC_FLOW_LOG,             "Provisioning Flow Logging Support" },
3811         { PKT_MDC_PROV_FLOWS,           "Supported Provisioning Flows" },
3812         /* PacketCable 1.5: */
3813         { PKT_MDC_T38_VERSION,          "T38 Version Support" },
3814         { PKT_MDC_T38_EC,               "T38 Error Correction Support" },
3815         { PKT_MDC_RFC2833_DTMF,         "RFC 2833 DTMF Support" },
3816         { PKT_MDC_VOICE_METRICS,        "Voice Metrics Support" },
3817         { PKT_MDC_MIBS,                 "MIB Support" },
3818         { PKT_MDC_MGPI,                 "Multiple Grants Per Interval Support" },
3819         { PKT_MDC_V152,                 "V.152 Support" },
3820         /* PacketCable 2.0: */
3821         { PKT_MDC_CBS,                  "Certificate Bootstrapping Support" },
3822         { PKT_MDC_CBS_LC,               "Certificate Bootstrapping Support" },
3823         { 0,                            NULL }
3824 };
3825
3826 static const value_string pkt_mdc_version_vals[] = {
3827         { 0x3030,       "PacketCable 1.0" },
3828         { 0x3031,       "PacketCable 1.1/1.5" }, /* 1.5 replaces 1.1-1.3 */
3829         { 0x3032,       "PacketCable 2.0" },
3830         { 0,            NULL }
3831 };
3832
3833 static const value_string pkt_mdc_boolean_vals[] = {
3834         { 0x3030,       "No" },
3835         { 0x3031,       "Yes" },
3836         { 0,            NULL }
3837 };
3838
3839 static const value_string pkt_mdc_codec_vals[] = {
3840         { 0x3031,       "other" },           /* "01" */
3841         { 0x3032,       "unknown" },
3842         { 0x3033,       "G.729" },
3843         { 0x3034,       "reserved" },
3844         { 0x3035,       "G.729E" },
3845         { 0x3036,       "PCMU" },
3846         { 0x3037,       "G.726-32" },
3847         { 0x3038,       "G.728" },
3848         { 0x3039,       "PCMA" },            /* "09" */
3849         { 0x3041,       "G.726-16" },        /* "0A" */
3850         { 0x3042,       "G.726-24" },
3851         { 0x3043,       "G.726-40" },
3852         { 0x3044,       "iLBC" },
3853         { 0x3045,       "BV16" },
3854         { 0x3046,       "telephone-event" }, /* "0F" */
3855         { 0,            NULL }
3856 };
3857
3858 static const value_string pkt_mdc_t38_version_vals[] = {
3859         { 0x3030,       "Unsupported" },
3860         { 0x3031,       "T.38 Version Zero" }, /* default */
3861         { 0x3032,       "T.38 Version One" },
3862         { 0x3033,       "T.38 Version Two" },
3863         { 0x3035,       "T.38 Version Three" },
3864         { 0,            NULL }
3865 };
3866
3867 static const value_string pkt_mdc_t38_ec_vals[] = {
3868         { 0x3030,       "None" },
3869         { 0x3031,       "Redundancy" }, /* default */
3870         { 0x3032,       "FEC" },
3871         { 0,            NULL }
3872 };
3873
3874 static const value_string pkt_mdc_mib_orgs[] = {
3875         { 0x3030,       "CableLabs" },
3876         { 0x3031,       "IETF" },
3877         { 0x3032,       "EuroCableLabs" },
3878         { 0x3033,       "Reserved" },
3879         { 0x3034,       "Reserved" },
3880         { 0x3035,       "Reserved" },
3881         { 0x3036,       "Reserved" },
3882         { 0x3037,       "Reserved" },
3883         { 0x3038,       "Reserved" },
3884         { 0x3039,       "Reserved" },
3885         { 0,            NULL }
3886 };
3887
3888 static const value_string pkt_mdc_supp_flow_vals[] = {
3889         { 1 << 0, "Secure Flow (Full Secure Provisioning Flow)" },
3890         { 1 << 1, "Hybrid Flow" },
3891         { 1 << 2, "Basic Flow" },
3892         { 0, NULL }
3893 };
3894
3895 #define PKT_MDC_MIB_CL 0x3030
3896 static const value_string pkt_mdc_cl_mib_vals[] = {
3897         { 1 << 0, "PacketCable 1.5 MTA MIB" },
3898         { 1 << 1, "PacketCable 1.5 Signaling MIB" },
3899         { 1 << 2, "PacketCable 1.5 Management Event MIB" },
3900         { 1 << 3, "PacketCable 1.5 MTA Extension MIB" },
3901         { 1 << 4, "PacketCable 1.5 Signaling Extension MIB" },
3902         { 1 << 5, "PacketCable 1.5 MEM Extension MIB" },
3903         { 1 << 6, "Reserved" },
3904         { 1 << 7, "Reserved" },
3905         { 0, NULL }
3906 };
3907
3908 #define PKT_MDC_MIB_IETF 0x3031
3909 static const value_string pkt_mdc_ietf_mib_vals[] = {
3910         { 1 << 0, "IETF MTA MIB" },
3911         { 1 << 1, "IETF Signaling MIB" },
3912         { 1 << 2, "IETF Management Event MIB" },
3913         { 1 << 3, "Reserved" },
3914         { 1 << 4, "Reserved" },
3915         { 1 << 5, "Reserved" },
3916         { 1 << 6, "Reserved" },
3917         { 1 << 7, "Reserved" },
3918         { 0, NULL }
3919 };
3920
3921 #define PKT_MDC_MIB_EURO 0x3032
3922 static const value_string pkt_mdc_euro_mib_vals[] = {
3923         { 1 << 0, "PacketCable 1.5 MTA MIB" },
3924         { 1 << 1, "PacketCable 1.5 Signaling MIB" },
3925         { 1 << 2, "PacketCable 1.5 Management Event MIB" },
3926         { 1 << 3, "PacketCable 1.5 MTA Extension MIB" },
3927         { 1 << 4, "PacketCable 1.5 Signaling Extension MIB" },
3928         { 1 << 5, "PacketCable 1.5 MEM Extension MIB" },
3929         { 1 << 6, "Reserved" },
3930         { 1 << 7, "Reserved" },
3931         { 0, NULL }
3932 };
3933
3934
3935 static void
3936 dissect_packetcable_mta_cap(proto_tree *v_tree, tvbuff_t *tvb, int voff, int len)
3937 {
3938         guint16        raw_val;
3939         unsigned long  flow_val   = 0;
3940         int            off        = PKT_MDC_TLV_OFF + voff;
3941         int            subopt_off, max_len;
3942         guint          tlv_len, i, mib_val;
3943         guint8         asc_val[3] = "  ", flow_val_str[5];
3944         char           bit_fld[64];
3945         proto_item    *ti, *mib_ti;
3946         proto_tree    *subtree, *subtree2;
3947
3948         tvb_memcpy (tvb, asc_val, off, 2);
3949         if (sscanf((gchar*)asc_val, "%x", &tlv_len) != 1 || tlv_len > 0xff) {
3950                 proto_tree_add_text(v_tree, tvb, off, len - off,
3951                         "Bogus length: %s", asc_val);
3952                 return;
3953         } else {
3954                 proto_tree_add_uint_format_value(v_tree, hf_bootp_pkt_mta_cap_len, tvb, off, 2,
3955                                 tlv_len, "%d", tlv_len);
3956                 off += 2;
3957
3958                 while (off - voff < len) {
3959                         /* Type */
3960                         raw_val = tvb_get_ntohs (tvb, off);
3961
3962                         /* Length */
3963                         tvb_memcpy(tvb, asc_val, off + 2, 2);
3964                         if (sscanf((gchar*)asc_val, "%x", &tlv_len) != 1
3965                             || tlv_len < 1 || tlv_len > G_MAXUINT16) {
3966                                 proto_tree_add_text(v_tree, tvb, off, len - off,
3967                                                     "[Bogus length: %s]", asc_val);
3968                                 return;
3969                         } else {
3970                                 /* Value(s) */
3971
3972                                 ti = proto_tree_add_text(v_tree,
3973                                     tvb, off, (tlv_len * 2) + 4,
3974                                     "0x%s: %s = ",
3975                                     tvb_format_text(tvb, off, 2),
3976                                     val_to_str_const(raw_val, pkt_mdc_type_vals, "unknown"));
3977                                 switch (raw_val) {
3978
3979                                 case PKT_MDC_VERSION:
3980                                         raw_val = tvb_get_ntohs(tvb, off + 4);
3981                                         proto_item_append_text(ti,
3982                                                                "%s (%s)",
3983                                                                val_to_str_const(raw_val, pkt_mdc_version_vals, "Reserved"),
3984                                                                tvb_format_stringzpad(tvb, off + 4, 2) );
3985                                         break;
3986
3987                                 case PKT_MDC_TEL_END:
3988                                 case PKT_MDC_IF_INDEX:
3989                                         proto_item_append_text(ti,
3990                                                                "%s",
3991                                                                tvb_format_stringzpad(tvb, off + 4, 2) );
3992                                         break;
3993
3994                                 case PKT_MDC_TGT:
3995                                 case PKT_MDC_HTTP_ACC:
3996                                 case PKT_MDC_SYSLOG:
3997                                 case PKT_MDC_NCS:
3998                                 case PKT_MDC_PRI_LINE:
3999                                 case PKT_MDC_NVRAM_STOR:
4000                                 case PKT_MDC_PROV_REP:
4001                                 case PKT_MDC_PROV_REP_LC:
4002                                 case PKT_MDC_SILENCE:
4003                                 case PKT_MDC_SILENCE_LC:
4004                                 case PKT_MDC_ECHO_CANCEL:
4005                                 case PKT_MDC_ECHO_CANCEL_LC:
4006                                 case PKT_MDC_RSVP:
4007                                 case PKT_MDC_RSVP_LC:
4008                                 case PKT_MDC_UGS_AD:
4009                                 case PKT_MDC_UGS_AD_LC:
4010                                 case PKT_MDC_FLOW_LOG:
4011                                 case PKT_MDC_RFC2833_DTMF:
4012                                 case PKT_MDC_VOICE_METRICS:
4013                                 case PKT_MDC_MGPI:
4014                                 case PKT_MDC_V152:
4015                                 case PKT_MDC_CBS:
4016                                 case PKT_MDC_CBS_LC:
4017                                         raw_val = tvb_get_ntohs(tvb, off + 4);
4018                                         proto_item_append_text(ti,
4019                                                                "%s (%s)",
4020                                                                val_to_str_const(raw_val, pkt_mdc_boolean_vals, "unknown"),
4021                                                                tvb_format_stringzpad(tvb, off + 4, 2) );
4022                                         break;
4023
4024                                 case PKT_MDC_SUPP_CODECS:
4025                                 case PKT_MDC_SUPP_CODECS_LC:
4026                                         for (i = 0; i < tlv_len; i++) {
4027                                                 raw_val = tvb_get_ntohs(tvb, off + 4 + (i * 2) );
4028                                                 proto_item_append_text(ti,
4029                                                                        "%s%s (%s)",
4030                                                                        plurality(i + 1, "", ", "),
4031                                                                        val_to_str_const(raw_val, pkt_mdc_codec_vals, "unknown"),
4032                                                                        tvb_format_stringzpad(tvb, off + 4 + (i * 2), 2) );
4033                                         }
4034                                         break;
4035
4036                                 case PKT_MDC_PROV_FLOWS:
4037                                         tvb_memcpy(tvb, flow_val_str, off + 4, 4);
4038                                         flow_val_str[4] = '\0';
4039                                         flow_val = strtoul((gchar*)flow_val_str, NULL, 16);
4040                                         proto_item_append_text(ti,
4041                                                                "0x%04lx", flow_val);
4042                                         break;
4043
4044                                 case PKT_MDC_T38_VERSION:
4045                                         raw_val = tvb_get_ntohs(tvb, off + 4);
4046                                         proto_item_append_text(ti,
4047                                                                "%s (%s)",
4048                                                                val_to_str_const(raw_val, pkt_mdc_t38_version_vals, "unknown"),
4049                                                                tvb_format_stringzpad(tvb, off + 4, 2) );
4050                                         break;
4051
4052                                 case PKT_MDC_T38_EC:
4053                                         raw_val = tvb_get_ntohs(tvb, off + 4);
4054                                         proto_item_append_text(ti,
4055                                                                "%s (%s)",
4056                                                                val_to_str_const(raw_val, pkt_mdc_t38_ec_vals, "unknown"),
4057                                                                tvb_format_stringzpad(tvb, off + 4, 2) );
4058                                         break;
4059
4060                                 case PKT_MDC_MIBS:
4061                                         break;
4062
4063                                 case PKT_MDC_VENDOR_TLV:
4064                                 default:
4065                                         proto_item_append_text(ti,
4066                                                                "%s",
4067                                                                tvb_format_stringzpad(tvb, off + 4, tlv_len * 2) );
4068                                         break;
4069                                 }
4070                         }
4071                         subtree = proto_item_add_subtree(ti, ett_bootp_option);
4072                         if (raw_val == PKT_MDC_PROV_FLOWS) {
4073                                 for (i = 0 ; i < 3; i++) {
4074                                         if (flow_val & pkt_mdc_supp_flow_vals[i].value) {
4075                                                 decode_bitfield_value(bit_fld, (guint32)flow_val, pkt_mdc_supp_flow_vals[i].value, 16);
4076                                                 proto_tree_add_text(subtree, tvb, off + 4, 4, "%s%s",
4077                                                         bit_fld, pkt_mdc_supp_flow_vals[i].strptr);
4078                                         }
4079                                 }
4080                         } else if (raw_val == PKT_MDC_MIBS) {
4081                         /* 17 06 02 00 38 02 01 07 */
4082                                 subopt_off = off + 4;
4083                                 max_len = subopt_off + (tlv_len * 2);
4084                                 while (subopt_off < max_len) {
4085                                         raw_val = tvb_get_ntohs(tvb, subopt_off);
4086                                         if (raw_val != 0x3032) { /* We only know how to handle a length of 2 */
4087                                                 tvb_memcpy(tvb, asc_val, subopt_off, 2);
4088                                                 proto_tree_add_text(subtree, tvb, subopt_off, 2,
4089                                                                         "[Bogus length: %s]", asc_val);
4090                                                 return;
4091                                         }
4092
4093                                         subopt_off += 2;
4094                                         raw_val = tvb_get_ntohs(tvb, subopt_off);
4095                                         tvb_memcpy(tvb, asc_val, subopt_off, 2);
4096
4097                                         mib_ti = proto_tree_add_text(subtree, tvb, subopt_off, 2, "%s (%s)",
4098                                                 val_to_str_const(raw_val, pkt_mdc_mib_orgs, "Unknown"), asc_val);
4099                                         if (subopt_off > off + 4 + 2) {
4100                                                 proto_item_append_text(ti, ", ");
4101                                         }
4102                                         proto_item_append_text(ti, "%s", val_to_str_const(raw_val, pkt_mdc_mib_orgs, "Unknown"));
4103
4104                                         subopt_off += 2;
4105                                         tvb_memcpy(tvb, asc_val, subopt_off, 2);
4106                                         if (sscanf((gchar*)asc_val, "%x", &mib_val) != 1) {
4107                                                 proto_tree_add_text(v_tree, tvb, subopt_off, 2,
4108                                                                         "[Bogus bitfield: %s]", asc_val);
4109                                                 return;
4110                                         }
4111                                         switch (raw_val) {
4112
4113                                         case PKT_MDC_MIB_CL:
4114                                                 subtree2 = proto_item_add_subtree(mib_ti, ett_bootp_option);
4115
4116                                                 for (i = 0; i < 8; i++) {
4117                                                         if (mib_val & pkt_mdc_cl_mib_vals[i].value) {
4118                                                                 decode_bitfield_value(bit_fld, mib_val, pkt_mdc_cl_mib_vals[i].value, 8);
4119                                                                 proto_tree_add_text(subtree2, tvb, subopt_off, 2,
4120                                                                                     "%s%s", bit_fld, pkt_mdc_cl_mib_vals[i].strptr);
4121                                                         }
4122                                                 }
4123                                                 break;
4124
4125                                         case PKT_MDC_MIB_IETF:
4126                                                 subtree2 = proto_item_add_subtree(mib_ti, ett_bootp_option);
4127
4128                                                 for (i = 0; i < 8; i++) {
4129                                                         if (mib_val & pkt_mdc_ietf_mib_vals[i].value) {
4130                                                                 decode_bitfield_value(bit_fld, mib_val, pkt_mdc_ietf_mib_vals[i].value, 8);
4131                                                                 proto_tree_add_text(subtree2, tvb, subopt_off, 2,
4132                                                                                     "%s%s", bit_fld, pkt_mdc_ietf_mib_vals[i].strptr);
4133                                                         }
4134                                                 }
4135                                                 break;
4136
4137                                         case PKT_MDC_MIB_EURO:
4138                                                 subtree2 = proto_item_add_subtree(mib_ti, ett_bootp_option);
4139
4140                                                 for (i = 0; i < 8; i++) {
4141                                                         if (mib_val & pkt_mdc_euro_mib_vals[i].value) {
4142                                                                 decode_bitfield_value(bit_fld, mib_val, pkt_mdc_euro_mib_vals[i].value, 8);
4143                                                                 proto_tree_add_text(subtree2, tvb, subopt_off, 2,
4144                                                                                     "%s%s", bit_fld, pkt_mdc_euro_mib_vals[i].strptr);
4145                                                         }
4146                                                 }
4147                                                 break;
4148
4149                                         default:
4150                                                 break;
4151                                         }
4152                                         subopt_off += 2;
4153                                 }
4154
4155                         }
4156                         off += (tlv_len * 2) + 4;
4157                 }
4158         }
4159 }
4160
4161 /* DOCSIS Cable Modem device capabilities (option 60/option 125). */
4162 #define DOCSIS_CM_CAP_TLV_OFF 12
4163
4164 #define DOCSIS_CM_CAP_CONCAT_SUP        0x01
4165 #define DOCSIS_CM_CAP_DOCSIS_VER        0x02
4166 #define DOCSIS_CM_CAP_FRAG_SUP          0x03
4167 #define DOCSIS_CM_CAP_PHS_SUP           0x04
4168 #define DOCSIS_CM_CAP_IGMP_SUP          0x05
4169 #define DOCSIS_CM_CAP_PRIV_SUP          0x06
4170 #define DOCSIS_CM_CAP_DSAID_SUP         0x07
4171 #define DOCSIS_CM_CAP_USSF_SUP          0x08
4172 #define DOCSIS_CM_CAP_FILT_SUP          0x09
4173 #define DOCSIS_CM_CAP_TET_MI            0x0a
4174 #define DOCSIS_CM_CAP_TET               0x0b
4175 #define DOCSIS_CM_CAP_DCC_SUP           0x0c
4176 #define DOCSIS_CM_CAP_IPFILT_SUP        0x0d
4177 #define DOCSIS_CM_CAP_LLCFILT_SUP       0x0e
4178 #define DOCSIS_CM_CAP_EXPUNI_SPACE      0x0f
4179 #define DOCSIS_CM_CAP_RNGHLDOFF_SUP     0x10
4180 #define DOCSIS_CM_CAP_L2VPN_SUP         0x11
4181 #define DOCSIS_CM_CAP_L2VPN_HOST_SUP    0x12
4182 #define DOCSIS_CM_CAP_DUTFILT_SUP       0x13
4183 #define DOCSIS_CM_CAP_USFREQRNG_SUP     0x14
4184 #define DOCSIS_CM_CAP_USSYMRATE_SUP     0x15
4185 #define DOCSIS_CM_CAP_SACM2_SUP         0x16
4186 #define DOCSIS_CM_CAP_SACM2HOP_SUP      0x17
4187 #define DOCSIS_CM_CAP_MULTTXCHAN_SUP    0x18
4188 #define DOCSIS_CM_CAP_512USTXCHAN_SUP   0x19
4189 #define DOCSIS_CM_CAP_256USTXCHAN_SUP   0x1a
4190 #define DOCSIS_CM_CAP_TOTALSIDCLU_SUP   0x1b
4191 #define DOCSIS_CM_CAP_SIDCLUPERSF_SUP   0x1c
4192 #define DOCSIS_CM_CAP_MULTRXCHAN_SUP    0x1d
4193 #define DOCSIS_CM_CAP_TOTALDSID_SUP     0x1e
4194 #define DOCSIS_CM_CAP_RESEQDSID_SUP     0x1f
4195 #define DOCSIS_CM_CAP_MULTDSID_SUP      0x20
4196 #define DOCSIS_CM_CAP_MULTDSIDFW_SUP    0x21
4197 #define DOCSIS_CM_CAP_FCTF_SUP          0x22
4198 #define DOCSIS_CM_CAP_DPV_SUP           0x23
4199 #define DOCSIS_CM_CAP_UGSPERUSFLOW_SUP  0x24
4200 #define DOCSIS_CM_CAP_MAPUCDRECEIPT_SUP 0x25
4201 #define DOCSIS_CM_CAP_USDROPCLASSIF_SUP 0x26
4202 #define DOCSIS_CM_CAP_IPV6_SUP          0x27
4203 #define DOCSIS_CM_CAP_ExUsTrPow         0x28
4204 #define DOCSIS_CM_CAP_Opt802MPLSSup             0x29
4205 #define DOCSIS_CM_CAP_DounEnc           0x2a
4206 #define DOCSIS_CM_CAP_EnrgMang          0x2c
4207
4208 static const value_string docsis_cm_cap_type_vals[] = {
4209         { DOCSIS_CM_CAP_CONCAT_SUP,             "Concatenation Support" },
4210         { DOCSIS_CM_CAP_DOCSIS_VER,             "DOCSIS Version" },
4211         { DOCSIS_CM_CAP_FRAG_SUP,               "Fragmentation Support" },
4212         { DOCSIS_CM_CAP_PHS_SUP,                "Payload Header Suppression Support" },
4213         { DOCSIS_CM_CAP_IGMP_SUP,               "IGMP Support" },
4214         { DOCSIS_CM_CAP_PRIV_SUP,               "Privacy Support" },
4215         { DOCSIS_CM_CAP_DSAID_SUP,              "Downstream SAID Support" },
4216         { DOCSIS_CM_CAP_USSF_SUP,               "Upstream Service Flow Support" },
4217         { DOCSIS_CM_CAP_FILT_SUP,               "Optional Filtering Support" },
4218         { DOCSIS_CM_CAP_TET_MI,                 "Transmit Equalizer Taps per Modulation Interval" },
4219         { DOCSIS_CM_CAP_TET,                    "Number of Transmit Equalizer Taps" },
4220         { DOCSIS_CM_CAP_DCC_SUP,                "DCC Support" },
4221         { DOCSIS_CM_CAP_IPFILT_SUP,             "IP Filters Support" },
4222         { DOCSIS_CM_CAP_LLCFILT_SUP,            "LLC Filters Support" },
4223         { DOCSIS_CM_CAP_EXPUNI_SPACE,           "Expanded Unicast SID Space" },
4224         { DOCSIS_CM_CAP_RNGHLDOFF_SUP,          "Ranging Hold-Off Support" },
4225         { DOCSIS_CM_CAP_L2VPN_SUP,              "L2VPN Capability" },
4226         { DOCSIS_CM_CAP_L2VPN_HOST_SUP,         "L2VPN eSAFE Host Capability" },
4227         { DOCSIS_CM_CAP_DUTFILT_SUP,            "Downstream Unencrypted Traffic (DUT) Filtering" },
4228         { DOCSIS_CM_CAP_USFREQRNG_SUP,          "Upstream Frequency Range Support" },
4229         { DOCSIS_CM_CAP_USSYMRATE_SUP,          "Upstream Symbol Rate Support" },
4230         { DOCSIS_CM_CAP_SACM2_SUP,              "Selectable Active Code Mode 2 Support" },
4231         { DOCSIS_CM_CAP_SACM2HOP_SUP,           "Code Hopping Mode 2 Support" },
4232         { DOCSIS_CM_CAP_MULTTXCHAN_SUP,         "Multiple Transmit Channel Support" },
4233         { DOCSIS_CM_CAP_512USTXCHAN_SUP,        "5.12 Msps Upstream Transmit Channel Support" },
4234         { DOCSIS_CM_CAP_256USTXCHAN_SUP,        "2.56 Msps Upstream Transmit Channel Support" },
4235         { DOCSIS_CM_CAP_TOTALSIDCLU_SUP,        "Total SID Cluster Support" },
4236         { DOCSIS_CM_CAP_SIDCLUPERSF_SUP,        "SID Clusters per Service Flow Support" },
4237         { DOCSIS_CM_CAP_MULTRXCHAN_SUP,         "Multiple Receive Channel Support" },
4238         { DOCSIS_CM_CAP_TOTALDSID_SUP,          "Total Downstream Service ID (DSID) Support" },
4239         { DOCSIS_CM_CAP_RESEQDSID_SUP,          "Resequencing Downstream Service ID (DSID) Support" },
4240         { DOCSIS_CM_CAP_MULTDSID_SUP,           "Multicast Downstream Service ID (DSID) Support" },
4241         { DOCSIS_CM_CAP_MULTDSIDFW_SUP,         "Multicast DSID Forwarding" },
4242         { DOCSIS_CM_CAP_FCTF_SUP,               "Frame Control Type Forwarding Capability" },
4243         { DOCSIS_CM_CAP_DPV_SUP,                "DPV Capability" },
4244         { DOCSIS_CM_CAP_UGSPERUSFLOW_SUP,       "Unsolicited Grant Service/Upstream Service Flow Support" },
4245         { DOCSIS_CM_CAP_MAPUCDRECEIPT_SUP,      "MAP and UCD Receipt Support" },
4246         { DOCSIS_CM_CAP_USDROPCLASSIF_SUP,      "Upstream Drop Classifier Support" },
4247         { DOCSIS_CM_CAP_IPV6_SUP,               "IPv6 Support" },
4248         { DOCSIS_CM_CAP_ExUsTrPow,              "Extended Upstream Transmit Power Capability (1/4 dB)" },
4249         { DOCSIS_CM_CAP_Opt802MPLSSup,          "Optional 802.1ad, 802.1ah, MPLS Classification Support" },
4250         { DOCSIS_CM_CAP_DounEnc,                "D-ONU Capabilities Encoding" },
4251         { DOCSIS_CM_CAP_EnrgMang,               "Energy Management Capabilities" },
4252         { 0, NULL }
4253 };
4254
4255 static const value_string docsis_cm_cap_supported_vals[] = {
4256         { 0x00, "Not Support" },
4257         { 0x01, "Supported" },
4258         { 0,            NULL }
4259 };
4260
4261 static const value_string docsis_cm_cap_version_vals[] = {
4262         { 0x00, "DOCSIS 1.0" },
4263         { 0x01, "DOCSIS 1.1" },
4264         { 0x02, "DOCSIS 2.0" },
4265         { 0x03, "DOCSIS 3.0" },
4266         { 0,            NULL }
4267 };
4268
4269 static const value_string docsis_cm_cap_privacy_vals[] = {
4270         { 0x00, "BPI Support" },
4271         { 0x01, "BPI Plus Support" },
4272         { 0,            NULL }
4273 };
4274
4275 static const value_string docsis_cm_cap_ranging_hold_off_vals[] = {
4276         { 1 << 0, "CM" },
4277         { 1 << 1, "ePS or eRouter" },
4278         { 1 << 2, "EMTA or EDVA" },
4279         { 1 << 3, "DSG/eSTB" },
4280         { 0, NULL }
4281 };
4282
4283 static const value_string docsis_cm_cap_l2vpn_vals[] = {
4284         { 0x00, "CM not compliant with DOCSIS L2VPN Section 7 (default)" },
4285         { 0x01, "CM compliant with DOCSIS L2VPN Section 7" },
4286         { 0,            NULL }
4287 };
4288
4289 static const value_string docsis_cm_cap_filt_vals[] = {
4290         { 0x00, "802.1P Filtering" },
4291         { 0x01, "802.1Q Filtering" },
4292         { 0,            NULL }
4293 };
4294
4295 static const value_string docsis_cm_cap_mpls_vals[] = {
4296         { 1 << 0,       "[IEEE 802.1ad] S-TPID" },
4297         { 1 << 1,       "[IEEE 802.1ad] S-VID" },
4298         { 1 << 2,       "[IEEE 802.1ad] S-PCP" },
4299         { 1 << 3, "[IEEE 802.1ad] S-DEI" },
4300         { 1 << 4,       "[IEEE 802.1ad] C-TPID" },
4301         { 1 << 5,       "[IEEE 802.1ad] C-VID" },
4302         { 1 << 6,       "[IEEE 802.1ad] C-PCP" },
4303         { 1 << 7,       "[IEEE 802.1ad] C-CFI" },
4304         { 1 << 8,       "[IEEE 802.1ad] S-TCI" },
4305         { 1 << 9,       "[IEEE 802.1ad] C-TCI" },
4306         { 1 << 10,      "[IEEE 802.1ah] I-TPID" },
4307         { 1 << 11,      "[IEEE 802.1ah] I-SID" },
4308         { 1 << 12,      "[IEEE 802.1ah] I-TCI" },
4309         { 1 << 13,      "[IEEE 802.1ah] I-PCP" },
4310         { 1 << 14,      "[IEEE 802.1ah] I-DEI" },
4311         { 1 << 15,      "[IEEE 802.1ah] I-UCA" },
4312         { 1 << 16,      "[IEEE 802.1ah] B-TPID" },
4313         { 1 << 17,      "[IEEE 802.1ah] B-TCI" },
4314         { 1 << 18,      "[IEEE 802.1ah] B-PCP" },
4315         { 1 << 19,      "[IEEE 802.1ah] B-DEI" },
4316         { 1 << 20,      "[IEEE 802.1ah] B-VID" },
4317         { 1 << 21,      "[IEEE 802.1ah] B-DA" },
4318         { 1 << 22,      "[IEEE 802.1ah] B-SA" },
4319         { 1 << 23,      "MPLS TC" },
4320         { 1 << 24,      "MPLS Label" },
4321         { 0,            NULL }
4322 };
4323
4324 static const value_string docsis_cm_cap_enrgmang_vals[] = {
4325         { 0x00, "Energy Management 1x1 Feature" },
4326         { 0,            NULL }
4327 };
4328
4329 static const value_string docsis_cm_cap_usfreqrng_vals[] = {
4330         { 0x00, "Standard Upstream Frequency Range" },
4331         { 0x01, "Standard Upstream Frequency Range and Extended Upstream Frequency Range" },
4332         { 0,            NULL }
4333 };
4334
4335 static const value_string docsis_cm_cap_map_ucd_receipt_vals[] = {
4336         { 0x00, "CM cannot support the receipt of MAPs and UCDs on downstreams other than the Primary Downstream Channel" },
4337         { 0x01, "CM can support the receipt of MAPs and UCDs on downstreams other than the Primary Downstream Channel" },
4338         { 0,            NULL }
4339 };
4340
4341 static const value_string docsis_cm_cap_map_dpv_support_vals[] = {
4342         { 0x00, "U1 supported as a Start Reference Point for DPV per Path" },
4343         { 0x01, "U1 supported as a Start Reference Point for DPV per Packet" },
4344         { 0,            NULL }
4345 };
4346
4347 static const value_string docsis_cm_cap_map_multDsidForward_support_vals[] = {
4348         { 0x00, "No support for multicast DSID forwarding" },
4349         { 0x01, "Support for GMAC explicit multicast DSID forwarding" },
4350         { 0x02, "Support for GMAC promiscuous multicast DSID forwarding" },
4351         { 0,            NULL }
4352 };
4353
4354 static const value_string docsis_cm_cap_map_fctfc_support_vals[] = {
4355         { 0x00, "Isolation Packet PDU MAC Header (FC_Type of 10) is not forwarded" },
4356         { 0x01, "Isolation Packet PDU MAC Header (FC_Type of 10) is forwarded" },
4357         { 0,            NULL }
4358 };
4359
4360 static const value_string docsis_cm_cap_map_l2vpn_esafe_index_support_vals[] = {
4361         { 0x01, "ePs or eRouter" },
4362         { 0x10, "eMTA" },
4363         { 0x11, "eSTB-IP" },
4364         { 0x12, "eSTB-DSG" },
4365         { 0x13, "eTEA" },
4366         { 0,            NULL }
4367 };
4368
4369 static const value_string docsis_cm_cap_ussymrate_vals[] = {
4370         { 1 << 0, "160  ksps symbol rate supported" },
4371         { 1 << 1, "320  ksps symbol rate supported" },
4372         { 1 << 2, "640  ksps symbol rate supported" },
4373         { 1 << 3, "1280 ksps symbol rate supported" },
4374         { 1 << 4, "2560 ksps symbol rate supported" },
4375         { 1 << 5, "5120 ksps symbol rate supported" },
4376         { 0, NULL }
4377 };
4378
4379 static void
4380 display_uint_with_range_checking(proto_item *ti, guint8 val_byte, guint16 val_uint16, int min_value, int max_value)
4381 {
4382         guint16 value;
4383
4384         if (0 != val_byte)
4385         {
4386                 value = val_byte;
4387         }
4388         else
4389         {
4390                 value = val_uint16;
4391         }
4392         proto_item_append_text(ti, "%i", value);
4393         if ((value < min_value) ||
4394             (value > max_value))
4395         {
4396                 proto_item_append_text(ti, " (Value Out-of-Range [%i..%i])", min_value, max_value);
4397         }
4398 }
4399
4400 static void get_opt125_tlv(tvbuff_t *tvb, guint off, guint8 *tlvtype, guint8 *tlvlen, guint8 **value)
4401 {
4402         /* Type */
4403         *tlvtype = tvb_get_guint8(tvb, off);
4404         /* Length */
4405         *tlvlen  = tvb_get_guint8(tvb, off+1);
4406         /* Value */
4407         *value = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, off + 2, *tlvlen);
4408 }
4409
4410 static void get_opt60_tlv(tvbuff_t *tvb, guint off, guint8 *tlvtype, guint8 *tlvlen, guint8 **value)
4411 {
4412         guint   i;
4413         guint8 *val_asc;
4414
4415         val_asc = (guint8 *)wmem_alloc0(wmem_packet_scope(), 4);
4416         /* Type */
4417         tvb_memcpy(tvb, val_asc, off, 2);
4418         *tlvtype = (guint8)strtoul((gchar*)val_asc, NULL, 16);
4419         /* Length */
4420         tvb_memcpy(tvb, val_asc, off + 2, 2);
4421         *tlvlen = (guint8)strtoul((gchar*)val_asc, NULL, 16);
4422         /* Value */
4423         *value = (guint8 *)wmem_alloc0(wmem_packet_scope(), *tlvlen);
4424         for (i=0; i<*tlvlen; i++)
4425         {
4426                 memset(val_asc, 0, 4);
4427                 tvb_memcpy(tvb, val_asc, off + ((i*2) + 4), 2);
4428                 (*value)[i] = (guint8)strtoul((gchar*)val_asc, NULL, 16);
4429         }
4430 }
4431
4432 static void
4433 dissect_docsis_cm_cap(proto_tree *v_tree, tvbuff_t *tvb, int voff, int len, gboolean opt125)
4434 {
4435         guint8     *asc_val;
4436         guint       i;
4437         proto_item *ti;
4438         proto_tree *subtree;
4439         char        bit_fld[64];
4440         guint8      tlv_type;
4441         guint8      tlv_len;
4442         guint8      val_byte   = 0;
4443         guint16     val_uint16 = 0;
4444         guint8     *val_other  = NULL;
4445         guint       off        = voff;
4446
4447         asc_val = (guint8*)wmem_alloc0(wmem_packet_scope(), 4);
4448
4449         if (opt125)
4450         {
4451                 /* Option 125 is formatted as uint8's */
4452                 /* Type */
4453                 tlv_type = tvb_get_guint8(tvb, off);
4454                 /* Length */
4455                 tlv_len  = tvb_get_guint8(tvb, off+1);
4456                 proto_tree_add_uint_format_value(v_tree, hf_bootp_docsis_cm_cap_len, tvb, off+1, 1,
4457                                                  tlv_len, "%d", tlv_len);
4458         }
4459         else
4460         {
4461                 /* Option 60 is formatted as an ASCII string.
4462                    Since the capabilities are the same for both options
4463                    I am converting the Option 60 values from ASCII to
4464                    uint8s to allow the same parser to work for both */
4465                 off += DOCSIS_CM_CAP_TLV_OFF;
4466                 tvb_memcpy (tvb, asc_val, off, 2);
4467                 tlv_len = (guint8)strtoul((gchar*)asc_val, NULL, 16);
4468                 proto_tree_add_uint_format_value(v_tree, hf_bootp_docsis_cm_cap_len, tvb, off+2, 2,
4469                                                  tlv_len, "%d", tlv_len);
4470         }
4471
4472         off+=2;
4473
4474         while (off - ((guint) voff) < ((guint) len))
4475         {
4476                 tlv_type = 0;
4477                 tlv_len = 0;
4478                 val_byte = 0;
4479                 val_uint16 = 0;
4480
4481                 if (opt125)
4482                 {
4483                         get_opt125_tlv(tvb, off, &tlv_type, &tlv_len, &val_other);
4484                         ti =  proto_tree_add_uint_format(v_tree, hf_bootp_docsis_cm_cap_type, tvb, off,
4485                                                          tlv_len + 2,
4486                                                          tlv_type,
4487                                                          "0x%02x: %s = ",
4488                                                          tlv_type,
4489                                                          val_to_str_const(tlv_type, docsis_cm_cap_type_vals, "unknown"));
4490                 }
4491                 else
4492                 {
4493                         /* Option 60 is formatted as an ASCII string.  Since the capabilities
4494                            are the same for both options I am converting the Option 60 values
4495                            from ASCII to uint8s to allow the same parser to work for both */
4496                         get_opt60_tlv(tvb, off, &tlv_type, &tlv_len, &val_other);
4497                         ti =  proto_tree_add_uint_format(v_tree, hf_bootp_docsis_cm_cap_type, tvb, off,
4498                                                          (tlv_len * 2) + 4,
4499                                                          tlv_type,
4500                                                          "0x%02x: %s = ",
4501                                                          tlv_type,
4502                                                          val_to_str_const(tlv_type, docsis_cm_cap_type_vals, "unknown"));
4503                 }
4504
4505                 if (tlv_len == 1)
4506                 {
4507                         /* The value refers to a byte. */
4508                         val_byte = val_other[0];
4509                 }
4510                 else
4511                 {
4512                         if (tlv_len == 2)
4513                         {
4514                                 /* The value refers to a uint16. */
4515                                 val_uint16 = (val_other[0] << 8) + val_other[1];
4516                         }
4517                 }
4518
4519                 switch (tlv_type)
4520                 {
4521                 case DOCSIS_CM_CAP_CONCAT_SUP:
4522                 case DOCSIS_CM_CAP_FRAG_SUP:
4523                 case DOCSIS_CM_CAP_PHS_SUP:
4524                 case DOCSIS_CM_CAP_IGMP_SUP:
4525                 case DOCSIS_CM_CAP_DCC_SUP:
4526                 case DOCSIS_CM_CAP_EXPUNI_SPACE:
4527                 case DOCSIS_CM_CAP_DUTFILT_SUP:
4528                 case DOCSIS_CM_CAP_SACM2_SUP:
4529                 case DOCSIS_CM_CAP_SACM2HOP_SUP:
4530                 case DOCSIS_CM_CAP_IPV6_SUP:
4531                         proto_item_append_text(ti,
4532                                                "%s",
4533                                                val_to_str_const(val_byte, docsis_cm_cap_supported_vals, "Reserved"));
4534                         break;
4535                 case DOCSIS_CM_CAP_DOCSIS_VER:
4536                         proto_item_append_text(ti,
4537                                                "%s",
4538                                                val_to_str_const(val_byte, docsis_cm_cap_version_vals, "Reserved"));
4539                         break;
4540                 case DOCSIS_CM_CAP_PRIV_SUP:
4541                         proto_item_append_text(ti,
4542                                                "%s",
4543                                                val_to_str_const(val_byte, docsis_cm_cap_privacy_vals, "Reserved"));
4544                         break;
4545                 case DOCSIS_CM_CAP_FILT_SUP:
4546                         proto_item_append_text(ti,
4547                                                "%s",
4548                                                val_to_str_const(val_byte, docsis_cm_cap_filt_vals, "Reserved"));
4549                         break;
4550                 case DOCSIS_CM_CAP_L2VPN_SUP:
4551                         proto_item_append_text(ti,
4552                                                "%s",
4553                                                val_to_str_const(val_byte, docsis_cm_cap_l2vpn_vals, "Reserved"));
4554                         break;
4555                 case DOCSIS_CM_CAP_L2VPN_HOST_SUP:
4556                         if (tlv_len == 7) {
4557                                 proto_item_append_text(ti,
4558                                                        "eSAFE ifIndex %s (%i)/eSAFE MAC %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
4559                                                        val_to_str_const(val_other[0], docsis_cm_cap_map_l2vpn_esafe_index_support_vals, "Reserved"),
4560                                                        val_other[0],
4561                                                        val_other[1],
4562                                                        val_other[2],
4563                                                        val_other[3],
4564                                                        val_other[4],
4565                                                        val_other[5],
4566                                                        val_other[6]);
4567                         } else {
4568                                 proto_item_append_text(ti,
4569                                                        "Invalid (length should be 7, is %d)",
4570                                                        tlv_len);
4571                         }
4572                         break;
4573                 case DOCSIS_CM_CAP_USFREQRNG_SUP:
4574                         proto_item_append_text(ti,
4575                                                "%s",
4576                                                val_to_str_const(val_byte, docsis_cm_cap_usfreqrng_vals, "Reserved"));
4577                         break;
4578                 case DOCSIS_CM_CAP_MAPUCDRECEIPT_SUP:
4579                         proto_item_append_text(ti,
4580                                                "%s",
4581                                                val_to_str_const(val_byte, docsis_cm_cap_map_ucd_receipt_vals, "Reserved"));
4582                         break;
4583                 case DOCSIS_CM_CAP_DPV_SUP:
4584                         proto_item_append_text(ti,
4585                                                "%s",
4586                                                val_to_str_const(val_byte, docsis_cm_cap_map_dpv_support_vals, "Reserved"));
4587                         break;
4588                 case DOCSIS_CM_CAP_DSAID_SUP:
4589                 case DOCSIS_CM_CAP_MULTTXCHAN_SUP:
4590                 case DOCSIS_CM_CAP_512USTXCHAN_SUP:
4591                 case DOCSIS_CM_CAP_256USTXCHAN_SUP:
4592                 case DOCSIS_CM_CAP_TOTALSIDCLU_SUP:
4593                 case DOCSIS_CM_CAP_MULTRXCHAN_SUP:
4594                 case DOCSIS_CM_CAP_UGSPERUSFLOW_SUP:
4595                 case DOCSIS_CM_CAP_USSF_SUP:
4596                         display_uint_with_range_checking(ti, val_byte, val_uint16, 0, 255);
4597                         break;
4598                 case DOCSIS_CM_CAP_RESEQDSID_SUP:
4599                 case DOCSIS_CM_CAP_MULTDSID_SUP:
4600                         display_uint_with_range_checking(ti, val_byte, val_uint16, 16, 255);
4601                         break;
4602                 case DOCSIS_CM_CAP_SIDCLUPERSF_SUP:
4603                         display_uint_with_range_checking(ti, val_byte, val_uint16, 2, 8);
4604                         break;
4605                 case DOCSIS_CM_CAP_TOTALDSID_SUP:
4606                         display_uint_with_range_checking(ti, val_byte, val_uint16, 32, 255);
4607                         break;
4608                 case DOCSIS_CM_CAP_TET:
4609                         display_uint_with_range_checking(ti, val_byte, val_uint16, 8, 64);
4610                         break;
4611                 case DOCSIS_CM_CAP_TET_MI:
4612                         if ((val_byte == 1) ||
4613                             (val_byte == 2) ||
4614                             (val_byte == 4))
4615                         {
4616                                 proto_item_append_text(ti,
4617                                                        " %i",
4618                                                        val_byte);
4619                         }
4620                         else
4621                         {
4622                                 proto_item_append_text(ti,
4623                                                        " (Invalid Value %i : Should be [1,2,4]",
4624                                                        val_byte);
4625                         }
4626                         break;
4627                 case DOCSIS_CM_CAP_IPFILT_SUP:
4628                 case DOCSIS_CM_CAP_USDROPCLASSIF_SUP:
4629                         display_uint_with_range_checking(ti, val_byte, val_uint16, 64, 65535);
4630                         break;
4631                 case DOCSIS_CM_CAP_LLCFILT_SUP:
4632                         display_uint_with_range_checking(ti, val_byte, val_uint16, 10, 65535);
4633                         break;
4634                 case DOCSIS_CM_CAP_ExUsTrPow:
4635                         if (val_byte == 0)
4636                         {
4637                                 proto_item_append_text(ti, "%i", val_byte);
4638                         }
4639                         else
4640                         {
4641                                 display_uint_with_range_checking(ti, val_byte, val_uint16, 205, 244);
4642                         }
4643                         break;
4644                 case DOCSIS_CM_CAP_Opt802MPLSSup:
4645                         proto_item_append_text(ti,
4646                                                "0x%02x", val_byte);
4647                 case DOCSIS_CM_CAP_DounEnc:
4648                         /* TODO: add D-ONU Capabilities Encoding according DPoE-SP-MULPIv1.0-I02-120607 */
4649                         break;
4650                 case DOCSIS_CM_CAP_EnrgMang:
4651                         proto_item_append_text(ti,
4652                                                "%s",
4653                                                val_to_str_const(val_byte, docsis_cm_cap_enrgmang_vals, "Reserved"));
4654                         break;
4655                 case DOCSIS_CM_CAP_RNGHLDOFF_SUP:
4656                         proto_item_append_text(ti,
4657                                                "Ranging ID ");
4658                         if (tlv_len == 4)
4659                         {
4660                                 proto_item_append_text(ti,
4661                                                 "(0x%04x)", (val_other[0] << sizeof(guint8)) + val_other[1]);
4662                                 proto_item_append_text(ti,
4663                                                 " Component Bit Mask ");
4664                                 proto_item_append_text(ti,
4665                                                 "(0x%04x)", (val_other[2] << sizeof(guint8)) + val_other[3]);
4666                         }
4667                         else
4668                         {
4669                                 proto_item_append_text(ti,
4670                                                 " (Invalid Length %u : Should be 4",
4671                                                 tlv_len);
4672                         }
4673                         break;
4674                 case DOCSIS_CM_CAP_USSYMRATE_SUP:
4675                         proto_item_append_text(ti,
4676                                                "0x%02x", val_byte);
4677                         break;
4678                 case DOCSIS_CM_CAP_FCTF_SUP:
4679                         proto_item_append_text(ti,
4680                                                "%s",
4681                                                val_to_str_const(val_byte, docsis_cm_cap_map_fctfc_support_vals, "Reserved"));
4682                         break;
4683                 case DOCSIS_CM_CAP_MULTDSIDFW_SUP:
4684                         proto_item_append_text(ti,
4685                                                "%s",
4686                                                val_to_str_const(val_byte, docsis_cm_cap_map_multDsidForward_support_vals, "Reserved"));
4687                         break;
4688                 }
4689
4690                 subtree = proto_item_add_subtree(ti, ett_bootp_option);
4691                 if (tlv_type == DOCSIS_CM_CAP_RNGHLDOFF_SUP && tlv_len >= 4)
4692                 {
4693                         for (i = 0 ; i < 4; i++)
4694                         {
4695                                 decode_bitfield_value(bit_fld,
4696                                                       (val_other[2] << sizeof(guint8)) + val_other[3],
4697                                                       docsis_cm_cap_ranging_hold_off_vals[i].value,
4698                                                       16);
4699                                 proto_tree_add_text(subtree, tvb, off + 2, 4, "%s%s",
4700                                                     bit_fld, docsis_cm_cap_ranging_hold_off_vals[i].strptr);
4701                         }
4702                 }
4703                 if (tlv_type == DOCSIS_CM_CAP_USSYMRATE_SUP)
4704                 {
4705                         for (i = 0 ; i < 6; i++)
4706                         {
4707                                 decode_bitfield_value(bit_fld, val_byte,docsis_cm_cap_ussymrate_vals[i].value, 8);
4708                                 proto_tree_add_text(subtree, tvb, off + 2, 1, "%s%s",
4709                                                     bit_fld, docsis_cm_cap_ussymrate_vals[i].strptr);
4710
4711                         }
4712                 }
4713                 if (tlv_type == DOCSIS_CM_CAP_Opt802MPLSSup && tlv_len >= 4)
4714                 {
4715                         for (i = 0 ; i < 25; i++)
4716                         {
4717                                 decode_bitfield_value(bit_fld,
4718                                                       (val_other[2] << sizeof(guint8)) + val_other[3],
4719                                                       docsis_cm_cap_mpls_vals[i].value,
4720                                                       32);
4721                                 proto_tree_add_text(subtree, tvb, off + 2, 4, "%s%s",
4722                                                     bit_fld, docsis_cm_cap_mpls_vals[i].strptr);
4723                         }
4724                 }
4725                 if (opt125)
4726                 {
4727                         off += (tlv_len) + 2;
4728                 }
4729                 else
4730                 {
4731                         off += (tlv_len *2) + 4;
4732                 }
4733
4734         }
4735 }
4736
4737 /* Definitions specific to PKT-SP-PROV-I05-021127 begin with "PKT_CCC_I05".
4738    Definitions specific to IETF draft 5 and RFC 3495 begin with "PKT_CCC_IETF".
4739    Shared definitions begin with "PKT_CCC".
4740  */
4741 #define PKT_CCC_PRI_DHCP       1
4742 #define PKT_CCC_SEC_DHCP       2
4743 #define PKT_CCC_I05_SNMP       3
4744 #define PKT_CCC_IETF_PROV_SRV  3
4745 #define PKT_CCC_I05_PRI_DNS    4
4746 #define PKT_CCC_IETF_AS_KRB    4
4747 #define PKT_CCC_I05_SEC_DNS    5
4748 #define PKT_CCC_IETF_AP_KRB    5
4749 #define PKT_CCC_KRB_REALM      6
4750 #define PKT_CCC_TGT_FLAG       7
4751 #define PKT_CCC_PROV_TIMER     8
4752 #define PKT_CCC_CMS_FQDN       9
4753 #define PKT_CCC_IETF_SEC_TKT   9
4754 #define PKT_CCC_AS_KRB        10
4755 #define PKT_CCC_AP_KRB        11
4756 #define PKT_CCC_MTA_KRB_CLEAR 12
4757
4758 static const value_string pkt_i05_ccc_opt_vals[] = {
4759         { PKT_CCC_PRI_DHCP,             "Primary DHCP Server" },
4760         { PKT_CCC_SEC_DHCP,             "Secondary DHCP Server" },
4761         { PKT_CCC_I05_SNMP,             "SNMP Entity" },
4762         { PKT_CCC_I05_PRI_DNS,          "Primary DNS Server" },
4763         { PKT_CCC_I05_SEC_DNS,          "Secondary DNS Server" },
4764         { PKT_CCC_KRB_REALM,            "Kerberos Realm" },
4765         { PKT_CCC_TGT_FLAG,             "MTA should fetch TGT?" },
4766         { PKT_CCC_PROV_TIMER,           "Provisioning Timer" },
4767         { PKT_CCC_CMS_FQDN,             "CMS FQDN" },
4768         { PKT_CCC_AS_KRB,               "AS-REQ/AS-REP Backoff and Retry" },
4769         { PKT_CCC_AP_KRB,               "AP-REQ/AP-REP Backoff and Retry" },
4770         { PKT_CCC_MTA_KRB_CLEAR,        "MTA should clear Kerberos tickets?" },
4771         { 0, NULL },
4772 };
4773
4774 static const value_string pkt_draft5_ccc_opt_vals[] = {
4775         { PKT_CCC_PRI_DHCP,             "TSP's Primary DHCP Server" },
4776         { PKT_CCC_SEC_DHCP,             "TSP's Secondary DHCP Server" },
4777         { PKT_CCC_IETF_PROV_SRV,        "TSP's Provisioning Server" },
4778         { PKT_CCC_IETF_AS_KRB,          "TSP's AS-REQ/AS-REP Backoff and Retry" },
4779         { PKT_CCC_IETF_AP_KRB,          "TSP's AP-REQ/AP-REP Backoff and Retry" },
4780         { PKT_CCC_KRB_REALM,            "TSP's Kerberos Realm Name" },
4781         { PKT_CCC_TGT_FLAG,             "TSP's Ticket Granting Server Utilization" },
4782         { PKT_CCC_PROV_TIMER,           "TSP's Provisioning Timer Value" },
4783         { PKT_CCC_IETF_SEC_TKT,         "PacketCable Security Ticket Control" },
4784         { 0, NULL },
4785 };
4786
4787 static const value_string pkt_i05_ccc_ticket_ctl_vals[] = {
4788         { 1, "Invalidate Provisioning Application Server's ticket" },
4789         { 2, "Invalidate all CMS Application Server tickets" },
4790         { 3, "Invalidate all Application Server tickets" },
4791         { 0, NULL },
4792 };
4793
4794 static int
4795 dissect_packetcable_i05_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
4796                             tvbuff_t *tvb, int optoff, int optend)
4797 {
4798         int         suboptoff = optoff;
4799         guint8      subopt, subopt_len, fetch_tgt, timer_val, ticket_ctl;
4800         proto_tree *pkt_s_tree;
4801         proto_item *vti;
4802
4803         subopt = tvb_get_guint8(tvb, optoff);
4804         suboptoff++;
4805
4806         if (suboptoff >= optend) {
4807                 expert_add_info_format(pinfo, v_ti, &ei_bootp_missing_subopt_length,
4808                                                                         "Suboption %d: no room left in option for suboption length", subopt);
4809                 return (optend);
4810         }
4811
4812         subopt_len = tvb_get_guint8(tvb, optoff);
4813         suboptoff++;
4814
4815         vti = proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
4816                 "Suboption %u: %s: ", subopt,
4817                 val_to_str_const(subopt, pkt_i05_ccc_opt_vals, "unknown/reserved") );
4818
4819         switch (subopt) {
4820
4821         case PKT_CCC_PRI_DHCP:  /* String values */
4822         case PKT_CCC_SEC_DHCP:
4823         case PKT_CCC_I05_SNMP:
4824         case PKT_CCC_I05_PRI_DNS:
4825         case PKT_CCC_I05_SEC_DNS:
4826         case PKT_CCC_KRB_REALM:
4827         case PKT_CCC_CMS_FQDN:
4828                 proto_item_append_text(vti, "%s (%u byte%s)",
4829                                        tvb_format_stringzpad(tvb, suboptoff, subopt_len),
4830                                        subopt_len,
4831                                        plurality(subopt_len, "", "s") );
4832                 suboptoff += subopt_len;
4833                 break;
4834
4835         case PKT_CCC_TGT_FLAG:
4836                 if (suboptoff+1 > optend) {
4837                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
4838                         return (optend);
4839                 }
4840                 fetch_tgt = tvb_get_guint8(tvb, suboptoff);
4841                 proto_item_append_text(vti, "%s (%u byte%s%s)",
4842                                        fetch_tgt ? "Yes" : "No",
4843                                        subopt_len,
4844                                        plurality(subopt_len, "", "s"),
4845                                        subopt_len != 1 ? " [Invalid]" : "");
4846                 suboptoff += subopt_len;
4847                 break;
4848
4849         case PKT_CCC_PROV_TIMER:
4850                 if (suboptoff+1 > optend) {
4851                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
4852                         return (optend);
4853                 }
4854                 timer_val = tvb_get_guint8(tvb, suboptoff);
4855                 proto_item_append_text(vti, "%u%s (%u byte%s%s)", timer_val,
4856                                        timer_val > 30 ? " [Invalid]" : "",
4857                                        subopt_len,
4858                                        plurality(subopt_len, "", "s"),
4859                                        subopt_len != 1 ? " [Invalid]" : "");
4860                 suboptoff += subopt_len;
4861                 break;
4862
4863         case PKT_CCC_AS_KRB:
4864                 if (suboptoff+12 > optend) {
4865                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
4866                         return (optend);
4867                 }
4868                 proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
4869                                        plurality(subopt_len, "", "s"),
4870                                        subopt_len != 12 ? " [Invalid]" : "");
4871                 if (subopt_len == 12) {
4872                         pkt_s_tree = proto_item_add_subtree(vti, ett_bootp_option);
4873                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff, 4,
4874                                             "pktcMtaDevRealmUnsolicitedKeyNomTimeout: %u",
4875                                             tvb_get_ntohl(tvb, suboptoff));
4876                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 4, 4,
4877                                             "pktcMtaDevRealmUnsolicitedKeyMaxTimeout: %u",
4878                                             tvb_get_ntohl(tvb, suboptoff + 4));
4879                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 8, 4,
4880                                             "pktcMtaDevRealmUnsolicitedKeyMaxRetries: %u",
4881                                             tvb_get_ntohl(tvb, suboptoff + 8));
4882                 }
4883                 suboptoff += subopt_len;
4884                 break;
4885
4886         case PKT_CCC_AP_KRB:
4887                 if (suboptoff+12 > optend) {
4888                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
4889                         return (optend);
4890                 }
4891                 proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
4892                                        plurality(subopt_len, "", "s"),
4893                                        subopt_len != 12 ? " [Invalid]" : "");
4894                 if (subopt_len == 12) {
4895                         pkt_s_tree = proto_item_add_subtree(vti, ett_bootp_option);
4896                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff, 4,
4897                                             "pktcMtaDevProvUnsolicitedKeyNomTimeout: %u",
4898                                             tvb_get_ntohl(tvb, suboptoff));
4899                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 4, 4,
4900                                             "pktcMtaDevProvUnsolicitedKeyMaxTimeout: %u",
4901                                             tvb_get_ntohl(tvb, suboptoff + 4));
4902                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 8, 4,
4903                                             "pktcMtaDevProvUnsolicitedKeyMaxRetries: %u",
4904                                             tvb_get_ntohl(tvb, suboptoff + 8));
4905                 }
4906                 suboptoff += subopt_len;
4907                 break;
4908
4909         case PKT_CCC_MTA_KRB_CLEAR:
4910                 if (suboptoff+1 > optend) {
4911                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
4912                         return (optend);
4913                 }
4914                 ticket_ctl = tvb_get_guint8(tvb, suboptoff);
4915                 proto_item_append_text(vti, "%s (%u) (%u byte%s%s)",
4916                                        val_to_str_const (ticket_ctl, pkt_i05_ccc_ticket_ctl_vals, "unknown/invalid"),
4917                                        ticket_ctl,
4918                                        subopt_len,
4919                                        plurality(subopt_len, "", "s"),
4920                                        subopt_len != 1 ? " [Invalid]" : "");
4921                 suboptoff += subopt_len;
4922                 break;
4923
4924         default:
4925                 suboptoff += subopt_len;
4926                 break;
4927
4928         }
4929         return suboptoff;
4930 }
4931
4932
4933 static const value_string sec_tcm_vals[] = {
4934         { 1 << 0, "PacketCable Provisioning Server" },
4935         { 1 << 1, "All PacketCable Call Management Servers" },
4936         { 0, NULL }
4937 };
4938
4939 static int
4940 dissect_packetcable_ietf_ccc(packet_info *pinfo, proto_item *v_ti, proto_tree *v_tree,
4941                              tvbuff_t *tvb, int optoff, int optend, int revision)
4942 {
4943         int           suboptoff     = optoff;
4944         guint8        subopt, subopt_len;
4945         guint32       ipv4addr;
4946         guint8        prov_type, fetch_tgt, timer_val;
4947         guint16       sec_tcm;
4948         proto_tree   *pkt_s_tree;
4949         proto_item   *vti;
4950         int           max_timer_val = 255, i;
4951         const guchar *dns_name;
4952         char          bit_fld[24];
4953
4954         subopt = tvb_get_guint8(tvb, suboptoff);
4955         suboptoff++;
4956
4957         if (suboptoff >= optend) {
4958                 expert_add_info_format(pinfo, v_ti, &ei_bootp_missing_subopt_length,
4959                                                                         "Suboption %d: no room left in option for suboption length", subopt);
4960                 return (optend);
4961         }
4962         subopt_len = tvb_get_guint8(tvb, suboptoff);
4963         suboptoff++;
4964
4965         vti = proto_tree_add_text(v_tree, tvb, optoff, subopt_len + 2,
4966             "Suboption %u: %s: ", subopt,
4967             val_to_str_const(subopt, pkt_draft5_ccc_opt_vals, "unknown/reserved") );
4968
4969         switch (subopt) {
4970
4971         case PKT_CCC_PRI_DHCP:  /* IPv4 values */
4972         case PKT_CCC_SEC_DHCP:
4973                 if (suboptoff+4 > optend) {
4974                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
4975                         return (optend);
4976                 }
4977                 ipv4addr = tvb_get_ipv4(tvb, suboptoff);
4978                 proto_item_append_text(vti, "%s (%u byte%s%s)",
4979                                        ip_to_str((guint8 *)&ipv4addr),
4980                                        subopt_len,
4981                                        plurality(subopt_len, "", "s"),
4982                                        subopt_len != 4 ? " [Invalid]" : "");
4983                 suboptoff += subopt_len;
4984                 break;
4985
4986         case PKT_CCC_IETF_PROV_SRV:
4987                 if (suboptoff+1 > optend) {
4988                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
4989                         return (optend);
4990                 }
4991                 prov_type = tvb_get_guint8(tvb, suboptoff);
4992                 suboptoff += 1;
4993                 switch (prov_type) {
4994
4995                 case 0:
4996                         get_dns_name(tvb, suboptoff, subopt_len, suboptoff, &dns_name);
4997                         proto_item_append_text(vti, "%s (%u byte%s)", dns_name,
4998                                                subopt_len - 1, plurality(subopt_len, "", "s") );
4999                         break;
5000
5001                 case 1:
5002                         if (suboptoff+4 > optend) {
5003                                 expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
5004                                 return (optend);
5005                         }
5006                         ipv4addr = tvb_get_ipv4(tvb, suboptoff);
5007                         proto_item_append_text(vti, "%s (%u byte%s%s)",
5008                                                ip_to_str((guint8 *)&ipv4addr),
5009                                                subopt_len,
5010                                                plurality(subopt_len, "", "s"),
5011                                                subopt_len != 5 ? " [Invalid]" : "");
5012                         break;
5013
5014                 default:
5015                         proto_item_append_text(vti, "Invalid type: %u (%u byte%s)",
5016                                                prov_type,
5017                                                subopt_len,
5018                                                plurality(subopt_len, "", "s") );
5019                         break;
5020                 }
5021                 suboptoff += subopt_len - 1;
5022                 break;
5023
5024         case PKT_CCC_IETF_AS_KRB:
5025                 if (suboptoff+12 > optend) {
5026                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
5027                         return (optend);
5028                 }
5029                 proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
5030                                        plurality(subopt_len, "", "s"),
5031                                        subopt_len != 12 ? " [Invalid]" : "");
5032                 if (subopt_len == 12) {
5033                         pkt_s_tree = proto_item_add_subtree(vti, ett_bootp_option);
5034                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff, 4,
5035                                             "pktcMtaDevRealmUnsolicitedKeyNomTimeout: %u",
5036                                             tvb_get_ntohl(tvb, suboptoff));
5037                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 4, 4,
5038                                             "pktcMtaDevRealmUnsolicitedKeyMaxTimeout: %u",
5039                                             tvb_get_ntohl(tvb, suboptoff + 4));
5040                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 8, 4,
5041                                             "pktcMtaDevRealmUnsolicitedKeyMaxRetries: %u",
5042                                             tvb_get_ntohl(tvb, suboptoff + 8));
5043                 }
5044                 suboptoff += subopt_len;
5045                 break;
5046
5047         case PKT_CCC_IETF_AP_KRB:
5048                 proto_item_append_text(vti, "(%u byte%s%s)", subopt_len,
5049                                        plurality(subopt_len, "", "s"),
5050                                        subopt_len != 12 ? " [Invalid]" : "");
5051                 if (subopt_len == 12) {
5052                         pkt_s_tree = proto_item_add_subtree(vti, ett_bootp_option);
5053                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff, 4,
5054                                             "pktcMtaDevProvUnsolicitedKeyNomTimeout: %u",
5055                                             tvb_get_ntohl(tvb, suboptoff));
5056                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 4, 4,
5057                                             "pktcMtaDevProvUnsolicitedKeyMaxTimeout: %u",
5058                                             tvb_get_ntohl(tvb, suboptoff + 4));
5059                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff + 8, 4,
5060                                             "pktcMtaDevProvUnsolicitedKeyMaxRetries: %u",
5061                                             tvb_get_ntohl(tvb, suboptoff + 8));
5062                 }
5063                 suboptoff += subopt_len;
5064                 break;
5065
5066         case PKT_CCC_KRB_REALM: /* String values */
5067                 get_dns_name(tvb, suboptoff, subopt_len, suboptoff, &dns_name);
5068                 proto_item_append_text(vti, "%s (%u byte%s)", dns_name,
5069                                        subopt_len, plurality(subopt_len, "", "s") );
5070                 suboptoff += subopt_len;
5071                 break;
5072
5073         case PKT_CCC_TGT_FLAG:
5074                 if (suboptoff+1 > optend) {
5075                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
5076                         return (optend);
5077                 }
5078                 fetch_tgt = tvb_get_guint8(tvb, suboptoff);
5079                 proto_item_append_text(vti, "%s (%u byte%s%s)",
5080                                        fetch_tgt ? "Yes" : "No",
5081                                        subopt_len,
5082                                        plurality(subopt_len, "", "s"),
5083                                        subopt_len != 1 ? " [Invalid]" : "");
5084                 suboptoff += 1;
5085                 break;
5086
5087         case PKT_CCC_PROV_TIMER:
5088                 if (suboptoff+1 > optend) {
5089                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
5090                         return (optend);
5091                 }
5092                 if (revision == PACKETCABLE_CCC_DRAFT5)
5093                         max_timer_val = 30;
5094                 timer_val = tvb_get_guint8(tvb, suboptoff);
5095                 proto_item_append_text(vti, "%u%s (%u byte%s%s)", timer_val,
5096                                        timer_val > max_timer_val ? " [Invalid]" : "",
5097                                        subopt_len,
5098                                        plurality(subopt_len, "", "s"),
5099                                        subopt_len != 1 ? " [Invalid]" : "");
5100                 suboptoff += 1;
5101                 break;
5102
5103         case PKT_CCC_IETF_SEC_TKT:
5104                 if (suboptoff+2 > optend) {
5105                         expert_add_info(pinfo, vti, &ei_bootp_missing_subopt_value);
5106                         return (optend);
5107                 }
5108                 sec_tcm = tvb_get_ntohs(tvb, suboptoff);
5109                 proto_item_append_text(vti, "0x%04x (%u byte%s%s)", sec_tcm, subopt_len,
5110                                        plurality(subopt_len, "", "s"),
5111                                        subopt_len != 2 ? " [Invalid]" : "");
5112                 if (subopt_len == 2) {
5113                         pkt_s_tree = proto_item_add_subtree(vti, ett_bootp_option);
5114                         for (i = 0; i < 2; i++) {
5115                                 if (sec_tcm & sec_tcm_vals[i].value) {
5116                                         decode_bitfield_value(bit_fld, sec_tcm, sec_tcm_vals[i].value, 16);
5117                                         proto_tree_add_text(pkt_s_tree, tvb, suboptoff, 2, "%sInvalidate %s",
5118                                                             bit_fld, sec_tcm_vals[i].strptr);
5119                                 }
5120                         }
5121                 }
5122                 suboptoff += subopt_len;
5123                 break;
5124
5125         default:
5126                 suboptoff += subopt_len;
5127                 break;
5128         }
5129         return suboptoff;
5130 }
5131
5132 #define BOOTREQUEST     1
5133 #define BOOTREPLY       2
5134
5135 static const value_string op_vals[] = {
5136         { BOOTREQUEST,  "Boot Request" },
5137         { BOOTREPLY,    "Boot Reply" },
5138         { 0,            NULL }
5139 };
5140
5141 static void
5142 dissect_bootp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5143 {
5144         proto_tree   *bp_tree;
5145         proto_item   *bp_ti, *ti;
5146         proto_tree   *flag_tree;
5147         proto_item   *fi, *hidden_item;
5148         guint8        op;
5149         guint8        htype, hlen;
5150         int           voff, eoff, tmpvoff; /* vendor offset, end offset */
5151         guint32       ip_addr;
5152         gboolean      at_end;
5153         const char   *dhcp_type                              = NULL;
5154         const guint8 *vendor_class_id                        = NULL;
5155         guint16       flags, secs;
5156         int           offset_delta;
5157         guint8        overload                               = 0; /* DHCP option overload */
5158         rfc3396_dns_domain_search_list.total_number_of_block = 0;
5159         rfc3396_dns_domain_search_list.tvb_composite         = NULL;
5160         rfc3396_sip_server.total_number_of_block             = 0;
5161         rfc3396_sip_server.tvb_composite                     = NULL;
5162
5163         col_set_str(pinfo->cinfo, COL_PROTOCOL, "BOOTP");
5164         /*
5165          * In case we throw an exception fetching the opcode, etc.
5166          */
5167         col_clear(pinfo->cinfo, COL_INFO);
5168
5169         op = tvb_get_guint8(tvb, 0);
5170         htype = tvb_get_guint8(tvb, 1);
5171         hlen = tvb_get_guint8(tvb, 2);
5172         switch (op) {
5173
5174         case BOOTREQUEST:
5175                 if ((htype == ARPHRD_ETHER || htype == ARPHRD_IEEE802)
5176                     && hlen == 6) {
5177                         col_add_fstr(pinfo->cinfo, COL_INFO, "Boot Request from %s (%s)",
5178                                      tvb_arphrdaddr_to_str(tvb, 28, hlen, htype),
5179                                      get_ether_name(tvb_get_ptr(tvb, 28, hlen)));
5180                 }
5181                 else {
5182                         col_add_fstr(pinfo->cinfo, COL_INFO, "Boot Request from %s",
5183                                      tvb_arphrdaddr_to_str(tvb, 28, hlen, htype));
5184                 }
5185                 break;
5186
5187         case BOOTREPLY:
5188                 col_set_str(pinfo->cinfo, COL_INFO, "Boot Reply");
5189                 break;
5190
5191         default:
5192                 col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown BOOTP message type (%u)", op);
5193                 break;
5194         }
5195
5196         voff = VENDOR_INFO_OFFSET;
5197
5198         /* rfc2132 says it SHOULD exist, not that it MUST exist */
5199         if (tvb_bytes_exist(tvb, voff, 4) &&
5200             (tvb_get_ntohl(tvb, voff) == 0x63825363)) {
5201                 voff += 4;
5202         } else {
5203                 voff += 64;
5204         }
5205         eoff = tvb_reported_length(tvb);
5206
5207         /*
5208          * In the first pass, we just look for the DHCP message type
5209          * and Vendor class identifier options.
5210          */
5211         tmpvoff = voff;
5212         at_end = FALSE;
5213         rfc3396_dns_domain_search_list.index_current_block = 0;
5214         rfc3396_sip_server.index_current_block = 0;
5215         while (tmpvoff < eoff && !at_end) {
5216                 offset_delta = bootp_option(tvb, pinfo, NULL, NULL, tmpvoff, eoff, TRUE, &at_end,
5217                     &dhcp_type, &vendor_class_id, &overload);
5218                 if (offset_delta <= 0) {
5219                         THROW(ReportedBoundsError);
5220                 }
5221                 tmpvoff += offset_delta;
5222         }
5223
5224         /*
5225          * If there was a DHCP message type option, flag this packet
5226          * as DHCP.
5227          */
5228         if (dhcp_type != NULL) {
5229                 /*
5230                  * Yes, this is a DHCP packet, and "dhcp_type" is the
5231                  * packet type.
5232                  */
5233                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DHCP");
5234
5235                 col_add_fstr(pinfo->cinfo, COL_INFO, "DHCP %-8s - Transaction ID 0x%x",
5236                              dhcp_type, tvb_get_ntohl(tvb, 4));
5237                 tap_queue_packet( bootp_dhcp_tap, pinfo, dhcp_type);
5238         }
5239
5240         /*
5241          * OK, now build the protocol tree.
5242          */
5243
5244         bp_ti = proto_tree_add_item(tree, proto_bootp, tvb, 0, -1, ENC_NA);
5245         bp_tree = proto_item_add_subtree(bp_ti, ett_bootp);
5246
5247         proto_tree_add_uint(bp_tree, hf_bootp_type, tvb,
5248                                    0, 1,
5249                                    op);
5250         proto_tree_add_item(bp_tree, hf_bootp_hw_type, tvb,
5251                                          1, 1, ENC_BIG_ENDIAN);
5252         proto_tree_add_uint(bp_tree, hf_bootp_hw_len, tvb,
5253                             2, 1, hlen);
5254         proto_tree_add_item(bp_tree, hf_bootp_hops, tvb,
5255                             3, 1, ENC_BIG_ENDIAN);
5256         proto_tree_add_item(bp_tree, hf_bootp_id, tvb,
5257                             4, 4, ENC_BIG_ENDIAN);
5258         /*
5259          * Windows (98, XP and Vista tested) sends the "secs" value on
5260          * the wire formatted as little-endian. See if the LE value
5261          * makes sense.
5262          */
5263         secs = tvb_get_letohs(tvb, 8);
5264         if (secs > 0 && secs <= 0xff) {
5265                 ti = proto_tree_add_uint_format_value(bp_tree, hf_bootp_secs, tvb,
5266                             8, 2, secs, "%u", secs);
5267                 expert_add_info_format(pinfo, ti, &ei_bootp_secs_le, "Seconds elapsed appears to be encoded as little-endian");
5268         } else {
5269                 proto_tree_add_item(bp_tree, hf_bootp_secs, tvb,
5270                             8, 2, ENC_BIG_ENDIAN);
5271         }
5272         flags = tvb_get_ntohs(tvb, 10);
5273         fi = proto_tree_add_uint(bp_tree, hf_bootp_flags, tvb,
5274                             10, 2, flags);
5275         proto_item_append_text(fi, " (%s)",
5276             (flags & BOOTP_BC) ? "Broadcast" : "Unicast");
5277         flag_tree = proto_item_add_subtree(fi, ett_bootp_flags);
5278         proto_tree_add_boolean(flag_tree, hf_bootp_flags_broadcast, tvb,
5279                             10, 2, flags);
5280         proto_tree_add_uint(flag_tree, hf_bootp_flags_reserved, tvb,
5281                             10, 2, flags);
5282         proto_tree_add_item(bp_tree, hf_bootp_ip_client, tvb,
5283                             12, 4, ENC_BIG_ENDIAN);
5284         proto_tree_add_item(bp_tree, hf_bootp_ip_your, tvb,
5285                             16, 4, ENC_BIG_ENDIAN);
5286         proto_tree_add_item(bp_tree, hf_bootp_ip_server, tvb,
5287                             20, 4, ENC_BIG_ENDIAN);
5288         proto_tree_add_item(bp_tree, hf_bootp_ip_relay, tvb,
5289                             24, 4, ENC_BIG_ENDIAN);
5290
5291         if (hlen > 0 && hlen <= 16) {
5292                 if ((htype == ARPHRD_ETHER || htype == ARPHRD_IEEE802)
5293                     && hlen == 6)
5294                         proto_tree_add_item(bp_tree, hf_bootp_hw_ether_addr, tvb, 28, 6, ENC_NA);
5295                 else
5296                         /* The chaddr element is 16 bytes in length,
5297                            although only the first hlen bytes are used */
5298                         proto_tree_add_bytes_format_value(bp_tree, hf_bootp_hw_addr, tvb, 28, 16,
5299                                            NULL, "%s", tvb_arphrdaddr_to_str(tvb, 28, hlen, htype));
5300                 if ((16 - hlen) > 0)
5301                         proto_tree_add_item(bp_tree, hf_bootp_hw_addr_padding, tvb, 28+hlen, 16-hlen, ENC_NA);
5302         } else {
5303                 proto_tree_add_text(bp_tree,  tvb,
5304                                            28, 16, "Client address not given");
5305         }
5306
5307         if (overload & OPT_OVERLOAD_SNAME) {
5308                 proto_tree_add_text (bp_tree, tvb,
5309                         SERVER_NAME_OFFSET, SERVER_NAME_LEN,
5310                         "Server name option overloaded by DHCP");
5311         } else {
5312                 /* The server host name is optional */
5313                 if (tvb_get_guint8(tvb, SERVER_NAME_OFFSET) != '\0') {
5314                         proto_tree_add_item(bp_tree, hf_bootp_server, tvb,
5315                                            SERVER_NAME_OFFSET,
5316                                            SERVER_NAME_LEN, ENC_ASCII|ENC_NA);
5317
5318                 } else {
5319                         proto_tree_add_string_format(bp_tree, hf_bootp_server, tvb,
5320                                                    SERVER_NAME_OFFSET,
5321                                                    SERVER_NAME_LEN,
5322                                                    "", "Server host name not given");
5323                 }
5324         }
5325
5326         if (overload & OPT_OVERLOAD_FILE) {
5327                 proto_tree_add_text (bp_tree, tvb,
5328                         FILE_NAME_OFFSET, FILE_NAME_LEN,
5329                         "Boot file name option overloaded by DHCP");
5330         } else {
5331                 /* Boot file is optional */
5332                 if (tvb_get_guint8(tvb, FILE_NAME_OFFSET) != '\0') {
5333                         proto_tree_add_item(bp_tree, hf_bootp_file, tvb,
5334                                            FILE_NAME_OFFSET,
5335                                            FILE_NAME_LEN, ENC_ASCII|ENC_NA);
5336                 } else {
5337                         proto_tree_add_string_format(bp_tree, hf_bootp_file, tvb,
5338                                                    FILE_NAME_OFFSET,
5339                                                    FILE_NAME_LEN,
5340                                                    "", "Boot file name not given");
5341                 }
5342         }
5343
5344         voff = VENDOR_INFO_OFFSET;
5345         if (dhcp_type != NULL) {
5346                 hidden_item = proto_tree_add_boolean(bp_tree, hf_bootp_dhcp, tvb, 0, 0, 1);
5347                 PROTO_ITEM_SET_HIDDEN(hidden_item);
5348         }
5349         if (tvb_bytes_exist(tvb, voff, 4) &&
5350             (tvb_get_ntohl(tvb, voff) == 0x63825363)) {
5351                 ip_addr = tvb_get_ipv4(tvb, voff);
5352                 proto_tree_add_ipv4_format_value(bp_tree, hf_bootp_cookie, tvb,
5353                         voff, 4, ip_addr, "DHCP");
5354                 voff += 4;
5355         } else {
5356                 proto_tree_add_text(bp_tree,  tvb,
5357                         voff, 64, "Bootp vendor specific options");
5358                 voff += 64;
5359         }
5360
5361         at_end = FALSE;
5362         rfc3396_dns_domain_search_list.index_current_block = 0;
5363         rfc3396_sip_server.index_current_block = 0;
5364         while (voff < eoff && !at_end) {
5365                 offset_delta = bootp_option(tvb, pinfo, bp_tree, bp_ti, voff, eoff, FALSE, &at_end,
5366                     &dhcp_type, &vendor_class_id, &overload);
5367                 if (offset_delta <= 0) {
5368                         THROW(ReportedBoundsError);
5369                 }
5370                 voff += offset_delta;
5371         }
5372         if ((dhcp_type != NULL) && (!at_end))
5373         {
5374                 expert_add_info(pinfo, bp_ti, &ei_bootp_end_option_missing);
5375         }
5376         if (voff < eoff) {
5377                 /*
5378                  * Padding after the end option.
5379                  */
5380                 proto_tree_add_text(bp_tree, tvb, voff, eoff - voff, "Padding");
5381         }
5382 }
5383
5384 static void
5385 bootp_init_protocol(void)
5386 {
5387         guint i;
5388
5389         /* first copy default_bootp_opt[] to bootp_opt[].  This resets all values to default */
5390         for(i=0; i<BOOTP_OPT_NUM; i++)
5391         {
5392                 bootp_opt[i].text = default_bootp_opt[i].text;
5393                 bootp_opt[i].ftype = default_bootp_opt[i].ftype;
5394                 bootp_opt[i].phf = default_bootp_opt[i].phf;
5395         }
5396
5397         /* Now apply the custom options */
5398         for (i = 0; i < num_bootp_records_uat; i++)
5399         {
5400                 bootp_opt[uat_bootp_records[i].opt].text = wmem_strdup(wmem_file_scope(), uat_bootp_records[i].text);
5401                 bootp_opt[uat_bootp_records[i].opt].ftype = uat_bootp_records[i].ftype;
5402                 bootp_opt[uat_bootp_records[i].opt].phf = NULL;
5403         }
5404 }
5405
5406 void
5407 proto_register_bootp(void)
5408 {
5409         static const value_string bootp_custom_type_vals[] = {
5410                 { ipv4,             "IP Address"},
5411                 { ipv4_list,        "IP Address List" },
5412                 { string,           "string" },
5413                 { bytes,            "bytes" },
5414                 { val_boolean,      "boolean" },
5415                 { val_u_byte,       "byte" },
5416                 { val_u_short,      "unsigned short" },
5417                 { val_u_short_list, "unsigned short list" },
5418                 { val_u_long,       "unsigned long" },
5419                 { time_in_s_secs,   "integer time in seconds" },
5420                 { time_in_u_secs,   "unsigned integer time in seconds" },
5421                 { 0x00, NULL }
5422         };
5423
5424         static hf_register_info hf[] = {
5425                 { &hf_bootp_dhcp,
5426                   { "Frame is DHCP", "bootp.dhcp",
5427                     FT_BOOLEAN, BASE_NONE, NULL, 0x0,
5428                     NULL, HFILL }},
5429
5430                 { &hf_bootp_type,
5431                   { "Message type", "bootp.type",
5432                     FT_UINT8, BASE_DEC, VALS(op_vals), 0x0,
5433                     NULL, HFILL }},
5434
5435                 { &hf_bootp_hw_type,
5436                   { "Hardware type", "bootp.hw.type",
5437                     FT_UINT8, BASE_HEX, VALS(arp_hrd_vals), 0x0,
5438                     NULL, HFILL }},
5439
5440                 { &hf_bootp_hw_len,
5441                   { "Hardware address length", "bootp.hw.len",
5442                     FT_UINT8, BASE_DEC, NULL, 0x0,
5443                     NULL, HFILL }},
5444
5445                 { &hf_bootp_hops,
5446                   { "Hops", "bootp.hops",
5447                     FT_UINT8, BASE_DEC, NULL, 0x0,
5448                     NULL, HFILL }},
5449
5450                 { &hf_bootp_id,
5451                   { "Transaction ID", "bootp.id",
5452                     FT_UINT32, BASE_HEX, NULL, 0x0,
5453                     NULL, HFILL }},
5454
5455                 { &hf_bootp_secs,
5456                   { "Seconds elapsed", "bootp.secs",
5457                     FT_UINT16, BASE_DEC, NULL, 0x0,
5458                     NULL, HFILL }},
5459
5460                 { &hf_bootp_flags,
5461                   { "Bootp flags", "bootp.flags",
5462                     FT_UINT16, BASE_HEX, NULL, 0x0,
5463                     NULL, HFILL }},
5464
5465                 { &hf_bootp_flags_broadcast,
5466                   { "Broadcast flag", "bootp.flags.bc",
5467                     FT_BOOLEAN, 16, TFS(&flag_set_broadcast), BOOTP_BC,
5468                     NULL, HFILL }},
5469
5470                 { &hf_bootp_flags_reserved,
5471                   { "Reserved flags", "bootp.flags.reserved",
5472                     FT_UINT16, BASE_HEX, NULL, BOOTP_MBZ,
5473                     NULL, HFILL }},
5474
5475                 { &hf_bootp_ip_client,
5476                   { "Client IP address", "bootp.ip.client",
5477                     FT_IPv4, BASE_NONE, NULL, 0x0,
5478                     NULL, HFILL }},
5479
5480                 { &hf_bootp_ip_your,
5481                   { "Your (client) IP address", "bootp.ip.your",
5482                     FT_IPv4, BASE_NONE, NULL, 0x0,
5483                     NULL, HFILL }},
5484
5485                 { &hf_bootp_ip_server,
5486                   { "Next server IP address", "bootp.ip.server",
5487                     FT_IPv4, BASE_NONE, NULL, 0x0,
5488                     NULL, HFILL }},
5489
5490                 { &hf_bootp_ip_relay,
5491                   { "Relay agent IP address", "bootp.ip.relay",
5492                     FT_IPv4, BASE_NONE, NULL, 0x0,
5493                     NULL, HFILL }},
5494
5495                 { &hf_bootp_hw_addr,
5496                   { "Client hardware address", "bootp.hw.addr",
5497                     FT_BYTES, BASE_NONE, NULL, 0x0,
5498                     NULL, HFILL }},
5499
5500                 { &hf_bootp_hw_addr_padding,
5501                   { "Client hardware address padding", "bootp.hw.addr_padding",
5502                     FT_BYTES, BASE_NONE, NULL, 0x0,
5503                     NULL, HFILL }},
5504
5505                 { &hf_bootp_hw_ether_addr,
5506                   { "Client MAC address", "bootp.hw.mac_addr",
5507                     FT_ETHER, BASE_NONE, NULL, 0x0,
5508                     NULL, HFILL }},
5509
5510                 { &hf_bootp_server,
5511                   { "Server host name", "bootp.server",
5512                     FT_STRING, BASE_NONE, NULL, 0x0,
5513                     NULL, HFILL }},
5514
5515                 { &hf_bootp_file,
5516                   { "Boot file name", "bootp.file",
5517                     FT_STRING, BASE_NONE, NULL, 0x0,
5518                     NULL, HFILL }},
5519
5520                 { &hf_bootp_cookie,
5521                   { "Magic cookie", "bootp.cookie",
5522                     FT_IPv4, BASE_NONE, NULL, 0x0,
5523                     NULL, HFILL }},
5524
5525                 { &hf_bootp_fqdn_s,
5526                   { "Server", "bootp.fqdn.s",
5527                     FT_BOOLEAN, 8, TFS(&tfs_fqdn_s), F_FQDN_S,
5528                     "If true, server should do DDNS update", HFILL }},
5529
5530                 { &hf_bootp_fqdn_o,
5531                   { "Server overrides", "bootp.fqdn.o",
5532                     FT_BOOLEAN, 8, TFS(&tfs_fqdn_o), F_FQDN_O,
5533                     "If true, server insists on doing DDNS update", HFILL }},
5534
5535                 { &hf_bootp_fqdn_e,
5536                   { "Encoding", "bootp.fqdn.e",
5537                     FT_BOOLEAN, 8, TFS(&tfs_fqdn_e), F_FQDN_E,
5538                     "If true, name is binary encoded", HFILL }},
5539
5540                 { &hf_bootp_fqdn_n,
5541                   { "Server DDNS", "bootp.fqdn.n",
5542                     FT_BOOLEAN, 8, TFS(&tfs_fqdn_n), F_FQDN_N,
5543                     "If true, server should not do any DDNS updates", HFILL }},
5544
5545                 { &hf_bootp_fqdn_mbz,
5546                   { "Reserved flags", "bootp.fqdn.mbz",
5547                     FT_UINT8, BASE_HEX, NULL, F_FQDN_MBZ,
5548                     NULL, HFILL }},
5549
5550                 { &hf_bootp_fqdn_rcode1,
5551                   { "A-RR result", "bootp.fqdn.rcode1",
5552                     FT_UINT8, BASE_DEC, NULL, 0x0,
5553                     "Result code of A-RR update", HFILL }},
5554
5555                 { &hf_bootp_fqdn_rcode2,
5556                   { "PTR-RR result", "bootp.fqdn.rcode2",
5557                     FT_UINT8, BASE_DEC, NULL, 0x0,
5558                     "Result code of PTR-RR update", HFILL }},
5559
5560                 { &hf_bootp_fqdn_name,
5561                   { "Client name", "bootp.fqdn.name",
5562                     FT_STRING, BASE_NONE, NULL, 0x0,
5563                     "Name to register via DDNS", HFILL }},
5564
5565                 { &hf_bootp_fqdn_asciiname,
5566                   { "Client name", "bootp.fqdn.name",
5567                     FT_STRING, BASE_NONE, NULL, 0x0,
5568                     "Name to register via DDNS", HFILL }},
5569
5570                 { &hf_bootp_pkt_mta_cap_len,
5571                   { "MTA DC Length", "bootp.vendor.pktc.mta_cap_len",
5572                     FT_UINT8, BASE_DEC, NULL, 0x0,
5573                     "PacketCable MTA Device Capabilities Length", HFILL }},
5574
5575                 { &hf_bootp_docsis_cm_cap_len,
5576                   { "CM DC Length", "bootp.vendor.docsis.cm_cap_len",
5577                     FT_UINT8, BASE_DEC, NULL, 0x0,
5578                     "DOCSIS Cable Modem Device Capabilities Length", HFILL }},
5579
5580                 { &hf_bootp_docsis_cm_cap_type,
5581                   { "CM DC Type", "bootp.docsis_cm_cap_type",
5582                     FT_UINT16, BASE_DEC, VALS(docsis_cm_cap_type_vals), 0x0,
5583                     "Docsis Cable Modem Device Capability type", HFILL }},
5584
5585                 { &hf_bootp_client_identifier_uuid,
5586                   { "Client Identifier (UUID)", "bootp.client_id_uuid",
5587                     FT_GUID, BASE_NONE, NULL, 0x0,
5588                     "Client Machine Identifier (UUID)", HFILL }},
5589
5590                 { &hf_bootp_client_identifier_duid_llt_hw_type,
5591                   { "Hardware type", "bootp.client_id_duid_llt_hw_type",
5592                     FT_UINT16, BASE_DEC, VALS(arp_hrd_vals), 0x0,
5593                     "Client Identifier DUID LLT Hardware type", HFILL }},
5594
5595                 { &hf_bootp_client_identifier_duid_ll_hw_type,
5596                   { "Hardware type", "bootp.client_id_duid_ll_hw_type",
5597                     FT_UINT16, BASE_DEC, VALS(arp_hrd_vals), 0x0,
5598                     "Client Identifier DUID LL Hardware type", HFILL }},
5599
5600                 { &hf_bootp_option_type,
5601                   { "Option", "bootp.option.type",
5602                     FT_UINT8, BASE_DEC, NULL, 0x0,
5603                     "Bootp/Dhcp option type", HFILL }},
5604
5605                 { &hf_bootp_option_length,
5606                   { "Length", "bootp.option.length",
5607                     FT_UINT8, BASE_DEC, NULL, 0x0,
5608                     "Bootp/Dhcp option length", HFILL }},
5609
5610                 { &hf_bootp_suboption_length,
5611                   { "Length", "bootp.option.suboption_length",
5612                     FT_UINT8, BASE_DEC, NULL, 0x0,
5613                     "Suboption length", HFILL }},
5614
5615                 { &hf_bootp_option_value,
5616                   { "Value", "bootp.option.value",
5617                     FT_BYTES, BASE_NONE, NULL, 0x0,
5618                     "Bootp/Dhcp option value", HFILL }},
5619
5620                 { &hf_bootp_option_value_8,
5621                   { "Value", "bootp.option.value.uint",
5622                     FT_UINT8, BASE_DEC, NULL, 0x0,
5623                     "8-bit Bootp/Dhcp option value", HFILL }},
5624
5625                 { &hf_bootp_option_value_16,
5626                   { "Value", "bootp.option.value.uint",
5627                     FT_UINT16, BASE_DEC, NULL, 0x0,
5628                     "16-bit Bootp/Dhcp option value", HFILL }},
5629
5630                 { &hf_bootp_option_value_u32,
5631                   { "Value", "bootp.option.value.uint",
5632                     FT_UINT32, BASE_HEX, NULL, 0x0,
5633                     "32-bit Bootp/Dhcp option value", HFILL }},
5634
5635                 { &hf_bootp_option_value_i32,
5636                   { "Value", "bootp.option.value.int",
5637                     FT_INT32, BASE_DEC, NULL, 0x0,
5638                     "32-bit Bootp/Dhcp option value", HFILL }},
5639
5640                 { &hf_bootp_option_value_stringz,
5641                   { "Value", "bootp.option.value.string",
5642                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
5643                     "Z-String Bootp/Dhcp option value", HFILL }},
5644
5645                 { &hf_bootp_option_value_ip_address,
5646                   { "Value", "bootp.option.value.address",
5647                     FT_IPv4, BASE_NONE, NULL, 0x00,
5648                     "IP address Bootp/Dhcp option value", HFILL }},
5649
5650                 { &hf_bootp_option_value_boolean,
5651                   { "Value", "bootp.option.value.bool",
5652                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_true_false), 0x00,
5653                     "Boolean Bootp/Dhcp option value", HFILL }},
5654
5655                 { &hf_bootp_option_padding,
5656                   { "Padding", "bootp.option.padding",
5657                     FT_BYTES, BASE_NONE, NULL, 0x0,
5658                     "Option 0: Padding", HFILL }},
5659
5660                 { &hf_bootp_option_subnet_mask,
5661                   { "Subnet Mask", "bootp.option.subnet_mask",
5662                     FT_IPv4, BASE_NONE, NULL, 0x00,
5663                     "Option 1: Subnet Mask", HFILL }},
5664
5665                 { &hf_bootp_option_time_offset,
5666                   { "Time Offset", "bootp.option.time_offset",
5667                     FT_INT32, BASE_DEC, NULL, 0x00,
5668                     "Option 2: Time Offset", HFILL }},
5669
5670                 { &hf_bootp_option_router,
5671                   { "Router", "bootp.option.router",
5672                     FT_IPv4, BASE_NONE, NULL, 0x00,
5673                     "Option 3: Router", HFILL }},
5674
5675                 { &hf_bootp_option_time_server,
5676                   { "Time Server", "bootp.option.time_server",
5677                     FT_IPv4, BASE_NONE, NULL, 0x00,
5678                     "Option 4: Time Server", HFILL }},
5679
5680                 { &hf_bootp_option_name_server,
5681                   { "Name Server", "bootp.option.name_server",
5682                     FT_IPv4, BASE_NONE, NULL, 0x00,
5683                     "Option 5: Name Server", HFILL }},
5684
5685                 { &hf_bootp_option_domain_name_server,
5686                   { "Domain Name Server", "bootp.option.domain_name_server",
5687                     FT_IPv4, BASE_NONE, NULL, 0x00,
5688                     "Option 6: Domain Name Server", HFILL }},
5689
5690                 { &hf_bootp_option_log_server,
5691                   { "Log Server", "bootp.option.log_server",
5692                     FT_IPv4, BASE_NONE, NULL, 0x00,
5693                     "Option 7: Log Server", HFILL }},
5694
5695                 { &hf_bootp_option_quotes_server,
5696                   { "Quotes Server", "bootp.option.quotes_server",
5697                     FT_IPv4, BASE_NONE, NULL, 0x00,
5698                     "Option 8: Quotes Server", HFILL }},
5699
5700                 { &hf_bootp_option_lpr_server,
5701                   { "LPR Server", "bootp.option.lpr_server",
5702                     FT_IPv4, BASE_NONE, NULL, 0x00,
5703                     "Option 9: LPR Server", HFILL }},
5704
5705                 { &hf_bootp_option_impress_server,
5706                   { "Impress Server", "bootp.option.impress_server",
5707                     FT_IPv4, BASE_NONE, NULL, 0x00,
5708                     "Option 10: Impress Server", HFILL }},
5709
5710                 { &hf_bootp_option_resource_location_server,
5711                   { "Resource Location Server", "bootp.option.resource_location_server",
5712                     FT_IPv4, BASE_NONE, NULL, 0x00,
5713                     "Option 11: Resource Location Server", HFILL }},
5714
5715                 { &hf_bootp_option_hostname,
5716                   { "Host Name", "bootp.option.hostname",
5717                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
5718                     "Option 12: Host Name", HFILL }},
5719
5720                 { &hf_bootp_option_boot_file_size,
5721                   { "Boot File Size", "bootp.option.boot_file_size",
5722                     FT_UINT16, BASE_DEC, NULL, 0x0,
5723                     "Option 13: Boot File Size", HFILL }},
5724
5725                 { &hf_bootp_option_merit_dump_file,
5726                   { "Merit Dump File", "bootp.option.merit_dump_file",
5727                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
5728                     "Option 14: Merit Dump File", HFILL }},
5729
5730                 { &hf_bootp_option_domain_name,
5731                   { "Domain Name", "bootp.option.domain_name",
5732                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
5733                     "Option 15: Domain Name", HFILL }},
5734
5735                 { &hf_bootp_option_swap_server,
5736                   { "Swap Server", "bootp.option.swap_server",
5737                     FT_IPv4, BASE_NONE, NULL, 0x00,
5738                     "Option 16: Swap Server", HFILL }},
5739
5740                 { &hf_bootp_option_root_path,
5741                   { "Root Path", "bootp.option.root_path",
5742                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
5743                     "Option 17: Root Path", HFILL }},
5744
5745                 { &hf_bootp_option_extension_path,
5746                   { "Extensions Path", "bootp.option.extension_path",
5747                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
5748                     "Option 18: Extensions Path", HFILL }},
5749
5750                 { &hf_bootp_option_ip_forwarding,
5751                   { "IP Forwarding", "bootp.option.ip_forwarding",
5752                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_enabled_disabled), 0x00,
5753                     "Option 19: IP Forwarding", HFILL }},
5754
5755                 { &hf_bootp_option_policy_filter_ip,
5756                   { "IP Address", "bootp.option.policy_filter.ip",
5757                     FT_IPv4, BASE_NONE, NULL, 0x00,
5758                     "Option 21: IP address", HFILL }},
5759
5760                 { &hf_bootp_option_policy_filter_subnet_mask,
5761                   { "Subnet Mask", "bootp.option.policy_filter.subnet_mask",
5762                     FT_IPv4, BASE_NONE, NULL, 0x00,
5763                     "Option 21: Subnet Mask", HFILL }},
5764
5765                 { &hf_bootp_option_non_local_source_routing,
5766                   { "Non-Local Source Routing", "bootp.option.non_local_source_routing",
5767                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_enabled_disabled), 0x00,
5768                     "Option 20: Non-Local Source Routing", HFILL }},
5769
5770                 { &hf_bootp_option_max_datagram_reassembly_size,
5771                   { "Maximum Datagram Reassembly Size", "bootp.option.max_datagram_reassembly_size",
5772                     FT_UINT16, BASE_DEC, NULL, 0x0,
5773                     "Option 22: Maximum Datagram Reassembly Size", HFILL }},
5774
5775                 { &hf_bootp_option_default_ip_ttl,
5776                   { "Default IP Time-to-Live", "bootp.option.default_ip_ttl",
5777                     FT_UINT8, BASE_DEC, NULL, 0x0,
5778                     "Option 23: Default IP Time-to-Live", HFILL }},
5779
5780                 { &hf_bootp_option_path_mtu_aging_timeout,
5781                   { "Path MTU Aging Timeout", "bootp.option.path_mtu_aging_timeout",
5782                     FT_UINT32, BASE_DEC, NULL, 0x00,
5783                     "Option 24: Path MTU Aging Timeout", HFILL }},
5784
5785                 { &hf_bootp_option_path_mtu_plateau_table_item,
5786                   { "Path MTU Plateau Table Item", "bootp.option.path_mtu_plateau_table_item",
5787                     FT_UINT16, BASE_DEC, NULL, 0x0,
5788                     "Option 25: Path MTU Plateau Table Item", HFILL }},
5789
5790                 { &hf_bootp_option_interface_mtu,
5791                   { "Interface MTU", "bootp.option.interface_mtu",
5792                     FT_UINT16, BASE_DEC, NULL, 0x0,
5793                     "Option 26: Interface MTU", HFILL }},
5794
5795                 { &hf_bootp_option_all_subnets_are_local,
5796                   { "All Subnets are Local", "bootp.option.all_subnets_are_local",
5797                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x00,
5798                     "Option 27: All Subnets are Local", HFILL }},
5799
5800                 { &hf_bootp_option_broadcast_address,
5801                   { "Broadcast Address", "bootp.option.broadcast_address",
5802                     FT_IPv4, BASE_NONE, NULL, 0x00,
5803                     "Option 28: Broadcast Address", HFILL }},
5804
5805                 { &hf_bootp_option_perform_mask_discovery,
5806                   { "Perform Mask Discovery", "bootp.option.perform_mask_discovery",
5807                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_enabled_disabled), 0x00,
5808                     "Option 29: Perform Mask Discovery", HFILL }},
5809
5810                 { &hf_bootp_option_mask_supplier,
5811                   { "Mask Supplier", "bootp.option.mask_supplier",
5812                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x00,
5813                     "Option 30: Mask Supplier", HFILL }},
5814
5815                 { &hf_bootp_option_perform_router_discover,
5816                   { "Perform Router Discover", "bootp.option.perform_router_discover",
5817                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_enabled_disabled), 0x00,
5818                     "Option 31: Perform Router Discover", HFILL }},
5819
5820                 { &hf_bootp_option_router_solicitation_address,
5821                   { "Router Solicitation Address", "bootp.option.router_solicitation_address",
5822                     FT_IPv4, BASE_NONE, NULL, 0x00,
5823                     "Option 32: Router Solicitation Address", HFILL }},
5824
5825                 { &hf_bootp_option_static_route_ip,
5826                   { "Destination IP Address", "bootp.option.static_route.ip",
5827                     FT_IPv4, BASE_NONE, NULL, 0x00,
5828                     "Option 33: Destination IP address", HFILL }},
5829
5830                 { &hf_bootp_option_static_route_router,
5831                   { "Destination Router", "bootp.option.static_route.router",
5832                     FT_IPv4, BASE_NONE, NULL, 0x00,
5833                     "Option 33: Destination Router", HFILL }},
5834
5835                 { &hf_bootp_option_trailer_encapsulation,
5836                   { "Trailer Encapsulation", "bootp.option.trailer_encapsulation",
5837                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_enabled_disabled), 0x00,
5838                     "Option 34: Trailer Encapsulation", HFILL }},
5839
5840                 { &hf_bootp_option_arp_cache_timeout,
5841                   { "ARP Cache Timeout", "bootp.option.arp_cache_timeout",
5842                     FT_UINT32, BASE_DEC, NULL, 0x00,
5843                     "Option 35: ARP Cache Timeout", HFILL }},
5844
5845                 { &hf_bootp_option_ethernet_encapsulation,
5846                   { "Ethernet Encapsulation", "bootp.option.ethernet_encapsulation",
5847                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_enabled_disabled), 0x00,
5848                     "Option 36: Ethernet Encapsulation", HFILL }},
5849
5850                 { &hf_bootp_option_tcp_default_ttl,
5851                   { "TCP Default TTL", "bootp.option.tcp_default_ttl",
5852                     FT_UINT8, BASE_DEC, NULL, 0x0,
5853                     "Option 37: TCP Default TTL", HFILL }},
5854
5855                 { &hf_bootp_option_tcp_keepalive_interval,
5856                   { "TCP Keepalive Interval", "bootp.option.tcp_keepalive_interval",
5857                     FT_UINT32, BASE_DEC, NULL, 0x00,
5858                     "Option 38: TCP Keepalive Interval", HFILL }},
5859
5860                 { &hf_bootp_option_tcp_keepalive_garbage,
5861                   { "TCP Keepalive Garbage", "bootp.option.tcp_keepalive_garbage",
5862                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_enabled_disabled), 0x00,
5863                     "Option 39: TCP Keepalive Garbage", HFILL }},
5864
5865                 { &hf_bootp_option_nis_domain,
5866                   { "Network Information Service Domain", "bootp.option.nis_domain",
5867                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
5868                     "Option 40: Network Information Service Domain", HFILL }},
5869
5870                 { &hf_bootp_option_nis_server,
5871                   { "Network Information Service Server", "bootp.option.nis_server",
5872                     FT_IPv4, BASE_NONE, NULL, 0x00,
5873                     "Option 41: Network Information Service Server", HFILL }},
5874
5875                 { &hf_bootp_option_ntp_server,
5876                   { "Network Time Protocol Server", "bootp.option.ntp_server",
5877                     FT_IPv4, BASE_NONE, NULL, 0x00,
5878                     "Option 42: Network Time Protocol Server", HFILL }},
5879
5880
5881                 { &hf_bootp_option43_value,
5882                   { "Value", "bootp.option.vendor.value",
5883                     FT_BYTES, BASE_NONE, NULL, 0x0,
5884                     "Option 43: Suboption value", HFILL }},
5885
5886                 { &hf_bootp_option43_value_8,
5887                   { "Value", "bootp.option.vendor.value.uint",
5888                     FT_UINT8, BASE_DEC, NULL, 0x0,
5889                     "Option 43: Suboption 8-bit value", HFILL }},
5890
5891                 { &hf_bootp_option43_value_32,
5892                   { "Value", "bootp.option.vendor.value.uint",
5893                     FT_UINT32, BASE_DEC, NULL, 0x0,
5894                     "Option 43: Suboption 32-bit value", HFILL }},
5895
5896                 { &hf_bootp_option43_value_stringz,
5897                   { "Value", "bootp.option.vendor.value.string",
5898                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
5899                     "Option 43: Suboption Z-String value", HFILL }},
5900
5901                 { &hf_bootp_option43_value_ip_address,
5902                   { "Value", "bootp.option.vendor.value.address",
5903                     FT_IPv4, BASE_NONE, NULL, 0x00,
5904                     "Option 43: Suboption IP address", HFILL }},
5905
5906
5907                 { &hf_bootp_option43_pxeclient_suboption,
5908                   { "Option 43 Suboption", "bootp.option.vendor.pxeclient.suboption",
5909                     FT_UINT8, BASE_DEC, VALS(option43_pxeclient_suboption_vals), 0x0,
5910                     "Option 43:PXE Client Suboption", HFILL }},
5911
5912                 { &hf_bootp_option43_pxeclient_padding,
5913                   { "Padding", "bootp.option.vendor.pxeclient.padding",
5914                     FT_UINT8, BASE_DEC, NULL, 0x0,
5915                     "Option 43:PXE Client 0 Padding", HFILL }},
5916
5917                 { &hf_bootp_option43_pxeclient_mtftp_ip,
5918                   { "mtftp IP", "bootp.option.vendor.pxeclient.mtftp_ip",
5919                     FT_IPv4, BASE_NONE, NULL, 0x00,
5920                     "Option 43:PXE Client 1 mtftp IP", HFILL }},
5921
5922                 { &hf_bootp_option43_pxeclient_mtftp_client_port,
5923                   { "mtftp IP", "bootp.option.vendor.pxeclient.mtftp_client_port",
5924                     FT_UINT16, BASE_DEC, NULL, 0x00,
5925                     "Option 43:PXE Client 2 mtftp client port", HFILL }},
5926
5927                 { &hf_bootp_option43_pxeclient_mtftp_server_port,
5928                   { "mtftp IP", "bootp.option.vendor.pxeclient.mtftp_server_port",
5929                     FT_UINT16, BASE_DEC, NULL, 0x00,
5930                     "Option 43:PXE Client 3 mtftp server port", HFILL }},
5931
5932                 { &hf_bootp_option43_pxeclient_mtftp_timeout,
5933                   { "mtftp timeout", "bootp.option.vendor.pxeclient.mtftp_timeout",
5934                     FT_UINT8, BASE_DEC, NULL, 0x0,
5935                     "Option 43:PXE Client 4 mtftp timeout", HFILL }},
5936
5937                 { &hf_bootp_option43_pxeclient_mtftp_delay,
5938                   { "mtftp delay", "bootp.option.vendor.pxeclient.mtftp_delay",
5939                     FT_UINT8, BASE_DEC, NULL, 0x0,
5940                     "Option 43:PXE Client 5 mtftp delay", HFILL }},
5941
5942                 { &hf_bootp_option43_pxeclient_discovery_control,
5943                   { "discovery control", "bootp.option.vendor.pxeclient.discovery_control",
5944                     FT_UINT8, BASE_HEX, NULL, 0x0,
5945                     "Option 43:PXE Client 6 discovery control", HFILL }},
5946
5947                 { &hf_bootp_option43_pxeclient_multicast_address,
5948                   { "multicast address", "bootp.option.vendor.pxeclient.multicast_address",
5949                     FT_IPv4, BASE_NONE, NULL, 0x00,
5950                     "Option 43:PXE Client 7 multicast address", HFILL }},
5951
5952                 { &hf_bootp_option43_pxeclient_boot_servers,
5953                   { "boot servers", "bootp.option.vendor.pxeclient.boot_servers",
5954                     FT_BYTES, BASE_NONE, NULL, 0x0,
5955                     "Option 43:PXE Client 8 boot servers", HFILL }},
5956
5957                 { &hf_bootp_option43_pxeclient_boot_menu,
5958                   { "boot menu", "bootp.option.vendor.pxeclient.boot_menu",
5959                     FT_BYTES, BASE_NONE, NULL, 0x0,
5960                     "Option 43:PXE Client 9 boot menu", HFILL }},
5961
5962                 { &hf_bootp_option43_pxeclient_menu_prompt,
5963                   { "menu prompt", "bootp.option.vendor.pxeclient.menu_prompt",
5964                     FT_BYTES, BASE_NONE, NULL, 0x0,
5965                     "Option 43:PXE Client 10 menu prompt", HFILL }},
5966
5967                 { &hf_bootp_option43_pxeclient_multicast_address_alloc,
5968                   { "multicast address alloc", "bootp.option.vendor.pxeclient.multicast_address_alloc",
5969                     FT_BYTES, BASE_NONE, NULL, 0x0,
5970                     "Option 43:PXE Client 11 multicast address alloc", HFILL }},
5971
5972                 { &hf_bootp_option43_pxeclient_credential_types,
5973                   { "credential types", "bootp.option.vendor.pxeclient.credential_types",
5974                     FT_BYTES, BASE_NONE, NULL, 0x0,
5975                     "Option 43:PXE Client 12 credential types", HFILL }},
5976
5977                 { &hf_bootp_option43_pxeclient_boot_item,
5978                   { "boot item", "bootp.option.vendor.pxeclient.boot_item",
5979                     FT_BYTES, BASE_NONE, NULL, 0x0,
5980                     "Option 43:PXE Client 71 boot item", HFILL }},
5981
5982                 { &hf_bootp_option43_pxeclient_end,
5983                   { "PXE Client End", "bootp.option.vendor.pxeclient.end",
5984                     FT_UINT8, BASE_DEC, NULL, 0x0,
5985                     "Option 43:PXE Client 255 End", HFILL }},
5986
5987
5988                 { &hf_bootp_option43_cl_suboption,
5989                   { "Option 43 Suboption", "bootp.option.vendor.cl.suboption",
5990                     FT_UINT8, BASE_DEC, VALS(option43_cl_suboption_vals), 0x0,
5991                     "Option 43:CL Suboption", HFILL }},
5992
5993                 { &hf_bootp_option43_cl_padding,
5994                   { "Padding", "bootp.option.vendor.cl.padding",
5995                     FT_UINT8, BASE_DEC, NULL, 0x0,
5996                     "Option 43:CL 0 Padding", HFILL }},
5997
5998                 { &hf_bootp_option43_cl_suboption_request_list,
5999                   { "Suboption Request List", "bootp.option.vendor.cl.suboption_request_list",
6000                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6001                     "Option 43:CL 1 Suboption Request List", HFILL }},
6002
6003                 { &hf_bootp_option43_cl_device_type,
6004                   { "Device Type", "bootp.option.vendor.cl.device_type",
6005                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6006                     "Option 43:CL 2 Device Type", HFILL }},
6007
6008                 { &hf_bootp_option43_cl_esafe_type,
6009                   { "eSAFE Types", "bootp.option.vendor.cl.esafe_type",
6010                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6011                     "Option 43:CL 3 eSAFE Types", HFILL }},
6012
6013                 { &hf_bootp_option43_cl_serial_number,
6014                   { "Serial Number", "bootp.option.vendor.cl.serial_number",
6015                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6016                     "Option 43:CL 4 Serial Number", HFILL }},
6017
6018                 { &hf_bootp_option43_cl_hardware_version,
6019                   { "Hardware Version", "bootp.option.vendor.cl.hardware_version",
6020                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6021                     "Option 43:CL 5 Hardware Version", HFILL }},
6022
6023                 { &hf_bootp_option43_cl_software_version,
6024                   { "Software Version", "bootp.option.vendor.cl.software_version",
6025                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6026                     "Option 43:CL 6 Software Version", HFILL }},
6027
6028                 { &hf_bootp_option43_cl_boot_rom_version,
6029                   { "Boot ROM version", "bootp.option.vendor.cl.boot_rom_version",
6030                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6031                     "Option 43:CL 7 Boot ROM version", HFILL }},
6032
6033                 { &hf_bootp_option43_cl_oui_string,
6034                   { "Organizationally Unique Identifier", "bootp.option.vendor.cl.oui_string",
6035                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6036                     "Option 43:CL 8 Organizationally Unique Identifier", HFILL }},
6037
6038                 { &hf_bootp_option43_cl_oui_bytes,
6039                   { "Organizationally Unique Identifier", "bootp.option.vendor.cl.oui_bytes",
6040                     FT_BYTES, BASE_NONE, NULL, 0x0,
6041                     "Option 43:CL 8 Organizationally Unique Identifier", HFILL }},
6042
6043                 { &hf_bootp_option43_cl_model_number,
6044                   { "Model Number", "bootp.option.vendor.cl.model_number",
6045                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6046                     "Option 43:CL 9 Model Number", HFILL }},
6047
6048                 { &hf_bootp_option43_cl_vendor_name10,
6049                   { "Vendor Name", "bootp.option.vendor.cl.vendor_name10",
6050                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6051                     "Option 43:CL 10 Vendor Name", HFILL }},
6052
6053                 { &hf_bootp_option43_cl_address_realm,
6054                   { "Address Realm", "bootp.option.vendor.cl.address_realm",
6055                     FT_UINT8, BASE_DEC, VALS(cablehome_subopt11_vals), 0x0,
6056                     "Option 43:CL 11 Address Realm", HFILL }},
6057
6058                 { &hf_bootp_option43_cl_cm_ps_system_desc,
6059                   { "CM/PS System Description", "bootp.option.vendor.cl.cm_ps_system_desc",
6060                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6061                     "Option 43:CL 12 CM/PS System Description", HFILL }},
6062
6063                 { &hf_bootp_option43_cl_cm_ps_firmware_revision,
6064                   { "CM/PS Firmware Revision", "bootp.option.vendor.cl.cm_ps_firmware_revision",
6065                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6066                     "Option 43:CL 13 CM/PS Firmware Revision", HFILL }},
6067
6068                 { &hf_bootp_option43_cl_firewall_policy_file_version,
6069                   { "Firewall Policy File Version", "bootp.option.vendor.cl.firewall_policy_file_version",
6070                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6071                     "Option 43:CL 14 Firewall Policy File Version", HFILL }},
6072
6073                 { &hf_bootp_option43_cl_esafe_config_file_devices,
6074                   { "eSafe Config File Devices", "bootp.option.vendor.cl.esafe_config_file_devices",
6075                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6076                     "Option 43:CL 15 eSafe Config File Devices", HFILL }},
6077
6078                 { &hf_bootp_option43_cl_video_security_tape,
6079                   { "Video Security Type", "bootp.option.vendor.cl.video_security_tape",
6080                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6081                     "Option 43:CL 18 Video Security Type", HFILL }},
6082
6083                 { &hf_bootp_option43_cl_mta_mac_address,
6084                   { "MTA MAC Address", "bootp.option.vendor.cl.mta_mac_address",
6085                     FT_ETHER, BASE_NONE, NULL, 0x0,
6086                     "Option 43:CL 31 MTA MAC Address", HFILL }},
6087
6088                 { &hf_bootp_option43_cl_correlation_ID,
6089                   { "Correlation ID", "bootp.option.vendor.cl.correlation_ID",
6090                     FT_UINT32, BASE_DEC, NULL, 0x0,
6091                     "Option 43: CL 32 Correlation ID", HFILL }},
6092
6093                 { &hf_bootp_option43_cl_vendor_name51,
6094                   { "Vendor Name", "bootp.option.vendor.cl.vendor_name51",
6095                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6096                     "Option 43:CL 51 Vendor Name", HFILL }},
6097
6098                 { &hf_bootp_option43_cl_cablecard_capability,
6099                   { "CableCARD Capability", "bootp.option.vendor.cl.cablecard_capability",
6100                     FT_BYTES, BASE_NONE, NULL, 0x0,
6101                     "Option 43:CL 52 CableCARD Capability", HFILL }},
6102
6103                 { &hf_bootp_option43_cl_device_id_ca,
6104                   { "Device Identification (CA)", "bootp.option.vendor.cl.device_id_ca",
6105                     FT_BYTES, BASE_NONE, NULL, 0x0,
6106                     "Option 43:CL 53 Device Identification (CA)", HFILL }},
6107
6108                 { &hf_bootp_option43_cl_device_id_x509,
6109                   { "Device Identification (X.509)", "bootp.option.vendor.cl.device_id_x509",
6110                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6111                     "Option 43:CL 54 Device Identification (X.509)", HFILL }},
6112
6113                 { &hf_bootp_option43_cl_end,
6114                   { "CL End", "bootp.option.vendor.cl.end",
6115                     FT_UINT8, BASE_DEC, NULL, 0x0,
6116                     "Option 43:CL 255 End", HFILL }},
6117
6118
6119                 { &hf_bootp_option43_alcatel_suboption,
6120                   { "Option 43 Suboption", "bootp.option.vendor.alu.suboption",
6121                     FT_UINT8, BASE_DEC, VALS(option43_alcatel_suboption_vals), 0x0,
6122                     "Option 43:Alcatel Suboption", HFILL }},
6123
6124                 { &hf_bootp_option43_alcatel_padding,
6125                   { "Padding", "bootp.option.vendor.alu.padding",
6126                     FT_UINT8, BASE_DEC, NULL, 0x0,
6127                     "Option 43:Alcatel 0 Padding", HFILL }},
6128
6129                 { &hf_bootp_option43_alcatel_vlan_id,
6130                   { "Voice VLAN ID", "bootp.option.vendor.alu.vid",
6131                     FT_UINT16, BASE_DEC, NULL, 0x0,
6132                     "Option 43:Alcatel 58 Voice VLAN ID", HFILL }},
6133
6134                 { &hf_bootp_option43_alcatel_tftp1,
6135                   { "Spatial Redundancy TFTP1", "bootp.option.vendor.alu.tftp1",
6136                     FT_IPv4, BASE_NONE, NULL, 0x0,
6137                     "Option 43:Alcatel 64 Spatial Redundancy TFTP1", HFILL }},
6138
6139                 { &hf_bootp_option43_alcatel_tftp2,
6140                   { "Spatial Redundancy TFTP2", "bootp.option.vendor.alu.tftp2",
6141                     FT_IPv4, BASE_NONE, NULL, 0x0,
6142                     "Option 43:Alcatel 65 Spatial Redundancy TFTP2", HFILL }},
6143
6144                 { &hf_bootp_option43_alcatel_app_type,
6145                   { "Application Type", "bootp.option.vendor.alu.app_type",
6146                     FT_UINT8, BASE_DEC, VALS(option43_alcatel_app_type_vals), 0x0,
6147                     "Option 43:Alcatel 66 Application Type", HFILL }},
6148
6149                 { &hf_bootp_option43_alcatel_sip_url,
6150                   { "SIP URL", "bootp.option.vendor.alu.sip_url",
6151                     FT_STRING, BASE_NONE, NULL, 0x0,
6152                     "Option 43:Alcatel 67 SIP URL", HFILL }},
6153
6154                 { &hf_bootp_option43_alcatel_end,
6155                   { "Alcatel End", "bootp.option.vendor.alu.end",
6156                     FT_UINT8, BASE_DEC, NULL, 0x0,
6157                     "Option 43:Alcatel 255 End", HFILL }},
6158
6159                 { &hf_bootp_option43_arubaap_controllerip,
6160                   { "Aruba Controller IP", "bootp.option.vendor.arubaap.controllerip",
6161                     FT_STRING, BASE_NONE, NULL, 0x0,
6162                     "Address IP of Aruba controller", HFILL }},
6163
6164                 { &hf_bootp_option43_arubaiap,
6165                   { "Aruba Instant AP", "bootp.option.vendor.arubaiap",
6166                     FT_STRING, BASE_NONE, NULL, 0x0,
6167                     "nameorg,amp-ip-address,password", HFILL }},
6168
6169                 { &hf_bootp_option43_arubaiap_nameorg,
6170                   { "Name Organisation", "bootp.option.vendor.arubaiap.name_org",
6171                     FT_STRING, BASE_NONE, NULL, 0x0,
6172                     NULL, HFILL }},
6173
6174                 { &hf_bootp_option43_arubaiap_ampip,
6175                   { "AMP IP Address", "bootp.option.vendor.arubaiap.amp_ip",
6176                     FT_STRING, BASE_NONE, NULL, 0x0,
6177                     "Address IP of Airwave server (AMP)", HFILL }},
6178
6179                 { &hf_bootp_option43_arubaiap_password,
6180                   { "Password", "bootp.option.vendor.arubaiap.password",
6181                     FT_STRING, BASE_NONE, NULL, 0x0,
6182                     "Password for Instant AP Airwave server (AMP)", HFILL }},
6183
6184                 { &hf_bootp_option_netbios_over_tcpip_name_server,
6185                   { "NetBIOS over TCP/IP Name Server", "bootp.option.netbios_over_tcpip_name_server",
6186                     FT_IPv4, BASE_NONE, NULL, 0x00,
6187                     "Option 44: NetBIOS over TCP/IP Name Server", HFILL }},
6188
6189                 { &hf_bootp_option_netbios_over_tcpip_dd_name_server,
6190                   { "NetBIOS over TCP/IP Datagram Distribution Name Server", "bootp.option.netbios_over_tcpip_dd_name_server",
6191                     FT_IPv4, BASE_NONE, NULL, 0x00,
6192                     "Option 45: NetBIOS over TCP/IP Datagram Distribution Name Server", HFILL }},
6193
6194                 { &hf_bootp_option_netbios_over_tcpip_node_type,
6195                   { "NetBIOS over TCP/IP Node Type", "bootp.option.netbios_over_tcpip_node_type",
6196                     FT_UINT8, BASE_DEC, VALS(bootp_nbnt_vals), 0x0,
6197                     "Option 46: NetBIOS over TCP/IP Node Type", HFILL }},
6198
6199                 { &hf_bootp_option_netbios_over_tcpip_scope,
6200                   { "NetBIOS over TCP/IP Scope", "bootp.option.netbios_over_tcpip_scope",
6201                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6202                     "Option 47: NetBIOS over TCP/IP Scope", HFILL }},
6203
6204                 { &hf_bootp_option_xwindows_system_font_server,
6205                   { "X Window System Font Server", "bootp.option.xwindows_system_font_server",
6206                     FT_IPv4, BASE_NONE, NULL, 0x00,
6207                     "Option 48: X Window System Font Server", HFILL }},
6208
6209                 { &hf_bootp_option_xwindows_system_display_manager,
6210                   { "X Window System Display Manager", "bootp.option.xwindows_system_display_manager",
6211                     FT_IPv4, BASE_NONE, NULL, 0x00,
6212                     "Option 49: X Window System Display Manager", HFILL }},
6213
6214                 { &hf_bootp_option_requested_ip_address,
6215                   { "Requested IP Address", "bootp.option.requested_ip_address",
6216                     FT_IPv4, BASE_NONE, NULL, 0x00,
6217                     "Option 50: Requested IP Address", HFILL }},
6218
6219                 { &hf_bootp_option_ip_address_lease_time,
6220                   { "IP Address Lease Time", "bootp.option.ip_address_lease_time",
6221                     FT_UINT32, BASE_DEC, NULL, 0x00,
6222                     "Option 51: IP Address Lease Time", HFILL }},
6223
6224                 { &hf_bootp_option_option_overload,
6225                   { "Option Overload", "bootp.option.option_overload",
6226                     FT_UINT8, BASE_DEC, VALS(opt_overload_vals), 0x0,
6227                     "Option 52: Option Overload", HFILL }},
6228
6229                 { &hf_bootp_option_dhcp,
6230                   { "DHCP", "bootp.option.dhcp",
6231                     FT_UINT8, BASE_DEC, VALS(opt53_text), 0x0,
6232                     "Option 53: DHCP option", HFILL }},
6233
6234                 { &hf_bootp_option_dhcp_server_id,
6235                   { "DHCP Server Identifier", "bootp.option.dhcp_server_id",
6236                     FT_IPv4, BASE_NONE, NULL, 0x00,
6237                     "Option 54: DHCP Server Identifier", HFILL }},
6238
6239                 { &hf_bootp_option_parameter_request_list_item,
6240                   { "Parameter Request List Item", "bootp.option.request_list_item",
6241                     FT_UINT8, BASE_DEC, NULL, 0x0,
6242                     "Option 55: Parameter Request List Item", HFILL }},
6243
6244                 { &hf_bootp_option_message,
6245                   { "Message", "bootp.option.message",
6246                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6247                     "Option 56: Option message", HFILL }},
6248
6249                 { &hf_bootp_option_dhcp_max_message_size,
6250                   { "Maximum DHCP Message Size", "bootp.option.dhcp_max_message_size",
6251                     FT_UINT16, BASE_DEC, NULL, 0x0,
6252                     "Option 57: Maximum DHCP Message Size", HFILL }},
6253
6254                 { &hf_bootp_option_renewal_time_value,
6255                   { "Renewal Time Value", "bootp.option.renewal_time_value",
6256                     FT_UINT32, BASE_DEC, NULL, 0x00,
6257                     "Option 58: Renewal Time Value", HFILL }},
6258
6259                 { &hf_bootp_option_rebinding_time_value,
6260                   { "Rebinding Time Value", "bootp.option.rebinding_time_value",
6261                     FT_UINT32, BASE_DEC, NULL, 0x00,
6262                     "Option 59: Rebinding Time Value", HFILL }},
6263
6264                 { &hf_bootp_option_vendor_class_id,
6265                   { "Vendor class identifier", "bootp.option.vendor_class_id",
6266                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6267                     "Option 60: Vendor class identifier", HFILL }},
6268
6269                 { &hf_bootp_option_novell_netware_ip_domain,
6270                   { "Novell/Netware IP domain", "bootp.option.novell_netware_ip_domain",
6271                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6272                     "Option 62: Novell/Netware IP domain", HFILL }},
6273
6274                 { &hf_bootp_option63_suboption,
6275                   { "Option 63 Suboption", "bootp.option.novell_options.suboption",
6276                     FT_UINT8, BASE_DEC, VALS(option63_suboption_vals), 0x0,
6277                     "Option 63: Suboption", HFILL }},
6278
6279                 { &hf_bootp_option63_value,
6280                   { "Value", "bootp.option.novell_options.value",
6281                     FT_BYTES, BASE_NONE, NULL, 0x0,
6282                     "Option 63: Suboption value", HFILL }},
6283
6284                 { &hf_bootp_option63_value_8,
6285                   { "Value", "bootp.option.novell_options.value.uint",
6286                     FT_UINT8, BASE_DEC, NULL, 0x0,
6287                     "Option 63: Suboption 8-bit value", HFILL }},
6288
6289                 { &hf_bootp_option63_value_ip_address,
6290                   { "Value", "bootp.option.novell_options.value.address",
6291                     FT_IPv4, BASE_NONE, NULL, 0x00,
6292                     "Option 63: Suboption IP address", HFILL }},
6293
6294                 { &hf_bootp_option63_value_boolean,
6295                   { "Value", "bootp.option.novell_options.value.bool",
6296                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_true_false), 0x00,
6297                     "Option 63: Suboption Boolean value", HFILL }},
6298
6299                 { &hf_bootp_option63_broadcast,
6300                   { "Broadcast for nearest Netware server", "bootp.option.novell_options.broadcast",
6301                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x00,
6302                     "Option 63:5 Broadcast for nearest Netware server", HFILL }},
6303
6304                 { &hf_bootp_option63_preferred_dss_server,
6305                   { "Preferred DSS server", "bootp.option.novell_options.preferred_dss_server",
6306                     FT_IPv4, BASE_NONE, NULL, 0x00,
6307                     "Option 63:6 Preferred DSS server", HFILL }},
6308
6309                 { &hf_bootp_option63_nearest_nwip_server,
6310                   { "Nearest NWIP server", "bootp.option.novell_options.nearest_nwip_server",
6311                     FT_IPv4, BASE_NONE, NULL, 0x00,
6312                     "Option 63:7 Nearest NWIP server", HFILL }},
6313
6314                 { &hf_bootp_option63_autoretries,
6315                   { "Autoretries", "bootp.option.novell_options.autoretries",
6316                     FT_UINT8, BASE_DEC, NULL, 0x0,
6317                     "Option 63:8 Autoretries", HFILL }},
6318
6319                 { &hf_bootp_option63_autoretry_delay,
6320                   { "Autoretry delay, sec",
6321                     "bootp.option.novell_options.autoretry_delay", FT_UINT8, BASE_DEC, NULL,
6322                     0x0, "Option 63:9 Autoretry delay, sec", HFILL }},
6323
6324                 { &hf_bootp_option63_support_netware_v1_1,
6325                   { "Broadcast for nearest Netware server", "bootp.option.novell_options.support_netware_v1_1",
6326                     FT_BOOLEAN, BASE_NONE, TFS(&tfs_yes_no), 0x00,
6327                     "Option 63:10 Broadcast for nearest Netware server", HFILL }},
6328
6329                 { &hf_bootp_option63_primary_dss,
6330                   { "Primary DSS", "bootp.option.novell_options.primary_dss",
6331                     FT_IPv4, BASE_NONE, NULL, 0x00,
6332                     "Option 63:11 Primary DSS", HFILL }},
6333
6334
6335                 { &hf_bootp_option_nis_plus_domain,
6336                   { "Network Information Service+ Domain", "bootp.option.nis_plus_domain",
6337                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6338                     "Option 64: Network Information Service+ Domain", HFILL }},
6339
6340                 { &hf_bootp_option_nis_plus_server,
6341                   { "Network Information Service+ Server", "bootp.option.nis_plus_server",
6342                     FT_IPv4, BASE_NONE, NULL, 0x00,
6343                     "Option 65: Network Information Service+ Server", HFILL }},
6344
6345                 { &hf_bootp_option_tftp_server_name,
6346                   { "TFTP Server Name", "bootp.option.tftp_server_name",
6347                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6348                     "Option 66: TFTP Server Name", HFILL }},
6349
6350                 { &hf_bootp_option_bootfile_name,
6351                   { "Bootfile name", "bootp.option.bootfile_name",
6352                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6353                     "Option 67: Bootfile name", HFILL }},
6354
6355                 { &hf_bootp_option_mobile_ip_home_agent,
6356                   { "Mobile IP Home Agent", "bootp.option.mobile_ip_home_agent",
6357                     FT_IPv4, BASE_NONE, NULL, 0x00,
6358                     "Option 68: Mobile IP Home Agent", HFILL }},
6359
6360                 { &hf_bootp_option_smtp_server,
6361                   { "SMTP Server", "bootp.option.smtp_server",
6362                     FT_IPv4, BASE_NONE, NULL, 0x00,
6363                     "Option 69: SMTP Server", HFILL }},
6364
6365                 { &hf_bootp_option_pop3_server,
6366                   { "POP3 Server", "bootp.option.pop3_server",
6367                     FT_IPv4, BASE_NONE, NULL, 0x00,
6368                     "Option 70: POP3 Server", HFILL }},
6369
6370                 { &hf_bootp_option_nntp_server,
6371                   { "NNTP Server", "bootp.option.nntp_server",
6372                     FT_IPv4, BASE_NONE, NULL, 0x00,
6373                     "Option 71: NNTP Server", HFILL }},
6374
6375                 { &hf_bootp_option_default_www_server,
6376                   { "Default WWW Server", "bootp.option.default_www_server",
6377                     FT_IPv4, BASE_NONE, NULL, 0x00,
6378                     "Option 72: Default WWW Server", HFILL }},
6379
6380                 { &hf_bootp_option_default_finger_server,
6381                   { "Default Finger Server", "bootp.option.default_finger_server",
6382                     FT_IPv4, BASE_NONE, NULL, 0x00,
6383                     "Option 73: Default Finger Server", HFILL }},
6384
6385                 { &hf_bootp_option_default_irc_server,
6386                   { "Default IRC Server", "bootp.option.default_irc_server",
6387                     FT_IPv4, BASE_NONE, NULL, 0x00,
6388                     "Option 74: Default IRC Server", HFILL }},
6389
6390                 { &hf_bootp_option_streettalk_server,
6391                   { "StreetTalk Server", "bootp.option.streettalk_server",
6392                     FT_IPv4, BASE_NONE, NULL, 0x00,
6393                     "Option 75: StreetTalk Server", HFILL }},
6394
6395                 { &hf_bootp_option_streettalk_da_server,
6396                   { "StreetTalk Directory Assistance Server", "bootp.option.streettalk_da_server",
6397                     FT_IPv4, BASE_NONE, NULL, 0x00,
6398                     "Option 76: StreetTalk Directory Assistance Server", HFILL }},
6399
6400                 { &hf_bootp_option77_user_class,
6401                   { "Instance of User Class", "bootp.option.user_class",
6402                     FT_UINT8, BASE_DEC, NULL, 0x0,
6403                     NULL, HFILL }},
6404
6405                 { &hf_bootp_option77_user_class_length,
6406                   { "User Class Length", "bootp.option.user_class.length",
6407                     FT_UINT8, BASE_DEC, NULL, 0x0,
6408                     "Length of User Class Instance", HFILL }},
6409
6410                 { &hf_bootp_option77_user_class_data,
6411                   { "User Class Data", "bootp.option.user_class.data",
6412                     FT_BYTES, BASE_NONE, NULL, 0x0,
6413                     "Data of User Class Instance", HFILL }},
6414
6415                 { &hf_bootp_option_slp_directory_agent_value,
6416                   { "Value", "bootp.option.slp_directory_agent.value",
6417                     FT_UINT8, BASE_DEC, VALS(slpda_vals), 0x0,
6418                     "Option 78: SLPDA Value", HFILL }},
6419
6420                 { &hf_bootp_option_slp_directory_agent_slpda_address,
6421                   { "IP Address", "bootp.option.slp_directory_agent.slpda_address",
6422                     FT_IPv4, BASE_NONE, NULL, 0x00,
6423                     "Option 78: SLPDA Address", HFILL }},
6424
6425                 { &hf_bootp_option_slp_service_scope_value,
6426                   { "Value", "bootp.option.slp_service_scope.value",
6427                     FT_UINT8, BASE_DEC, VALS(slp_scope_vals), 0x0,
6428                     "Option 79: SLP Service Scope Value", HFILL }},
6429
6430                 { &hf_bootp_option_slp_service_scope_string,
6431                   { "SLP Service Scope", "bootp.option.slp_service_scope.string",
6432                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6433                     "Option 79: SLP Service Scope", HFILL }},
6434
6435
6436                 { &hf_bootp_option82_suboption,
6437                   { "Option 82 Suboption", "bootp.option.agent_information_option.suboption",
6438                     FT_UINT8, BASE_DEC, VALS(option82_suboption_vals), 0x0,
6439                     "Option 82: Suboption", HFILL }},
6440
6441                 { &hf_bootp_option82_value,
6442                   { "Value", "bootp.option.agent_information_option.value",
6443                     FT_BYTES, BASE_NONE, NULL, 0x0,
6444                     "Option 82: Suboption value", HFILL }},
6445
6446                 { &hf_bootp_option82_value_8,
6447                   { "Value", "bootp.option.agent_information_option.value.uint",
6448                     FT_UINT8, BASE_DEC, NULL, 0x0,
6449                     "Option 82: Suboption 8-bit value", HFILL }},
6450
6451                 { &hf_bootp_option82_value_32,
6452                   { "Value", "bootp.option.agent_information_option.value.uint",
6453                     FT_UINT32, BASE_DEC, NULL, 0x0,
6454                     "Option 82: Suboption 32-bit value", HFILL }},
6455
6456                 { &hf_bootp_option82_value_ip_address,
6457                   { "Value", "bootp.option.agent_information_option.value.address",
6458                     FT_IPv4, BASE_NONE, NULL, 0x00,
6459                     "Option 82: Suboption IP address", HFILL }},
6460
6461                 { &hf_bootp_option82_value_stringz,
6462                   { "Value", "bootp.option.agent_information_option.value.string",
6463                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6464                     "Option 82: Suboption Z-String value", HFILL }},
6465
6466                 { &hf_bootp_option82_padding,
6467                   { "Padding", "bootp.option.agent_information_option.padding",
6468                     FT_UINT8, BASE_DEC, NULL, 0x0,
6469                     "Option 82:0 Padding", HFILL }},
6470
6471                 { &hf_bootp_option82_agent_circuit_id,
6472                   { "Agent Circuit ID", "bootp.option.agent_information_option.agent_circuit_id",
6473                     FT_BYTES, BASE_NONE, NULL, 0x0,
6474                     "Option 82:1 Agent Circuit ID", HFILL }},
6475
6476                 { &hf_bootp_option82_agent_remote_id,
6477                   { "Agent Remote ID", "bootp.option.agent_information_option.agent_remote_id",
6478                     FT_BYTES, BASE_NONE, NULL, 0x0,
6479                     "Option 82:2 Agent Remote ID", HFILL }},
6480
6481                 { &hf_bootp_option82_reserved,
6482                   { "Reserved", "bootp.option.agent_information_option.reserved",
6483                     FT_BYTES, BASE_NONE, NULL, 0x0,
6484                     "Option 82:3 Reserved", HFILL }},
6485
6486                 { &hf_bootp_option82_docsis_device_class,
6487                   { "DOCSIS Device Class", "bootp.option.agent_information_option.docsis_device_class",
6488                     FT_UINT32, BASE_HEX, NULL, 0x0,
6489                     "Option 82:4 DOCSIS Device Class", HFILL }},
6490
6491                 { &hf_bootp_option82_link_selection,
6492                   { "Link selection", "bootp.option.agent_information_option.link_selection",
6493                     FT_IPv4, BASE_NONE, NULL, 0x00,
6494                     "Option 82:5 Link selection", HFILL }},
6495
6496                 { &hf_bootp_option82_subscriber_id,
6497                   { "Subscriber ID", "bootp.option.agent_information_option.subscriber_id",
6498                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6499                     "Option 82:6 Subscriber ID", HFILL }},
6500
6501                 { &hf_bootp_option82_radius_attributes,
6502                   { "RADIUS Attributes", "bootp.option.agent_information_option.radius_attributes",
6503                     FT_BYTES, BASE_NONE, NULL, 0x0,
6504                     "Option 82:7 RADIUS Attributes", HFILL }},
6505
6506                 { &hf_bootp_option82_authentication,
6507                   { "Authentication", "bootp.option.agent_information_option.authentication",
6508                     FT_BYTES, BASE_NONE, NULL, 0x0,
6509                     "Option 82:8 Authentication", HFILL }},
6510
6511                 { &hf_bootp_option82_vi,
6512                   { "Vendor-Specific Information", "bootp.option.agent_information_option.vi",
6513                     FT_BYTES, BASE_NONE, NULL, 0x0,
6514                     "Option 82:9 Vendor-Specific Information", HFILL }},
6515
6516                 { &hf_bootp_option82_vi_enterprise,
6517                   { "Enterprise", "bootp.option.agent_information_option.vi.enterprise",
6518                     FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0x0,
6519                     "Option 82:9 VI Enterprise", HFILL }},
6520
6521                 { &hf_bootp_option82_vi_data_length,
6522                   { "Data Length", "bootp.option.agent_information_option.vi.data_length",
6523                     FT_UINT8, BASE_DEC, NULL, 0x0,
6524                     "Option 82:9 VI Data Length", HFILL }},
6525
6526                 { &hf_bootp_option82_vi_cl_option,
6527                   { "Option", "bootp.option.agent_information_option.vi.cl.option",
6528                     FT_UINT8, BASE_DEC, NULL, 0x0,
6529                     "Option 82:9 VI CL Option", HFILL }},
6530
6531                 { &hf_bootp_option82_vi_cl_length,
6532                   { "Length", "bootp.option.agent_information_option.vi.cl.length",
6533                     FT_UINT8, BASE_DEC, NULL, 0x0,
6534                     "Option 82:9 VI CL Length", HFILL }},
6535
6536                 { &hf_bootp_option82_vi_cl_tag,
6537                   { "Tag", "bootp.option.agent_information_option.vi.cl.tag",
6538                     FT_UINT8, BASE_DEC, NULL, 0x0,
6539                     "Option 82:9 VI CL Tag", HFILL }},
6540
6541                 { &hf_bootp_option82_vi_cl_tag_length,
6542                   { "Tag Length", "bootp.option.agent_information_option.vi.cl.tag_length",
6543                     FT_UINT8, BASE_DEC, NULL, 0x0,
6544                     "Option 82:9 VI CL Tag Length", HFILL }},
6545
6546                 { &hf_bootp_option82_vi_cl_docsis_version,
6547                   { "DOCSIS Version Number", "bootp.option.agent_information_option.vi.cl.docsis_version",
6548                     FT_UINT16, BASE_HEX, NULL, 0x0,
6549                     "Option 82:9 VI CL DOCSIS Version Number", HFILL }},
6550
6551                 { &hf_bootp_option82_flags,
6552                   { "Flags", "bootp.option.agent_information_option.flags",
6553                     FT_UINT8, BASE_HEX, NULL, 0x0,
6554                     "Option 82:10 Flags", HFILL }},
6555
6556                 { &hf_bootp_option82_server_id_override,
6557                   { "Server ID Override", "bootp.option.agent_information_option.server_id_override",
6558                     FT_IPv4, BASE_NONE, NULL, 0x00,
6559                     "Option 82:11 Server ID Override", HFILL }},
6560
6561                 { &hf_bootp_option82_link_selection_cisco,
6562                   { "Link selection (Cisco proprietary)", "bootp.option.agent_information_option.link_selection_cisco",
6563                     FT_IPv4, BASE_NONE, NULL, 0x00,
6564                     "Option 82:150 Link selection (Cisco proprietary)", HFILL }},
6565
6566                 { &hf_bootp_option82_vrf_name_vpn_id,
6567                   { "VRF name/VPN ID", "bootp.option.agent_information_option.vrf_name.vpn_id",
6568                     FT_BYTES, BASE_NONE, NULL, 0x00,
6569                     "Option 82:151 VRF name/VPN ID", HFILL }},
6570
6571                 { &hf_bootp_option82_vrf_name_global,
6572                   { "Global, default VPN", "bootp.option.agent_information_option.vrf_name.global",
6573                     FT_UINT8, BASE_DEC, NULL, 0x00,
6574                     "Option 82:151 Global, default VPN", HFILL }},
6575
6576                 { &hf_bootp_option82_vrf_name,
6577                   { "VRF name", "bootp.option.agent_information_option.vrf_name",
6578                     FT_STRING, BASE_NONE, NULL, 0x00,
6579                     "Option 82:151 VRF name", HFILL }},
6580
6581                 { &hf_bootp_option82_vrf_name_vpn_id_oui,
6582                   { "VRF name/VPN ID OUI", "bootp.option.agent_information_option.vrf_name.vpn_id.oui",
6583                     FT_UINT24, BASE_HEX, NULL, 0x00,
6584                     "Option 82:151 VRF name/VPN ID OUI", HFILL }},
6585
6586                 { &hf_bootp_option82_vrf_name_vpn_id_index,
6587                   { "VRF name/VPN ID Index", "bootp.option.agent_information_option.vrf_name.vpn_id.index",
6588                     FT_UINT32, BASE_HEX, NULL, 0x00,
6589                     "Option 82:151 VRF name/VPN ID Index", HFILL }},
6590
6591                 { &hf_bootp_option82_server_id_override_cisco,
6592                   { "Server ID Override (Cisco proprietary)", "bootp.option.agent_information_option.server_id_override_cisco",
6593                     FT_IPv4, BASE_NONE, NULL, 0x00,
6594                     "Option 82:152 Server ID Override (Cisco proprietary)", HFILL }},
6595
6596
6597                 { &hf_bootp_option_novell_dss_string,
6598                   { "Novell Directory Services Servers String", "bootp.option.novell_dss.string",
6599                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6600                     "Option 85: Novell Directory Services Servers String", HFILL }},
6601
6602                 { &hf_bootp_option_novell_dss_ip,
6603                   { "IP Address", "bootp.option.novell_dss.ip",
6604                     FT_IPv4, BASE_NONE, NULL, 0x00,
6605                     "Option 85: Novell Directory Services Servers IP Address", HFILL }},
6606
6607                 { &hf_bootp_option_novell_ds_tree_name,
6608                   { "Novell Directory Services Tree Name", "bootp.option.novell_ds_tree_name",
6609                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6610                     "Option 86: Novell Directory Services Tree Name", HFILL }},
6611
6612                 { &hf_bootp_option_novell_ds_context,
6613                   { "Novell Directory Services Context", "bootp.option.novell_ds_context",
6614                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6615                     "Option 87: Novell Directory Services Context", HFILL }},
6616
6617                 { &hf_bootp_option_dhcp_authentication_protocol,
6618                   { "Protocol", "bootp.option.dhcp_authentication.protocol",
6619                     FT_UINT8, BASE_DEC, VALS(authen_protocol_vals), 0x0,
6620                     "Option 90: Authentication Protocol", HFILL }},
6621
6622                 { &hf_bootp_option_dhcp_authentication_alg_delay,
6623                   { "Delay Algorithm", "bootp.option.dhcp_authentication.alg_delay",
6624                     FT_UINT8, BASE_DEC, VALS(authen_da_algo_vals), 0x0,
6625                     "Option 90: Delayed Authentication Algorithm", HFILL }},
6626
6627                 { &hf_bootp_option_dhcp_authentication_algorithm,
6628                   { "Algorithm", "bootp.option.dhcp_authentication.algorithm",
6629                     FT_UINT8, BASE_DEC, NULL, 0x0,
6630                     "Option 90: Authentication Algorithm", HFILL }},
6631
6632                 { &hf_bootp_option_dhcp_authentication_rdm,
6633                   { "Replay Detection Method", "bootp.option.dhcp_authentication.rdm",
6634                     FT_UINT8, BASE_DEC, VALS(authen_rdm_vals), 0x0,
6635                     "Option 90: Replay Detection Method", HFILL }},
6636
6637                 { &hf_bootp_option_dhcp_authentication_rdm_replay_detection,
6638                   { "RDM Replay Detection Value", "bootp.option.dhcp_authentication.rdm_replay_detection",
6639                     FT_UINT64, BASE_HEX, NULL, 0x0,
6640                     "Option 90: RDM Replay Detection Value", HFILL }},
6641
6642                 { &hf_bootp_option_dhcp_authentication_rdm_rdv,
6643                   { "Replay Detection Value", "bootp.option.dhcp_authentication.rdm_rdv",
6644                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6645                     "Option 90: Replay Detection Value", HFILL }},
6646
6647                 { &hf_bootp_option_dhcp_authentication_secret_id,
6648                   { "Secret ID", "bootp.option.dhcp_authentication.secret_id",
6649                     FT_UINT32, BASE_HEX, NULL, 0x0,
6650                     "Option 90: Secret ID", HFILL }},
6651
6652                 { &hf_bootp_option_dhcp_authentication_hmac_md5_hash,
6653                   { "HMAC MD5 Hash", "bootp.option.dhcp_authentication.hmac_md5_hash",
6654                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6655                     "Option 90: HMAC MD5 Hash", HFILL }},
6656
6657                 { &hf_bootp_option_dhcp_authentication_information,
6658                   { "Authentication Information", "bootp.option.dhcp_authentication.information",
6659                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6660                     "Option 90: Authentication Information", HFILL }},
6661
6662                 { &hf_bootp_option_client_last_transaction_time,
6663                   { "Client last transaction time", "bootp.option.client_last_transaction_time",
6664                     FT_UINT32, BASE_DEC, NULL, 0x00,
6665                     "Option 91: Client last transaction time", HFILL }},
6666
6667                 { &hf_bootp_option_associated_ip_option,
6668                   { "Associated IP option", "bootp.option.associated_ip_option",
6669                     FT_IPv4, BASE_NONE, NULL, 0x00,
6670                     "Option 92: Associated IP option", HFILL }},
6671
6672                 { &hf_bootp_option_client_system_architecture,
6673                   { "Client System Architecture", "bootp.option.client_system_architecture",
6674                     FT_UINT16, BASE_DEC, VALS(bootp_client_arch), 0x0,
6675                     "Option 93: Client System Architecture", HFILL }},
6676
6677                 { &hf_bootp_option_client_network_id_major_ver,
6678                   { "Major Version", "bootp.client_network_id_major",
6679                     FT_UINT8, BASE_DEC, NULL, 0x0,
6680                     "Option 94: Major Version", HFILL }},
6681
6682                 { &hf_bootp_option_client_network_id_minor_ver,
6683                   { "Minor Version", "bootp.client_network_id_minor",
6684                     FT_UINT8, BASE_DEC, NULL, 0x0,
6685                     "Option 94: Minor Version", HFILL }},
6686
6687                 { &hf_bootp_option_civic_location_what,
6688                   { "What", "bootp.option.civic_location.what",
6689                     FT_UINT8, BASE_DEC, VALS(civic_address_what_values), 0x0,
6690                     "Option 99: What", HFILL }},
6691
6692                 { &hf_bootp_option_civic_location_country,
6693                   { "Country", "bootp.option.civic_location.country",
6694                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6695                     "Option 99: Country", HFILL }},
6696
6697                 { &hf_bootp_option_civic_location_ca_type,
6698                   { "CA Type", "bootp.option.civic_location.ca_type",
6699                     FT_UINT8, BASE_DEC, VALS(civic_address_type_values), 0x0,
6700                     "Option 99: CA Type", HFILL }},
6701
6702                 { &hf_bootp_option_civic_location_ca_length,
6703                   { "CA Length", "bootp.option.civic_location.ca_length",
6704                     FT_UINT8, BASE_DEC, NULL, 0x0,
6705                     "Option 99: CA Length", HFILL }},
6706
6707                 { &hf_bootp_option_civic_location_ca_value,
6708                   { "CA Value", "bootp.option.civic_location.ca_value",
6709                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6710                     "Option 99: CA Value", HFILL }},
6711
6712                 { &hf_bootp_option_netinfo_parent_server_address,
6713                   { "NetInfo Parent Server Address", "bootp.option.netinfo_parent_server_address",
6714                     FT_IPv4, BASE_NONE, NULL, 0x00,
6715                     "Option 112: NetInfo Parent Server Address", HFILL }},
6716
6717                 { &hf_bootp_option_netinfo_parent_server_tag,
6718                   { "NetInfo Parent Server Tag", "bootp.option.netinfo_parent_server_tag",
6719                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6720                     "Option 113: NetInfo Parent Server Tag", HFILL }},
6721
6722                 { &hf_bootp_option_dhcp_auto_configuration,
6723                   { "DHCP Auto-Configuration", "bootp.option.dhcp_auto_configuration",
6724                     FT_UINT8, BASE_DEC, VALS(dhcp_autoconfig), 0x0,
6725                     "Option 116: DHCP Auto-Configuration", HFILL }},
6726
6727                 { &hf_bootp_option_dhcp_name_service_search_option,
6728                   { "Name Service", "bootp.option.dhcp_name_service_search_option",
6729                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6730                     "Option 117: Name Service", HFILL }},
6731
6732                 { &hf_bootp_option_dhcp_dns_domain_search_list_rfc_3396_detected,
6733                   { "Encoding Long Options detected (RFC 3396)", "bootp.option.dhcp_dns_domain_search_list_rfc_3396_detected",
6734                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6735                     "Option 119: Encoding Long Options detected (RFC 3396)", HFILL }},
6736
6737                 { &hf_bootp_option_dhcp_dns_domain_search_list_refer_last_option,
6738                   { "For the data, please refer to last option 119", "bootp.option.dhcp_dns_domain_search_list_refer_last_option",
6739                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6740                     "Option 119: For the data, please refer to last option 119", HFILL }},
6741
6742                 { &hf_bootp_option_dhcp_dns_domain_search_list_fqdn,
6743                   { "FQDN", "bootp.option.dhcp_dns_domain_search_list_fqdn",
6744                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6745                     "Option 119: FQDN", HFILL }},
6746
6747                 { &hf_bootp_option_sip_server_rfc_3396_detected,
6748                   { "Encoding Long Options detected (RFC 3396)", "bootp.option.sip_server.rfc_3396_detected",
6749                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6750                     "Option 120: Encoding Long Options detected (RFC 3396)", HFILL }},
6751
6752                 { &hf_bootp_option_sip_server_refer_last_option,
6753                   { "For the data, please refer to last option 120", "bootp.option.sip_server.refer_last_option",
6754                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6755                     "Option 120: For the data, please refer to last option 120", HFILL }},
6756
6757                 { &hf_bootp_option_sip_server_enc,
6758                   { "SIP Server Encoding", "bootp.option.sip_server.encoding",
6759                     FT_UINT8, BASE_DEC, VALS(sip_server_enc_vals), 0x0,
6760                     "Option 120: SIP Server encoding", HFILL }},
6761
6762                 { &hf_bootp_option_sip_server_name,
6763                   { "SIP Server Name", "bootp.option.sip_server.name",
6764                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6765                     "Option 120: SIP Server Name", HFILL }},
6766
6767                 { &hf_bootp_option_sip_server_address,
6768                   { "SIP Server Address", "bootp.option.sip_server.address",
6769                     FT_IPv4, BASE_NONE, NULL, 0x0,
6770                     "Option 120: SIP Server Address", HFILL }},
6771
6772                 { &hf_bootp_option_sip_server_address_stringz,
6773                   { "SIP Server Address", "bootp.option.sip_server.address.stringz",
6774                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6775                     "Option 120: SIP Server Address", HFILL }},
6776
6777                 { &hf_bootp_option_cl_dss_id_option,
6778                   { "DSS_ID Type", "bootp.option.cl_dss_id.option",
6779                     FT_UINT8, BASE_DEC, VALS(cl_dss_id_type_vals), 0x0,
6780                     "Option 123:CL DSS_ID Type", HFILL }},
6781
6782                 { &hf_bootp_option_cl_dss_id_len,
6783                   { "DSS_ID Length", "bootp.option.cl_dss_id.len",
6784                     FT_UINT8, BASE_DEC, NULL, 0x0,
6785                     "Option 123:CL DSS_ID Length", HFILL }},
6786
6787                 { &hf_bootp_option_cl_dss_id,
6788                   { "Country", "bootp.option.cl_dss_id",
6789                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6790                     "Option 123:CL DSS_ID", HFILL }},
6791
6792                 { &hf_bootp_option_vi_class_cl_address_mode,
6793                   { "CableLab Address Mode", "bootp.option.vi_class.cl_address_mode",
6794                     FT_UINT8, BASE_DEC, VALS(cablelab_ipaddr_mode_vals), 0x0,
6795                     "Option 124: CableLab Address Mode", HFILL }},
6796
6797                 { &hf_bootp_option_vi_class_enterprise,
6798                   { "Enterprise", "bootp.option.vi_class.enterprise",
6799                     FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0x00,
6800                     "Option 124: Enterprise", HFILL }},
6801
6802                 { &hf_bootp_option_vi_class_data_length,
6803                   { "CableLab Address Mode", "bootp.option.vi_class.length",
6804                     FT_UINT8, BASE_DEC, NULL, 0x0,
6805                     "Option 124: Length", HFILL }},
6806
6807                 { &hf_bootp_option_vi_class_data,
6808                   { "NetInfo Parent Server Tag", "bootp.option.vi_class.data",
6809                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6810                     "Option 124: Data", HFILL }},
6811
6812                 { &hf_bootp_option125_enterprise,
6813                   { "Enterprise", "bootp.option.vi.enterprise",
6814                     FT_UINT32, BASE_DEC|BASE_EXT_STRING, &sminmpec_values_ext, 0x00,
6815                     "Option 125: Enterprise", HFILL }},
6816
6817                 { &hf_bootp_option125_value,
6818                   { "Value", "bootp.option.vi.value",
6819                     FT_BYTES, BASE_NONE, NULL, 0x0,
6820                     "Option 125: Suboption value", HFILL }},
6821
6822                 { &hf_bootp_option125_value_8,
6823                   { "Value", "bootp.option.vi.value.uint",
6824                     FT_UINT8, BASE_DEC, NULL, 0x0,
6825                     "Option 125: Suboption 8-bit value", HFILL }},
6826
6827                 { &hf_bootp_option125_value_16,
6828                   { "Value", "bootp.option.vi.value.uint",
6829                     FT_UINT16, BASE_DEC, NULL, 0x0,
6830                     "Option 125: Suboption 16-bit value", HFILL }},
6831
6832                 { &hf_bootp_option125_value_ip_address,
6833                   { "Value", "bootp.option.vi.value.address",
6834                     FT_IPv4, BASE_NONE, NULL, 0x00,
6835                     "Option 125: Suboption IP address value", HFILL }},
6836
6837                 { &hf_bootp_option125_value_stringz,
6838                   { "Value", "bootp.option.vi.value.string",
6839                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6840                     "Option 125: Suboption Z-String value", HFILL }},
6841
6842                 { &hf_bootp_option125_tr111_suboption,
6843                   { "Option 125 Suboption", "bootp.option.vi.tr111.suboption",
6844                     FT_UINT8, BASE_DEC, VALS(option125_tr111_suboption_vals), 0x0,
6845                     "Option 125:TR 111 Suboption", HFILL }},
6846
6847                 { &hf_bootp_option125_tr111_device_manufacturer_oui,
6848                   { "DeviceManufacturerOUI", "bootp.option.vi.tr111.device_manufacturer_oui",
6849                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6850                     "Option 125:TR 111 1 DeviceManufacturerOUI", HFILL }},
6851
6852                 { &hf_bootp_option125_tr111_device_serial_number,
6853                   { "DeviceSerialNumber", "bootp.option.vi.tr111.device_serial_number",
6854                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6855                     "Option 125:TR 111 2 DeviceSerialNumber", HFILL }},
6856
6857                 { &hf_bootp_option125_tr111_device_product_class,
6858                   { "DeviceProductClass", "bootp.option.vi.tr111.device_product_class",
6859                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6860                     "Option 125:TR 111 3 DeviceProductClass", HFILL }},
6861
6862                 { &hf_bootp_option125_tr111_gateway_manufacturer_oui,
6863                   { "GatewayManufacturerOUI", "bootp.option.vi.tr111.gateway_manufacturer_oui",
6864                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6865                     "Option 125:TR 111 4 GatewayManufacturerOUI", HFILL }},
6866
6867                 { &hf_bootp_option125_tr111_gateway_serial_number,
6868                   { "GatewaySerialNumber", "bootp.option.vi.tr111.gateway_serial_number",
6869                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6870                     "Option 125:TR 111 5 GatewaySerialNumber", HFILL }},
6871
6872                 { &hf_bootp_option125_tr111_gateway_product_class,
6873                   { "GatewayProductClass", "bootp.option.vi.tr111.gateway_product_class",
6874                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6875                     "Option 125:TR 111 6 GatewayProductClass", HFILL }},
6876
6877                 { &hf_bootp_option125_cl_suboption,
6878                   { "Option 125 Suboption", "bootp.option.vi.cl.suboption",
6879                     FT_UINT8, BASE_DEC, VALS(option125_cl_suboption_vals), 0x0,
6880                     "Option 125:CL Suboption", HFILL }},
6881
6882                 { &hf_bootp_option125_cl_option_request,
6883                   { "Option Request", "bootp.option.vi.cl.option_request",
6884                     FT_UINT8, BASE_DEC, NULL, 0x0,
6885                     "Option 125:CL 1 Option Request", HFILL }},
6886
6887                 { &hf_bootp_option125_cl_tftp_server_addresses,
6888                   { "TFTP Server Addresses", "bootp.option.vi.cl.tftp_server_addresses",
6889                     FT_IPv4, BASE_NONE, NULL, 0x00,
6890                     "Option 125:CL 2 TFTP Server Addresses", HFILL }},
6891
6892                 { &hf_bootp_option125_cl_erouter_container_option,
6893                   { "eRouter Container Option", "bootp.option.vi.cl.erouter_container_option",
6894                     FT_BYTES, BASE_NONE, NULL, 0x0,
6895                     "Option 125:CL 3 eRouter Container Option", HFILL }},
6896
6897                 { &hf_bootp_option125_cl_mib_environment_indicator_option,
6898                   { "MIB Environment Indicator Option", "bootp.option.vi.cl.suboption",
6899                     FT_UINT8, BASE_DEC, VALS(pkt_mib_env_ind_opt_vals), 0x0,
6900                     "Option 125:CL 4 MIB Environment Indicator Option", HFILL }},
6901
6902                 { &hf_bootp_option125_cl_modem_capabilities,
6903                   { "Modem Capabilities", "bootp.option.vi.cl.modem_capabilities",
6904                     FT_BYTES, BASE_NONE, NULL, 0x0,
6905                     "Option 125:CL 5 Modem Capabilities", HFILL }},
6906
6907                 { &hf_bootp_option_subnet_selection_option,
6908                   { "Subnet Selection Option", "bootp.option.subnet_selection_option",
6909                     FT_IPv4, BASE_NONE, NULL, 0x00,
6910                     "Option 118: Subnet Selection Option", HFILL }},
6911
6912                 { &hf_bootp_option_lost_server_domain_name,
6913                   { "LoST Server Domain Name", "bootp.option.lost_server_domain_name",
6914                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6915                     "Option 137: LoST Server Domain Name", HFILL }},
6916
6917                 { &hf_bootp_option_capwap_access_controller,
6918                   { "CAPWAP Access Controllers", "bootp.option.capwap_access_controller",
6919                     FT_IPv4, BASE_NONE, NULL, 0x00,
6920                     "Option 138: CAPWAP Access Controllers", HFILL }},
6921
6922                 { &hf_bootp_option_tftp_server_address,
6923                   { "TFTP Server Address", "bootp.option.tftp_server_address",
6924                     FT_IPv4, BASE_NONE, NULL, 0x00,
6925                     "Option 150: TFTP Server Address", HFILL }},
6926
6927                 { &hf_bootp_option_6RD_ipv4_mask_len,
6928                   { "6RD IPv4 Mask Length", "bootp.option.6RD.ipv4_mask_len",
6929                     FT_UINT8, BASE_DEC, NULL, 0x0,
6930                     "Option 212: 6RD IPv4 Mask Length", HFILL }},
6931
6932                 { &hf_bootp_option_6RD_prefix_len,
6933                   { "6RD Prefix Length", "bootp.option.6RD.prefix_len",
6934                     FT_UINT8, BASE_DEC, NULL, 0x0,
6935                     "Option 212: 6RD Prefix Length", HFILL }},
6936
6937                 { &hf_bootp_option_6RD_prefix,
6938                   { "6RD Prefix", "bootp.option.6RD.prefix",
6939                     FT_IPv6, BASE_NONE, NULL, 0x00,
6940                     "Option 212: 6RD Prefix", HFILL }},
6941
6942                 { &hf_bootp_option_6RD_border_relay_ip,
6943                   { "Border Relay IP", "bootp.option.6RD.border_relay_ip",
6944                     FT_IPv4, BASE_NONE, NULL, 0x00,
6945                     "Option 212: Border Relay IP", HFILL }},
6946
6947                 { &hf_bootp_option_private_proxy_autodiscovery,
6948                   { "Private/Proxy autodiscovery", "bootp.option.private_proxy_autodiscovery",
6949                     FT_STRINGZ, BASE_NONE, NULL, 0x0,
6950                     "Option 252: Private/Proxy autodiscovery", HFILL }},
6951
6952                 { &hf_bootp_option_end,
6953                   { "Option End", "bootp.option.end",
6954                     FT_UINT8, BASE_DEC, NULL, 0x0,
6955                     "Option 255: End", HFILL }},
6956
6957                 { &hf_bootp_option_end_overload,
6958                   { "Option End (Overload)", "bootp.option.end",
6959                     FT_UINT8, BASE_DEC, NULL, 0x0,
6960                     "Option 255: End (Overload)", HFILL }},
6961
6962                 { &hf_bootp_vendor_unknown_suboption,
6963                   { "Option 125 Suboption", "bootp.vendor.suboption",
6964                     FT_UINT8, BASE_DEC, NULL, 0x0,
6965                     NULL, HFILL }},
6966
6967                 { &hf_bootp_suboption_data,
6968                   { "Data", "bootp.vendor.data",
6969                     FT_BYTES, BASE_NONE, NULL, 0x0,
6970                     NULL, HFILL }},
6971         };
6972
6973         static uat_field_t bootp_uat_flds[] = {
6974                 UAT_FLD_DEC(uat_bootp_records, opt, "Option number", "Custom Option Number"),
6975                 UAT_FLD_CSTRING(uat_bootp_records, text, "Option Name", "Custom Option Name"),
6976                 UAT_FLD_VS(uat_bootp_records, ftype, "Option type", bootp_custom_type_vals, "Option datatype"),
6977                 UAT_END_FIELDS
6978         };
6979
6980         static gint *ett[] = {
6981                 &ett_bootp,
6982                 &ett_bootp_flags,
6983                 &ett_bootp_option,
6984                 &ett_bootp_option43_suboption,
6985                 &ett_bootp_option63_suboption,
6986                 &ett_bootp_option77_instance,
6987                 &ett_bootp_option82_suboption,
6988                 &ett_bootp_option82_suboption9,
6989                 &ett_bootp_option125_suboption,
6990                 &ett_bootp_option125_tr111_suboption,
6991                 &ett_bootp_option125_cl_suboption,
6992                 &ett_bootp_fqdn,
6993         };
6994
6995         static ei_register_info ei[] = {
6996                 { &ei_bootp_bad_length, { "bootp.bad_length", PI_PROTOCOL, PI_ERROR, "length isn't 0", EXPFILL }},
6997                 { &ei_bootp_missing_subopt_length, { "bootp.missing_subopt_length", PI_PROTOCOL, PI_ERROR, "no room left in option for suboption length", EXPFILL }},
6998                 { &ei_bootp_missing_subopt_value, { "bootp.missing_subopt_value", PI_PROTOCOL, PI_ERROR, "no room left in option for suboption value", EXPFILL }},
6999                 { &ei_bootp_mal_duid, { "bootp.malformed.duid", PI_PROTOCOL, PI_ERROR, "DUID: malformed option", EXPFILL }},
7000                 { &hf_bootp_opt_overload_file_end_missing, { "bootp.option.option_overload.file_end_missing", PI_PROTOCOL, PI_ERROR, "file overload end option missing", EXPFILL }},
7001                 { &hf_bootp_opt_overload_sname_end_missing, { "bootp.option.option_overload.sname_end_missing", PI_PROTOCOL, PI_ERROR, "sname overload end option missing", EXPFILL }},
7002                 { &hf_bootp_subopt_unknown_type, { "bootp.subopt.unknown_type", PI_PROTOCOL, PI_ERROR, "ERROR, please report: Unknown subopt type handler", EXPFILL }},
7003                 { &ei_bootp_option77_user_class_malformed, { "bootp.option.user_class.malformed", PI_PROTOCOL, PI_ERROR, "User Class Information: malformed option", EXPFILL }},
7004                 { &ei_bootp_option_civic_location_bad_cattype, { "bootp.option.civic_location.bad_cattype", PI_PROTOCOL, PI_ERROR, "Error with CAType", EXPFILL }},
7005                 { &ei_bootp_option_dhcp_name_service_invalid, { "bootp.option.dhcp_name_service.invalid", PI_PROTOCOL, PI_ERROR, "Invalid Name Service", EXPFILL }},
7006                 { &ei_bootp_option_sip_server_address_encoding, { "bootp.option.sip_server_address.encoding", PI_PROTOCOL, PI_ERROR, "RFC 3361 defines only 0 and 1 for Encoding byte", EXPFILL }},
7007                 { &ei_bootp_option_classless_static_route, { "bootp.option.classless_static.route", PI_PROTOCOL, PI_ERROR, "Mask width > 32", EXPFILL }},
7008                 { &ei_bootp_option125_enterprise_malformed, { "bootp.option.enterprise.malformed", PI_PROTOCOL, PI_ERROR, "no room left in option for enterprise data", EXPFILL }},
7009                 { &ei_bootp_option_6RD_malformed, { "bootp.option.6RD.malformed", PI_PROTOCOL, PI_ERROR, "6RD: malformed option", EXPFILL }},
7010                 { &ei_bootp_option82_vi_cl_tag_unknown, { "bootp.option.option.vi.cl.tag_unknown", PI_PROTOCOL, PI_ERROR, "Unknown tag", EXPFILL }},
7011                 { &ei_bootp_suboption_invalid, { "bootp.suboption_invalid", PI_PROTOCOL, PI_ERROR, "Invalid suboption", EXPFILL }},
7012                 { &ei_bootp_secs_le, { "bootp.secs_le", PI_PROTOCOL, PI_NOTE, "Seconds elapsed appears to be encoded as little-endian", EXPFILL }},
7013                 { &ei_bootp_end_option_missing, { "bootp.end_option_missing", PI_PROTOCOL, PI_ERROR, "End option missing", EXPFILL }},
7014         };
7015
7016         module_t *bootp_module;
7017         expert_module_t* expert_bootp;
7018
7019         proto_bootp = proto_register_protocol("Bootstrap Protocol", "BOOTP/DHCP",
7020                                               "bootp");
7021         proto_register_field_array(proto_bootp, hf, array_length(hf));
7022         proto_register_subtree_array(ett, array_length(ett));
7023         bootp_dhcp_tap = register_tap("bootp");
7024
7025         expert_bootp = expert_register_protocol(proto_bootp);
7026         expert_register_field_array(expert_bootp, ei, array_length(ei));
7027
7028         /* register init routine to setup the custom bootp options */
7029         register_init_routine(&bootp_init_protocol);
7030
7031         /* Allow dissector to find be found by name. */
7032         bootp_handle = register_dissector("bootp", dissect_bootp, proto_bootp);
7033
7034         bootp_module = prefs_register_protocol(proto_bootp, NULL);
7035
7036         prefs_register_bool_preference(bootp_module, "novellserverstring",
7037                                        "Decode Option 85 as String",
7038                                        "Novell Servers option 85 can be configured as a string instead of address",
7039                                        &novell_string);
7040
7041         prefs_register_enum_preference(bootp_module, "pkt.ccc.protocol_version",
7042                                        "PacketCable CCC protocol version",
7043                                        "The PacketCable CCC protocol version",
7044                                        &pkt_ccc_protocol_version,
7045                                        pkt_ccc_protocol_versions,
7046                                        FALSE);
7047
7048         prefs_register_uint_preference(bootp_module, "pkt.ccc.option",
7049                                        "PacketCable CCC option",
7050                                        "Option Number for PacketCable CableLabs Client Configuration",
7051                                        10,
7052                                        &pkt_ccc_option);
7053
7054         prefs_register_obsolete_preference(bootp_module, "displayasstring");
7055
7056         bootp_uat = uat_new("Custom BootP/DHCP Options (Excl. suboptions)",
7057                         sizeof(uat_bootp_record_t), /* record size           */
7058                         "custom_bootp",             /* filename              */
7059                         TRUE,                       /* from_profile          */
7060                         &uat_bootp_records,         /* data_ptr              */
7061                         &num_bootp_records_uat,     /* numitems_ptr          */
7062                         UAT_AFFECTS_DISSECTION,     /* affects dissection of packets, but not set of named fields */
7063                         NULL,                       /* help                  */
7064                         uat_bootp_record_copy_cb,   /* copy callback         */
7065                         uat_bootp_record_update_cb, /* update callback       */
7066                         uat_bootp_record_free_cb,   /* free callback         */
7067                         NULL,                       /* post update callback  */
7068                         bootp_uat_flds);            /* UAT field definitions */
7069
7070         prefs_register_uat_preference(bootp_module,
7071                                       "custom_bootp_table",
7072                                       "Custom BootP/DHCP Options (Excl. suboptions)",
7073                                       "Custom BootP/DHCP Options (Excl. suboptions)",
7074                                       bootp_uat);
7075 }
7076
7077 void
7078 proto_reg_handoff_bootp(void)
7079 {
7080         dissector_add_uint("udp.port", UDP_PORT_BOOTPS, bootp_handle);
7081         dissector_add_uint("udp.port", UDP_PORT_BOOTPC, bootp_handle);
7082 }
7083
7084 /*
7085  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
7086  *
7087  * Local variables:
7088  * c-basic-offset: 8
7089  * tab-width: 8
7090  * indent-tabs-mode: t
7091  * End:
7092  *
7093  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
7094  * :indentSize=8:tabSize=8:noTabs=false:
7095  */