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