Cleanup use of #includes in non-generated epan/dissector/*.c
[metze/wireshark/wip.git] / epan / dissectors / packet-ppp.c
1 /* packet-ppp.c
2  * Routines for ppp packet disassembly
3  * RFC 1661, RFC 1662
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  *
8  * This file created and by Mike Hall <mlh@io.com>
9  * Copyright 1998
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 #include "config.h"
27
28 #include <epan/packet.h>
29 #include <wsutil/pint.h>
30 #include <epan/prefs.h>
31 #include "packet-ppp.h"
32 #include <epan/ppptypes.h>
33 #include <epan/etypes.h>
34 #include <epan/expert.h>
35 #include <epan/ip_opts.h>
36 #include <epan/atalk-utils.h>
37 #include "packet-chdlc.h"
38 #include "packet-ip.h"
39 #include "packet-ipx.h"
40 #include "packet-vines.h"
41 #include <epan/nlpid.h>
42 #include <epan/crc16-tvb.h>
43 #include <epan/crc32-tvb.h>
44 #include <epan/ipproto.h>
45 #include <epan/addr_resolv.h>
46 #include <epan/oui.h>
47 #include "packet-usb.h"
48 #include "packet-sll.h"
49 #include "packet-juniper.h"
50 #include "packet-sflow.h"
51
52 void proto_register_ppp_raw_hdlc(void);
53 void proto_reg_handoff_ppp_raw_hdlc(void);
54 void proto_register_ppp(void);
55 void proto_reg_handoff_ppp(void);
56 void proto_register_mp(void);
57 void proto_reg_handoff_mp(void);
58 void proto_register_lcp(void);
59 void proto_reg_handoff_lcp(void);
60 void proto_register_vsncp(void);
61 void proto_reg_handoff_vsncp(void);
62 void proto_register_vsnp(void);
63 void proto_reg_handoff_vsnp(void);
64 void proto_register_ipcp(void);
65 void proto_reg_handoff_ipcp(void);
66 void proto_register_bcp(void);
67 void proto_register_osinlcp(void);
68 void proto_reg_handoff_bcp(void);
69 void proto_reg_handoff_osinlcp(void);
70 void proto_register_ccp(void);
71 void proto_reg_handoff_ccp(void);
72 void proto_register_cbcp(void);
73 void proto_reg_handoff_cbcp(void);
74 void proto_register_bacp(void);
75 void proto_reg_handoff_bacp(void);
76 void proto_register_bap(void);
77 void proto_reg_handoff_bap(void);
78 void proto_register_comp_data(void);
79 void proto_reg_handoff_comp_data(void);
80 void proto_register_pap(void);
81 void proto_reg_handoff_pap(void);
82 void proto_register_chap(void);
83 void proto_reg_handoff_chap(void);
84 void proto_register_pppmuxcp(void);
85 void proto_reg_handoff_pppmuxcp(void);
86 void proto_register_pppmux(void);
87 void proto_reg_handoff_pppmux(void);
88 void proto_register_mplscp(void);
89 void proto_reg_handoff_mplscp(void);
90 void proto_register_cdpcp(void);
91 void proto_reg_handoff_cdpcp(void);
92 void proto_register_ipv6cp(void);
93 void proto_reg_handoff_ipv6cp(void);
94 void proto_register_iphc_crtp(void);
95 void proto_reg_handoff_iphc_crtp(void);
96
97
98 static int proto_ppp = -1;
99 static int hf_ppp_direction = -1;
100 static int hf_ppp_address = -1;
101 static int hf_ppp_control = -1;
102 static int hf_ppp_protocol = -1;
103 static int hf_ppp_code = -1;
104 static int hf_ppp_identifier = -1;
105 static int hf_ppp_length = -1;
106 static int hf_ppp_magic_number = -1;
107 static int hf_ppp_oui = -1;
108 static int hf_ppp_kind = -1;
109 static int hf_ppp_data = -1;
110 static int hf_ppp_opt_type = -1;
111 static int hf_ppp_opt_type_copy = -1;
112 static int hf_ppp_opt_type_class = -1;
113 static int hf_ppp_opt_type_number = -1;
114 /* Generated from convert_proto_tree_add_text.pl */
115 static int hf_ppp_fcs_16 = -1;
116 static int hf_ppp_fcs_32 = -1;
117
118 static gint ett_ppp = -1;
119 static gint ett_ppp_opt_type = -1;
120
121 static expert_field ei_ppp_opt_len_invalid = EI_INIT;
122
123 static int proto_ppp_hdlc = -1;
124
125 /* Generated from convert_proto_tree_add_text.pl */
126 static int hf_ppp_hdlc_data = -1;
127 static int hf_ppp_hdlc_fragment = -1;
128
129 static gint ett_ppp_hdlc_data = -1;
130
131 static int proto_lcp = -1;
132
133 static gint ett_lcp = -1;
134 static gint ett_lcp_options = -1;
135 static gint ett_lcp_vendor_opt = -1;
136 static gint ett_lcp_mru_opt = -1;
137 static gint ett_lcp_asyncmap_opt = -1;
138 static gint ett_lcp_authprot_opt = -1;
139 static gint ett_lcp_qualprot_opt = -1;
140 static gint ett_lcp_magicnumber_opt = -1;
141 static gint ett_lcp_linkqualmon_opt = -1;
142 static gint ett_lcp_pcomp_opt = -1;
143 static gint ett_lcp_acccomp_opt = -1;
144 static gint ett_lcp_fcs_alternatives_opt = -1;
145 static gint ett_lcp_self_desc_pad_opt = -1;
146 static gint ett_lcp_numbered_mode_opt = -1;
147 static gint ett_lcp_callback_opt = -1;
148 static gint ett_lcp_compound_frames_opt = -1;
149 static gint ett_lcp_nomdataencap_opt = -1;
150 static gint ett_lcp_multilink_mrru_opt = -1;
151 static gint ett_lcp_multilink_ssnh_opt = -1;
152 static gint ett_lcp_multilink_ep_disc_opt = -1;
153 static gint ett_lcp_magic_block = -1;
154 static gint ett_lcp_dce_identifier_opt = -1;
155 static gint ett_lcp_multilink_pp_opt = -1;
156 static gint ett_lcp_bacp_link_discrim_opt = -1;
157 static gint ett_lcp_auth_opt = -1;
158 static gint ett_lcp_cobs_opt = -1;
159 static gint ett_lcp_prefix_elision_opt = -1;
160 static gint ett_multilink_hdr_fmt_opt = -1;
161 static gint ett_lcp_internationalization_opt = -1;
162 static gint ett_lcp_simple_opt = -1;
163
164 static int proto_ipcp = -1;
165
166 static gint ett_ipcp = -1;
167 static gint ett_ipcp_options = -1;
168 static gint ett_ipcp_ipaddrs_opt = -1;
169 static gint ett_ipcp_compress_opt = -1;
170 static gint ett_ipcp_ipaddr_opt = -1;
171 static gint ett_ipcp_mobileipv4_opt = -1;
172 static gint ett_ipcp_pridns_opt = -1;
173 static gint ett_ipcp_secdns_opt = -1;
174 static gint ett_ipcp_prinbns_opt = -1;
175 static gint ett_ipcp_secnbns_opt = -1;
176
177 static gint ett_ipcp_iphc_rtp_compress_opt = -1;
178 static gint ett_ipcp_iphc_enhanced_rtp_compress_opt = -1;
179 static gint ett_ipcp_iphc_neghdrcomp_opt = -1;
180 static gint ett_ipcp_rohc_profiles_opt = -1;
181
182 static int proto_vsncp = -1;
183
184 /* Generated from convert_proto_tree_add_text.pl */
185 static int hf_vsncp_protocol_configuration_length = -1;
186 static int hf_vsncp_error_code = -1;
187 static int hf_vsncp_identifier = -1;
188 static int hf_vsncp_attach_type = -1;
189 static int hf_vsncp_protocol_configuration_data = -1;
190 static int hf_vsncp_default_router_address = -1;
191 static int hf_vsncp_pdn_identifier = -1;
192 static int hf_vsncp_address_allocation_cause = -1;
193 static int hf_vsncp_length = -1;
194 static int hf_vsncp_code = -1;
195 static int hf_vsncp_protocol = -1;
196 static int hf_vsncp_pdn_type = -1;
197 static int hf_vsncp_ipv6_interface_identifier = -1;
198 static int hf_vsncp_pdn_ipv4 = -1;
199 static int hf_vsncp_access_point_name = -1;
200 static int hf_vsncp_ambr_data = -1;
201 static int hf_vsncp_pdn_ipv6 = -1;
202
203 static gint ett_vsncp = -1;
204 static gint ett_vsncp_options = -1;
205
206 static int proto_vsnp = -1;
207 static gint hf_vsnp_pdnid = -1;
208
209 static gint ett_vsnp =-1;
210
211 static int proto_osinlcp = -1;
212
213 static gint ett_osinlcp = -1;
214 static gint ett_osinlcp_options = -1;
215 static gint ett_osinlcp_align_npdu_opt = -1;
216
217 static int proto_bcp = -1;
218 static int hf_bcp_flags = -1;
219 static int hf_bcp_fcs_present = -1;
220 static int hf_bcp_zeropad = -1;
221 static int hf_bcp_bcontrol = -1;
222 static int hf_bcp_pads = -1;
223 static int hf_bcp_mac_type = -1;
224 static int hf_bcp_pad = -1;
225
226 static gint ett_bcp = -1;
227 static gint ett_bcp_flags = -1;
228
229 static int proto_ccp = -1;
230
231 static gint ett_ccp = -1;
232 static gint ett_ccp_options = -1;
233 static gint ett_ccp_oui_opt = -1;
234 static gint ett_ccp_predict1_opt = -1;
235 static gint ett_ccp_predict2_opt = -1;
236 static gint ett_ccp_puddle_opt = -1;
237 static gint ett_ccp_hpppc_opt = -1;
238 static gint ett_ccp_stac_opt = -1;
239 static gint ett_ccp_stac_opt_check_mode = -1;
240 static gint ett_ccp_mppe_opt = -1;
241 static gint ett_ccp_mppe_opt_supp_bits = -1;
242 static gint ett_ccp_gfza_opt = -1;
243 static gint ett_ccp_v42bis_opt = -1;
244 static gint ett_ccp_bsdcomp_opt = -1;
245 static gint ett_ccp_lzsdcp_opt = -1;
246 static gint ett_ccp_mvrca_opt = -1;
247 static gint ett_ccp_dce_opt = -1;
248 static gint ett_ccp_deflate_opt = -1;
249 static gint ett_ccp_v44lzjh_opt = -1;
250
251 static int proto_cbcp = -1;
252
253 /* Generated from convert_proto_tree_add_text.pl */
254 static int hf_cbcp_address_type = -1;
255 static int hf_cbcp_address = -1;
256 static int hf_cbcp_callback_delay = -1;
257 static int hf_cbcp_no_callback = -1;
258
259 static gint ett_cbcp = -1;
260 static gint ett_cbcp_options = -1;
261 static gint ett_cbcp_callback_opt = -1;
262 static gint ett_cbcp_callback_opt_addr = -1;
263
264 static expert_field ei_cbcp_address = EI_INIT;
265
266 static int proto_bacp = -1;
267
268 /* Generated from convert_proto_tree_add_text.pl */
269 static int hf_bacp_link_speed = -1;
270 static int hf_bacp_magic_number = -1;
271 static int hf_bacp_link_type = -1;
272
273 static gint ett_bacp = -1;
274 static gint ett_bacp_options = -1;
275 static gint ett_bacp_favored_peer_opt = -1;
276
277 static int proto_bap = -1;
278
279 /* Generated from convert_proto_tree_add_text.pl */
280 static int hf_bap_sub_option_length = -1;
281 static int hf_bap_call_status = -1;
282 static int hf_bap_unknown_option_data = -1;
283 static int hf_bap_sub_option_type = -1;
284 static int hf_bap_reason = -1;
285 static int hf_bap_link_descriminator = -1;
286 static int hf_bap_unique_digit = -1;
287 static int hf_bap_type = -1;
288 static int hf_bap_identifier = -1;
289 static int hf_bap_subscriber_number = -1;
290 static int hf_bap_phone_number_sub_address = -1;
291 static int hf_bap_response_code = -1;
292 static int hf_bap_call_action = -1;
293 static int hf_bap_length = -1;
294
295 static gint ett_bap = -1;
296 static gint ett_bap_options = -1;
297 static gint ett_bap_link_type_opt = -1;
298 static gint ett_bap_phone_delta_opt = -1;
299 static gint ett_bap_phone_delta_subopt = -1;
300 static gint ett_bap_call_status_opt = -1;
301
302 static expert_field ei_bap_sub_option_length = EI_INIT;
303
304 static int proto_comp_data = -1;
305
306 #if 0  /* see dissect_comp_data() */
307 static gint ett_comp_data = -1;
308 #endif
309 static int proto_pppmuxcp = -1;
310
311 static int hf_pppmux_flags_pid = -1;
312 static int hf_pppmux_flags_field_length = -1;
313 /* Generated from convert_proto_tree_add_text.pl */
314 static int hf_pppmux_sub_frame_length = -1;
315 static int hf_pppmux_flags = -1;
316 static int hf_pppmux_def_prot_id = -1;
317
318 static gint ett_pppmuxcp = -1;
319 static gint ett_pppmuxcp_options = -1;
320
321 static int proto_pppmux = -1;
322 static int hf_pppmux_protocol = -1;
323
324 static gint ett_pppmux = -1;
325 static gint ett_pppmux_subframe = -1;
326 static gint ett_pppmux_subframe_hdr = -1;
327 static gint ett_pppmux_subframe_flags = -1;
328 static gint ett_pppmux_subframe_info = -1;
329
330 static int proto_mp = -1;
331 static int hf_mp_frag = -1;
332 static int hf_mp_frag_first = -1;
333 static int hf_mp_frag_last = -1;
334 static int hf_mp_short_sequence_num_reserved = -1;
335 static int hf_mp_sequence_num = -1;
336 static int hf_mp_sequence_num_reserved = -1;
337 static int hf_mp_short_sequence_num = -1;
338
339 static int ett_mp = -1;
340 static int ett_mp_flags = -1;
341
342 static int proto_mplscp = -1;
343 static gint ett_mplscp = -1;
344 static gint ett_mplscp_options  = -1;
345
346 static int proto_cdpcp = -1;
347 static gint ett_cdpcp = -1;
348 static gint ett_cdpcp_options   = -1;
349
350 static int proto_pap = -1;           /* PAP vars */
351 static gint ett_pap = -1;
352 static gint ett_pap_data = -1;
353
354 static gint hf_pap_code = -1;
355 static gint hf_pap_identifier = -1;
356 static gint hf_pap_length = -1;
357 static gint hf_pap_data = -1;
358 static gint hf_pap_peer_id = -1;
359 static gint hf_pap_peer_id_length = -1;
360 static gint hf_pap_password = -1;
361 static gint hf_pap_password_length = -1;
362 static gint hf_pap_message = -1;
363 static gint hf_pap_message_length = -1;
364 static gint hf_pap_stuff = -1;
365
366 static int proto_chap = -1;           /* CHAP vars */
367 static gint ett_chap = -1;
368 static gint ett_chap_data = -1;
369
370
371 static gint hf_chap_code = -1;
372 static gint hf_chap_identifier = -1;
373 static gint hf_chap_length = -1;
374 static gint hf_chap_data = -1;
375 static gint hf_chap_value_size = -1;
376 static gint hf_chap_value = -1;
377 static gint hf_chap_name = -1;
378 static gint hf_chap_message = -1;
379 static int hf_chap_stuff = -1;
380
381 static int proto_ipv6cp = -1;  /* IPv6CP vars */
382
383 /* Generated from convert_proto_tree_add_text.pl */
384 static int hf_ipv6cp_interface_identifier = -1;
385
386 static gint ett_ipv6cp = -1;
387 static gint ett_ipv6cp_options = -1;
388 static gint ett_ipv6cp_if_id_opt = -1;
389 static gint ett_ipv6cp_compress_opt = -1;
390
391 static int proto_iphc_crtp = -1;            /* CRTP vars */
392 static int hf_iphc_crtp_cid8 = -1;
393 static int hf_iphc_crtp_cid16 = -1;
394 static int hf_iphc_crtp_gen = -1;
395 static int hf_iphc_crtp_seq = -1;
396 static int hf_iphc_crtp_fh_flags = -1;
397 static int hf_iphc_crtp_cs_flags = -1;
398 static int hf_iphc_crtp_cs_cnt = -1;
399 static int hf_iphc_crtp_cs_invalid = -1;
400 static int hf_iphc_crtp_data = -1;
401
402 static gint ett_iphc_crtp = -1;
403 static gint ett_iphc_crtp_hdr = -1;
404 static gint ett_iphc_crtp_info = -1;
405
406 static expert_field ei_iphc_crtp_ip_version = EI_INIT;
407 static expert_field ei_iphc_crtp_next_protocol = EI_INIT;
408
409 static dissector_table_t ppp_subdissector_table;
410 static dissector_handle_t chdlc_handle;
411 static dissector_handle_t data_handle;
412 static dissector_handle_t eth_withfcs_handle;
413 static dissector_handle_t eth_withoutfcs_handle;
414
415 static const value_string ppp_direction_vals[] = {
416     {P2P_DIR_RECV, "DCE->DTE"},
417     {P2P_DIR_SENT, "DTE->DCE"},
418     {0,            NULL}
419 };
420
421 /* options */
422 static gint ppp_fcs_decode = 0; /* 0 = No FCS, 1 = 16 bit FCS, 2 = 32 bit FCS */
423 #define NO_FCS 0
424 #define FCS_16 1
425 #define FCS_32 2
426
427 const enum_val_t fcs_options[] = {
428     {"none",   "None",   NO_FCS},
429     {"16-bit", "16-Bit", FCS_16},
430     {"32-bit", "32-Bit", FCS_32},
431     {NULL,     NULL,     -1}
432 };
433
434 gboolean ppp_vj_decomp = TRUE; /* Default to VJ header decompression */
435
436 /*
437  * For Default Protocol ID negotiated with PPPMuxCP. We need to
438  * this ID so that if the first subframe doesn't have protocol
439  * ID, we can use it
440  */
441
442 static guint pppmux_def_prot_id = 0;
443
444 /* PPP definitions */
445
446 /*
447  * Used by the GTP dissector as well.
448  * www.iana.org/assignments/ppp-numbers
449  */
450 static const value_string ppp_vals[] = {
451     {PPP_PADDING,     "Padding Protocol"},
452     {PPP_ROHC_SCID,   "ROHC small-CID"},
453     {PPP_ROHC_LCID,   "ROHC large-CID"},
454     {PPP_IP,          "Internet Protocol version 4"},
455     {PPP_OSI,         "OSI Network Layer"},
456     {PPP_XNSIDP,      "Xerox NS IDP"},
457     {PPP_DEC4,        "DECnet Phase IV"},
458     {PPP_AT,          "Appletalk"},
459     {PPP_IPX,         "Novell IPX"},
460     {PPP_VJC_COMP,    "Van Jacobson Compressed TCP/IP"},
461     {PPP_VJC_UNCOMP,  "Van Jacobson Uncompressed TCP/IP"},
462     {PPP_BCP,         "Bridging PDU"},
463     {PPP_ST,          "Stream Protocol (ST-II)"},
464     {PPP_VINES,       "Banyan Vines"},
465     {PPP_AT_EDDP,     "AppleTalk EDDP"},
466     {PPP_AT_SB,       "AppleTalk SmartBuffered"},
467     {PPP_MP,          "Multi-Link"},
468     {PPP_NB,          "NETBIOS Framing"},
469     {PPP_CISCO,       "Cisco Systems"},
470     {PPP_ASCOM,       "Ascom Timeplex"},
471     {PPP_LBLB,        "Fujitsu Link Backup and Load Balancing (LBLB)"},
472     {PPP_RL,          "DCA Remote Lan"},
473     {PPP_SDTP,        "Serial Data Transport Protocol (PPP-SDTP)"},
474     {PPP_LLC,         "SNA over 802.2"},
475     {PPP_SNA,         "SNA"},
476     {PPP_IPV6HC,      "IPv6 Header Compression "},
477     {PPP_KNX,         "KNX Bridging Data"},
478     {PPP_ENCRYPT,     "Encryption"},
479     {PPP_ILE,         "Individual Link Encryption"},
480     {PPP_IPV6,        "Internet Protocol version 6"},
481     {PPP_MUX,         "PPP Muxing"},
482     {PPP_VSNP,        "Vendor-Specific Network Protocol (VSNP)"},
483     {PPP_TNP,         "TRILL Network Protocol (TNP)"},
484     {PPP_RTP_FH,      "RTP IPHC Full Header"},
485     {PPP_RTP_CTCP,    "RTP IPHC Compressed TCP"},
486     {PPP_RTP_CNTCP,   "RTP IPHC Compressed Non TCP"},
487     {PPP_RTP_CUDP8,   "RTP IPHC Compressed UDP 8"},
488     {PPP_RTP_CRTP8,   "RTP IPHC Compressed RTP 8"},
489     {PPP_STAMPEDE,    "Stampede Bridging"},
490     {PPP_MPPLUS,      "MP+ Protocol"},
491     {PPP_NTCITS_IPI,  "NTCITS IPI"},
492     {PPP_ML_SLCOMP,   "Single link compression in multilink"},
493     {PPP_COMP,        "Compressed datagram"},
494     {PPP_STP_HELLO,   "802.1d Hello Packets"},
495     {PPP_IBM_SR,      "IBM Source Routing BPDU"},
496     {PPP_DEC_LB,      "DEC LANBridge100 Spanning Tree"},
497     {PPP_CDP,         "Cisco Discovery Protocol"},
498     {PPP_NETCS,       "Netcs Twin Routing"},
499     {PPP_STP,         "STP - Scheduled Transfer Protocol"},
500     {PPP_EDP,         "EDP - Extreme Discovery Protocol"},
501     {PPP_OSCP,        "Optical Supervisory Channel Protocol (OSCP)"},
502     {PPP_OSCP2,       "Optical Supervisory Channel Protocol (OSCP)"},
503     {PPP_LUXCOM,      "Luxcom"},
504     {PPP_SIGMA,       "Sigma Network Systems"},
505     {PPP_ACSP,        "Apple Client Server Protocol"},
506     {PPP_MPLS_UNI,    "MPLS Unicast"},
507     {PPP_MPLS_MULTI,  "MPLS Multicast"},
508     {PPP_P12844,      "IEEE p1284.4 standard - data packets"},
509     {PPP_TETRA,       "ETSI TETRA Network Protocol Type 1"},
510     {PPP_MFTP,        "Multichannel Flow Treatment Protocol"},
511     {PPP_RTP_CTCPND,  "RTP IPHC Compressed TCP No Delta"},
512     {PPP_RTP_CS,      "RTP IPHC Context State"},
513     {PPP_RTP_CUDP16,  "RTP IPHC Compressed UDP 16"},
514     {PPP_RTP_CRDP16,  "RTP IPHC Compressed RTP 16"},
515     {PPP_CCCP,        "Cray Communications Control Protocol"},
516     {PPP_CDPD_MNRP,   "CDPD Mobile Network Registration Protocol"},
517     {PPP_EXPANDAP,    "Expand accelerator protocol"},
518     {PPP_ODSICP,      "ODSICP NCP"},
519     {PPP_DOCSIS,      "DOCSIS DLL"},
520     {PPP_CETACEANNDP, "Cetacean Network Detection Protocol"},
521     {PPP_LZS,         "Stacker LZS"},
522     {PPP_REFTEK,      "RefTek Protocol"},
523     {PPP_FC,          "Fibre Channel"},
524     {PPP_EMIT,        "EMIT Protocols"},
525     {PPP_VSP,         "Vendor-Specific Protocol (VSP)"},
526     {PPP_TLSP,        "TRILL Link State Protocol (TLSP)"},
527     {PPP_IPCP,        "Internet Protocol Control Protocol"},
528     {PPP_OSINLCP,     "OSI Network Layer Control Protocol"},
529     {PPP_XNSIDPCP,    "Xerox NS IDP Control Protocol"},
530     {PPP_DECNETCP,    "DECnet Phase IV Control Protocol"},
531     {PPP_ATCP,        "AppleTalk Control Protocol"},
532     {PPP_IPXCP,       "Novell IPX Control Protocol"},
533     {PPP_BRIDGENCP,   "Bridging NCP"},
534     {PPP_SPCP,        "Stream Protocol Control Protocol"},
535     {PPP_BVCP,        "Banyan Vines Control Protocol"},
536     {PPP_MLCP,        "Multi-Link Control Protocol"},
537     {PPP_NBCP,        "NETBIOS Framing Control Protocol"},
538     {PPP_CISCOCP,     "Cisco Systems Control Protocol"},
539     {PPP_ASCOMCP,     "Ascom Timeplex"},
540     {PPP_LBLBCP,      "Fujitsu LBLB Control Protocol"},
541     {PPP_RLNCP,       "DCA Remote Lan Network Control Protocol (RLNCP)"},
542     {PPP_SDCP,        "Serial Data Control Protocol (PPP-SDCP)"},
543     {PPP_LLCCP,       "SNA over 802.2 Control Protocol"},
544     {PPP_SNACP,       "SNA Control Protocol"},
545     {PPP_IP6HCCP,     "IP6 Header Compression Control Protocol"},
546     {PPP_KNXCP,       "KNX Bridging Control Protocol"},
547     {PPP_ECP,         "Encryption Control Protocol"},
548     {PPP_ILECP,       "Individual Link Encryption Control Protocol"},
549     {PPP_IPV6CP,      "IPv6 Control Protocol"},
550     {PPP_MUXCP,       "PPP Muxing Control Protocol"},
551     {PPP_VSNCP,       "Vendor-Specific Network Control Protocol (VSNCP)"},
552     {PPP_TNCP,        "TRILL Network Control Protocol"},
553     {PPP_STAMPEDECP,  "Stampede Bridging Control Protocol"},
554     {PPP_MPPCP,       "MP+ Control Protocol"},
555     {PPP_IPICP,       "NTCITS IPI Control Protocol"},
556     {PPP_SLCC,        "Single link compression in multilink control"},
557     {PPP_CCP,         "Compression Control Protocol"},
558     {PPP_CDPCP,       "Cisco Discovery Protocol Control Protocol"},
559     {PPP_NETCSCP,     "Netcs Twin Routing"},
560     {PPP_STPCP,       "STP - Control Protocol"},
561     {PPP_EDPCP,       "EDPCP - Extreme Discovery Protocol Control Protocol"},
562     {PPP_ACSPC,       "Apple Client Server Protocol Control"},
563     {PPP_MPLSCP,      "MPLS Control Protocol"},
564     {PPP_P12844CP,    "IEEE p1284.4 standard - Protocol Control"},
565     {PPP_TETRACP,     "ETSI TETRA TNP1 Control Protocol"},
566     {PPP_MFTPCP,      "Multichannel Flow Treatment Protocol"},
567     {PPP_LCP,         "Link Control Protocol"},
568     {PPP_PAP,         "Password Authentication Protocol"},
569     {PPP_LQR,         "Link Quality Report"},
570     {PPP_SPAP,        "Shiva Password Authentication Protocol"},
571     {PPP_CBCP,        "Callback Control Protocol (CBCP)"},
572     {PPP_BACP,        "BACP Bandwidth Allocation Control Protocol"},
573     {PPP_BAP,         "BAP Bandwidth Allocation Protocol"},
574     {PPP_VSAP,        "Vendor-Specific Authentication Protocol (VSAP)"},
575     {PPP_CONTCP,      "Container Control Protocol"},
576     {PPP_CHAP,        "Challenge Handshake Authentication Protocol"},
577     {PPP_RSAAP,       "RSA Authentication Protocol"},
578     {PPP_EAP,         "Extensible Authentication Protocol"},
579     {PPP_SIEP,        "Mitsubishi Security Information Exchange Protocol (SIEP)"},
580     {PPP_SBAP,        "Stampede Bridging Authorization Protocol"},
581     {PPP_PRPAP,       "Proprietary Authentication Protocol"},
582     {PPP_PRPAP2,      "Proprietary Authentication Protocol"},
583     {PPP_PRPNIAP,     "Proprietary Node ID Authentication Protocol"},
584     {0,               NULL}
585 };
586 value_string_ext ppp_vals_ext = VALUE_STRING_EXT_INIT(ppp_vals);
587
588 /* CP (LCP, CCP, IPCP, etc.) codes.
589  * from pppd fsm.h
590  */
591 #define VNDRSPCFC  0  /* Vendor Specific: RFC 2153 */
592 #define CONFREQ    1  /* Configuration Request */
593 #define CONFACK    2  /* Configuration Ack */
594 #define CONFNAK    3  /* Configuration Nak */
595 #define CONFREJ    4  /* Configuration Reject */
596 #define TERMREQ    5  /* Termination Request */
597 #define TERMACK    6  /* Termination Ack */
598 #define CODEREJ    7  /* Code Reject */
599
600 static const value_string cp_vals[] = {
601     {VNDRSPCFC, "Vendor Specific"},
602     {CONFREQ,   "Configuration Request"},
603     {CONFACK,   "Configuration Ack"},
604     {CONFNAK,   "Configuration Nak"},
605     {CONFREJ,   "Configuration Reject"},
606     {TERMREQ,   "Termination Request"},
607     {TERMACK,   "Termination Ack"},
608     {CODEREJ,   "Code Reject"},
609     {0,         NULL}
610 };
611
612 /*
613  * LCP-specific packet types.
614  */
615 #define PROTREJ    8  /* Protocol Reject */
616 #define ECHOREQ    9  /* Echo Request */
617 #define ECHOREP    10 /* Echo Reply */
618 #define DISCREQ    11 /* Discard Request */
619 #define IDENT      12 /* Identification */
620 #define TIMEREMAIN 13 /* Time remaining */
621
622 /*
623  * CCP-specific packet types.
624  */
625 #define RESETREQ   14  /* Reset Request */
626 #define RESETACK   15  /* Reset Ack */
627
628 /*
629  * CBCP-specific packet types.
630  */
631 #define CBREQ      1  /* Callback Request */
632 #define CBRES      2  /* Callback Response */
633 #define CBACK      3  /* Callback Ack */
634
635 #define CBCP_OPT  6 /* Use callback control protocol */
636
637 /*
638  * BAP-specific packet types.
639  */
640 #define BAP_CREQ   1  /* Call Request */
641 #define BAP_CRES   2  /* Call Response */
642 #define BAP_CBREQ  3  /* Callback Request */
643 #define BAP_CBRES  4  /* Callback Response */
644 #define BAP_LDQREQ 5  /* Link Drop Query Request */
645 #define BAP_LDQRES 6  /* Link Drop Query Response */
646 #define BAP_CSI    7  /* Call Status Indication */
647 #define BAP_CSRES  8  /* Call Status Response */
648
649 static const value_string lcp_vals[] = {
650     {VNDRSPCFC,  "Vendor Specific"},
651     {CONFREQ,    "Configuration Request"},
652     {CONFACK,    "Configuration Ack"},
653     {CONFNAK,    "Configuration Nak"},
654     {CONFREJ,    "Configuration Reject"},
655     {TERMREQ,    "Termination Request"},
656     {TERMACK,    "Termination Ack"},
657     {CODEREJ,    "Code Reject"},
658     {PROTREJ,    "Protocol Reject"},
659     {ECHOREQ,    "Echo Request"},
660     {ECHOREP,    "Echo Reply"},
661     {DISCREQ,    "Discard Request"},
662     {IDENT,      "Identification"},
663     {TIMEREMAIN, "Time Remaining"},
664     {0,          NULL}
665 };
666
667 static const value_string ccp_vals[] = {
668     {VNDRSPCFC, "Vendor Specific"},
669     {CONFREQ,   "Configuration Request"},
670     {CONFACK,   "Configuration Ack"},
671     {CONFNAK,   "Configuration Nak"},
672     {CONFREJ,   "Configuration Reject"},
673     {TERMREQ,   "Termination Request"},
674     {TERMACK,   "Termination Ack"},
675     {CODEREJ,   "Code Reject"},
676     {RESETREQ,  "Reset Request"},
677     {RESETACK,  "Reset Ack"},
678     {0,         NULL}
679 };
680
681 static const value_string cbcp_vals[] = {
682     {CBREQ, "Callback Request"},
683     {CBRES, "Callback Response"},
684     {CBACK, "Callback Ack"},
685     {0,     NULL}
686 };
687
688 static const value_string bap_vals[] = {
689     {BAP_CREQ,   "Call Request"},
690     {BAP_CRES,   "Call Response"},
691     {BAP_CBREQ,  "Callback Request"},
692     {BAP_CBRES,  "Callback Response"},
693     {BAP_LDQREQ, "Link Drop Query Request"},
694     {BAP_LDQRES, "Link Drop Query Response"},
695     {BAP_CSI,    "Call Status Indication"},
696     {BAP_CSRES,  "Call Status Response"},
697     {0,          NULL}
698 };
699
700 #define BAP_RESP_CODE_REQACK     0x00
701 #define BAP_RESP_CODE_REQNAK     0x01
702 #define BAP_RESP_CODE_REQREJ     0x02
703 #define BAP_RESP_CODE_REQFULLNAK 0x03
704 static const value_string bap_resp_code_vals[] = {
705     {BAP_RESP_CODE_REQACK,     "Request Ack"},
706     {BAP_RESP_CODE_REQNAK,     "Request Nak"},
707     {BAP_RESP_CODE_REQREJ,     "Request Rej"},
708     {BAP_RESP_CODE_REQFULLNAK, "Request Full Nak"},
709     {0,                        NULL}
710 };
711
712 #define BAP_LINK_TYPE_ISDN      0       /* ISDN */
713 #define BAP_LINK_TYPE_X25       1       /* X.25 */
714 #define BAP_LINK_TYPE_ANALOG    2       /* Analog */
715 #define BAP_LINK_TYPE_SD        3       /* Switched Digital (non-ISDN) */
716 #define BAP_LINK_TYPE_ISDNOV    4       /* ISDN data over voice */
717 #define BAP_LINK_TYPE_RESV5     5       /* Reserved */
718 #define BAP_LINK_TYPE_RESV6     6       /* Reserved */
719 #define BAP_LINK_TYPE_RESV7     7       /* Reserved */
720 static const value_string bap_link_type_vals[] = {
721     {BAP_LINK_TYPE_ISDN,   "ISDN"},
722     {BAP_LINK_TYPE_X25,    "X.25"},
723     {BAP_LINK_TYPE_ANALOG, "Analog"},
724     {BAP_LINK_TYPE_SD,     "Switched Digital (non-ISDN)"},
725     {BAP_LINK_TYPE_ISDNOV, "ISDN data over voice"},
726     {BAP_LINK_TYPE_RESV5,  "Reserved"},
727     {BAP_LINK_TYPE_RESV6,  "Reserved"},
728     {BAP_LINK_TYPE_RESV7,  "Reserved"},
729     {0,                    NULL}
730 };
731
732 #define BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT       1 /* Unique Digit */
733 #define BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM        2 /* Subscriber Number */
734 #define BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR 3 /* Phone Number Sub Address */
735 static const value_string bap_phone_delta_subopt_vals[] = {
736     {BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT,       "Unique Digit"},
737     {BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM,        "Subscriber Number"},
738     {BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR, "Phone Number Sub Address"},
739     {0,                                       NULL}
740 };
741
742 /*
743  * Cause codes for Cause.
744  *
745  * The following code table is taken from packet-q931.c but is slightly
746  * adapted to BAP protocol.
747  */
748 static const value_string q931_cause_code_vals[] = {
749     {0x00, "Call successful"},
750     {0x01, "Unallocated (unassigned) number"},
751     {0x02, "No route to specified transit network"},
752     {0x03, "No route to destination"},
753     {0x04, "Send special information tone"},
754     {0x05, "Misdialled trunk prefix"},
755     {0x06, "Channel unacceptable"},
756     {0x07, "Call awarded and being delivered in an established channel"},
757     {0x08, "Prefix 0 dialed but not allowed"},
758     {0x09, "Prefix 1 dialed but not allowed"},
759     {0x0A, "Prefix 1 dialed but not required"},
760     {0x0B, "More digits received than allowed, call is proceeding"},
761     {0x10, "Normal call clearing"},
762     {0x11, "User busy"},
763     {0x12, "No user responding"},
764     {0x13, "No answer from user (user alerted)"},
765     {0x14, "Subscriber absent"},
766     {0x15, "Call rejected"},
767     {0x16, "Number changed"},
768     {0x17, "Reverse charging rejected"},
769     {0x18, "Call suspended"},
770     {0x19, "Call resumed"},
771     {0x1A, "Non-selected user clearing"},
772     {0x1B, "Destination out of order"},
773     {0x1C, "Invalid number format (incomplete number)"},
774     {0x1D, "Facility rejected"},
775     {0x1E, "Response to STATUS ENQUIRY"},
776     {0x1F, "Normal unspecified"},
777     {0x21, "Circuit out of order"},
778     {0x22, "No circuit/channel available"},
779     {0x23, "Destination unattainable"},
780     {0x25, "Degraded service"},
781     {0x26, "Network out of order"},
782     {0x27, "Transit delay range cannot be achieved"},
783     {0x28, "Throughput range cannot be achieved"},
784     {0x29, "Temporary failure"},
785     {0x2A, "Switching equipment congestion"},
786     {0x2B, "Access information discarded"},
787     {0x2C, "Requested circuit/channel not available"},
788     {0x2D, "Pre-empted"},
789     {0x2E, "Precedence call blocked"},
790     {0x2F, "Resources unavailable, unspecified"},
791     {0x31, "Quality of service unavailable"},
792     {0x32, "Requested facility not subscribed"},
793     {0x33, "Reverse charging not allowed"},
794     {0x34, "Outgoing calls barred"},
795     {0x35, "Outgoing calls barred within CUG"},
796     {0x36, "Incoming calls barred"},
797     {0x37, "Incoming calls barred within CUG"},
798     {0x38, "Call waiting not subscribed"},
799     {0x39, "Bearer capability not authorized"},
800     {0x3A, "Bearer capability not presently available"},
801     {0x3E, "Inconsistency in designated outgoing access information and subscriber class"},
802     {0x3F, "Service or option not available, unspecified"},
803     {0x41, "Bearer capability not implemented"},
804     {0x42, "Channel type not implemented"},
805     {0x43, "Transit network selection not implemented"},
806     {0x44, "Message not implemented"},
807     {0x45, "Requested facility not implemented"},
808     {0x46, "Only restricted digital information bearer capability is available"},
809     {0x4F, "Service or option not implemented, unspecified"},
810     {0x51, "Invalid call reference value"},
811     {0x52, "Identified channel does not exist"},
812     {0x53, "Call identity does not exist for suspended call"},
813     {0x54, "Call identity in use"},
814     {0x55, "No call suspended"},
815     {0x56, "Call having the requested call identity has been cleared"},
816     {0x57, "Called user not member of CUG"},
817     {0x58, "Incompatible destination"},
818     {0x59, "Non-existent abbreviated address entry"},
819     {0x5A, "Destination address missing, and direct call not subscribed"},
820     {0x5B, "Invalid transit network selection (national use)"},
821     {0x5C, "Invalid facility parameter"},
822     {0x5D, "Mandatory information element is missing"},
823     {0x5F, "Invalid message, unspecified"},
824     {0x60, "Mandatory information element is missing"},
825     {0x61, "Message type non-existent or not implemented"},
826     {0x62, "Message not compatible with call state or message type non-existent or not implemented"},
827     {0x63, "Information element non-existent or not implemented"},
828     {0x64, "Invalid information element contents"},
829     {0x65, "Message not compatible with call state"},
830     {0x66, "Recovery on timer expiry"},
831     {0x67, "Parameter non-existent or not implemented - passed on"},
832     {0x6E, "Message with unrecognized parameter discarded"},
833     {0x6F, "Protocol error, unspecified"},
834     {0x7F, "Internetworking, unspecified"},
835     {0xFF, "Non-specific failure"},
836     {0,    NULL}
837 };
838 static value_string_ext q931_cause_code_vals_ext = VALUE_STRING_EXT_INIT(q931_cause_code_vals);
839
840 static const value_string bap_call_status_opt_action_vals[] = {
841     {0, "No retry"},
842     {1, "Retry"},
843     {0, NULL}
844 };
845
846 #define STAC_CM_NONE            0
847 #define STAC_CM_LCB             1
848 #define STAC_CM_CRC             2
849 #define STAC_CM_SN              3
850 #define STAC_CM_EXTMODE         4
851 static const value_string stac_checkmode_vals[] = {
852     {STAC_CM_NONE,    "None"},
853     {STAC_CM_LCB,     "LCB"},
854     {STAC_CM_CRC,     "CRC"},
855     {STAC_CM_SN,      "Sequence Number"},
856     {STAC_CM_EXTMODE, "Extended Mode"},
857     {0,               NULL}
858 };
859
860 #define LZSDCP_CM_NONE          0
861 #define LZSDCP_CM_LCB           1
862 #define LZSDCP_CM_SN            2
863 #define LZSDCP_CM_SN_LCB        3
864 static const value_string lzsdcp_checkmode_vals[] = {
865     {LZSDCP_CM_NONE,   "None"},
866     {LZSDCP_CM_LCB,    "LCB"},
867     {LZSDCP_CM_SN,     "Sequence Number"},
868     {LZSDCP_CM_SN_LCB, "Sequence Number + LCB (default)"},
869     {0,                NULL}
870 };
871
872 #define LZSDCP_PM_NONE          0
873 #define LZSDCP_PM_PROC_UNCOMP   1
874 static const value_string lzsdcp_processmode_vals[] = {
875     {LZSDCP_PM_NONE,        "None (default)"},
876     {LZSDCP_PM_PROC_UNCOMP, "Process-Uncompressed"},
877     {0,                     NULL}
878 };
879
880 #define DCE_MODE_1  1
881 #define DCE_MODE_2  2
882 static const value_string dce_mode_vals[] = {
883     {DCE_MODE_1, "No Additional Negotiation"},
884     {DCE_MODE_2, "Full PPP Negotiation and State Machine"},
885     {0,          NULL}
886 };
887
888 /*
889  * Options.  (LCP)
890  */
891 #define CI_VENDORSPECIFIC       0   /* Vendor Specific [RFC2153] */
892 #define CI_MRU                  1   /* Maximum Receive Unit [RFC1661] */
893 #define CI_ASYNCMAP             2   /* Async Control Character Map */
894 #define CI_AUTHPROT             3   /* Authentication Protocol [RFC1661] */
895 #define CI_QUALITY              4   /* Quality Protocol [RFC1661] */
896 #define CI_MAGICNUMBER          5   /* Magic Number [RFC1661] */
897 #define CI_LINKQUALMON          6   /* DEPRECATED (Quality Protocol) [RFC1172] */
898 #define CI_PCOMPRESSION         7   /* Protocol Field Compression [RFC1661] */
899 #define CI_ACCOMPRESSION        8   /* Address/Control Field Compression
900                                        [RFC1661] */
901 #define CI_FCS_ALTERNATIVES     9   /* FCS Alternatives [RFC1570] */
902 #define CI_SELF_DESCRIBING_PAD  10  /* Self-Describing Pad [RFC1570] */
903 #define CI_NUMBERED_MODE        11  /* Numbered Mode [RFC1663] */
904 #define CI_MULTILINK_PROC       12  /* DEPRECATED (Multi-Link Procedure) */
905 #define CI_CALLBACK             13  /* Callback [RFC1570] */
906 #define CI_CONNECTTIME          14  /* DEPRECATED (Connect Time) */
907 #define CI_COMPOUND_FRAMES      15  /* DEPRECATED (Compound Frames) [RFC1570] */
908 #define CI_NOMDATAENCAP         16  /* DEPRECATED (Nominal Data Encapsulation) */
909 /* NOTE: IANA lists CI_NOMDATAENCAP as 16, but it is listed as 14 in
910  *       http://tools.ietf.org/html/draft-ietf-pppext-dataencap-03.
911  *       Which is correct is anyone's guess. */
912 #define CI_MULTILINK_MRRU       17  /* Multilink MRRU [RFC1990] */
913 #define CI_MULTILINK_SSNH       18  /* Multilink Short Sequence Number Header
914                                        [RFC1990] */
915 #define CI_MULTILINK_EP_DISC    19  /* Multilink Endpoint Discriminator
916                                        [RFC1990] */
917 #define CI_PROP_KEN             20  /* Proprietary [Ken Culbert] ken@funk.com */
918 #define CI_DCE_IDENTIFIER       21  /* DCE Identifier [RFC1976]: Warning:
919                                        Option type 25 in the RFC is incorrect */
920 #define CI_MULTILINK_PLUS_PROC  22  /* Multilink Plus Procedure [RFC1934] */
921 #define CI_LINK_DISC_FOR_BACP   23  /* Link Discriminator for BACP [RFC2125] */
922 #define CI_LCP_AUTHENTICATION   24  /* LCP Authentication Option [Culbert] */
923 #define CI_COBS                 25  /* Consistent Overhead Byte Stuffing (COBS)
924                                        [Carlson] */
925 #define CI_PREFIX_ELISION       26  /* Prefix elision [RFC2686][RFC2687] */
926 #define CI_MULTILINK_HDR_FMT    27  /* Multilink header format
927                                        [RFC2686][RFC2687] */
928 #define CI_INTERNATIONALIZATION 28  /* Internationalization [RFC2484] */
929 #define CI_SDL_ON_SONET_SDH     29  /* Simple Data Link on SONET/SDH
930                                       [RFC2823] */
931 #define CI_UNASSIGNED           30  /* Unassigned ... but so are 31-255, so
932                                        why do they bother specifically
933                                        mentioning this one, I wonder? */
934
935 static int hf_lcp_magic_number = -1;
936 static int hf_lcp_data = -1;
937 static int hf_lcp_message = -1;
938 static int hf_lcp_secs_remaining = -1;
939 static int hf_lcp_rej_proto = -1;
940 static int hf_lcp_opt_type = -1;
941 static int hf_lcp_opt_length = -1;
942 static int hf_lcp_opt_oui = -1;
943 static int hf_lcp_opt_kind = -1;
944 static int hf_lcp_opt_data = -1;
945 static int hf_lcp_opt_mru = -1;
946 static int hf_lcp_opt_asyncmap = -1;
947 static int hf_lcp_opt_asyncmap_nul = -1;
948 static int hf_lcp_opt_asyncmap_soh = -1;
949 static int hf_lcp_opt_asyncmap_stx = -1;
950 static int hf_lcp_opt_asyncmap_etx = -1;
951 static int hf_lcp_opt_asyncmap_eot = -1;
952 static int hf_lcp_opt_asyncmap_enq = -1;
953 static int hf_lcp_opt_asyncmap_ack = -1;
954 static int hf_lcp_opt_asyncmap_bel = -1;
955 static int hf_lcp_opt_asyncmap_bs = -1;
956 static int hf_lcp_opt_asyncmap_ht = -1;
957 static int hf_lcp_opt_asyncmap_lf = -1;
958 static int hf_lcp_opt_asyncmap_vt = -1;
959 static int hf_lcp_opt_asyncmap_ff = -1;
960 static int hf_lcp_opt_asyncmap_cr = -1;
961 static int hf_lcp_opt_asyncmap_so = -1;
962 static int hf_lcp_opt_asyncmap_si = -1;
963 static int hf_lcp_opt_asyncmap_dle = -1;
964 static int hf_lcp_opt_asyncmap_dc1 = -1;
965 static int hf_lcp_opt_asyncmap_dc2 = -1;
966 static int hf_lcp_opt_asyncmap_dc3 = -1;
967 static int hf_lcp_opt_asyncmap_dc4 = -1;
968 static int hf_lcp_opt_asyncmap_nak = -1;
969 static int hf_lcp_opt_asyncmap_syn = -1;
970 static int hf_lcp_opt_asyncmap_etb = -1;
971 static int hf_lcp_opt_asyncmap_can = -1;
972 static int hf_lcp_opt_asyncmap_em = -1;
973 static int hf_lcp_opt_asyncmap_sub = -1;
974 static int hf_lcp_opt_asyncmap_esc = -1;
975 static int hf_lcp_opt_asyncmap_fs = -1;
976 static int hf_lcp_opt_asyncmap_gs = -1;
977 static int hf_lcp_opt_asyncmap_rs = -1;
978 static int hf_lcp_opt_asyncmap_us = -1;
979 static int hf_lcp_opt_auth_protocol = -1;
980 static int hf_lcp_opt_algorithm = -1;
981 static int hf_lcp_opt_quality_protocol = -1;
982 static int hf_lcp_opt_magic_number = -1;
983 static int hf_lcp_opt_reportingperiod = -1;
984 static int hf_lcp_opt_fcs_alternatives = -1;
985 static int hf_lcp_opt_fcs_alternatives_null = -1;
986 static int hf_lcp_opt_fcs_alternatives_ccitt16 = -1;
987 static int hf_lcp_opt_fcs_alternatives_ccitt32 = -1;
988 static int hf_lcp_opt_maximum = -1;
989 static int hf_lcp_opt_window = -1;
990 static int hf_lcp_opt_hdlc_address = -1;
991 static int hf_lcp_opt_operation = -1;
992 static int hf_lcp_opt_message = -1;
993 static int hf_lcp_opt_mrru = -1;
994 static int hf_lcp_opt_ep_disc_class = -1;
995 static int hf_lcp_opt_ip_address = -1;
996 static int hf_lcp_opt_802_1_address = -1;
997 static int hf_lcp_opt_magic_block = -1;
998 static int hf_lcp_opt_psndn = -1;
999 static int hf_lcp_opt_mode = -1;
1000 static int hf_lcp_opt_unused = -1;
1001 static int hf_lcp_opt_link_discrim = -1;
1002 static int hf_lcp_opt_id = -1;
1003 static int hf_lcp_opt_cobs_flags = -1;
1004 static int hf_lcp_opt_cobs_flags_res = -1;
1005 static int hf_lcp_opt_cobs_flags_pre = -1;
1006 static int hf_lcp_opt_cobs_flags_zxe = -1;
1007 static int hf_lcp_opt_class = -1;
1008 static int hf_lcp_opt_prefix = -1;
1009 static int hf_lcp_opt_code = -1;
1010 static int hf_lcp_opt_max_susp_classes = -1;
1011 static int hf_lcp_opt_MIBenum = -1;
1012 static int hf_lcp_opt_language_tag = -1;
1013
1014 static void dissect_lcp_vendor_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1015     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1016 static void dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1017     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1018 static void dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1019     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1020 static void dissect_lcp_authprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1021     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1022 static void dissect_lcp_qualprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1023     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1024 static void dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1025     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1026 static void dissect_lcp_linkqualmon_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1027     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1028 static void dissect_lcp_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1029     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1030 static void dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp,
1031     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1032     proto_tree *tree, void *data _U_);
1033 static void dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp,
1034     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1035     proto_tree *tree, void *data _U_);
1036 static void dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp,
1037     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1038     proto_tree *tree, void *data _U_);
1039 static void dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1040     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1041 static void dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp,
1042     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1043     proto_tree *tree, void *data _U_);
1044 static void dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp,
1045     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1046         proto_tree *tree, void *data _U_);
1047 static void dissect_lcp_dce_identifier_opt(const ip_tcp_opt *optp,
1048     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1049     proto_tree *tree, void *data _U_);
1050 static void dissect_lcp_multilink_pp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1051     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1052 static void dissect_lcp_bacp_link_discriminator_opt(const ip_tcp_opt *optp,
1053     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1054     proto_tree *tree, void *data _U_);
1055 static void dissect_lcp_auth_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1056     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1057 static void dissect_lcp_cobs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1058     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1059 static void dissect_lcp_prefix_elision_opt(const ip_tcp_opt *optp,
1060     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1061     proto_tree *tree, void *data _U_);
1062 static void dissect_lcp_multilink_hdr_fmt_opt(const ip_tcp_opt *optp,
1063     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1064     proto_tree *tree, void *data _U_);
1065 static void dissect_lcp_internationalization_opt(const ip_tcp_opt *optp,
1066     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1067     proto_tree *tree, void *data _U_);
1068 static void dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1069
1070 static const ip_tcp_opt lcp_opts[] = {
1071     {CI_VENDORSPECIFIC, "Vendor Specific", &ett_lcp_vendor_opt,
1072         OPT_LEN_VARIABLE_LENGTH, 6, dissect_lcp_vendor_opt},
1073     {CI_MRU, "Maximum Receive Unit", &ett_lcp_mru_opt,
1074         OPT_LEN_FIXED_LENGTH, 4, dissect_lcp_mru_opt},
1075     {CI_ASYNCMAP, "Async Control Character Map", &ett_lcp_asyncmap_opt,
1076         OPT_LEN_FIXED_LENGTH, 6, dissect_lcp_async_map_opt},
1077     {CI_AUTHPROT, "Authentication Protocol", &ett_lcp_authprot_opt,
1078         OPT_LEN_VARIABLE_LENGTH, 4, dissect_lcp_authprot_opt},
1079     {CI_QUALITY, "Quality Protocol", &ett_lcp_qualprot_opt,
1080         OPT_LEN_VARIABLE_LENGTH, 4, dissect_lcp_qualprot_opt},
1081     {CI_MAGICNUMBER, "Magic Number", &ett_lcp_magicnumber_opt,
1082         OPT_LEN_FIXED_LENGTH, 6, dissect_lcp_magicnumber_opt},
1083     {CI_LINKQUALMON, "Link Quality Monitoring", &ett_lcp_linkqualmon_opt,
1084         OPT_LEN_FIXED_LENGTH, 6, dissect_lcp_linkqualmon_opt},
1085     {CI_PCOMPRESSION, "Protocol Field Compression", &ett_lcp_pcomp_opt,
1086         OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt},
1087     {CI_ACCOMPRESSION, "Address and Control Field Compression", &ett_lcp_acccomp_opt,
1088         OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt},
1089     {CI_FCS_ALTERNATIVES, "FCS Alternatives", &ett_lcp_fcs_alternatives_opt,
1090         OPT_LEN_FIXED_LENGTH, 3, dissect_lcp_fcs_alternatives_opt},
1091     {CI_SELF_DESCRIBING_PAD, "Self Describing Pad", &ett_lcp_self_desc_pad_opt,
1092         OPT_LEN_FIXED_LENGTH, 3, dissect_lcp_self_describing_pad_opt},
1093     {CI_NUMBERED_MODE, "Numbered Mode", &ett_lcp_numbered_mode_opt,
1094         OPT_LEN_VARIABLE_LENGTH, 4, dissect_lcp_numbered_mode_opt},
1095     /* TODO? CI_MULTILINK_PROC */
1096     {CI_CALLBACK, "Callback", &ett_lcp_callback_opt,
1097         OPT_LEN_VARIABLE_LENGTH, 3, dissect_lcp_callback_opt},
1098     /* TODO? CI_CONNECTTIME */
1099     {CI_COMPOUND_FRAMES, "Compound Frames (Deprecated)", &ett_lcp_compound_frames_opt,
1100         OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt},
1101     {CI_NOMDATAENCAP, "Nominal Data Encapsulation (Deprecated)", &ett_lcp_nomdataencap_opt,
1102         OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt},
1103     {CI_MULTILINK_MRRU, "Multilink MRRU", &ett_lcp_multilink_mrru_opt,
1104         OPT_LEN_FIXED_LENGTH, 4, dissect_lcp_multilink_mrru_opt},
1105     {CI_MULTILINK_SSNH, "Multilink Short Sequence Number Header", &ett_lcp_multilink_ssnh_opt,
1106         OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt},
1107     {CI_MULTILINK_EP_DISC, "Multilink Endpoint Discriminator", &ett_lcp_multilink_ep_disc_opt,
1108         OPT_LEN_VARIABLE_LENGTH, 3, dissect_lcp_multilink_ep_disc_opt},
1109     /* TODO? CI_PROP_KEN: ken@funk.com: www.funk.com => www.juniper.net */
1110     {CI_DCE_IDENTIFIER, "DCE Identifier", &ett_lcp_dce_identifier_opt,
1111         OPT_LEN_FIXED_LENGTH, 3, dissect_lcp_dce_identifier_opt},
1112     {CI_MULTILINK_PLUS_PROC, "Multi Link Plus Procedure", &ett_lcp_multilink_pp_opt,
1113         OPT_LEN_FIXED_LENGTH, 4, dissect_lcp_multilink_pp_opt},
1114     {CI_LINK_DISC_FOR_BACP, "Link Discriminator for BACP", &ett_lcp_bacp_link_discrim_opt,
1115         OPT_LEN_FIXED_LENGTH, 4, dissect_lcp_bacp_link_discriminator_opt},
1116     {CI_LCP_AUTHENTICATION, "LCP Authentication Option", &ett_lcp_auth_opt,
1117         OPT_LEN_VARIABLE_LENGTH, 3, dissect_lcp_auth_opt},
1118     {CI_COBS, "Consistent Overhead Byte Stuffing (COBS)", &ett_lcp_cobs_opt,
1119         OPT_LEN_FIXED_LENGTH, 3, dissect_lcp_cobs_opt},
1120     {CI_PREFIX_ELISION, "Prefix Elision", &ett_lcp_prefix_elision_opt,
1121         OPT_LEN_VARIABLE_LENGTH, 2, dissect_lcp_prefix_elision_opt},
1122     {CI_MULTILINK_HDR_FMT, "Multilink header format", &ett_multilink_hdr_fmt_opt,
1123         OPT_LEN_FIXED_LENGTH, 4, dissect_lcp_multilink_hdr_fmt_opt},
1124     {CI_INTERNATIONALIZATION, "Internationalization", &ett_lcp_internationalization_opt,
1125         OPT_LEN_VARIABLE_LENGTH, 7, dissect_lcp_internationalization_opt},
1126     {CI_SDL_ON_SONET_SDH, "Simple Data Link on SONET/SDH", &ett_lcp_simple_opt,
1127         OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt}
1128     /* TODO? CI_UNASSIGNED */
1129 };
1130
1131 #define N_LCP_OPTS      (sizeof lcp_opts / sizeof lcp_opts[0])
1132
1133 /* 3GPP2 X.S0057-B v1.0
1134  * 9.1.4.1 3GPP2 VSNCP Configuration Options
1135  * Options.  (VSNCP)
1136  */
1137
1138 #define CI_PDN_IDENTIFIER       1
1139 #define CI_ACCESS_POINT_NM      2
1140 #define CI_PDN_TYPE             3
1141 #define CI_PDN_ADDRESS          4
1142 #define CI_PROTOCOL_CONFIG      5
1143 #define CI_ERROR_CODE           6
1144 #define CI_ATTACH_TYPE          7
1145 #define CI_IPv4DEFAULT_ROUTER   8
1146 #define CI_ADDRESS_ALLOC        9
1147 #define CI_APN_AMBR             10
1148 #define CI_IPv6_HSGW_LLA_IID    11
1149
1150 static void dissect_vsncp_pdnid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1151     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1152 static void dissect_vsncp_apname_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1153     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1154 static void dissect_vsncp_pdntype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1155     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1156 static void dissect_vsncp_pdnaddress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1157     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1158 static void dissect_vsncp_pco_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1159     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1160 static void dissect_vsncp_errorcode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1161     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1162 static void dissect_vsncp_attachtype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1163     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1164 static void dissect_vsncp_ipv4address_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1165     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1166 static void dissect_vsncp_addressalloc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1167     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1168 static void dissect_vsncp_apn_ambr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1169     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1170 static void dissect_vsncp_ipv6_hsgw_lla_iid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1171     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1172
1173 static const ip_tcp_opt vsncp_opts[] = {
1174     {CI_PDN_IDENTIFIER, "PDN Identifier", NULL,
1175         OPT_LEN_FIXED_LENGTH, 3, dissect_vsncp_pdnid_opt},
1176     {CI_ACCESS_POINT_NM, "Access Point Name", NULL,
1177         OPT_LEN_VARIABLE_LENGTH, 2, dissect_vsncp_apname_opt},
1178     {CI_PDN_TYPE, "PDN Type", NULL,
1179         OPT_LEN_FIXED_LENGTH, 3, dissect_vsncp_pdntype_opt},
1180     {CI_PDN_ADDRESS, "PDN Address", NULL,
1181         OPT_LEN_VARIABLE_LENGTH, 3, dissect_vsncp_pdnaddress_opt},
1182     {CI_PROTOCOL_CONFIG, "Protocol Configuration Options", NULL,
1183         OPT_LEN_VARIABLE_LENGTH, 3, dissect_vsncp_pco_opt},
1184     {CI_ERROR_CODE, "Error Code", NULL,
1185         OPT_LEN_FIXED_LENGTH, 3, dissect_vsncp_errorcode_opt},
1186     {CI_ATTACH_TYPE, "Attach Type", NULL,
1187         OPT_LEN_FIXED_LENGTH, 3, dissect_vsncp_attachtype_opt},
1188     {CI_IPv4DEFAULT_ROUTER, "IPv4 Default Router Address", NULL,
1189         OPT_LEN_FIXED_LENGTH, 6, dissect_vsncp_ipv4address_opt},
1190     {CI_ADDRESS_ALLOC, "Address Allocation Cause", NULL,
1191         OPT_LEN_FIXED_LENGTH, 3, dissect_vsncp_addressalloc_opt},
1192     {CI_APN_AMBR, "APN Aggregate Maximum Bit Rate(APN-AMBR)", NULL,
1193         OPT_LEN_VARIABLE_LENGTH, 4, dissect_vsncp_apn_ambr_opt},
1194     {CI_IPv6_HSGW_LLA_IID, "IPv6 HSGW Link Local Address IID", NULL,
1195         OPT_LEN_FIXED_LENGTH, 10, dissect_vsncp_ipv6_hsgw_lla_iid_opt}
1196 };
1197
1198 #define N_VSNCP_OPTS    (sizeof vsncp_opts / sizeof vsncp_opts[0])
1199
1200 /*
1201  * CHAP Algorithms
1202  */
1203 /* 0-4: Reserved */
1204 #define CHAP_ALG_MD5    5       /* CHAP with MD5 */
1205 #define CHAP_AGL_SHA1   6       /* CHAP with SHA-1 [Black] */
1206 /* 7-127: Unassigned */
1207 #define CHAP_ALG_MSV1   128     /* MS-CHAP */
1208 #define CHAP_ALG_MSV2   129     /* MS-CHAP-2 */
1209
1210 static const range_string chap_alg_rvals[] = {
1211     {0,             4,             "Reserved"},
1212     {CHAP_ALG_MD5,  CHAP_ALG_MD5,  "CHAP with MD5"},
1213     {CHAP_AGL_SHA1, CHAP_AGL_SHA1, "CHAP with SHA-1"},
1214     {CHAP_ALG_MSV1, CHAP_ALG_MSV1, "MS-CHAP"},
1215     {CHAP_ALG_MSV2, CHAP_ALG_MSV2, "MS-CHAP-2"},
1216     {0,             0,             NULL}
1217 };
1218
1219
1220 /*
1221  * Options.  (IPCP)
1222  * http://tools.ietf.org/html/rfc1172
1223  * http://tools.ietf.org/html/rfc1332
1224  * http://tools.ietf.org/html/rfc1877
1225  * http://tools.ietf.org/html/rfc2290
1226  * http://tools.ietf.org/html/rfc3241
1227  * http://tools.ietf.org/html/rfc3545
1228  */
1229 #define CI_ADDRS            1       /* IP Addresses (deprecated) (RFC 1172) */
1230 #define CI_COMPRESS_PROTO   2       /* Compression Protocol (RFC 1332) */
1231 #define CI_ADDR             3       /* IP Address (RFC 1332) */
1232 #define CI_MOBILE_IPv4      4       /* Mobile IPv4 (RFC 2290) */
1233 #define CI_PRI_DNS          129     /* Primary DNS value (RFC 1877) */
1234 #define CI_PRI_NBNS         130     /* Primary NBNS value (RFC 1877) */
1235 #define CI_SEC_DNS          131     /* Secondary DNS value (RFC 1877) */
1236 #define CI_SEC_NBNS         132     /* Secondary NBNS value (RFC 1877) */
1237
1238 static int hf_ipcp_opt_type = -1;
1239 static int hf_ipcp_opt_length = -1;
1240 static int hf_ipcp_opt_src_address = -1;
1241 static int hf_ipcp_opt_dst_address = -1;
1242 static int hf_ipcp_opt_compress_proto = -1;
1243 static int hf_ipcp_opt_max_cid = -1;
1244 static int hf_ipcp_opt_mrru = -1;
1245 static int hf_ipcp_opt_max_slot_id = -1;
1246 static int hf_ipcp_opt_comp_slot_id = -1;
1247 static int hf_ipcp_opt_tcp_space = -1;
1248 static int hf_ipcp_opt_non_tcp_space = -1;
1249 static int hf_ipcp_opt_f_max_period = -1;
1250 static int hf_ipcp_opt_f_max_time = -1;
1251 static int hf_ipcp_opt_max_header = -1;
1252 static int hf_ipcp_data = -1;
1253 static int hf_ipcp_opt_ip_address = -1;
1254 static int hf_ipcp_opt_mobilenodehomeaddr = -1;
1255 static int hf_ipcp_opt_pri_dns_address = -1;
1256 static int hf_ipcp_opt_pri_nbns_address = -1;
1257 static int hf_ipcp_opt_sec_dns_address = -1;
1258 static int hf_ipcp_opt_sec_nbns_address = -1;
1259
1260 static int hf_ipcp_opt_rohc_type = -1;
1261 static int hf_ipcp_opt_rohc_length = -1;
1262 static int hf_ipcp_opt_rohc_profile = -1;
1263 static int hf_ipcp_opt_iphc_type = -1;
1264 static int hf_ipcp_opt_iphc_length = -1;
1265 static int hf_ipcp_opt_iphc_param = -1;
1266
1267 static void dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1268     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1269 static void dissect_ipcp_compress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1270     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1271 static void dissect_ipcp_rohc_profiles_opt(const ip_tcp_opt *optp,
1272     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1273     proto_tree *tree, void *data _U_);
1274 static void dissect_ipcp_iphc_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1275     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1276 static void dissect_ipcp_iphc_neghdrcomp_opt(const ip_tcp_opt *optp,
1277     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1278     proto_tree *tree, void *data _U_);
1279 static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1280     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1281 static void dissect_ipcp_mobileipv4_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1282     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1283 static void dissect_ipcp_pri_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1284     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1285 static void dissect_ipcp_pri_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1286     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1287 static void dissect_ipcp_sec_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1288     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1289 static void dissect_ipcp_sec_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1290     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1291
1292 static const ip_tcp_opt ipcp_opts[] = {
1293     {CI_ADDRS, "IP Addresses (deprecated)", &ett_ipcp_ipaddrs_opt,
1294         OPT_LEN_FIXED_LENGTH, 10, dissect_ipcp_addrs_opt},
1295     {CI_COMPRESS_PROTO, "IP Compression Protocol", &ett_ipcp_compress_opt,
1296         OPT_LEN_VARIABLE_LENGTH, 4, dissect_ipcp_compress_opt},
1297     {CI_ADDR, "IP address", &ett_ipcp_ipaddr_opt,
1298         OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_addr_opt},
1299     {CI_MOBILE_IPv4, "Mobile Node's Home IP Address", &ett_ipcp_mobileipv4_opt,
1300         OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_mobileipv4_opt},
1301     {CI_PRI_DNS, "Primary DNS Server IP Address", &ett_ipcp_pridns_opt,
1302         OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_pri_dns_opt},
1303     {CI_PRI_NBNS, "Primary NBNS Server IP Address", &ett_ipcp_prinbns_opt,
1304         OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_pri_nbns_opt},
1305     {CI_SEC_DNS, "Secondary DNS Server IP Address", &ett_ipcp_secdns_opt,
1306         OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_sec_dns_opt},
1307     {CI_SEC_NBNS, "Secondary NBNS Server IP Address", &ett_ipcp_secnbns_opt,
1308         OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_sec_nbns_opt}
1309 };
1310
1311 #define N_IPCP_OPTS     (sizeof ipcp_opts / sizeof ipcp_opts[0])
1312
1313
1314 /*
1315  * IP Compression options
1316  */
1317 #define IPCP_ROHC               0x0003  /* RFC3241 */
1318 #define IPCP_COMPRESS_VJ_1172   0x0037  /* value defined in RFC1172 (typo) */
1319 #define IPCP_COMPRESS_VJ        0x002d  /* value defined in RFC1332 (correct) */
1320 #define IPCP_COMPRESS_IPHC      0x0061  /* RFC3544 (and RFC2509) */
1321
1322 static const value_string ipcp_compress_proto_vals[] = {
1323     {IPCP_ROHC,             "Robust Header Compression (ROHC)"},
1324     {IPCP_COMPRESS_VJ,      "VJ compression"},
1325     {IPCP_COMPRESS_VJ_1172, "VJ compression (RFC1172-typo)"},
1326     {IPCP_COMPRESS_IPHC,    "IPHC compression"},
1327     {0,                     NULL}
1328 };
1329
1330 /* IPHC suboptions (RFC2508, 3544) */
1331 #define IPCP_IPHC_CRTP          1
1332 #define IPCP_IPHC_ECRTP         2
1333 #define IPCP_IPHC_NEGHC         3
1334
1335 static const value_string ipcp_iphc_parameter_vals[] = {
1336     {1, "The number of contexts for TCP Space is 0"},
1337     {2, "The number of contexts for Non TCP Space is 0"},
1338     {0, NULL}
1339 };
1340
1341 static const ip_tcp_opt ipcp_iphc_subopts[] = {
1342     {IPCP_IPHC_CRTP, "RTP compression (RFC2508)",
1343         &ett_ipcp_iphc_rtp_compress_opt, OPT_LEN_FIXED_LENGTH, 2,
1344         dissect_ipcp_iphc_simple_opt},
1345     {IPCP_IPHC_ECRTP, "Enhanced RTP compression (RFC3545)",
1346         &ett_ipcp_iphc_enhanced_rtp_compress_opt, OPT_LEN_FIXED_LENGTH, 2,
1347         dissect_ipcp_iphc_simple_opt},
1348     {IPCP_IPHC_NEGHC, "Negotiating header compression (RFC3545)",
1349         &ett_ipcp_iphc_neghdrcomp_opt, OPT_LEN_FIXED_LENGTH, 3,
1350         dissect_ipcp_iphc_neghdrcomp_opt}
1351 };
1352
1353 #define N_IPCP_IPHC_SUBOPTS (sizeof ipcp_iphc_subopts / sizeof ipcp_iphc_subopts[0])
1354
1355
1356 /* ROHC suboptions */
1357 #define IPCP_ROHC_PROFILES      1
1358
1359 /* From http://tools.ietf.org/html/rfc3095 */
1360 static const value_string ipcp_rohc_profile_vals[] = {
1361     {0x0000, "ROHC uncompressed -- no compression"},
1362     {0x0002, "ROHC UDP -- non-RTP UDP/IP compression"},
1363     {0x0003, "ROHC ESP -- ESP/IP compression"},
1364     {0,      NULL}
1365 };
1366
1367 static const ip_tcp_opt ipcp_rohc_subopts[] = {
1368     {IPCP_ROHC_PROFILES, "Profiles (RFC3241)", &ett_ipcp_rohc_profiles_opt,
1369         OPT_LEN_VARIABLE_LENGTH, 2, dissect_ipcp_rohc_profiles_opt}
1370 };
1371
1372 #define N_IPCP_ROHC_SUBOPTS (sizeof ipcp_rohc_subopts / sizeof ipcp_rohc_subopts[0])
1373
1374 static ip_tcp_opt_type PPP_OPT_TYPES = {&hf_ppp_opt_type, &ett_ppp_opt_type,
1375     &hf_ppp_opt_type_copy, &hf_ppp_opt_type_class, &hf_ppp_opt_type_number};
1376
1377 /*
1378  * Options.  (OSINLCP)
1379  */
1380 #define CI_OSINLCP_ALIGN_NPDU    1  /* Alignment of the OSI NPDU (RFC 1377) */
1381
1382 static int hf_osinlcp_opt_type = -1;
1383 static int hf_osinlcp_opt_length = -1;
1384 static int hf_osinlcp_opt_alignment = -1;
1385
1386 static void dissect_osinlcp_align_npdu_opt(const ip_tcp_opt *optp,
1387     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo,
1388     proto_tree *tree, void *data _U_);
1389
1390 static const ip_tcp_opt osinlcp_opts[] = {
1391     {CI_OSINLCP_ALIGN_NPDU, "Align-NPDU", &ett_osinlcp_align_npdu_opt,
1392         OPT_LEN_FIXED_LENGTH, 3, dissect_osinlcp_align_npdu_opt}
1393 };
1394
1395 #define N_OSINLCP_OPTS   (sizeof osinlcp_opts / sizeof osinlcp_opts[0])
1396
1397 /*
1398  * Options.  (CCP)
1399  */
1400 #define CI_CCP_OUI      0       /* OUI (RFC1962) */
1401 #define CI_CCP_PREDICT1 1       /* Predictor type 1 (RFC1962) */
1402 #define CI_CCP_PREDICT2 2       /* Predictor type 2 (RFC1962) */
1403 #define CI_CCP_PUDDLE   3       /* Puddle Jumper (RFC1962) */
1404 #define CI_CCP_HPPPC    16      /* Hewlett-Packard PPC (RFC1962) */
1405 #define CI_CCP_STAC     17      /* stac Electronics LZS (RFC1974) */
1406 #define CI_CCP_MPPE     18      /* Microsoft PPE/C (RFC2118/3078) */
1407 #define CI_CCP_GFZA     19      /* Gandalf FZA (RFC1962) */
1408 #define CI_CCP_V42BIS   20      /* V.42bis compression */
1409 #define CI_CCP_BSDLZW   21      /* BSD LZW Compress (RFC1977) */
1410 #define CI_CCP_LZSDCP   23      /* LZS-DCP (RFC1967) */
1411 #define CI_CCP_MVRCA    24      /* MVRCA (Magnalink) (RFC1975) */
1412 #define CI_CCP_DCE      25      /* DCE (RFC1976) */
1413 #define CI_CCP_DEFLATE  26      /* Deflate (RFC1979) */
1414 #define CI_CCP_V44LZJH  27      /* V.44/LZJH (http://www.watersprings.org/pub/id/draft-heath-ppp-v44-01.txt) */
1415 #define CI_CCP_RESERVED 255     /* Reserved (RFC1962) */
1416
1417 static int hf_ccp_opt_type = -1;
1418 static int hf_ccp_opt_length = -1;
1419 static int hf_ccp_opt_oui = -1;
1420 static int hf_ccp_opt_subtype = -1;
1421 static int hf_ccp_opt_data = -1;
1422 static int hf_ccp_opt_history_count = -1;
1423 static int hf_ccp_opt_cm = -1;
1424 static int hf_ccp_opt_cm_reserved = -1;
1425 static int hf_ccp_opt_cm_check_mode = -1;
1426 static int hf_ccp_opt_supported_bits = -1;
1427 static int hf_ccp_opt_supported_bits_h = -1;
1428 static int hf_ccp_opt_supported_bits_m = -1;
1429 static int hf_ccp_opt_supported_bits_s = -1;
1430 static int hf_ccp_opt_supported_bits_l = -1;
1431 static int hf_ccp_opt_supported_bits_d = -1;
1432 static int hf_ccp_opt_supported_bits_c = -1;
1433 static int hf_ccp_opt_history = -1;
1434 static int hf_ccp_opt_version = -1;
1435 static int hf_ccp_opt_vd = -1;
1436 static int hf_ccp_opt_vd_vers = -1;
1437 static int hf_ccp_opt_vd_dict = -1;
1438 static int hf_ccp_opt_check_mode = -1;
1439 static int hf_ccp_opt_process_mode = -1;
1440 static int hf_ccp_opt_fe = -1;
1441 static int hf_ccp_opt_p = -1;
1442 static int hf_ccp_opt_History = -1; /* Different than hf_ccp_opt_history */
1443 static int hf_ccp_opt_contexts = -1;
1444 static int hf_ccp_opt_mode = -1;
1445 static int hf_ccp_opt_window = -1;
1446 static int hf_ccp_opt_method = -1;
1447 static int hf_ccp_opt_mbz = -1;
1448 static int hf_ccp_opt_chk = -1;
1449 static int hf_ccp_opt_mode_dictcount = -1;
1450 static int hf_ccp_opt_dict_size = -1;
1451 static int hf_ccp_opt_history_length = -1;
1452
1453 static void dissect_ccp_oui_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1454     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1455 static void dissect_ccp_other_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1456     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1457 #define dissect_ccp_predict1_opt    dissect_ccp_other_opt
1458 #define dissect_ccp_predict2_opt    dissect_ccp_other_opt
1459 #define dissect_ccp_puddle_opt      dissect_ccp_other_opt
1460 #define dissect_ccp_hpppc_opt       dissect_ccp_other_opt
1461 static void dissect_ccp_stac_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1462     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1463 static void dissect_ccp_mppe_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1464     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1465 static void dissect_ccp_gfza_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1466     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1467 #define dissect_ccp_v42bis_opt      dissect_ccp_other_opt
1468 static void dissect_ccp_bsdcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1469     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1470 static void dissect_ccp_lzsdcp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1471     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1472 static void dissect_ccp_mvrca_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1473     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1474 static void dissect_ccp_dce_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1475     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1476 static void dissect_ccp_deflate_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1477     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1478 static void dissect_ccp_v44lzjh_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1479     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1480
1481 static const ip_tcp_opt ccp_opts[] = {
1482
1483     {CI_CCP_OUI, "OUI", &ett_ccp_oui_opt,
1484         OPT_LEN_VARIABLE_LENGTH, 6, dissect_ccp_oui_opt},
1485     {CI_CCP_PREDICT1, "Predictor type 1", &ett_ccp_predict1_opt,
1486         OPT_LEN_VARIABLE_LENGTH, 2, dissect_ccp_predict1_opt},
1487     {CI_CCP_PREDICT2, "Predictor type 2", &ett_ccp_predict2_opt,
1488         OPT_LEN_VARIABLE_LENGTH, 2, dissect_ccp_predict2_opt},
1489     {CI_CCP_PUDDLE, "Puddle Jumper", &ett_ccp_puddle_opt,
1490         OPT_LEN_VARIABLE_LENGTH, 2, dissect_ccp_puddle_opt},
1491     {CI_CCP_HPPPC, "Hewlett-Packard PPC", &ett_ccp_hpppc_opt,
1492         OPT_LEN_VARIABLE_LENGTH, 2, dissect_ccp_hpppc_opt},
1493     {CI_CCP_STAC, "Stac Electronics LZS", &ett_ccp_stac_opt,
1494         /* In RFC 1974, this is a fixed-length field of size 5, but in
1495          * Ascend Proprietary STAC compression this field is 6 octets. */
1496         OPT_LEN_VARIABLE_LENGTH, 5, dissect_ccp_stac_opt},
1497     {CI_CCP_MPPE, "Microsoft PPE/PPC", &ett_ccp_mppe_opt,
1498         OPT_LEN_FIXED_LENGTH, 6, dissect_ccp_mppe_opt},
1499     {CI_CCP_GFZA, "Gandalf FZA", &ett_ccp_gfza_opt,
1500         OPT_LEN_VARIABLE_LENGTH, 3, dissect_ccp_gfza_opt},
1501     {CI_CCP_V42BIS, "V.42bis compression", &ett_ccp_v42bis_opt,
1502         OPT_LEN_VARIABLE_LENGTH, 2, dissect_ccp_v42bis_opt},
1503     {CI_CCP_BSDLZW, "BSD LZW Compress", &ett_ccp_bsdcomp_opt,
1504         OPT_LEN_FIXED_LENGTH, 3, dissect_ccp_bsdcomp_opt},
1505     {CI_CCP_LZSDCP, "LZS-DCP", &ett_ccp_lzsdcp_opt,
1506         OPT_LEN_FIXED_LENGTH, 6, dissect_ccp_lzsdcp_opt},
1507     {CI_CCP_MVRCA, "MVRCA (Magnalink)", &ett_ccp_mvrca_opt,
1508         OPT_LEN_FIXED_LENGTH, 4, dissect_ccp_mvrca_opt},
1509     {CI_CCP_DCE,
1510         "PPP for Data Compression in Data Circuit-Terminating Equipment (DCE)",
1511         &ett_ccp_dce_opt,
1512         OPT_LEN_FIXED_LENGTH, 3, dissect_ccp_dce_opt},
1513     {CI_CCP_DEFLATE, "Deflate", &ett_ccp_deflate_opt,
1514         /* RFC1979 says the length is 3 but it's actually 4. */
1515         OPT_LEN_FIXED_LENGTH, 4, dissect_ccp_deflate_opt},
1516     {CI_CCP_V44LZJH, "V.44/LZJH compression", &ett_ccp_v44lzjh_opt,
1517         OPT_LEN_VARIABLE_LENGTH, 4, dissect_ccp_v44lzjh_opt}
1518 };
1519
1520 #define N_CCP_OPTS      (sizeof ccp_opts / sizeof ccp_opts[0])
1521
1522 /*
1523  * Options.  (CBCP)
1524  */
1525 #define CI_CBCP_NO_CALLBACK     1  /* No callback */
1526 #define CI_CBCP_CB_USER         2  /* Callback to a user-specified number */
1527 #define CI_CBCP_CB_PRE          3  /* Callback to a pre-specified or
1528                                       administrator specified number */
1529 #define CI_CBCP_CB_ANY          4  /* Callback to any of a list of numbers */
1530
1531 static void dissect_cbcp_no_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1532     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1533
1534 static void dissect_cbcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1535     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1536
1537 static const ip_tcp_opt cbcp_opts[] = {
1538     {CI_CBCP_NO_CALLBACK, "No callback", NULL,
1539         OPT_LEN_FIXED_LENGTH, 2, dissect_cbcp_no_callback_opt},
1540     {CI_CBCP_CB_USER, "Callback to a user-specified number", &ett_cbcp_callback_opt,
1541         OPT_LEN_VARIABLE_LENGTH, 4, dissect_cbcp_callback_opt},
1542     {CI_CBCP_CB_PRE, "Callback to a pre-specified or admin-specified number", &ett_cbcp_callback_opt,
1543         OPT_LEN_FIXED_LENGTH, 3, dissect_cbcp_callback_opt},
1544     {CI_CBCP_CB_ANY, "Callback to any of a list of numbers", &ett_cbcp_callback_opt,
1545         OPT_LEN_VARIABLE_LENGTH, 4, dissect_cbcp_callback_opt}
1546 };
1547
1548 #define N_CBCP_OPTS     (sizeof cbcp_opts / sizeof cbcp_opts[0])
1549
1550 /*
1551  * Options.  (BACP)
1552  */
1553 #define CI_BACP_FAVORED_PEER    1  /* Favored-Peer */
1554
1555 static void dissect_bacp_favored_peer_opt(const ip_tcp_opt *optp,
1556     tvbuff_t *tvb, int offset, guint length, packet_info *pinfo,
1557     proto_tree *tree, void *data _U_);
1558
1559 static const ip_tcp_opt bacp_opts[] = {
1560     {CI_BACP_FAVORED_PEER, "Favored-Peer", &ett_bacp_favored_peer_opt,
1561         OPT_LEN_FIXED_LENGTH, 6, dissect_bacp_favored_peer_opt}
1562 };
1563
1564 #define N_BACP_OPTS     (sizeof bacp_opts / sizeof bacp_opts[0])
1565
1566 /*
1567  * Options.  (BAP)
1568  */
1569 #define CI_BAP_LINK_TYPE           1  /* Link Type */
1570 #define CI_BAP_PHONE_DELTA         2  /* Phone-Delta */
1571 #define CI_BAP_NO_PHONE_NUM_NEEDED 3  /* No Phone Number Needed */
1572 #define CI_BAP_REASON              4  /* Reason */
1573 #define CI_BAP_LINK_DISC           5  /* Link Discriminator */
1574 #define CI_BAP_CALL_STATUS         6  /* Call Status */
1575
1576 static void dissect_bap_link_type_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1577     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1578 static void dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1579     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1580 static void dissect_bap_link_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1581     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1582 static void dissect_bap_reason_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1583     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1584 static void dissect_bap_call_status_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1585     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1586
1587 static const ip_tcp_opt bap_opts[] = {
1588     {CI_BAP_LINK_TYPE, "Link Type", &ett_bap_link_type_opt,
1589         OPT_LEN_FIXED_LENGTH, 5, dissect_bap_link_type_opt},
1590     {CI_BAP_PHONE_DELTA, "Phone Delta", &ett_bap_phone_delta_opt,
1591         OPT_LEN_VARIABLE_LENGTH, 4, dissect_bap_phone_delta_opt},
1592     {CI_BAP_NO_PHONE_NUM_NEEDED, "No Phone Number Needed", NULL,
1593         OPT_LEN_FIXED_LENGTH, 2, NULL},
1594     {CI_BAP_REASON, "Reason", NULL,
1595         OPT_LEN_VARIABLE_LENGTH, 2, dissect_bap_reason_opt},
1596     {CI_BAP_LINK_DISC, "Link Discriminator", NULL,
1597         OPT_LEN_FIXED_LENGTH, 4, dissect_bap_link_disc_opt},
1598     {CI_BAP_CALL_STATUS, "Call Status", &ett_bap_call_status_opt,
1599         OPT_LEN_FIXED_LENGTH, 4, dissect_bap_call_status_opt}
1600 };
1601
1602 #define N_BAP_OPTS     (sizeof bap_opts / sizeof bap_opts[0])
1603
1604 static void dissect_ppp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1605
1606 static const value_string pap_vals[] = {
1607     {CONFREQ, "Authenticate-Request"},
1608     {CONFACK, "Authenticate-Ack"},
1609     {CONFNAK, "Authenticate-Nak"},
1610     {0,       NULL}
1611 };
1612
1613 static void dissect_pap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1614
1615 #define CHAP_CHAL  1  /* CHAP Challenge */
1616 #define CHAP_RESP  2  /* CHAP Response */
1617 #define CHAP_SUCC  3  /* CHAP Success */
1618 #define CHAP_FAIL  4  /* CHAP Failure */
1619
1620 static const value_string chap_vals[] = {
1621     {CHAP_CHAL, "Challenge"},
1622     {CHAP_RESP, "Response"},
1623     {CHAP_SUCC, "Success"},
1624     {CHAP_FAIL, "Failure"},
1625     {0,         NULL}
1626 };
1627
1628 static void dissect_chap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1629
1630 static const value_string pppmuxcp_vals[] = {
1631     {CONFREQ, "Configuration Request"},
1632     {CONFACK, "Configuration Ack"},
1633     {0,       NULL}
1634 };
1635
1636 /*
1637  * PPPMuxCP options
1638  */
1639
1640 #define CI_DEFAULT_PID   1
1641
1642 static void dissect_pppmuxcp_def_pid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1643     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1644
1645
1646 static const ip_tcp_opt pppmuxcp_opts[] = {
1647     {CI_DEFAULT_PID, "Default Protocol ID", NULL,
1648         OPT_LEN_FIXED_LENGTH, 4, dissect_pppmuxcp_def_pid_opt}
1649 };
1650
1651 static const true_false_string tfs_pppmux_length_field = { "2 bytes", "1 byte" };
1652
1653 #define N_PPPMUXCP_OPTS (sizeof pppmuxcp_opts / sizeof pppmuxcp_opts[0])
1654
1655 /*
1656  * Options.  (IPv6CP)
1657  */
1658 #define CI_IPV6CP_IF_ID         1       /* Interface Identifier (RFC 2472) */
1659 #define CI_IPV6CP_COMPRESSTYPE  2       /* Compression Type (RFC 2472) */
1660
1661 static void dissect_ipv6cp_if_id_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1662     int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1663
1664 static const ip_tcp_opt ipv6cp_opts[] = {
1665     {CI_IPV6CP_IF_ID, "Interface Identifier", &ett_ipv6cp_if_id_opt,
1666         OPT_LEN_FIXED_LENGTH, 10, dissect_ipv6cp_if_id_opt},
1667     {CI_COMPRESS_PROTO, "IPv6 compression", &ett_ipv6cp_compress_opt,
1668         OPT_LEN_VARIABLE_LENGTH, 4, dissect_ipcp_compress_opt}
1669 };
1670
1671 #define N_IPV6CP_OPTS   (sizeof ipv6cp_opts / sizeof ipv6cp_opts[0])
1672
1673 /*
1674 *******************************************************************************
1675 * DETAILS : Calculate a new FCS-16 given the current FCS-16 and the new data.
1676 *******************************************************************************
1677 */
1678 static guint16
1679 fcs16(tvbuff_t *tvbuff)
1680 {
1681     guint len = tvb_length(tvbuff) - 2;
1682
1683     /* Check for Invalid Length */
1684     if (len == 0)
1685         return (0x0000);
1686     return crc16_ccitt_tvb(tvbuff, len);
1687 }
1688
1689 /*
1690 *******************************************************************************
1691 * DETAILS : Calculate a new FCS-32 given the current FCS-32 and the new data.
1692 *******************************************************************************
1693 */
1694 static guint32
1695 fcs32(tvbuff_t *tvbuff)
1696 {
1697     guint len = tvb_length(tvbuff) - 4;
1698
1699     /* Check for invalid Length */
1700     if (len == 0)
1701         return (0x00000000);
1702     return crc32_ccitt_tvb(tvbuff, len);
1703 }
1704
1705 tvbuff_t *
1706 decode_fcs(tvbuff_t *tvb, proto_tree *fh_tree, int fcs_decode, int proto_offset)
1707 {
1708     tvbuff_t *next_tvb;
1709     gint      len, reported_len;
1710     int       rx_fcs_offset;
1711     guint32   rx_fcs_exp;
1712     guint32   rx_fcs_got;
1713
1714     /*
1715      * Remove the FCS, if any, from the packet data.
1716      */
1717     switch (fcs_decode) {
1718
1719     case NO_FCS:
1720         next_tvb = tvb_new_subset_remaining(tvb, proto_offset);
1721         break;
1722
1723     case FCS_16:
1724         /*
1725          * Do we have the entire packet, and does it include a 2-byte FCS?
1726          */
1727         len = tvb_length_remaining(tvb, proto_offset);
1728         reported_len = tvb_reported_length_remaining(tvb, proto_offset);
1729         if (reported_len < 2 || len < 0) {
1730             /*
1731              * The packet is claimed not to even have enough data for a 2-byte
1732              * FCS, or we're already past the end of the captured data.
1733              * Don't slice anything off.
1734              */
1735             next_tvb = tvb_new_subset_remaining(tvb, proto_offset);
1736         } else if (len < reported_len) {
1737             /*
1738              * The packet is claimed to have enough data for a 2-byte FCS, but
1739              * we didn't capture all of the packet.
1740              * Slice off the 2-byte FCS from the reported length, and trim the
1741              * captured length so it's no more than the reported length; that
1742              * will slice off what of the FCS, if any, is in the captured
1743              * length.
1744              */
1745             reported_len -= 2;
1746             if (len > reported_len)
1747                 len = reported_len;
1748             next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1749         } else {
1750             /*
1751              * We have the entire packet, and it includes a 2-byte FCS.
1752              * Slice it off.
1753              */
1754             len -= 2;
1755             reported_len -= 2;
1756             next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1757
1758             /*
1759              * Compute the FCS and put it into the tree.
1760              */
1761             rx_fcs_offset = proto_offset + len;
1762             rx_fcs_exp = fcs16(tvb);
1763             rx_fcs_got = tvb_get_letohs(tvb, rx_fcs_offset);
1764             if (rx_fcs_got != rx_fcs_exp) {
1765                 proto_tree_add_uint_format_value(fh_tree, hf_ppp_fcs_16, tvb, rx_fcs_offset, 2,
1766                     rx_fcs_got, "0x%04x [incorrect, should be 0x%04x]",
1767                     rx_fcs_got, rx_fcs_exp);
1768             } else {
1769                 proto_tree_add_uint_format_value(fh_tree, hf_ppp_fcs_16, tvb, rx_fcs_offset, 2,
1770                     rx_fcs_got, "0x%04x [correct]", rx_fcs_got);
1771             }
1772         }
1773         break;
1774
1775     case FCS_32:
1776         /*
1777          * Do we have the entire packet, and does it include a 4-byte FCS?
1778          */
1779         len = tvb_length_remaining(tvb, proto_offset);
1780         reported_len = tvb_reported_length_remaining(tvb, proto_offset);
1781         if (reported_len < 4) {
1782             /*
1783              * The packet is claimed not to even have enough data for a 4-byte
1784              * FCS.  Just pass on the tvbuff as is.
1785              */
1786             next_tvb = tvb_new_subset_remaining(tvb, proto_offset);
1787         } else if (len < reported_len) {
1788             /*
1789              * The packet is claimed to have enough data for a 4-byte FCS, but
1790              * we didn't capture all of the packet.
1791              * Slice off the 4-byte FCS from the reported length, and trim the
1792              * captured length so it's no more than the reported length; that
1793              * will slice off what of the FCS, if any, is in the captured
1794              * length.
1795              */
1796             reported_len -= 4;
1797             if (len > reported_len)
1798                 len = reported_len;
1799             next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1800         } else {
1801             /*
1802              * We have the entire packet, and it includes a 4-byte FCS.
1803              * Slice it off.
1804              */
1805             len -= 4;
1806             reported_len -= 4;
1807             next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1808
1809             /*
1810              * Compute the FCS and put it into the tree.
1811              */
1812             rx_fcs_offset = proto_offset + len;
1813             rx_fcs_exp = fcs32(tvb);
1814             rx_fcs_got = tvb_get_letohl(tvb, rx_fcs_offset);
1815             if (rx_fcs_got != rx_fcs_exp) {
1816                 proto_tree_add_uint_format_value(fh_tree, hf_ppp_fcs_32, tvb, rx_fcs_offset, 4,
1817                     rx_fcs_got, "0x%08x [incorrect, should be 0x%08x]",
1818                     rx_fcs_got, rx_fcs_exp);
1819             } else {
1820                 proto_tree_add_uint_format_value(fh_tree, hf_ppp_fcs_32, tvb, rx_fcs_offset, 4,
1821                     rx_fcs_got, "0x%08x [correct]", rx_fcs_got);
1822             }
1823         }
1824         break;
1825
1826     default:
1827         DISSECTOR_ASSERT_NOT_REACHED();
1828         next_tvb = NULL;
1829         break;
1830     }
1831
1832     return next_tvb;
1833 }
1834
1835 void
1836 capture_ppp_hdlc(const guchar *pd, int offset, int len, packet_counts *ld)
1837 {
1838     if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
1839         ld->other++;
1840         return;
1841     }
1842     if (pd[0] == CHDLC_ADDR_UNICAST || pd[0] == CHDLC_ADDR_MULTICAST) {
1843         capture_chdlc(pd, offset, len, ld);
1844         return;
1845     }
1846     if (!BYTES_ARE_IN_FRAME(offset, len, 4)) {
1847         ld->other++;
1848         return;
1849     }
1850     switch (pntoh16(&pd[offset + 2])) {
1851     case PPP_IP:
1852         capture_ip(pd, offset + 4, len, ld);
1853         break;
1854     case PPP_IPX:
1855         capture_ipx(ld);
1856         break;
1857     case PPP_VINES:
1858         capture_vines(ld);
1859         break;
1860     default:
1861         ld->other++;
1862         break;
1863     }
1864 }
1865
1866 static void
1867 dissect_lcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
1868     const char *name)
1869 {
1870     guint8 type;
1871
1872     type = tvb_get_guint8(tvb, offset);
1873     proto_tree_add_uint_format_value(tree, hf_lcp_opt_type, tvb, offset, 1,
1874         type, "%s (%u)", name, type);
1875     proto_tree_add_item(tree, hf_lcp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
1876 }
1877
1878 static void
1879 dissect_lcp_vendor_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1880     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1881 {
1882     proto_tree *field_tree;
1883     proto_item *ti;
1884     guint32 oui;
1885     const gchar *manuf;
1886
1887     oui = tvb_get_ntoh24(tvb, offset + 2);
1888     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
1889     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1890     ti = proto_tree_add_uint_format_value(field_tree, hf_lcp_opt_oui, tvb,
1891         offset + 2, 3, oui, "%02x:%02x:%02x",
1892         (oui >> 16) & 0xff, (oui >> 8) & 0xff, oui & 0xff);
1893     manuf = uint_get_manuf_name_if_known(oui);
1894     if (manuf)
1895         proto_item_append_text(ti, "(%s)", manuf);
1896
1897     proto_tree_add_item(field_tree, hf_lcp_opt_kind, tvb, offset + 5, 1,
1898         ENC_BIG_ENDIAN);
1899     if (length > 6) {
1900         proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset + 6,
1901             length - 6, ENC_NA);
1902     }
1903 }
1904
1905 static void
1906 dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1907     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1908 {
1909     proto_tree *field_tree;
1910
1911     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
1912                     *optp->subtree_index, NULL, "%s: %u", optp->name,
1913                     tvb_get_ntohs(tvb, offset + 2));
1914     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1915     proto_tree_add_item(field_tree, hf_lcp_opt_mru, tvb, offset + 2, 2,
1916         ENC_BIG_ENDIAN);
1917 }
1918
1919 static void
1920 dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1921     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1922 {
1923     proto_tree *field_tree;
1924     proto_item *tf, *ti;
1925     static const int *asyncmap_fields[] = {
1926         &hf_lcp_opt_asyncmap_us,  &hf_lcp_opt_asyncmap_rs,
1927         &hf_lcp_opt_asyncmap_gs,  &hf_lcp_opt_asyncmap_fs,
1928         &hf_lcp_opt_asyncmap_esc, &hf_lcp_opt_asyncmap_sub,
1929         &hf_lcp_opt_asyncmap_em,  &hf_lcp_opt_asyncmap_can,
1930         &hf_lcp_opt_asyncmap_etb, &hf_lcp_opt_asyncmap_syn,
1931         &hf_lcp_opt_asyncmap_nak, &hf_lcp_opt_asyncmap_dc4,
1932         &hf_lcp_opt_asyncmap_dc3, &hf_lcp_opt_asyncmap_dc2,
1933         &hf_lcp_opt_asyncmap_dc1, &hf_lcp_opt_asyncmap_dle,
1934         &hf_lcp_opt_asyncmap_si,  &hf_lcp_opt_asyncmap_so,
1935         &hf_lcp_opt_asyncmap_cr,  &hf_lcp_opt_asyncmap_ff,
1936         &hf_lcp_opt_asyncmap_vt,  &hf_lcp_opt_asyncmap_lf,
1937         &hf_lcp_opt_asyncmap_ht,  &hf_lcp_opt_asyncmap_bs,
1938         &hf_lcp_opt_asyncmap_bel, &hf_lcp_opt_asyncmap_ack,
1939         &hf_lcp_opt_asyncmap_enq, &hf_lcp_opt_asyncmap_eot,
1940         &hf_lcp_opt_asyncmap_etx, &hf_lcp_opt_asyncmap_stx,
1941         &hf_lcp_opt_asyncmap_soh, &hf_lcp_opt_asyncmap_nul,
1942         NULL
1943     };
1944
1945     static const char *ctrlchars[32] = {
1946         "NUL", "SOH",       "STX", "ETX",        "EOT", "ENQ", "ACK", "BEL",
1947         "BS",  "HT",        "LF",  "VT",         "FF",  "CR",  "SO",  "SI",
1948         "DLE", "DC1 (XON)", "DC2", "DC3 (XOFF)", "DC4", "NAK", "SYN", "ETB",
1949         "CAN", "EM",        "SUB", "ESC",        "FS",  "GS",  "RS",  "US"
1950     };
1951
1952     gboolean anyctrlchars;
1953     guint32 map;
1954     int i;
1955
1956     map = tvb_get_ntohl(tvb, offset + 2);
1957     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length, *optp->subtree_index, &tf, "%s: 0x%08x (",
1958         optp->name, map);
1959     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1960     ti = proto_tree_add_bitmask(field_tree, tvb, offset + 2,
1961         hf_lcp_opt_asyncmap, *optp->subtree_index, asyncmap_fields,
1962         ENC_BIG_ENDIAN);
1963     if (map == 0x00000000) {
1964         proto_item_append_text(tf, "None)");
1965         proto_item_append_text(ti, " (None)");
1966     } else if (map == 0xffffffff) {
1967         proto_item_append_text(tf, "All)");
1968         proto_item_append_text(ti, " (All)");
1969     } else {
1970         for (anyctrlchars = FALSE, i = 31; i >= 0; i--) {
1971             if (map & (1 << i)) {
1972                 if (anyctrlchars)
1973                     proto_item_append_text(tf, ", %s", ctrlchars[i]);
1974                 else {
1975                     anyctrlchars = TRUE;
1976                     proto_item_append_text(tf, "%s", ctrlchars[i]);
1977                 }
1978             }
1979         }
1980         proto_item_append_text(tf, ")");
1981     }
1982 }
1983
1984 static void
1985 dissect_lcp_authprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1986     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1987 {
1988     proto_tree *field_tree;
1989     guint16 protocol;
1990
1991     protocol = tvb_get_ntohs(tvb, offset + 2);
1992     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length, *optp->subtree_index, NULL,
1993         "%s: %s (0x%02x)", optp->name, val_to_str_ext_const(protocol, &ppp_vals_ext, "Unknown"),
1994         protocol);
1995     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1996     proto_tree_add_item(field_tree, hf_lcp_opt_auth_protocol, tvb, offset + 2,
1997         2, ENC_BIG_ENDIAN);
1998
1999     if (length > 4) {
2000         offset += 4;
2001         length -= 4;
2002         if (protocol == PPP_CHAP) {
2003             proto_tree_add_item(field_tree, hf_lcp_opt_algorithm, tvb, offset,
2004                 1, ENC_BIG_ENDIAN);
2005             if (length > 1) {
2006                 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb,
2007                     offset + 1, length - 1, ENC_NA);
2008             }
2009         } else {
2010             proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2011                 length, ENC_NA);
2012         }
2013     }
2014 }
2015
2016 static void
2017 dissect_lcp_qualprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2018     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2019 {
2020     proto_tree *field_tree;
2021     guint16 protocol;
2022
2023     protocol = tvb_get_ntohs(tvb, offset + 2);
2024     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length, *optp->subtree_index, NULL, "%s: %s (0x%02x)",
2025         optp->name, val_to_str_ext_const(protocol, &ppp_vals_ext, "Unknown"),
2026         protocol);
2027     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2028     proto_tree_add_item(field_tree, hf_lcp_opt_quality_protocol, tvb,
2029         offset + 2, 2, ENC_BIG_ENDIAN);
2030
2031     if (length > 4) {
2032         proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset + 4,
2033             length + 4, ENC_NA);
2034     }
2035 }
2036
2037 static void
2038 dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2039     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2040 {
2041     proto_tree *field_tree;
2042
2043     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length, *optp->subtree_index, NULL, "%s: 0x%08x",
2044         optp->name, tvb_get_ntohl(tvb, offset + 2));
2045     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2046     proto_tree_add_item(field_tree, hf_lcp_opt_magic_number, tvb, offset + 2,
2047         4, ENC_BIG_ENDIAN);
2048 }
2049
2050 static void
2051 dissect_lcp_linkqualmon_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2052     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2053 {
2054     proto_tree *field_tree;
2055     guint32 reportingperiod;
2056
2057     reportingperiod = tvb_get_ntohl(tvb, offset + 2);
2058     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2059         *optp->subtree_index, NULL, "%s: %u microsecond%s%s", optp->name, reportingperiod,
2060         plurality(reportingperiod, "", "s"),
2061         reportingperiod ? "" : " [illegal]");
2062     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2063     proto_tree_add_uint_format_value(field_tree, hf_lcp_opt_reportingperiod,
2064         tvb, offset + 2, 4, reportingperiod, "%u microsecond%s%s",
2065         reportingperiod, plurality(reportingperiod, "", "s"),
2066         reportingperiod ? "" : "[illegal]");
2067 }
2068
2069 /* Used for:
2070  *  Protocol Field Compression
2071  *  Address and Control Field Compression
2072  *  Compound Frames (Deprecated)
2073  *  Nominal Data Encapsulation (Deprecated)
2074  *  Multilink Short Sequence Number Header
2075  *  Simple Data Link on SONET/SDH
2076  */
2077 static void
2078 dissect_lcp_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2079     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2080 {
2081     proto_tree *field_tree;
2082
2083     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
2084     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2085 }
2086
2087 static void
2088 dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2089     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
2090     void *data _U_)
2091 {
2092     proto_tree *field_tree;
2093     static const int *fcs_alternatives_fields[] = {
2094         &hf_lcp_opt_fcs_alternatives_ccitt32,
2095         &hf_lcp_opt_fcs_alternatives_ccitt16,
2096         &hf_lcp_opt_fcs_alternatives_null,
2097         NULL
2098     };
2099
2100     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2101         *optp->subtree_index, NULL, "%s: 0x%02x",
2102         optp->name, tvb_get_guint8(tvb, offset + 2));
2103     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2104     proto_tree_add_bitmask(field_tree, tvb, offset + 2,
2105         hf_lcp_opt_fcs_alternatives, *optp->subtree_index,
2106         fcs_alternatives_fields, ENC_NA);
2107 }
2108
2109 static void
2110 dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2111     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
2112     void *data _U_)
2113 {
2114     proto_tree *field_tree;
2115     guint8 maximum;
2116
2117     maximum = tvb_get_guint8(tvb, offset + 2);
2118     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2119         *optp->subtree_index, NULL, "%s: %u octet%s%s",
2120         optp->name, maximum, plurality(maximum, "", "s"),
2121         maximum ? "" : " [invalid]");
2122     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2123     proto_tree_add_uint_format_value(field_tree, hf_lcp_opt_maximum, tvb,
2124         offset + 2, 1, maximum, "%u octet%s%s", maximum,
2125         plurality(maximum, "", "s"), maximum ? "" : " [invalid]");
2126 }
2127
2128 static void
2129 dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2130     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
2131     void *data _U_)
2132 {
2133     proto_tree *field_tree;
2134     guint8 window;
2135
2136     window = tvb_get_guint8(tvb, offset + 2);
2137     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2138         *optp->subtree_index, NULL, "%s: %u frame%s%s",
2139         optp->name, window, plurality(window, "", "s"),
2140         (window == 0 || window > 127) ? " [invalid]" : "");
2141     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2142     proto_tree_add_uint_format_value(field_tree, hf_lcp_opt_window, tvb,
2143         offset + 2, 1, window, "%u frame%s%s", window,
2144         plurality(window, "", "s"),
2145         (window == 0 || window > 127) ? " [invalid]" : "");
2146     if (length > 3) {
2147         proto_tree_add_item(field_tree, hf_lcp_opt_hdlc_address, tvb,
2148             offset + 3, length - 3, ENC_NA);
2149     }
2150 }
2151
2152 /* http://tools.ietf.org/html/rfc1570#section-2.3 only lists 0-4, but
2153  * http://tools.ietf.org/html/draft-ietf-pppext-callback-ds-02 lists 5 as
2154  * "E.165 number", rather than "unassigned", and
2155  * http://msdn.microsoft.com/en-us/library/ff632847%28v=prot.10%29.aspx does
2156  * indicate 6 as below.  Since 5 is only mentioned in the draft, leave it as
2157  * "unassigned"?
2158  */
2159 static const value_string callback_op_vals[] = {
2160     {0, "Location is determined by user authentication"},
2161     {1, "Message is dialing string"},
2162     {2, "Message is location identifier"},
2163     {3, "Message is E.164"},
2164     {4, "Message is distinguished name"},
2165     {5, "unassigned"}, /* "Message is E.165"? */
2166     {6, "Location is determined during CBCP negotiation"},
2167     {0, NULL}
2168 };
2169
2170 static void
2171 dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2172     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2173 {
2174     proto_tree *field_tree;
2175     guint8 operation;
2176
2177     operation = tvb_get_guint8(tvb, offset + 2);
2178     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2179         *optp->subtree_index, NULL, "%s: %s", optp->name,
2180         val_to_str_const(operation, callback_op_vals, "Unknown"));
2181     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2182     proto_tree_add_item(field_tree, hf_lcp_opt_operation, tvb, offset + 2, 1,
2183         ENC_BIG_ENDIAN);
2184
2185     if (length > 3) {
2186         proto_tree_add_item(field_tree, hf_lcp_opt_message, tvb, offset + 3,
2187             length - 3, ENC_NA);
2188     }
2189 }
2190
2191 /* http://tools.ietf.org/html/rfc1990#section-5.1.1 */
2192 static void
2193 dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2194     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
2195     void *data _U_)
2196 {
2197     proto_tree *field_tree;
2198
2199     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2200         *optp->subtree_index, NULL, "%s: %u", optp->name,
2201         tvb_get_ntohs(tvb, offset + 2));
2202     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2203     proto_tree_add_item(field_tree, hf_lcp_opt_mrru, tvb, offset + 2, 2,
2204         ENC_BIG_ENDIAN);
2205 }
2206
2207 #define CLASS_NULL                      0
2208 #define CLASS_LOCAL                     1
2209 #define CLASS_IP                        2
2210 #define CLASS_IEEE_802_1                3
2211 #define CLASS_PPP_MAGIC_NUMBER          4
2212 #define CLASS_PSDN_DIRECTORY_NUMBER     5
2213
2214 static const value_string multilink_ep_disc_class_vals[] = {
2215     {CLASS_NULL,                  "Null"},
2216     {CLASS_LOCAL,                 "Locally assigned address"},
2217     {CLASS_IP,                    "Internet Protocol (IP) address"},
2218     {CLASS_IEEE_802_1,            "IEEE 802.1 globally assigned MAC address"},
2219     {CLASS_PPP_MAGIC_NUMBER,      "PPP magic-number block"},
2220     {CLASS_PSDN_DIRECTORY_NUMBER, "Public switched network directory number"},
2221     {0,                           NULL}
2222 };
2223
2224 static void
2225 dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2226     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
2227     void *data _U_)
2228 {
2229     proto_tree *field_tree;
2230     proto_tree *magic_tree;
2231     proto_item *tm;
2232     guint8 ep_disc_class;
2233
2234     ep_disc_class = tvb_get_guint8(tvb, offset + 2);
2235     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2236         *optp->subtree_index, NULL, "%s: Class: %s",
2237         optp->name, val_to_str_const(ep_disc_class,
2238             multilink_ep_disc_class_vals, "Unknown"));
2239     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2240     proto_tree_add_item(field_tree, hf_lcp_opt_ep_disc_class, tvb, offset + 2,
2241         1, ENC_BIG_ENDIAN);
2242
2243     if (length <= 3)
2244         return;
2245
2246     length -= 3;
2247     offset += 3;
2248     switch (ep_disc_class) {
2249     case CLASS_NULL:
2250         break;
2251
2252     case CLASS_LOCAL:
2253         proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2254             length <= 20 ? length : 20, ENC_NA);
2255         break;
2256
2257     case CLASS_IP:
2258         if (length >= 4) {
2259             proto_tree_add_item(field_tree, hf_lcp_opt_ip_address, tvb, offset,
2260                 4, ENC_BIG_ENDIAN);
2261         } else {
2262             proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2263                 length, ENC_NA);
2264         }
2265         break;
2266
2267     case CLASS_IEEE_802_1:
2268         if (length >= 6) {
2269             proto_tree_add_item(field_tree, hf_lcp_opt_802_1_address, tvb,
2270                 offset, 6, ENC_NA);
2271         } else {
2272             proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2273                 length, ENC_NA);
2274         }
2275         break;
2276
2277     case CLASS_PPP_MAGIC_NUMBER:
2278         if (length % 4) {
2279             proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2280                 length, ENC_NA);
2281         } else {
2282             tm = proto_tree_add_item(field_tree, hf_lcp_opt_magic_block, tvb,
2283                 offset, length <= 20 ? length : 20, ENC_NA);
2284             magic_tree = proto_item_add_subtree(tm, ett_lcp_magic_block);
2285             for ( ; length >= 4; length -= 4, offset += 4) {
2286                 proto_tree_add_item(magic_tree, hf_lcp_opt_magic_number, tvb,
2287                     offset, 4, ENC_BIG_ENDIAN);
2288             }
2289         }
2290         break;
2291
2292     case CLASS_PSDN_DIRECTORY_NUMBER:
2293         proto_tree_add_item(field_tree, hf_lcp_opt_psndn, tvb, offset,
2294             length > 15 ? 15 : length, ENC_NA);
2295         break;
2296
2297     default:
2298         proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset, length,
2299             ENC_NA);
2300         break;
2301     }
2302 }
2303
2304 static const value_string dce_id_mode_vals[] = {
2305     {1, "Mode-1 (No Additional Negotiation)"},
2306     {2, "Mode-2 (Full PPP Negotiation and State Machine)"},
2307     {0, NULL}
2308 };
2309
2310 static void
2311 dissect_lcp_dce_identifier_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2312     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2313 {
2314     proto_tree *field_tree;
2315     guint8 mode;
2316
2317     mode = tvb_get_guint8(tvb, offset + 2);
2318     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2319         *optp->subtree_index, NULL, "%s: %s", optp->name,
2320         val_to_str_const(mode, dce_id_mode_vals, "Unknown"));
2321     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2322     proto_tree_add_item(field_tree, hf_lcp_opt_mode, tvb, offset + 2, 1,
2323         ENC_BIG_ENDIAN);
2324 }
2325
2326 static void
2327 dissect_lcp_multilink_pp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2328     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2329 {
2330     proto_tree *field_tree;
2331
2332     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
2333     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2334     proto_tree_add_item(field_tree, hf_lcp_opt_unused, tvb, offset + 2, 2,
2335         ENC_NA);
2336 }
2337
2338 static void
2339 dissect_lcp_bacp_link_discriminator_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2340     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2341 {
2342     proto_tree *field_tree;
2343
2344     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2345         *optp->subtree_index, NULL, "%s: %u (0x%04x)",
2346         optp->name, tvb_get_ntohs(tvb, offset + 2),
2347         tvb_get_ntohs(tvb, offset + 2));
2348     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2349     proto_tree_add_item(field_tree, hf_lcp_opt_link_discrim, tvb, offset + 2,
2350         2, ENC_BIG_ENDIAN);
2351 }
2352
2353 /* Assuming it's this one:
2354  * http://tools.ietf.org/html/draft-ietf-pppext-link-negot-00
2355  */
2356 static void
2357 dissect_lcp_auth_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2358     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2359 {
2360     proto_tree *field_tree;
2361     guint8 id_len;
2362
2363     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
2364     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2365     proto_tree_add_item(field_tree, hf_lcp_opt_id, tvb, offset + 2, 1, ENC_NA);
2366
2367     if (length > 3) {
2368         id_len = tvb_get_guint8(tvb, offset + 2);
2369         length -= 3;
2370         offset += 3;
2371         if (id_len < length) {
2372             length -= id_len;
2373             offset += id_len;
2374             proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2375                 length, ENC_NA);
2376         }
2377     }
2378 }
2379
2380 /* Asuming it's this one:
2381  * http://tools.ietf.org/html/draft-ietf-pppext-cobs-00
2382  */
2383 static void
2384 dissect_lcp_cobs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2385     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2386 {
2387     proto_tree *field_tree;
2388     static const int *cobs_flags_fields[] = {
2389         &hf_lcp_opt_cobs_flags_res,
2390         &hf_lcp_opt_cobs_flags_pre,
2391         &hf_lcp_opt_cobs_flags_zxe,
2392         NULL
2393     };
2394
2395     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
2396     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2397     proto_tree_add_bitmask(field_tree, tvb, offset + 2, hf_lcp_opt_cobs_flags,
2398         *optp->subtree_index, cobs_flags_fields, ENC_NA);
2399 }
2400
2401 static void
2402 dissect_lcp_prefix_elision_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2403     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2404 {
2405     proto_tree *field_tree;
2406     guint8 pre_len;
2407
2408     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
2409     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2410
2411     if (length > 2) {
2412         length -= 2;
2413         offset += 2;
2414         while (length >= 2) {
2415             proto_tree_add_item(field_tree, hf_lcp_opt_class, tvb, offset, 1,
2416                 ENC_BIG_ENDIAN);
2417             pre_len = tvb_get_guint8(tvb, offset + 1);
2418             if ((guint)(pre_len + 2) <= length) {
2419                 proto_tree_add_item(field_tree, hf_lcp_opt_prefix, tvb,
2420                     offset + 2, 1, ENC_NA);
2421                 length -= (2 + pre_len);
2422             } else {
2423                 /* Prefix length doesn't make sense, so bail out */
2424                 length = 0;
2425             }
2426         }
2427     }
2428 }
2429
2430 static const value_string ml_hdr_fmt_code_vals[] = {
2431     {2, "Long sequence number fragment format with classes"},
2432     {6, "Short sequence number fragment format with classes"},
2433     {0, NULL}
2434 };
2435
2436 static void
2437 dissect_lcp_multilink_hdr_fmt_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2438     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2439 {
2440     proto_tree *field_tree;
2441
2442     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
2443     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2444     proto_tree_add_item(field_tree, hf_lcp_opt_code, tvb, offset + 2, 1,
2445         ENC_BIG_ENDIAN);
2446     proto_tree_add_item(field_tree, hf_lcp_opt_max_susp_classes, tvb,
2447         offset + 3, 1, ENC_BIG_ENDIAN);
2448 }
2449
2450
2451 /* Character sets from http://www.iana.org/assignments/character-sets. */
2452 static const value_string charset_vals[] = {
2453     {3,    "ANSI_X3.4-1968"},
2454     {4,    "ISO_8859-1:1987"},
2455     {5,    "ISO_8859-2:1987"},
2456     {6,    "ISO_8859-3:1988"},
2457     {7,    "ISO_8859-4:1988"},
2458     {8,    "ISO_8859-5:1988"},
2459     {9,    "ISO_8859-6:1987"},
2460     {10,   "ISO_8859-7:1987"},
2461     {11,   "ISO_8859-8:1988"},
2462     {12,   "ISO_8859-9:1989"},
2463     {13,   "ISO-8859-10"},
2464     {14,   "ISO_6937-2-add"},
2465     {15,   "JIS_X0201"},
2466     {16,   "JIS_Encoding"},
2467     {17,   "Shift_JIS"},
2468     {18,   "Extended_UNIX_Code_Packed_Format_for_Japanese"},
2469     {19,   "Extended_UNIX_Code_Fixed_Width_for_Japanese"},
2470     {20,   "BS_4730"},
2471     {21,   "SEN_850200_C"},
2472     {22,   "IT"},
2473     {23,   "ES"},
2474     {24,   "DIN_66003"},
2475     {25,   "NS_4551-1"},
2476     {26,   "NF_Z_62-010"},
2477     {27,   "ISO-10646-UTF-1"},
2478     {28,   "ISO_646.basic:1983"},
2479     {29,   "INVARIANT"},
2480     {30,   "ISO_646.irv:1983"},
2481     {31,   "NATS-SEFI"},
2482     {32,   "NATS-SEFI-ADD"},
2483     {33,   "NATS-DANO"},
2484     {34,   "NATS-DANO-ADD"},
2485     {35,   "SEN_850200_B"},
2486     {36,   "KS_C_5601-1987"},
2487     {37,   "ISO-2022-KR"},
2488     {38,   "EUC-KR"},
2489     {39,   "ISO-2022-JP"},
2490     {40,   "ISO-2022-JP-2"},
2491     {41,   "JIS_C6220-1969-jp"},
2492     {42,   "JIS_C6220-1969-ro"},
2493     {43,   "PT"},
2494     {44,   "greek7-old"},
2495     {45,   "latin-greek"},
2496     {46,   "NF_Z_62-010_(1973)"},
2497     {47,   "Latin-greek-1"},
2498     {48,   "ISO_5427"},
2499     {49,   "JIS_C6226-1978"},
2500     {50,   "BS_viewdata"},
2501     {51,   "INIS"},
2502     {52,   "INIS-8"},
2503     {53,   "INIS-cyrillic"},
2504     {54,   "ISO_5427:1981"},
2505     {55,   "ISO_5428:1980"},
2506     {56,   "GB_1988-80"},
2507     {57,   "GB_2312-80"},
2508     {58,   "NS_4551-2"},
2509     {59,   "videotex-suppl"},
2510     {60,   "PT2"},
2511     {61,   "ES2"},
2512     {62,   "MSZ_7795.3"},
2513     {63,   "JIS_C6226-1983"},
2514     {64,   "greek7"},
2515     {65,   "ASMO_449"},
2516     {66,   "iso-ir-90"},
2517     {67,   "JIS_C6229-1984-a"},
2518     {68,   "JIS_C6229-1984-b"},
2519     {69,   "JIS_C6229-1984-b-add"},
2520     {70,   "JIS_C6229-1984-hand"},
2521     {71,   "JIS_C6229-1984-hand-add"},
2522     {72,   "JIS_C6229-1984-kana"},
2523     {73,   "ISO_2033-1983"},
2524     {74,   "ANSI_X3.110-1983"},
2525     {75,   "T.61-7bit"},
2526     {76,   "T.61-8bit"},
2527     {77,   "ECMA-cyrillic"},
2528     {78,   "CSA_Z243.4-1985-1"},
2529     {79,   "CSA_Z243.4-1985-2"},
2530     {80,   "CSA_Z243.4-1985-gr"},
2531     {81,   "ISO_8859-6-E"},
2532     {82,   "ISO_8859-6-I"},
2533     {83,   "T.101-G2"},
2534     {84,   "ISO_8859-8-E"},
2535     {85,   "ISO_8859-8-I"},
2536     {86,   "CSN_369103"},
2537     {87,   "JUS_I.B1.002"},
2538     {88,   "IEC_P27-1"},
2539     {89,   "JUS_I.B1.003-serb"},
2540     {90,   "JUS_I.B1.003-mac"},
2541     {91,   "greek-ccitt"},
2542     {92,   "NC_NC00-10:81"},
2543     {93,   "ISO_6937-2-25"},
2544     {94,   "GOST_19768-74"},
2545     {95,   "ISO_8859-supp"},
2546     {96,   "ISO_10367-box"},
2547     {97,   "latin-lap"},
2548     {98,   "JIS_X0212-1990"},
2549     {99,   "DS_2089"},
2550     {100,  "us-dk"},
2551     {101,  "dk-us"},
2552     {102,  "KSC5636"},
2553     {103,  "UNICODE-1-1-UTF-7"},
2554     {104,  "ISO-2022-CN"},
2555     {105,  "ISO-2022-CN-EXT"},
2556     {106,  "UTF-8"},
2557     {109,  "ISO-8859-13"},
2558     {110,  "ISO-8859-14"},
2559     {111,  "ISO-8859-15"},
2560     {112,  "ISO-8859-16"},
2561     {113,  "GBK"},
2562     {114,  "GB18030"},
2563     {115,  "OSD_EBCDIC_DF04_15"},
2564     {116,  "OSD_EBCDIC_DF03_IRV"},
2565     {117,  "OSD_EBCDIC_DF04_1"},
2566     {118,  "ISO-11548-1"},
2567     {119,  "KZ-1048"},
2568     {1000, "ISO-10646-UCS-2"},
2569     {1001, "ISO-10646-UCS-4"},
2570     {1002, "ISO-10646-UCS-Basic"},
2571     {1003, "ISO-10646-Unicode-Latin1"},
2572     {1004, "ISO-10646-J-1"},
2573     {1005, "ISO-Unicode-IBM-1261"},
2574     {1006, "ISO-Unicode-IBM-1268"},
2575     {1007, "ISO-Unicode-IBM-1276"},
2576     {1008, "ISO-Unicode-IBM-1264"},
2577     {1009, "ISO-Unicode-IBM-1265"},
2578     {1010, "UNICODE-1-1"},
2579     {1011, "SCSU"},
2580     {1012, "UTF-7"},
2581     {1013, "UTF-16BE"},
2582     {1014, "UTF-16LE"},
2583     {1015, "UTF-16"},
2584     {1016, "CESU-8"},
2585     {1017, "UTF-32"},
2586     {1018, "UTF-32BE"},
2587     {1019, "UTF-32LE"},
2588     {1020, "BOCU-1"},
2589     {2000, "ISO-8859-1-Windows-3.0-Latin-1"},
2590     {2001, "ISO-8859-1-Windows-3.1-Latin-1"},
2591     {2002, "ISO-8859-2-Windows-Latin-2"},
2592     {2003, "ISO-8859-9-Windows-Latin-5"},
2593     {2004, "hp-roman8"},
2594     {2005, "Adobe-Standard-Encoding"},
2595     {2006, "Ventura-US"},
2596     {2007, "Ventura-International"},
2597     {2008, "DEC-MCS"},
2598     {2009, "IBM850"},
2599     {2010, "IBM852"},
2600     {2011, "IBM437"},
2601     {2012, "PC8-Danish-Norwegian"},
2602     {2013, "IBM862"},
2603     {2014, "PC8-Turkish"},
2604     {2015, "IBM-Symbols"},
2605     {2016, "IBM-Thai"},
2606     {2017, "HP-Legal"},
2607     {2018, "HP-Pi-font"},
2608     {2019, "HP-Math8"},
2609     {2020, "Adobe-Symbol-Encoding"},
2610     {2021, "HP-DeskTop"},
2611     {2022, "Ventura-Math"},
2612     {2023, "Microsoft-Publishing"},
2613     {2024, "Windows-31J"},
2614     {2025, "GB2312"},
2615     {2026, "Big5"},
2616     {2027, "macintosh"},
2617     {2028, "IBM037"},
2618     {2029, "IBM038"},
2619     {2030, "IBM273"},
2620     {2031, "IBM274"},
2621     {2032, "IBM275"},
2622     {2033, "IBM277"},
2623     {2034, "IBM278"},
2624     {2035, "IBM280"},
2625     {2036, "IBM281"},
2626     {2037, "IBM284"},
2627     {2038, "IBM285"},
2628     {2039, "IBM290"},
2629     {2040, "IBM297"},
2630     {2041, "IBM420"},
2631     {2042, "IBM423"},
2632     {2043, "IBM424"},
2633     {2044, "IBM500"},
2634     {2045, "IBM851"},
2635     {2046, "IBM855"},
2636     {2047, "IBM857"},
2637     {2048, "IBM860"},
2638     {2049, "IBM861"},
2639     {2050, "IBM863"},
2640     {2051, "IBM864"},
2641     {2052, "IBM865"},
2642     {2053, "IBM868"},
2643     {2054, "IBM869"},
2644     {2055, "IBM870"},
2645     {2056, "IBM871"},
2646     {2057, "IBM880"},
2647     {2058, "IBM891"},
2648     {2059, "IBM903"},
2649     {2060, "IBM904"},
2650     {2061, "IBM905"},
2651     {2062, "IBM918"},
2652     {2063, "IBM1026"},
2653     {2064, "EBCDIC-AT-DE"},
2654     {2065, "EBCDIC-AT-DE-A"},
2655     {2066, "EBCDIC-CA-FR"},
2656     {2067, "EBCDIC-DK-NO"},
2657     {2068, "EBCDIC-DK-NO-A"},
2658     {2069, "EBCDIC-FI-SE"},
2659     {2070, "EBCDIC-FI-SE-A"},
2660     {2071, "EBCDIC-FR"},
2661     {2072, "EBCDIC-IT"},
2662     {2073, "EBCDIC-PT"},
2663     {2074, "EBCDIC-ES"},
2664     {2075, "EBCDIC-ES-A"},
2665     {2076, "EBCDIC-ES-S"},
2666     {2077, "EBCDIC-UK"},
2667     {2078, "EBCDIC-US"},
2668     {2079, "UNKNOWN-8BIT"},
2669     {2080, "MNEMONIC"},
2670     {2081, "MNEM"},
2671     {2082, "VISCII"},
2672     {2083, "VIQR"},
2673     {2084, "KOI8-R"},
2674     {2085, "HZ-GB-2312"},
2675     {2086, "IBM866"},
2676     {2087, "IBM775"},
2677     {2088, "KOI8-U"},
2678     {2089, "IBM00858"},
2679     {2090, "IBM00924"},
2680     {2091, "IBM01140"},
2681     {2092, "IBM01141"},
2682     {2093, "IBM01142"},
2683     {2094, "IBM01143"},
2684     {2095, "IBM01144"},
2685     {2096, "IBM01145"},
2686     {2097, "IBM01146"},
2687     {2098, "IBM01147"},
2688     {2099, "IBM01148"},
2689     {2100, "IBM01149"},
2690     {2101, "Big5-HKSCS"},
2691     {2102, "IBM1047"},
2692     {2103, "PTCP154"},
2693     {2104, "Amiga-1251"},
2694     {2105, "KOI7-switched"},
2695     {2106, "BRF"},
2696     {2107, "TSCII"},
2697     {2108, "CP51932"},
2698     {2109, "windows-874"},
2699     {2250, "windows-1250"},
2700     {2251, "windows-1251"},
2701     {2252, "windows-1252"},
2702     {2253, "windows-1253"},
2703     {2254, "windows-1254"},
2704     {2255, "windows-1255"},
2705     {2256, "windows-1256"},
2706     {2257, "windows-1257"},
2707     {2258, "windows-1258"},
2708     {2259, "TIS-620"},
2709     {2260, "CP50220"},
2710     {0,    NULL}
2711 };
2712 value_string_ext charset_vals_ext = VALUE_STRING_EXT_INIT(charset_vals);
2713
2714 static void
2715 dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2716     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2717 {
2718     proto_tree *field_tree;
2719
2720     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
2721     dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2722     proto_tree_add_item(field_tree, hf_lcp_opt_MIBenum, tvb, offset + 2, 4,
2723         ENC_BIG_ENDIAN);
2724     proto_tree_add_item(field_tree, hf_lcp_opt_language_tag, tvb, offset + 6,
2725         length - 6, ENC_ASCII|ENC_NA);
2726 }
2727
2728 static void
2729 dissect_ipcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2730     const char *name)
2731 {
2732     guint8 type;
2733
2734     type = tvb_get_guint8(tvb, offset);
2735     proto_tree_add_uint_format_value(tree, hf_ipcp_opt_type, tvb, offset, 1,
2736         type, "%s (%u)", name, type);
2737     proto_tree_add_item(tree, hf_ipcp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
2738 }
2739
2740 /* http://tools.ietf.org/html/rfc1172#section-5.1 */
2741 static void
2742 dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2743     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2744 {
2745     proto_tree *field_tree;
2746
2747     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2748         *optp->subtree_index, NULL, "%s: Src: %s, Dst: %s",
2749         optp->name, tvb_ip_to_str(tvb, offset + 2),
2750         tvb_ip_to_str(tvb, offset + 6));
2751     dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2752     proto_tree_add_item(field_tree, hf_ipcp_opt_src_address, tvb, offset + 2,
2753         4, ENC_BIG_ENDIAN);
2754     proto_tree_add_item(field_tree, hf_ipcp_opt_dst_address, tvb, offset + 6,
2755         4, ENC_BIG_ENDIAN);
2756 }
2757
2758 static const true_false_string tfs_comp_slot_id = {
2759     "The slot identifier may be compressed",
2760     "The slot identifier must not be compressed"
2761 };
2762
2763 /* http://tools.ietf.org/html/rfc1332#section-3.2 */
2764 static void
2765 dissect_ipcp_compress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2766     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2767 {
2768     proto_tree *field_tree;
2769     guint16     us;
2770
2771     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2772         *optp->subtree_index, NULL, "%s: %s", optp->name,
2773         val_to_str_const(tvb_get_ntohs(tvb, offset + 2),
2774             ipcp_compress_proto_vals, "Unknown"));
2775     dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2776     proto_tree_add_item(field_tree, hf_ipcp_opt_compress_proto, tvb,
2777         offset + 2, 2, ENC_BIG_ENDIAN);
2778
2779     us = tvb_get_ntohs(tvb, offset + 2);
2780     switch (us) {
2781     case IPCP_ROHC:
2782         proto_tree_add_item(field_tree, hf_ipcp_opt_max_cid, tvb, offset + 4,
2783             2, ENC_BIG_ENDIAN);
2784         proto_tree_add_item(field_tree, hf_ipcp_opt_mrru, tvb, offset + 6, 2,
2785             ENC_BIG_ENDIAN);
2786         proto_tree_add_item(field_tree, hf_ipcp_opt_max_header, tvb,
2787             offset + 8, 2, ENC_BIG_ENDIAN);
2788
2789         if (length > 10) {
2790             proto_tree *subopt_tree;
2791
2792             /* suboptions */
2793             offset += 10;
2794             length -= 10;
2795             subopt_tree = proto_tree_add_subtree_format(field_tree, tvb, offset, length,
2796                 *optp->subtree_index, NULL, "Suboptions: (%u byte%s)", length, plurality(length, "", "s"));
2797             dissect_ip_tcp_options(tvb, offset, length, ipcp_rohc_subopts,
2798                 N_IPCP_ROHC_SUBOPTS, -1, &PPP_OPT_TYPES, &ei_ppp_opt_len_invalid, pinfo, subopt_tree, NULL, NULL);
2799         }
2800         break;
2801
2802     case IPCP_COMPRESS_VJ_1172:
2803     case IPCP_COMPRESS_VJ:
2804         proto_tree_add_item(field_tree, hf_ipcp_opt_max_slot_id, tvb,
2805             offset + 4, 1, ENC_BIG_ENDIAN);
2806         proto_tree_add_item(field_tree, hf_ipcp_opt_comp_slot_id, tvb,
2807             offset + 5, 1, ENC_NA);
2808       break;
2809
2810     case IPCP_COMPRESS_IPHC:
2811         proto_tree_add_item(field_tree, hf_ipcp_opt_tcp_space, tvb, offset + 4,
2812             2, ENC_BIG_ENDIAN);
2813         proto_tree_add_item(field_tree, hf_ipcp_opt_non_tcp_space, tvb,
2814             offset + 6, 2, ENC_BIG_ENDIAN);
2815         us = tvb_get_ntohs(tvb, offset + 8);
2816         proto_tree_add_uint_format_value(field_tree, hf_ipcp_opt_f_max_period,
2817             tvb, offset + 8, 2, us, "%u%s", us,
2818             (us == 0) ? " (infinity)" : "");
2819         us = tvb_get_ntohs(tvb, offset + 10);
2820         proto_tree_add_uint_format_value(field_tree, hf_ipcp_opt_f_max_time,
2821             tvb, offset + 10, 2, us, "%u%s", us,
2822             (us == 0) ? " (infinity)" : "");
2823         proto_tree_add_item(field_tree, hf_ipcp_opt_max_header, tvb,
2824             offset + 12, 2, ENC_BIG_ENDIAN);
2825
2826         if ( length > 14 ) {
2827             proto_tree *subopt_tree;
2828
2829             /* suboptions */
2830             offset += 14;
2831             length -= 14;
2832             subopt_tree = proto_tree_add_subtree_format(field_tree, tvb, offset, length,
2833                 *optp->subtree_index, NULL, "Suboptions: (%u byte%s)", length, plurality(length, "", "s"));
2834             dissect_ip_tcp_options(tvb, offset, length, ipcp_iphc_subopts,
2835                 N_IPCP_IPHC_SUBOPTS, -1, &PPP_OPT_TYPES, &ei_ppp_opt_len_invalid, pinfo, subopt_tree, NULL, NULL);
2836         }
2837         break;
2838
2839     default:
2840         if (length > 4) {
2841             proto_tree_add_item(field_tree, hf_ipcp_data, tvb, offset + 4,
2842                 length - 4, ENC_NA);
2843         }
2844         break;
2845     }
2846 }
2847
2848 static void
2849 dissect_ipcp_opt_rohc_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2850     const char *name)
2851 {
2852     guint8 type;
2853
2854     type = tvb_get_guint8(tvb, offset);
2855     proto_tree_add_uint_format_value(tree, hf_ipcp_opt_rohc_type, tvb, offset,
2856         1, type, "%s (%u)", name, type);
2857     proto_tree_add_item(tree, hf_ipcp_opt_rohc_length, tvb, offset + 1, 1,
2858         ENC_BIG_ENDIAN);
2859 }
2860
2861 static void
2862 dissect_ipcp_rohc_profiles_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2863     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2864 {
2865     proto_tree *field_tree;
2866
2867     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
2868     dissect_ipcp_opt_rohc_type_len(tvb, offset, field_tree, optp->name);
2869     if (length <= 2)
2870         return;
2871
2872     for (offset += 2, length -= 2; length >= 2; length -= 2, offset += 2) {
2873         proto_tree_add_item(field_tree, hf_ipcp_opt_rohc_profile, tvb,
2874             offset, 2, ENC_BIG_ENDIAN);
2875     }
2876 }
2877
2878 static void
2879 dissect_ipcp_opt_iphc_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2880     const char *name)
2881 {
2882     guint8 type;
2883
2884     type = tvb_get_guint8(tvb, offset);
2885     proto_tree_add_uint_format_value(tree, hf_ipcp_opt_iphc_type, tvb, offset,
2886         1, type, "%s (%u)", name, type);
2887     proto_tree_add_item(tree, hf_ipcp_opt_iphc_length, tvb, offset + 1, 1,
2888         ENC_BIG_ENDIAN);
2889 }
2890
2891 static void
2892 dissect_ipcp_iphc_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2893     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2894 {
2895     proto_tree *field_tree;
2896
2897     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
2898     dissect_ipcp_opt_iphc_type_len(tvb, offset, field_tree, optp->name);
2899 }
2900
2901 static void
2902 dissect_ipcp_iphc_neghdrcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2903     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2904 {
2905     proto_tree *field_tree;
2906
2907     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
2908     dissect_ipcp_opt_iphc_type_len(tvb, offset, field_tree, optp->name);
2909     proto_tree_add_item(field_tree, hf_ipcp_opt_iphc_param, tvb, offset + 2, 1,
2910         ENC_BIG_ENDIAN);
2911 }
2912
2913 static void
2914 dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2915     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2916 {
2917     proto_tree *field_tree;
2918
2919     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2920         *optp->subtree_index, NULL, "%s: %s", optp->name,
2921         tvb_ip_to_str(tvb, offset + 2));
2922     dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2923     proto_tree_add_item(field_tree, hf_ipcp_opt_ip_address, tvb, offset + 2, 4,
2924         ENC_BIG_ENDIAN);
2925 }
2926
2927 static void
2928 dissect_ipcp_mobileipv4_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2929     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2930 {
2931     proto_tree *field_tree;
2932
2933     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2934         *optp->subtree_index, NULL, "%s: %s", optp->name,
2935         tvb_ip_to_str(tvb, offset + 2));
2936     dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2937     proto_tree_add_item(field_tree, hf_ipcp_opt_mobilenodehomeaddr, tvb,
2938         offset + 2, 4, ENC_BIG_ENDIAN);
2939 }
2940
2941 static void
2942 dissect_ipcp_pri_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2943     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2944 {
2945     proto_tree *field_tree;
2946
2947     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2948         *optp->subtree_index, NULL, "%s: %s", optp->name,
2949         tvb_ip_to_str(tvb, offset + 2));
2950     dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2951     proto_tree_add_item(field_tree, hf_ipcp_opt_pri_dns_address, tvb,
2952         offset + 2, 4, ENC_BIG_ENDIAN);
2953 }
2954
2955 static void
2956 dissect_ipcp_pri_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2957     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2958 {
2959     proto_tree *field_tree;
2960
2961     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2962         *optp->subtree_index, NULL, "%s: %s", optp->name,
2963         tvb_ip_to_str(tvb, offset + 2));
2964     dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2965     proto_tree_add_item(field_tree, hf_ipcp_opt_pri_nbns_address, tvb,
2966         offset + 2, 4, ENC_BIG_ENDIAN);
2967 }
2968
2969 static void
2970 dissect_ipcp_sec_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2971     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2972 {
2973     proto_tree *field_tree;
2974
2975     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2976         *optp->subtree_index, NULL, "%s: %s", optp->name,
2977         tvb_ip_to_str(tvb, offset + 2));
2978     dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2979     proto_tree_add_item(field_tree, hf_ipcp_opt_sec_dns_address, tvb,
2980         offset + 2, 4, ENC_BIG_ENDIAN);
2981 }
2982
2983 static void
2984 dissect_ipcp_sec_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2985     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2986 {
2987     proto_tree *field_tree;
2988
2989     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
2990         *optp->subtree_index, NULL, "%s: %s", optp->name,
2991         tvb_ip_to_str(tvb, offset + 2));
2992     dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2993     proto_tree_add_item(field_tree, hf_ipcp_opt_sec_nbns_address, tvb,
2994         offset + 2, 4, ENC_BIG_ENDIAN);
2995 }
2996
2997
2998 static void
2999 dissect_osinlcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
3000     const char *name)
3001 {
3002     guint8 type;
3003
3004     type = tvb_get_guint8(tvb, offset);
3005     proto_tree_add_uint_format_value(tree, hf_osinlcp_opt_type, tvb, offset, 1,
3006         type, "%s (%u)", name, type);
3007     proto_tree_add_item(tree, hf_osinlcp_opt_length, tvb, offset + 1, 1,
3008         ENC_BIG_ENDIAN);
3009 }
3010
3011 static void
3012 dissect_osinlcp_align_npdu_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3013     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3014 {
3015     proto_tree *field_tree;
3016
3017     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
3018         *optp->subtree_index, NULL, "%s: Alignment: %u",
3019         optp->name, tvb_get_guint8(tvb, offset + 2));
3020     dissect_osinlcp_opt_type_len(tvb, offset, field_tree, optp->name);
3021     proto_tree_add_item(field_tree, hf_osinlcp_opt_alignment, tvb, offset + 2,
3022         1, ENC_BIG_ENDIAN);
3023 }
3024
3025 static void
3026 dissect_pppmuxcp_def_pid_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
3027     guint length _U_, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3028 {
3029     pppmux_def_prot_id = tvb_get_ntohs(tvb, offset + 2);
3030     proto_tree_add_item(tree, hf_pppmux_def_prot_id, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
3031 }
3032
3033
3034 static void
3035 dissect_ccp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
3036     const char *name)
3037 {
3038     guint8 type;
3039
3040     type = tvb_get_guint8(tvb, offset);
3041     proto_tree_add_uint_format_value(tree, hf_ccp_opt_type, tvb, offset, 1,
3042         type, "%s (%u)", name, type);
3043     proto_tree_add_item(tree, hf_ccp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
3044 }
3045
3046 /* http://tools.ietf.org/html/rfc1962 */
3047 static void dissect_ccp_oui_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3048     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3049 {
3050     proto_tree *field_tree;
3051     proto_item *ti;
3052     guint32 oui;
3053     const gchar *manuf;
3054
3055     oui = tvb_get_ntoh24(tvb, offset + 2);
3056     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3057     dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3058     ti = proto_tree_add_uint_format_value(field_tree, hf_ccp_opt_oui, tvb,
3059         offset + 2, 3, oui, "%02x:%02x:%02x",
3060         (oui >> 16) & 0xff, (oui >> 8) & 0xff, oui & 0xff);
3061     manuf = uint_get_manuf_name_if_known(oui);
3062     if (manuf)
3063         proto_item_append_text(ti, "(%s)", manuf);
3064
3065     proto_tree_add_item(field_tree, hf_ccp_opt_subtype, tvb, offset + 5, 1,
3066         ENC_BIG_ENDIAN);
3067     if (length > 6) {
3068         proto_tree_add_item(field_tree, hf_ccp_opt_data, tvb, offset + 6,
3069             length - 6, ENC_NA);
3070     }
3071 }
3072
3073 /* The following configuration option types are mentioned at
3074  * http://www.iana.org/assignments/ppp-numbers as referencing RFC1962; however,
3075  * RFC1962 only mentions Proprietary Compression OUI in section 4.1.  These
3076  * others are therefore being treated as section 4.2 "Other Compression Types",
3077  * in terms of how they are dissected:
3078  *      1)  Predictor type 1
3079  *      2)  Predictor type 2
3080  *      3)  Puddle Jumper
3081  *      16) Hewlett-Packard PPC
3082  *      20) V.42bis compression
3083  */
3084 static void dissect_ccp_other_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3085     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3086 {
3087     proto_tree *field_tree;
3088
3089     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3090     dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3091
3092     if (length > 2) {
3093         proto_tree_add_item(field_tree, hf_ccp_opt_data, tvb, offset + 2,
3094             length - 2, ENC_NA);
3095     }
3096 }
3097
3098 /* http://tools.ietf.org/html/rfc1974 */
3099 static void
3100 dissect_ccp_stac_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3101     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3102 {
3103     proto_tree *field_tree;
3104     const char *stac_ascend = "Stac Electronics LZS (Ascend Proprietary version)";
3105     static const int *check_mode_fields[] = {
3106         &hf_ccp_opt_cm_reserved,
3107         &hf_ccp_opt_cm_check_mode,
3108         NULL
3109     };
3110
3111     if (length == 6) {
3112         field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, stac_ascend);
3113         dissect_ccp_opt_type_len(tvb, offset, field_tree, stac_ascend);
3114
3115         /* We don't know how to decode the following 4 octets, since
3116            there are no public documents that describe their usage. */
3117         proto_tree_add_item(field_tree, hf_ccp_opt_data, tvb, offset + 2,
3118             length - 2, ENC_NA);
3119     } else {
3120         field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3121         dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3122
3123         proto_tree_add_item(field_tree, hf_ccp_opt_history_count, tvb,
3124             offset + 2, 2, ENC_BIG_ENDIAN);
3125         proto_tree_add_bitmask(field_tree, tvb, offset + 4, hf_ccp_opt_cm,
3126             ett_ccp_stac_opt_check_mode, check_mode_fields, ENC_NA);
3127     }
3128 }
3129
3130 /*
3131  * Microsoft Point-To-Point Compression (MPPC) and Encryption (MPPE)
3132  * supported bits.
3133  */
3134 #define MPPC_SUPPORTED_BITS_C   0x00000001      /* MPPC negotiation */
3135 #define MPPE_SUPPORTED_BITS_D   0x00000010      /* Obsolete */
3136 #define MPPE_SUPPORTED_BITS_L   0x00000020      /* 40-bit encryption */
3137 #define MPPE_SUPPORTED_BITS_S   0x00000040      /* 128-bit encryption */
3138 #define MPPE_SUPPORTED_BITS_M   0x00000080      /* 56-bit encryption */
3139 #define MPPE_SUPPORTED_BITS_H   0x01000000      /* stateless mode */
3140
3141 static const true_false_string ccp_mppe_h_tfs = {
3142     "Stateless mode ON",
3143     "Stateless mode OFF"
3144 };
3145 static const true_false_string ccp_mppe_m_tfs = {
3146     "56-bit encryption ON",
3147     "56-bit encryption OFF"
3148 };
3149 static const true_false_string ccp_mppe_s_tfs = {
3150     "128-bit encryption ON",
3151     "128-bit encryption OFF"
3152 };
3153 static const true_false_string ccp_mppe_l_tfs = {
3154     "40-bit encryption ON",
3155     "40-bit encryption OFF"
3156 };
3157 static const true_false_string ccp_mppe_d_tfs = {
3158     "Obsolete (should NOT be 1)",
3159     "Obsolete (should ALWAYS be 0)"
3160 };
3161 static const true_false_string ccp_mppe_c_tfs = {
3162     "Desire to negotiate MPPC",
3163     "No desire to negotiate MPPC"
3164 };
3165
3166 /* http://tools.ietf.org/html/rfc2118,
3167  * http://tools.ietf.org/html/rfc3078 */
3168 static void
3169 dissect_ccp_mppe_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3170     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3171 {
3172     proto_tree *field_tree;
3173     static const int *supported_bits_fields[] = {
3174         &hf_ccp_opt_supported_bits_h,
3175         &hf_ccp_opt_supported_bits_m,
3176         &hf_ccp_opt_supported_bits_s,
3177         &hf_ccp_opt_supported_bits_l,
3178         &hf_ccp_opt_supported_bits_d,
3179         &hf_ccp_opt_supported_bits_c,
3180         NULL
3181     };
3182
3183     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3184     dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3185
3186     proto_tree_add_bitmask(field_tree, tvb, offset + 2,
3187         hf_ccp_opt_supported_bits, ett_ccp_mppe_opt_supp_bits,
3188         supported_bits_fields, ENC_BIG_ENDIAN);
3189 }
3190
3191 /* http://tools.ietf.org/html/rfc1993 */
3192 static void dissect_ccp_gfza_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3193     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3194 {
3195     proto_tree *field_tree;
3196
3197     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3198     dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3199
3200     proto_tree_add_item(field_tree, hf_ccp_opt_history, tvb, offset + 2, 1,
3201         ENC_BIG_ENDIAN);
3202
3203     if (length > 3) {
3204         proto_tree_add_item(field_tree, hf_ccp_opt_version, tvb, offset + 3,
3205             length - 3, ENC_NA);
3206     }
3207 }
3208
3209 /* http://tools.ietf.org/html/rfc1977 */
3210 static void
3211 dissect_ccp_bsdcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3212     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3213 {
3214     proto_tree *field_tree;
3215     static const int *vd_fields[] = {
3216         &hf_ccp_opt_vd_vers,
3217         &hf_ccp_opt_vd_dict,
3218         NULL
3219     };
3220
3221     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3222     dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3223
3224     proto_tree_add_bitmask(field_tree, tvb, offset + 2, hf_ccp_opt_vd,
3225         *optp->subtree_index, vd_fields, ENC_BIG_ENDIAN);
3226 }
3227
3228 /* http://tools.ietf.org/html/rfc1967 */
3229 static void
3230 dissect_ccp_lzsdcp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3231     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3232 {
3233     proto_tree *field_tree;
3234
3235     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3236     dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3237
3238     proto_tree_add_item(field_tree, hf_ccp_opt_history_count, tvb,
3239         offset + 2, 2, ENC_BIG_ENDIAN);
3240     proto_tree_add_item(field_tree, hf_ccp_opt_check_mode, tvb, offset + 4, 1,
3241         ENC_BIG_ENDIAN);
3242     proto_tree_add_item(field_tree, hf_ccp_opt_process_mode, tvb, offset + 5,
3243         1, ENC_BIG_ENDIAN);
3244 }
3245
3246 /* http://tools.ietf.org/html/rfc1975 */
3247 static void
3248 dissect_ccp_mvrca_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3249     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3250 {
3251     proto_tree *field_tree;
3252
3253     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3254     dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3255
3256     proto_tree_add_item(field_tree, hf_ccp_opt_fe, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
3257     proto_tree_add_item(field_tree, hf_ccp_opt_p, tvb, offset + 2, 1, ENC_NA);
3258     proto_tree_add_item(field_tree, hf_ccp_opt_History, tvb, offset + 2, 1,
3259         ENC_BIG_ENDIAN);
3260     proto_tree_add_item(field_tree, hf_ccp_opt_contexts, tvb, offset + 3, 1,
3261         ENC_BIG_ENDIAN);
3262 }
3263
3264 /* http://tools.ietf.org/html/rfc1976 */
3265 static void
3266 dissect_ccp_dce_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3267     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3268 {
3269     proto_tree *field_tree;
3270
3271     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3272     dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3273
3274     proto_tree_add_item(field_tree, hf_ccp_opt_mode, tvb, offset + 2, 1,
3275         ENC_BIG_ENDIAN);
3276 }
3277
3278 static const value_string deflate_method_vals[] = {
3279     {8, "zlib compression"},
3280     {0, NULL}
3281 };
3282
3283 static const value_string deflate_chk_vals[] = {
3284     {0, "sequence number check method"},
3285     {0, NULL}
3286 };
3287
3288 /* http://tools.ietf.org/html/rfc1979 */
3289 static void
3290 dissect_ccp_deflate_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3291     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3292 {
3293     proto_tree *field_tree;
3294     guint8 window;
3295
3296     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3297     dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3298
3299     window = tvb_get_guint8(tvb, offset + 2);
3300     proto_tree_add_uint_format_value(field_tree, hf_ccp_opt_window, tvb,
3301         offset + 2, 1, window, "%u", 1 << (hi_nibble(window) + 8));
3302     proto_tree_add_item(field_tree, hf_ccp_opt_method, tvb, offset + 2, 1,
3303         ENC_BIG_ENDIAN);
3304     proto_tree_add_item(field_tree, hf_ccp_opt_mbz, tvb, offset + 3, 1,
3305         ENC_BIG_ENDIAN);
3306     proto_tree_add_item(field_tree, hf_ccp_opt_chk, tvb, offset + 3, 1,
3307         ENC_BIG_ENDIAN);
3308 }
3309
3310 static const range_string v44lzjh_mode_dict_rvals[] = {
3311     {0, 0, "Datagram Mode (one dictionary and no history)"},
3312     {1, 1, "Multi-Datagram Mode (one dictionary with history)"},
3313     {2, G_MAXUINT16, "Individual Link Mode" /* "(and proposed number of
3314                                                  dictionaries each with a
3315                                                  corresponding history" */},
3316     {0, 0, NULL}
3317 };
3318
3319 /* http://www.watersprings.org/pub/id/draft-heath-ppp-v44-01.txt */
3320 static void dissect_ccp_v44lzjh_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3321     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3322 {
3323     proto_tree *field_tree;
3324
3325     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3326     dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3327
3328     proto_tree_add_item(field_tree, hf_ccp_opt_mode_dictcount, tvb, offset + 2,
3329         2, ENC_BIG_ENDIAN);
3330
3331     if (length > 4) {
3332         proto_tree_add_item(field_tree, hf_ccp_opt_dict_size, tvb, offset + 4,
3333             2, ENC_BIG_ENDIAN);
3334         if (length > 6) {
3335             proto_tree_add_item(field_tree, hf_ccp_opt_history_length, tvb,
3336                 offset + 6, 2, ENC_BIG_ENDIAN);
3337         }
3338     }
3339 }
3340
3341
3342 static void
3343 dissect_cbcp_no_callback_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
3344     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3345 {
3346     proto_tree_add_item(tree, hf_cbcp_no_callback, tvb, offset, length, ENC_NA);
3347 }
3348
3349 static void
3350 dissect_cbcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3351     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3352 {
3353     proto_tree *field_tree;
3354     proto_tree *addr_tree;
3355     proto_item *ti;
3356     guint8      addr_type;
3357     guint       addr_len;
3358
3359     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3360
3361     proto_tree_add_item(field_tree, hf_cbcp_callback_delay, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
3362     offset += 3;
3363     length -= 3;
3364
3365     while (length > 0) {
3366         addr_tree = proto_tree_add_subtree(field_tree, tvb, offset, length,
3367             ett_cbcp_callback_opt_addr, NULL, "Callback Address");
3368         addr_type = tvb_get_guint8(tvb, offset);
3369         ti = proto_tree_add_uint_format_value(addr_tree, hf_cbcp_address_type, tvb, offset, 1, addr_type,
3370              "%s (%u)", ((addr_type == 1) ? "PSTN/ISDN" : "Other"), addr_type);
3371         offset++;
3372         length--;
3373         addr_len = tvb_strsize(tvb, offset);
3374         if (addr_len > length) {
3375             expert_add_info(pinfo, ti, &ei_cbcp_address);
3376             break;
3377         }
3378         proto_tree_add_item(addr_tree, hf_cbcp_address, tvb, offset, addr_len, ENC_NA|ENC_ASCII);
3379         offset += addr_len;
3380         length -= addr_len;
3381     }
3382 }
3383
3384 static void
3385 dissect_bacp_favored_peer_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3386     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3387 {
3388     proto_tree *field_tree;
3389
3390     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3391
3392     proto_tree_add_item(field_tree, hf_bacp_magic_number, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
3393 }
3394
3395 static void
3396 dissect_bap_link_type_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3397     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3398 {
3399     proto_tree *field_tree;
3400     guint16     link_speed;
3401
3402     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3403
3404     link_speed = tvb_get_ntohs(tvb, offset + 2);
3405     proto_tree_add_uint_format_value(field_tree, hf_bacp_link_speed, tvb, offset + 2, 2, link_speed, "%u kbps", link_speed);
3406     proto_tree_add_item(field_tree, hf_bacp_link_type, tvb, offset + 4, 1, ENC_BIG_ENDIAN);
3407 }
3408
3409 static void
3410 dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3411     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3412 {
3413     proto_tree *field_tree;
3414     proto_tree *suboption_tree;
3415     proto_item *ti;
3416     guint8      subopt_type;
3417     guint8      subopt_len;
3418
3419     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3420
3421     offset += 2;
3422     length -= 2;
3423
3424     while (length > 0) {
3425         subopt_type = tvb_get_guint8(tvb, offset);
3426         subopt_len = tvb_get_guint8(tvb, offset + 1);
3427         suboption_tree = proto_tree_add_subtree_format(field_tree, tvb, offset, subopt_len,
3428             ett_bap_phone_delta_subopt, NULL, "Sub-Option (%u byte%s)", subopt_len,
3429             plurality(subopt_len, "", "s"));
3430
3431         proto_tree_add_item(suboption_tree, hf_bap_sub_option_type, tvb, offset, 1, ENC_BIG_ENDIAN);
3432         ti = proto_tree_add_item(suboption_tree, hf_bap_sub_option_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
3433
3434         if (subopt_len < 2) {
3435             expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
3436                 "Sub-Option Length invalid, must be >= 2");
3437             return;
3438         }
3439         if (subopt_len > length) {
3440             expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
3441                 "Sub-Option Length invalid, must be <= length remaining in option %u)", length);
3442             return;
3443         }
3444
3445         switch (subopt_type) {
3446         case BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT:
3447             if (subopt_len == 3) {
3448                 proto_tree_add_item(suboption_tree, hf_bap_unique_digit, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
3449             } else {
3450                 expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
3451                     "Invalid suboption length: %u (must be == 3)", subopt_len);
3452             }
3453             break;
3454         case BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM:
3455             if (subopt_len > 2) {
3456                 proto_tree_add_item(suboption_tree, hf_bap_subscriber_number, tvb, offset + 2, subopt_len - 2, ENC_NA|ENC_ASCII);
3457             } else {
3458                 expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
3459                     "Invalid suboption length: %u (must be > 2)", subopt_len);
3460             }
3461             break;
3462         case BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR:
3463             if (subopt_len > 2) {
3464                 proto_tree_add_item(suboption_tree, hf_bap_phone_number_sub_address, tvb, offset + 2, subopt_len - 2, ENC_NA|ENC_ASCII);
3465             } else {
3466                 expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
3467                     "Invalid suboption length: %u (must be > 2)", subopt_len);
3468             }
3469             break;
3470         default:
3471             if (subopt_len > 2) {
3472                 proto_tree_add_item(suboption_tree, hf_bap_unknown_option_data, tvb, offset + 2, subopt_len - 2, ENC_NA);
3473             } else {
3474                 expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
3475                     "Invalid suboption length: %u (must be > 2)", subopt_len);
3476             }
3477             break;
3478         }
3479         offset += subopt_len;
3480         length -= subopt_len;
3481     }
3482 }
3483
3484 static void
3485 dissect_bap_reason_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
3486     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3487 {
3488     if (length > 2) {
3489         proto_tree_add_item(tree, hf_bap_reason, tvb, offset+2, length-2, ENC_NA|ENC_ASCII);
3490     }
3491 }
3492
3493 static void
3494 dissect_bap_link_disc_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
3495     guint length _U_, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3496 {
3497     proto_tree_add_item(tree, hf_bap_link_descriminator, tvb, offset+2, 2, ENC_BIG_ENDIAN);
3498 }
3499
3500 static void
3501 dissect_bap_call_status_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3502     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3503 {
3504     proto_tree *field_tree;
3505
3506     field_tree = proto_tree_add_subtree(tree, tvb, offset, length, *optp->subtree_index, NULL, optp->name);
3507
3508     proto_tree_add_item(field_tree, hf_bap_call_status, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
3509     proto_tree_add_item(field_tree, hf_bap_call_action, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
3510 }
3511
3512 static void
3513 dissect_vsncp_pdnid_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
3514     guint length _U_, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3515 {
3516     proto_tree_add_item(tree, hf_vsncp_pdn_identifier, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3517 }
3518
3519 static const value_string vsncp_attach_vals[] = {
3520     {1, "Initial Attach"},
3521     {3, "Handover Attach"},
3522     {0, NULL}
3523 };
3524
3525 static void
3526 dissect_vsncp_attachtype_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
3527     guint length _U_, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3528 {
3529     proto_tree_add_item(tree, hf_vsncp_attach_type, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3530 }
3531
3532 static const value_string vsncp_pdntype_vals[] = {
3533     {0, "Initial Request by UE"},
3534     {1, "IPv4"},
3535     {2, "IPv6"},
3536     {3, "IPv6/IPv4"},
3537     {0, NULL}
3538 };
3539
3540 static void
3541 dissect_vsncp_pdntype_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
3542     guint length _U_, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3543 {
3544     proto_tree_add_item(tree, hf_vsncp_pdn_type, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3545 }
3546
3547 static const value_string vsncp_errorcode_vals[] = {
3548     {0,  "General Eror"},
3549     {1,  "Unauthorized APN"},
3550     {2,  "PDN Limit Exceeded"},
3551     {3,  "NO PG-W Available"},
3552     {4,  "P-GW Unreachable"},
3553     {5,  "P-GW Reject"},
3554     {6,  "Insufficient Parameters"},
3555     {7,  "Resource Unavailable"},
3556     {8,  "Admin Prohibited"},
3557     {9,  "PDN-ID Already in Use"},
3558     {10, "Subscription Limitation"},
3559     {11, "PDN connection already exists for APN"},
3560     {12, "Emergency services not supported"},
3561     {13, "Reconnect to this APN not allowed"},
3562     {14, "APN congested"},
3563     {0,  NULL}
3564 };
3565
3566 static void
3567 dissect_vsncp_errorcode_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
3568     guint length _U_, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3569 {
3570     proto_tree_add_item(tree, hf_vsncp_error_code, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3571 }
3572
3573 static void
3574 dissect_vsncp_pdnaddress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3575     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3576 {
3577     guint8 pdnaddtype;
3578     proto_tree *field_tree;
3579
3580     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
3581         ett_lcp_options, NULL, "%s: (%d byte%s)",
3582         optp->name, length, plurality(length, "", "s"));
3583
3584     pdnaddtype = tvb_get_guint8(tvb, offset + 2);
3585     proto_tree_add_item(field_tree, hf_vsncp_pdn_type, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
3586
3587     switch (pdnaddtype) {
3588     case 1:
3589         proto_tree_add_ipv4_format(field_tree, hf_vsncp_pdn_ipv4, tvb, offset + 3, 4,
3590             tvb_get_ntohl(tvb, offset + 3), "%s: %s",
3591             val_to_str_const(pdnaddtype, vsncp_pdntype_vals, "Unknown"),
3592             tvb_ip_to_str(tvb, offset + 3));
3593         break;
3594
3595     case 2:
3596     {
3597         struct e_in6_addr *ad = wmem_new0(wmem_packet_scope(),struct e_in6_addr);
3598
3599         tvb_memcpy(tvb, &ad->bytes[8], offset + 3, 8);
3600         proto_tree_add_ipv6_format(field_tree, hf_vsncp_pdn_ipv6, tvb, offset + 3, length - 3, ad->bytes,
3601             "%s: %s", val_to_str_const(pdnaddtype, vsncp_pdntype_vals, "Unknown"),
3602             ip6_to_str(ad));
3603         break;
3604     }
3605
3606     case 3:
3607     {
3608         struct e_in6_addr *ad = wmem_new0(wmem_packet_scope(), struct e_in6_addr);
3609
3610         tvb_memcpy(tvb, &ad->bytes[8], offset + 3, 8);
3611         proto_tree_add_ipv6_format(field_tree, hf_vsncp_pdn_ipv6, tvb, offset + 3, length - 3, ad->bytes,
3612             "%s: %s", val_to_str_const(pdnaddtype, vsncp_pdntype_vals, "Unknown"),
3613             ip6_to_str(ad));
3614         proto_tree_add_ipv4_format(field_tree, hf_vsncp_pdn_ipv4, tvb, offset + 11, length - 11,
3615             tvb_get_ntohl(tvb, offset + 11), "%s: %s", val_to_str_const(pdnaddtype, vsncp_pdntype_vals, "Unknown"),
3616             tvb_ip_to_str(tvb, offset + 11));
3617         break;
3618     }
3619
3620     default:
3621         break;
3622     }
3623 }
3624
3625 static void
3626 dissect_vsncp_ipv4address_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
3627     int offset, guint length _U_, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3628 {
3629     proto_tree_add_item(tree, hf_vsncp_default_router_address, tvb, offset+2, 4, ENC_BIG_ENDIAN);
3630 }
3631
3632 static void
3633 dissect_vsncp_apname_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3634     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3635 {
3636     proto_tree *field_tree;
3637
3638     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
3639         ett_lcp_options, NULL, "%s: (%d byte%s)",
3640         optp->name, length, plurality(length, "", "s"));
3641
3642     if (length > 2) {
3643         guint8 i = 0;
3644         guint8 j = 1;
3645         guint8 lengthofapn;
3646         int off = offset + 2;
3647
3648         while (i < (length - 2)) {
3649             lengthofapn = tvb_get_guint8(tvb, off++);
3650             proto_tree_add_string_format(field_tree, hf_vsncp_access_point_name, tvb, off, lengthofapn,
3651                 tvb_get_string_enc(wmem_packet_scope(), tvb, off, lengthofapn, ENC_ASCII),
3652                 "Label%d (%d byte%s): %s", j++, lengthofapn,
3653                 plurality(lengthofapn, "", "s"),
3654                 tvb_format_text(tvb, off, lengthofapn));
3655             off += lengthofapn;
3656             i += lengthofapn + 1;
3657         }
3658     }
3659 }
3660
3661 static const value_string vsncp_alloc_vals[] = {
3662     {0,   "Null Value (Attach or Handover)"},
3663     {18,  "New PDN type due to network preference"},
3664     {255, "Success"},
3665     {0,   NULL}
3666 };
3667
3668 static void
3669 dissect_vsncp_addressalloc_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
3670     int offset, guint length _U_, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3671 {
3672     proto_tree_add_item(tree, hf_vsncp_address_allocation_cause, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3673 }
3674
3675 static void
3676 dissect_vsncp_apn_ambr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3677                            int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3678 {
3679     proto_tree *field_tree;
3680
3681     if (tree) {
3682
3683         field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
3684                                  ett_lcp_options, NULL, "%s: (%d byte%s)",
3685                                  optp->name, length, plurality(length, "", "s"));
3686
3687         /*de_esm_apn_aggr_max_br(tvb, field_tree, pinfo, offset, length, NULL, 0);*/
3688         proto_tree_add_item(field_tree, hf_vsncp_ambr_data, tvb, offset, length, ENC_NA);
3689     }
3690 }
3691
3692 static void
3693 dissect_vsncp_ipv6_hsgw_lla_iid_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
3694                                     int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3695 {
3696     proto_tree *field_tree;
3697
3698     if (tree) {
3699         field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
3700                                  ett_lcp_options, NULL, "%s: (%d byte%s)",
3701                                  optp->name, length, plurality(length, "", "s"));
3702
3703         proto_tree_add_item(field_tree, hf_vsncp_ipv6_interface_identifier, tvb, offset, length, ENC_NA);
3704     }
3705 }
3706
3707 /* Ch 10.5.6.3 3GPP TS 24.008 version 11.5.0 Release 11 */
3708 static const value_string vsncp_pco_vals[] = {
3709     {0x8021, "IPCP (DNS Address Request)"},
3710     {0x0001, "P-CSCF Address Request (IPv6)"},
3711     {0x0005, "MS Support of Network Requested Bearer Control indicator"},
3712     {0x0003, "DNS Server Address (IPv6)"},
3713     {0x000A, "IP address allocation via NAS signalling"},
3714     {0x000B, "IPv4 address allocation via DHCPv4"},
3715     {0x000D, "DNS Server IPv4 Address Request"},
3716     {0,      NULL}
3717 };
3718
3719 static void
3720 dissect_vsncp_pco_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3721     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3722 {
3723     int off = offset + 3;
3724     guint8  i = 0;
3725     guint8 len;
3726     proto_tree *field_tree;
3727
3728     field_tree = proto_tree_add_subtree_format(tree, tvb, offset, length,
3729         ett_lcp_options, NULL, "%s: (%d byte%s)",
3730         optp->name, length, plurality(length, "", "s"));
3731
3732     while (i < (length - 3)) {
3733         len = tvb_get_guint8(tvb, (off + 2));
3734         proto_tree_add_item(field_tree, hf_vsncp_protocol, tvb, off, 2, ENC_BIG_ENDIAN);
3735         proto_tree_add_item(field_tree, hf_vsncp_protocol_configuration_length, tvb, off + 2, 1, ENC_BIG_ENDIAN);
3736         if (len > 0) {
3737             proto_tree_add_item(field_tree, hf_vsncp_protocol_configuration_data, tvb, off + 3, len, ENC_NA);
3738         }
3739
3740         off += 3 + len;
3741         i += 3 + len;
3742     }
3743 }
3744
3745 static void
3746 dissect_cp(tvbuff_t *tvb, int proto_id, int proto_subtree_index,
3747     const value_string *proto_vals, int options_subtree_index,
3748     const ip_tcp_opt *opts, int nopts, packet_info *pinfo, proto_tree *tree)
3749 {
3750     proto_item *ti;
3751     proto_tree *fh_tree = NULL;
3752     guint8 code;
3753     int length, offset;
3754
3755     code   = tvb_get_guint8(tvb, 0);
3756     length = tvb_get_ntohs(tvb, 2);
3757
3758     col_set_str(pinfo->cinfo, COL_PROTOCOL,
3759         proto_get_protocol_short_name(find_protocol_by_id(proto_id)));
3760     col_set_str(pinfo->cinfo, COL_INFO,
3761         val_to_str_const(code, proto_vals, "Unknown"));
3762
3763     if (tree) {
3764         ti = proto_tree_add_item(tree, proto_id, tvb, 0, length, ENC_NA);
3765         fh_tree = proto_item_add_subtree(ti, proto_subtree_index);
3766         proto_tree_add_uint_format_value(fh_tree, hf_ppp_code, tvb, 0, 1, code,
3767             "%s (%u)", val_to_str_const(code, proto_vals, "Unknown"), code);
3768         proto_tree_add_item(fh_tree, hf_ppp_identifier, tvb, 1, 1, ENC_BIG_ENDIAN);
3769         proto_tree_add_item(fh_tree, hf_ppp_length, tvb, 2, 2, ENC_BIG_ENDIAN);
3770     }
3771     offset = 4;
3772     length -= 4;
3773
3774     switch (code) {
3775     case VNDRSPCFC:
3776         if (tree) {
3777             guint32 oui;
3778             const gchar *manuf;
3779
3780             proto_tree_add_item(fh_tree, hf_ppp_magic_number, tvb, offset, 4,
3781                 ENC_BIG_ENDIAN);
3782             oui = tvb_get_ntoh24(tvb, offset + 4);
3783             ti = proto_tree_add_uint_format_value(fh_tree, hf_ppp_oui, tvb,
3784                 offset + 4, 3, oui, "%02x:%02x:%02x", (oui >> 16) & 0xff,
3785                 (oui >> 8) & 0xff, oui & 0xff);
3786             manuf = uint_get_manuf_name_if_known(oui);
3787             if (manuf){
3788                 proto_item_append_text(ti, "(%s)", manuf);
3789             }else{
3790                 /* check if we have the name in oui_vals */
3791                 manuf = try_val_to_str(oui,oui_vals);
3792                 if (manuf){
3793                     proto_item_append_text(ti, "(%s)", manuf);
3794                 }
3795             }
3796             proto_tree_add_item(fh_tree, hf_ppp_kind, tvb, offset + 7, 1,
3797                 ENC_BIG_ENDIAN);
3798             if (length > 8) {
3799                 proto_tree_add_item(fh_tree, hf_ppp_data, tvb, offset + 8,
3800                     length - 8, ENC_NA);
3801             }
3802         }
3803         break;
3804
3805     case CONFREQ:
3806     case CONFACK:
3807     case CONFNAK:
3808     case CONFREJ:
3809         if (length > 0) {
3810             proto_tree *field_tree;
3811
3812             field_tree = proto_tree_add_subtree_format(fh_tree, tvb, offset, length,
3813                 options_subtree_index, NULL, "Options: (%d byte%s)", length, plurality(length, "", "s"));
3814             dissect_ip_tcp_options(tvb, offset, length, opts, nopts, -1, &PPP_OPT_TYPES,
3815                 &ei_ppp_opt_len_invalid, pinfo, field_tree, NULL, NULL);
3816         }
3817         break;
3818
3819     case CODEREJ:
3820         if (tree && (length > 0)) {
3821             /* TODO: Decode the rejected packet here ... but wait until we have
3822              * a valid capture file with a CODEREJ, since the only capture file
3823              * with CODEREJ packets in it that I know of is pppoe.dump.gz from
3824              * the menagerie, and that file appears to have malformed CODEREJ
3825              * packets as they don't include the Code, Identifier or Length
3826              * fields so it's impossible to do the decode. */
3827             proto_tree_add_bytes_format(fh_tree, hf_ppp_data, tvb, offset,
3828                 length, NULL, "Rejected Packet (%d byte%s): %s", length,
3829                 plurality(length, "", "s"),
3830                 tvb_bytes_to_ep_str(tvb, offset, length));
3831         }
3832         break;
3833
3834     case PROTREJ:       /* LCP only: RFC 1661 */
3835         if (tree) {
3836             proto_tree_add_item(fh_tree, hf_lcp_rej_proto, tvb, offset, 2,
3837                 ENC_BIG_ENDIAN);
3838         }
3839         if (length > 2) {
3840             gboolean save_in_error_pkt;
3841             tvbuff_t *next_tvb;
3842             guint16 protocol;
3843
3844             protocol = tvb_get_ntohs(tvb, offset);
3845             offset += 2;
3846             length -= 2;
3847
3848             /*
3849              * Save the current value of the "we're inside an error packet"
3850              * flag, and set that flag; subdissectors may treat packets that
3851              * are the payload of error packets differently from "real"
3852              * packets.
3853              */
3854             save_in_error_pkt = pinfo->flags.in_error_pkt;
3855             pinfo->flags.in_error_pkt = TRUE;
3856
3857             /* Decode the rejected packet. */
3858             next_tvb = tvb_new_subset_length(tvb, offset, length);
3859             if (!dissector_try_uint(ppp_subdissector_table, protocol, next_tvb,
3860                 pinfo, fh_tree)) {
3861                 call_dissector(data_handle, next_tvb, pinfo, fh_tree);
3862             }
3863
3864             /* Restore the "we're inside an error packet" flag. */
3865             pinfo->flags.in_error_pkt = save_in_error_pkt;
3866         }
3867         break;
3868
3869     case ECHOREQ: /* All 3 are LCP only: RFC 1661 */
3870     case ECHOREP:
3871     case DISCREQ:
3872         if (tree) {
3873             proto_tree_add_item(fh_tree, hf_lcp_magic_number, tvb, offset, 4,
3874                 ENC_BIG_ENDIAN);
3875             if (length > 4) {
3876                 proto_tree_add_item(fh_tree, hf_lcp_data, tvb, offset + 4,
3877                     length - 4, ENC_NA);
3878             }
3879         }
3880         break;
3881
3882     case IDENT:         /* LCP only: RFC 1570 */
3883         if (tree) {
3884             proto_tree_add_item(fh_tree, hf_lcp_magic_number, tvb, offset, 4,
3885                 ENC_BIG_ENDIAN);
3886             if (length > 4) {
3887                 proto_tree_add_item(fh_tree, hf_lcp_message, tvb, offset + 4,
3888                     length - 4, ENC_ASCII|ENC_NA);
3889             }
3890         }
3891         break;
3892
3893     case TIMEREMAIN:    /* LCP only: RFC 1570 */
3894         if (tree) {
3895             guint32 secs_remaining;
3896
3897             proto_tree_add_item(fh_tree, hf_lcp_magic_number, tvb, offset, 4,
3898                 ENC_BIG_ENDIAN);
3899             secs_remaining = tvb_get_ntohl(tvb, offset + 4);
3900             proto_tree_add_uint_format_value(fh_tree, hf_lcp_secs_remaining,
3901                 tvb, offset + 4, 4, secs_remaining, "%u %s", secs_remaining,
3902                 (secs_remaining == 0xffffffff) ? "(forever)" : "seconds");
3903             if (length > 8) {
3904                 proto_tree_add_item(fh_tree, hf_lcp_message, tvb, offset + 8,
3905                     length - 8, ENC_ASCII|ENC_NA);
3906             }
3907         }
3908         break;
3909
3910     case TERMREQ:
3911     case TERMACK:
3912     case RESETREQ:  /* RESETREQ and RESETACK are CCP only: RFC 1962 */
3913     case RESETACK:
3914     default:
3915         if (tree && (length > 0)) {
3916             proto_tree_add_item(fh_tree, hf_ppp_data, tvb, offset, length,
3917                 ENC_NA);
3918         }
3919         break;
3920     }
3921 }
3922
3923 /* Protocol field compression */
3924 #define PFC_BIT 0x01
3925
3926 static void
3927 dissect_ppp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3928     proto_tree *fh_tree, proto_item *ti, int proto_offset)
3929 {
3930     guint16   ppp_prot;
3931     int       proto_len;
3932     tvbuff_t *next_tvb;
3933
3934     /* Make direction information filterable */
3935     if (tree &&
3936         (pinfo->p2p_dir == P2P_DIR_RECV || pinfo->p2p_dir == P2P_DIR_SENT)) {
3937         proto_item *direction_ti = proto_tree_add_uint(tree, hf_ppp_direction,
3938             tvb, 0, 0, pinfo->p2p_dir);
3939         PROTO_ITEM_SET_GENERATED(direction_ti);
3940     }
3941
3942     ppp_prot = tvb_get_guint8(tvb, 0);
3943     if (ppp_prot & PFC_BIT) {
3944         /* Compressed protocol field - just the byte we fetched. */
3945         proto_len = 1;
3946     } else {
3947         /* Uncompressed protocol field - fetch all of it. */
3948         ppp_prot = tvb_get_ntohs(tvb, 0);
3949         proto_len = 2;
3950     }
3951
3952     /* If "ti" is not null, it refers to the top-level "proto_ppp" item
3953        for PPP, and proto_offset is the length of any stuff in the header
3954        preceding the protocol type, e.g. an HDLC header; add the length
3955        of the protocol type field to it, and set the length of that item
3956        to the result. */
3957     if (ti != NULL)
3958         proto_item_set_len(ti, proto_offset + proto_len);
3959
3960     if (tree) {
3961         proto_tree_add_uint(fh_tree, hf_ppp_protocol, tvb, 0, proto_len,
3962             ppp_prot);
3963     }
3964
3965     next_tvb = tvb_new_subset_remaining(tvb, proto_len);
3966
3967     /* do lookup with the subdissector table */
3968     if (!dissector_try_uint(ppp_subdissector_table, ppp_prot, next_tvb, pinfo,
3969         tree)) {
3970         col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", ppp_prot);
3971         col_add_fstr(pinfo->cinfo, COL_INFO, "PPP %s (0x%04x)",
3972             val_to_str_ext_const(ppp_prot, &ppp_vals_ext, "Unknown"),
3973             ppp_prot);
3974         call_dissector(data_handle,next_tvb, pinfo, tree);
3975     }
3976 }
3977
3978 static void
3979 dissect_lcp_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3980 {
3981     dissect_ip_tcp_options(tvb, 0, tvb_reported_length(tvb), lcp_opts,
3982         N_LCP_OPTS, -1, &PPP_OPT_TYPES, &ei_ppp_opt_len_invalid, pinfo, tree, NULL, NULL);
3983 }
3984
3985 /*
3986  * RFC's 1661, 2153 and 1570.
3987  */
3988 static void
3989 dissect_lcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3990 {
3991     dissect_cp(tvb, proto_lcp, ett_lcp, lcp_vals, ett_lcp_options, lcp_opts,
3992         N_LCP_OPTS, pinfo, tree);
3993 }
3994
3995 static void
3996 dissect_vsncp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3997 {
3998     proto_item *ti;
3999     proto_tree *fh_tree = NULL;
4000     proto_tree *field_tree;
4001     guint8 code;
4002     int length, offset;
4003
4004     code = tvb_get_guint8(tvb, 0);
4005     length = tvb_get_ntohs(tvb, 2);
4006
4007     col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSNCP");
4008     col_set_str(pinfo->cinfo, COL_INFO,
4009         val_to_str_const(code, cp_vals, "Unknown"));
4010
4011     if (tree) {
4012         ti = proto_tree_add_item(tree, proto_vsncp, tvb, 0, length, ENC_NA);
4013         fh_tree = proto_item_add_subtree(ti, ett_vsncp);
4014         proto_tree_add_item(fh_tree, hf_vsncp_code, tvb, 0, 1, ENC_BIG_ENDIAN);
4015         proto_tree_add_item(fh_tree, hf_vsncp_identifier, tvb, 1, 1, ENC_BIG_ENDIAN);
4016         proto_tree_add_item(fh_tree, hf_vsncp_length, tvb, 2, 2, ENC_BIG_ENDIAN);
4017         proto_tree_add_item(fh_tree, hf_ppp_oui, tvb, 4, 3, ENC_BIG_ENDIAN);
4018
4019     }
4020     offset = 7;
4021     length -= 7;
4022
4023     switch (code) {
4024     case CONFREQ:
4025     case CONFACK:
4026     case CONFNAK:
4027     case CONFREJ:
4028     case TERMREQ:
4029     case TERMACK:
4030         if (length > 0) {
4031             field_tree = proto_tree_add_subtree_format(fh_tree, tvb, offset, length,
4032                                      ett_vsncp_options, NULL, "Options: (%d byte%s)", length,
4033                                      plurality(length, "", "s"));
4034             dissect_ip_tcp_options(tvb, offset, length, vsncp_opts, N_VSNCP_OPTS, -1, &PPP_OPT_TYPES,
4035                                     &ei_ppp_opt_len_invalid, pinfo, field_tree, NULL, NULL);
4036         }
4037         break;
4038
4039     default:
4040         /* TODO? */
4041         break;
4042     }
4043 }
4044
4045 static void
4046 dissect_vsnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4047 {
4048     proto_item *vsnp_item = NULL;
4049     proto_tree *vsnp_tree = NULL;
4050     guint32     offset    = 0;
4051     tvbuff_t *next_tvb;
4052
4053     col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSNP");
4054
4055     if (tree) {
4056         vsnp_item = proto_tree_add_item(tree, proto_vsnp, tvb, 0, -1, ENC_NA);
4057         vsnp_tree = proto_item_add_subtree(vsnp_item, ett_vsnp);
4058         proto_tree_add_item(vsnp_tree, hf_vsnp_pdnid, tvb, offset, 1,
4059             ENC_BIG_ENDIAN);
4060     }
4061
4062     next_tvb = tvb_new_subset_remaining(tvb, 1);
4063     if (!dissector_try_uint(ppp_subdissector_table, PPP_IP, next_tvb, pinfo,
4064         tree)) {
4065         col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", PPP_IP);
4066         col_add_fstr(pinfo->cinfo, COL_INFO, "PPP %s (0x%04x)",
4067             val_to_str_ext_const(PPP_IP, &ppp_vals_ext, "Unknown"), PPP_IP);
4068         call_dissector(data_handle, next_tvb, pinfo, tree);
4069     }
4070 }
4071
4072 /*
4073  * RFC 1332.
4074  */
4075 static void
4076 dissect_ipcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4077 {
4078     dissect_cp(tvb, proto_ipcp, ett_ipcp, cp_vals, ett_ipcp_options, ipcp_opts,
4079         N_IPCP_OPTS, pinfo, tree);
4080 }
4081
4082 /*
4083  * RFC 3518
4084  */
4085 #define BCP_FCS_PRESENT         0x80
4086 #define BCP_ZEROPAD             0x20
4087 #define BCP_IS_BCONTROL         0x10
4088 #define BCP_PADS_MASK           0x0f
4089
4090 #define BCP_MACT_ETHERNET       1
4091 #define BCP_MACT_802_4          2
4092 #define BCP_MACT_802_5_NONCANON 3
4093 #define BCP_MACT_FDDI_NONCANON  4
4094 #define BCP_MACT_802_5_CANON    11
4095 #define BCP_MACT_FDDI_CANON     12
4096
4097 static const value_string bcp_mac_type_vals[] = {
4098     {BCP_MACT_ETHERNET,       "IEEE 802.3/Ethernet"},
4099     {BCP_MACT_802_4,          "IEEE 802.4"},
4100     {BCP_MACT_802_5_NONCANON, "IEEE 802.5, non-canonical addresses"},
4101     {BCP_MACT_FDDI_NONCANON,  "FDDI, non-canonical addresses"},
4102     {BCP_MACT_802_5_CANON,    "IEEE 802.5, canonical addresses"},
4103     {BCP_MACT_FDDI_CANON,     "FDDI, canonical addresses"},
4104     {0,                       NULL}
4105 };
4106
4107 static void
4108 dissect_bcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4109 {
4110     proto_item *ti;
4111     proto_tree *bcp_tree;
4112     int offset = 0;
4113     guint8 flags;
4114     guint8 mac_type;
4115     gint captured_length, reported_length, pad_length;
4116     tvbuff_t *next_tvb;
4117         static const int * bcp_flags[] = {
4118                 &hf_bcp_fcs_present,
4119                 &hf_bcp_zeropad,
4120                 &hf_bcp_bcontrol,
4121                 &hf_bcp_pads,
4122                 NULL
4123         };
4124
4125     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP BCP");
4126     col_clear(pinfo->cinfo, COL_INFO);
4127
4128     ti = proto_tree_add_item(tree, proto_bcp, tvb, 0, -1, ENC_NA);
4129     bcp_tree = proto_item_add_subtree(ti, ett_bcp);
4130
4131     flags = tvb_get_guint8(tvb, offset);
4132     if (flags & BCP_IS_BCONTROL) {
4133         col_set_str(pinfo->cinfo, COL_INFO, "Bridge control");
4134     }
4135
4136     proto_tree_add_bitmask(bcp_tree, tvb, offset, hf_bcp_flags, ett_bcp_flags, bcp_flags, ENC_NA);
4137     offset++;
4138
4139     mac_type = tvb_get_guint8(tvb, offset);
4140     if (!(flags & BCP_IS_BCONTROL)) {
4141         col_add_str(pinfo->cinfo, COL_INFO,
4142                 val_to_str(mac_type, bcp_mac_type_vals,
4143                 "Unknown MAC type %u"));
4144     }
4145     proto_tree_add_uint(bcp_tree, hf_bcp_mac_type, tvb, offset, 1, mac_type);
4146     offset++;
4147
4148     switch (mac_type) {
4149
4150     case BCP_MACT_802_4:
4151     case BCP_MACT_802_5_NONCANON:
4152     case BCP_MACT_FDDI_NONCANON:
4153     case BCP_MACT_802_5_CANON:
4154     case BCP_MACT_FDDI_CANON:
4155         proto_tree_add_item(bcp_tree, hf_bcp_pad, tvb, offset, 1, ENC_NA);
4156         offset++;
4157         break;
4158
4159     default:
4160         /* TODO? */
4161         break;
4162     }
4163
4164     if (!(flags & BCP_IS_BCONTROL)) {
4165         captured_length = tvb_length_remaining(tvb, offset);
4166         reported_length = tvb_reported_length_remaining(tvb, offset);
4167         pad_length = flags & BCP_PADS_MASK;
4168         if (reported_length >= pad_length) {
4169             reported_length -= pad_length;
4170             if (captured_length > reported_length)
4171                 captured_length = reported_length;
4172             next_tvb = tvb_new_subset(tvb, offset, captured_length,
4173                 reported_length);
4174             switch (mac_type) {
4175
4176             case BCP_MACT_ETHERNET:
4177                 if (flags & BCP_FCS_PRESENT) {
4178                     call_dissector(eth_withfcs_handle, next_tvb, pinfo, tree);
4179                 } else {
4180                     call_dissector(eth_withoutfcs_handle, next_tvb, pinfo,
4181                         tree);
4182                 }
4183                 break;
4184
4185             case BCP_MACT_802_4:
4186             case BCP_MACT_802_5_NONCANON:
4187             case BCP_MACT_FDDI_NONCANON:
4188             case BCP_MACT_802_5_CANON:
4189             case BCP_MACT_FDDI_CANON:
4190                 break;
4191
4192             default:
4193                 call_dissector(data_handle, next_tvb, pinfo, tree);
4194                 break;
4195             }
4196         }
4197     }
4198 }
4199
4200 /*
4201  * RFC 1377.
4202  */
4203 static void
4204 dissect_osinlcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4205 {
4206     dissect_cp(tvb, proto_osinlcp, ett_osinlcp, cp_vals, ett_osinlcp_options,
4207         osinlcp_opts, N_OSINLCP_OPTS, pinfo, tree);
4208 }
4209
4210 /*
4211  * RFC 1962.
4212  */
4213 static void
4214 dissect_ccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4215 {
4216     dissect_cp(tvb, proto_ccp, ett_ccp, ccp_vals, ett_ccp_options, ccp_opts,
4217         N_CCP_OPTS, pinfo, tree);
4218 }
4219
4220 /*
4221  * Callback Control Protocol - see
4222  *
4223  * http://www.linet.gr.jp/~manabe/PPxP/doc/Standards/draft-gidwani-ppp-callback-cp-00.txt
4224  */
4225 static void
4226 dissect_cbcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4227 {
4228     dissect_cp(tvb, proto_cbcp, ett_cbcp, cbcp_vals, ett_cbcp_options,
4229         cbcp_opts, N_CBCP_OPTS, pinfo, tree);
4230 }
4231
4232 /*
4233  * RFC 2125 (BACP and BAP).
4234  */
4235 static void
4236 dissect_bacp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4237 {
4238     dissect_cp(tvb, proto_bacp, ett_bacp, cp_vals, ett_bacp_options, bacp_opts,
4239         N_BACP_OPTS, pinfo, tree);
4240 }
4241
4242 static void
4243 dissect_bap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4244 {
4245     proto_item *ti;
4246     proto_tree *fh_tree = NULL;
4247     proto_tree *field_tree;
4248     guint8 type;
4249     int length, offset;
4250
4251     type = tvb_get_guint8(tvb, 0);
4252     length = tvb_get_ntohs(tvb, 2);
4253
4254     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP BAP");
4255     col_set_str(pinfo->cinfo, COL_INFO,
4256         val_to_str_const(type, bap_vals, "Unknown"));
4257
4258     if (tree) {
4259         ti = proto_tree_add_item(tree, proto_bap, tvb, 0, length, ENC_NA);
4260         fh_tree = proto_item_add_subtree(ti, ett_bap_options);
4261         proto_tree_add_item(fh_tree, hf_bap_type, tvb, 0, 1, ENC_BIG_ENDIAN);
4262         proto_tree_add_item(fh_tree, hf_bap_identifier, tvb, 1, 1, ENC_BIG_ENDIAN);
4263         proto_tree_add_item(fh_tree, hf_bap_length, tvb, 2, 2, ENC_BIG_ENDIAN);
4264     }
4265     offset = 4;
4266     length -= 4;
4267
4268     if (type == BAP_CRES || type == BAP_CBRES ||
4269         type == BAP_LDQRES || type == BAP_CSRES) {
4270         proto_tree_add_item(fh_tree, hf_bap_response_code, tvb, offset, 1, ENC_BIG_ENDIAN);
4271         offset++;
4272         length--;
4273     }
4274
4275     if (length > 0) {
4276         field_tree = proto_tree_add_subtree_format(fh_tree, tvb, offset, length,
4277                                  ett_bap_options, NULL, "Data (%d byte%s)", length, plurality(length, "", "s"));
4278         dissect_ip_tcp_options(tvb, offset, length, bap_opts, N_BAP_OPTS, -1, &PPP_OPT_TYPES,
4279                                 &ei_ppp_opt_len_invalid, pinfo, field_tree, NULL, NULL);
4280     }
4281 }
4282
4283 #if 0 /* TODO? */
4284 static void
4285 dissect_comp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4286 {
4287     proto_item *ti;
4288     proto_tree *comp_data_tree;
4289
4290     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP Comp");
4291     col_set_str(pinfo->cinfo, COL_INFO, "Compressed data");
4292
4293     if (tree) {
4294         ti = proto_tree_add_item(tree, proto_comp_data, tvb, 0, -1, ENC_NA);
4295         comp_data_tree = proto_item_add_subtree(ti, ett_comp_data);
4296     }
4297 }
4298 #else
4299 static void
4300 dissect_comp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4301 {
4302     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP Comp");
4303     col_set_str(pinfo->cinfo, COL_INFO, "Compressed data");
4304
4305     proto_tree_add_item(tree, proto_comp_data, tvb, 0, -1, ENC_NA);
4306 }
4307 #endif
4308
4309 /*
4310  * RFC 3153 (both PPPMuxCP and PPPMux).
4311  */
4312 static void
4313 dissect_pppmuxcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4314 {
4315     dissect_cp(tvb, proto_pppmuxcp, ett_pppmuxcp, pppmuxcp_vals,
4316         ett_pppmuxcp_options, pppmuxcp_opts, N_PPPMUXCP_OPTS,pinfo, tree);
4317 }
4318
4319 #define PPPMUX_FLAGS_MASK          0xc0
4320 #define PPPMUX_PFF_BIT_SET         0x80
4321 #define PPPMUX_LXT_BIT_SET         0x40
4322
4323 static void
4324 dissect_pppmux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4325 {
4326     proto_tree     *mux_tree, *hdr_tree, *sub_tree;
4327     proto_tree     *info_tree;
4328     proto_item     *ti           = NULL;
4329     guint8          flags, byte;
4330     guint16         length;
4331     static guint16  pid;
4332     tvbuff_t       *next_tvb;
4333     int             offset       = 0, length_remaining;
4334     int             length_field = 0, pid_field = 0, hdr_length = 0;
4335     static const int * subframe_flags[] = {
4336         &hf_pppmux_flags_pid,
4337         &hf_pppmux_flags_field_length,
4338         NULL
4339     };
4340
4341     col_set_str(pinfo->cinfo,COL_PROTOCOL, "PPP PPPMux");
4342     col_set_str(pinfo->cinfo, COL_INFO, "PPP Multiplexing");
4343
4344     length_remaining = tvb_reported_length(tvb);
4345
4346     ti = proto_tree_add_item(tree, proto_pppmux, tvb, 0, -1, ENC_NA);
4347     mux_tree = proto_item_add_subtree(ti, ett_pppmux);
4348
4349     while (length_remaining > 0) {
4350         flags = tvb_get_guint8(tvb,offset) & PPPMUX_FLAGS_MASK;
4351
4352         if (flags & PPPMUX_LXT_BIT_SET) {
4353             length = tvb_get_ntohs(tvb,offset) & 0x3fff;
4354             length_field = 2;
4355         } else {
4356             length = tvb_get_guint8(tvb,offset) & 0x3f;
4357             length_field = 1;
4358         }
4359
4360         if (flags & PPPMUX_PFF_BIT_SET) {
4361             byte = tvb_get_guint8(tvb,offset + length_field);
4362             if (byte & PFC_BIT) {             /* Compressed PID field */
4363                 pid = byte;
4364                 pid_field = 1;
4365             } else {                  /* PID field is 2 bytes */
4366                 pid = tvb_get_ntohs(tvb,offset + length_field);
4367                 pid_field = 2;
4368             }
4369         } else {
4370             pid_field = 0;   /* PID field is 0 bytes */
4371             if (!pid) {       /* No Last PID, hence use the default */
4372                 if (pppmux_def_prot_id)
4373                     pid = pppmux_def_prot_id;
4374             }
4375         }
4376
4377         hdr_length = length_field + pid_field;
4378
4379         sub_tree = proto_tree_add_subtree(mux_tree, tvb, offset, length + length_field,
4380             ett_pppmux_subframe, NULL, "PPPMux Sub-frame");
4381         hdr_tree = proto_tree_add_subtree(sub_tree, tvb, offset, hdr_length,
4382             ett_pppmux_subframe_hdr, NULL, "Header field");
4383
4384         proto_tree_add_bitmask(tree, tvb, offset, hf_pppmux_flags, ett_pppmux_subframe_flags, subframe_flags, ENC_BIG_ENDIAN);
4385         proto_tree_add_uint(hdr_tree, hf_pppmux_sub_frame_length, tvb,offset, length_field, length);
4386
4387         ti = proto_tree_add_uint(hdr_tree, hf_pppmux_protocol, tvb,
4388             offset + length_field, pid_field, pid);
4389
4390         /* if protocol is not present in the sub-frame */
4391         if (!(flags & PPPMUX_PFF_BIT_SET)) {
4392             /* mark this item as generated */
4393             PROTO_ITEM_SET_GENERATED(ti);
4394         }
4395
4396         offset += hdr_length;
4397         length_remaining -= hdr_length;
4398         length -= pid_field;
4399
4400         tvb_ensure_bytes_exist (tvb, offset, length);
4401         info_tree = proto_tree_add_subtree(sub_tree, tvb,offset, length,
4402             ett_pppmux_subframe_info, NULL, "Information Field");
4403         next_tvb = tvb_new_subset_length(tvb, offset, length);
4404
4405         if (!dissector_try_uint(ppp_subdissector_table, pid, next_tvb, pinfo,
4406             info_tree)) {
4407             call_dissector(data_handle, next_tvb, pinfo, info_tree);
4408         }
4409         offset += length;
4410         length_remaining -= length;
4411     }
4412 }
4413
4414 /*
4415  * RFC 2508 Internet Protocol Header Compression
4416  */
4417 #define IPHC_CRTP_FH_FLAG_MASK  0xc0
4418 #define IPHC_CRTP_FH_FLAG_POS   6
4419 #define IPHC_CRTP_FH_CID8       1
4420 #define IPHC_CRTP_FH_CID16      3
4421
4422 #define IPHC_CRTP_CS_CID8       1
4423 #define IPHC_CRTP_CS_CID16      2
4424
4425 static const value_string iphc_crtp_fh_flags[] = {
4426     {IPHC_CRTP_FH_CID8,  "8-bit Context Id"},
4427     {IPHC_CRTP_FH_CID16, "16-bit Context Id"},
4428     {0,                  NULL}
4429 };
4430
4431 static const value_string iphc_crtp_cs_flags[] = {
4432     {IPHC_CRTP_CS_CID8,  "8-bit Context Id"},
4433     {IPHC_CRTP_CS_CID16, "16-bit Context Id"},
4434     {0,                  NULL}
4435 };
4436
4437 /*
4438  * 0x61 Packets: Full IP/UDP Header
4439  */
4440 static void
4441 dissect_iphc_crtp_fh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4442 {
4443     proto_tree *fh_tree = NULL, *info_tree;
4444     proto_item *ti = NULL;
4445     guint     ip_hdr_len, flags;
4446     guint     length;
4447     guint     hdr_len;
4448     tvbuff_t *next_tvb;
4449     int       offset_seq;
4450     int       offset_cid;
4451     guint8    ip_version;
4452     guint8    next_protocol;
4453     guchar   *ip_packet;
4454
4455     length = tvb_reported_length(tvb);
4456
4457     col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
4458     col_set_str(pinfo->cinfo, COL_INFO, "Full Header");
4459
4460     /* only dissect IPv4 and UDP */
4461     ip_version = tvb_get_guint8(tvb, 0) >> 4;
4462     flags = (tvb_get_guint8(tvb, 2) & IPHC_CRTP_FH_FLAG_MASK) >>
4463         IPHC_CRTP_FH_FLAG_POS;
4464     next_protocol = tvb_get_guint8(tvb, 9);
4465
4466     if (tree) {
4467         ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
4468             "%s", val_to_str_ext_const(PPP_RTP_FH, &ppp_vals_ext, "Unknown"));
4469         fh_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
4470
4471         proto_tree_add_item(fh_tree, hf_iphc_crtp_fh_flags, tvb, 2, 1,
4472             ENC_BIG_ENDIAN);
4473         proto_tree_add_item(fh_tree, hf_iphc_crtp_gen, tvb, 2, 1,
4474             ENC_BIG_ENDIAN);
4475
4476     }
4477
4478     /* calculate length of IP header, assume IPv4 */
4479     ip_hdr_len = (tvb_get_guint8(tvb, 0) & 0x0f) * 4;
4480
4481     /* calculate total hdr length, assume UDP */
4482     hdr_len = ip_hdr_len + 8;
4483
4484     if (ip_version != 4) {
4485         proto_tree_add_expert_format(fh_tree, pinfo, &ei_iphc_crtp_ip_version, tvb, 3, -1,
4486                             "IP version is %u: the only supported version is 4",
4487                             ip_version);
4488         return;
4489     }
4490
4491     if (next_protocol != IP_PROTO_UDP) {
4492         proto_tree_add_expert_format(fh_tree, pinfo, &ei_iphc_crtp_next_protocol, tvb, 3, -1,
4493                             "Next protocol is %s (%u): the only supported protocol is UDP",
4494                             ipprotostr(next_protocol), next_protocol);
4495         return;
4496     }
4497
4498     /* context id and sequence fields */
4499     switch (flags) {
4500     case IPHC_CRTP_FH_CID8:
4501         offset_cid = 3;
4502         offset_seq = ip_hdr_len + 5;
4503         proto_tree_add_item(fh_tree, hf_iphc_crtp_cid8, tvb, offset_cid, 1,
4504                             ENC_BIG_ENDIAN);
4505         proto_tree_add_item(fh_tree, hf_iphc_crtp_seq, tvb, offset_seq, 1,
4506                             ENC_BIG_ENDIAN);
4507         break;
4508
4509     case IPHC_CRTP_FH_CID16:
4510         offset_seq = 3;
4511         offset_cid = ip_hdr_len + 4;
4512         proto_tree_add_item(fh_tree, hf_iphc_crtp_seq, tvb, offset_seq, 1,
4513                             ENC_BIG_ENDIAN);
4514         proto_tree_add_item(fh_tree, hf_iphc_crtp_cid16, tvb, offset_cid,
4515                             2, ENC_BIG_ENDIAN);
4516         break;
4517
4518     default:
4519         /* TODO? */
4520         break;
4521     }
4522
4523     /* information field */
4524     info_tree = proto_tree_add_subtree(fh_tree, tvb, 0, length, ett_iphc_crtp_info, NULL, "Information Field");
4525
4526     /* XXX: 1: May trap above; 2: really only need to check for ip_hdr_len+6 ?? */
4527     tvb_ensure_bytes_exist (tvb, 0, hdr_len);  /* ip_hdr_len + 8 */
4528
4529     /* allocate a copy of the IP packet */
4530     ip_packet = (guchar *)tvb_memdup(NULL, tvb, 0, length);
4531
4532     /* restore the proper values to the IP and UDP length fields */
4533     ip_packet[2] = length >> 8;
4534     ip_packet[3] = length;
4535
4536     ip_packet[ip_hdr_len + 4] = (length - ip_hdr_len) >> 8;
4537     ip_packet[ip_hdr_len + 5] = (length - ip_hdr_len);
4538
4539     next_tvb = tvb_new_child_real_data(tvb, ip_packet, length, length);
4540     add_new_data_source(pinfo, next_tvb, "Decompressed Data");
4541     tvb_set_free_cb(next_tvb, g_free);
4542
4543     if (!dissector_try_uint(ppp_subdissector_table, PPP_IP, next_tvb, pinfo,
4544         info_tree)) {
4545         call_dissector_only(data_handle, next_tvb, pinfo, info_tree, NULL);
4546     }
4547 }
4548
4549 /*
4550  * 0x2067 Packets:  Compressed UDP with 16-bit Context Identifier
4551  */
4552 static void
4553 dissect_iphc_crtp_cudp16(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4554 {
4555     proto_tree *cudp_tree;
4556     proto_item *ti     = NULL;
4557     guint       length;
4558     guint       hdr_length;
4559     int         offset = 0;
4560
4561     col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
4562     col_set_str(pinfo->cinfo, COL_INFO, "Compressed UDP 16");
4563
4564     length = tvb_reported_length(tvb);
4565
4566     if (tree) {
4567         ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
4568             "%s",
4569             val_to_str_ext_const(PPP_RTP_CUDP16, &ppp_vals_ext, "Unknown"));
4570         cudp_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
4571
4572         hdr_length = 3;
4573
4574         proto_tree_add_item(cudp_tree, hf_iphc_crtp_cid16, tvb, 0, 2,
4575             ENC_BIG_ENDIAN);
4576         proto_tree_add_item(cudp_tree, hf_iphc_crtp_seq, tvb, 2, 1,
4577             ENC_BIG_ENDIAN);
4578
4579         offset += hdr_length;
4580         length -= hdr_length;
4581
4582         proto_tree_add_item(cudp_tree, hf_iphc_crtp_data, tvb, offset, length, ENC_NA);
4583     }
4584 }
4585
4586 /*
4587  * 0x67 Packets:  Compressed UDP with 8-bit Context Identifier
4588  */
4589 static void
4590 dissect_iphc_crtp_cudp8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4591 {
4592     proto_tree *cudp_tree;
4593     proto_item *ti     = NULL;
4594     guint       length;
4595     guint       hdr_length;
4596     int         offset = 0;
4597
4598     col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
4599     col_set_str(pinfo->cinfo, COL_INFO, "Compressed UDP 8");
4600
4601     length = tvb_reported_length(tvb);
4602
4603     if (tree) {
4604         ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
4605             "%s",
4606             val_to_str_ext_const(PPP_RTP_CUDP8, &ppp_vals_ext, "Unknown"));
4607         cudp_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
4608
4609         hdr_length = 2;
4610
4611         proto_tree_add_item(cudp_tree, hf_iphc_crtp_cid8, tvb, 0, 1,
4612             ENC_BIG_ENDIAN);
4613         proto_tree_add_item(cudp_tree, hf_iphc_crtp_seq, tvb, 1, 1,
4614             ENC_BIG_ENDIAN);
4615
4616         offset += hdr_length;
4617         length -= hdr_length;
4618
4619         proto_tree_add_item(cudp_tree, hf_iphc_crtp_data, tvb, offset, length, ENC_NA);
4620     }
4621 }
4622
4623
4624 /*
4625  * 0x2065 Packets:  Context State
4626  */
4627 static void
4628 dissect_iphc_crtp_cs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4629 {
4630     proto_tree *cs_tree;
4631     proto_item *ti     = NULL;
4632     guint8      flags, cnt;
4633     guint       length, cid_size;
4634     guint       offset = 2, hf;
4635
4636     col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
4637     col_set_str(pinfo->cinfo, COL_INFO, "Context State");
4638
4639     if (tree) {
4640         ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
4641             "%s", val_to_str_ext_const(PPP_RTP_CS, &ppp_vals_ext, "Unknown"));
4642
4643         cs_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
4644
4645         proto_tree_add_item(cs_tree, hf_iphc_crtp_cs_flags, tvb, 0, 1,
4646             ENC_BIG_ENDIAN);
4647         proto_tree_add_item(cs_tree, hf_iphc_crtp_cs_cnt, tvb, 1, 1,
4648             ENC_BIG_ENDIAN);
4649
4650         /* calculate required length */
4651         flags = tvb_get_guint8(tvb, 0);
4652         cnt = tvb_get_guint8(tvb, 1);
4653
4654         if (flags == IPHC_CRTP_CS_CID8) {
4655             hf = hf_iphc_crtp_cid8;
4656             cid_size = 1;
4657             length = 3 * cnt;
4658         } else {
4659             hf = hf_iphc_crtp_cid16;
4660             cid_size = 2;
4661             length = 4 * cnt;
4662         }
4663
4664         tvb_ensure_bytes_exist(tvb, offset, length);
4665
4666         while (offset < length) {
4667             proto_tree_add_item(cs_tree, hf, tvb, offset, cid_size,
4668                 ENC_BIG_ENDIAN);
4669             offset += cid_size;
4670             proto_tree_add_item(cs_tree, hf_iphc_crtp_cs_invalid, tvb, offset,
4671                 1, ENC_BIG_ENDIAN);
4672             proto_tree_add_item(cs_tree, hf_iphc_crtp_seq, tvb, offset, 1,
4673                 ENC_BIG_ENDIAN);
4674             ++offset;
4675             proto_tree_add_item(cs_tree, hf_iphc_crtp_gen, tvb, offset, 1,
4676                 ENC_BIG_ENDIAN);
4677             ++offset;
4678         }
4679     }
4680 }
4681
4682
4683 /*
4684  * RFC 3032.
4685  */
4686 static void
4687 dissect_mplscp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4688 {
4689     dissect_cp(tvb, proto_mplscp, ett_mplscp, cp_vals, ett_mplscp_options,
4690         NULL, 0, pinfo, tree);
4691 }
4692
4693 /*
4694  * Cisco Discovery Protocol Control Protocol.
4695  * XXX - where is this documented?
4696  */
4697 static void
4698 dissect_cdpcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4699 {
4700     dissect_cp(tvb, proto_cdpcp, ett_cdpcp, cp_vals, ett_cdpcp_options, NULL,
4701         0, pinfo, tree);
4702 }
4703
4704 static gboolean mp_short_seqno = FALSE; /* Default to long sequence numbers */
4705
4706 #define MP_FRAG_MASK           0xC0
4707 #define MP_FRAG_FIRST          0x80
4708 #define MP_FRAG_LAST           0x40
4709 #define MP_FRAG_RESERVED       0x3f
4710 #define MP_FRAG_RESERVED_SHORT 0x30
4711
4712 static const value_string mp_frag_vals[] = {
4713    { MP_FRAG_FIRST,              "First"       },
4714    { MP_FRAG_LAST,               "Last"        },
4715    { MP_FRAG_FIRST|MP_FRAG_LAST, "First, Last" },
4716    { 0,                 NULL                 }
4717 };
4718
4719 /* According to RFC 1990, the length the MP header isn't indicated anywhere
4720    in the header itself.  It starts out at four bytes and can be
4721    negotiated down to two using LCP.  We currently have a preference
4722    to select short headers.  - gcc & gh
4723 */
4724 static void
4725 dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4726 {
4727     proto_tree  *mp_tree;
4728     proto_item  *ti;
4729     gint        hdrlen;
4730     tvbuff_t    *next_tvb;
4731     static const int * mp_flags[] = {
4732         &hf_mp_frag_first,
4733         &hf_mp_frag_last,
4734         &hf_mp_sequence_num_reserved,
4735         NULL
4736     };
4737     static const int * mp_short_flags[] = {
4738         &hf_mp_frag_first,
4739         &hf_mp_frag_last,
4740         &hf_mp_short_sequence_num_reserved,
4741         NULL
4742     };
4743
4744     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP MP");
4745     col_set_str(pinfo->cinfo, COL_INFO, "PPP Multilink");
4746
4747     ti = proto_tree_add_item(tree, proto_mp, tvb, 0,
4748             mp_short_seqno ? 2 : 4, ENC_NA);
4749     mp_tree = proto_item_add_subtree(ti, ett_mp);
4750
4751     if (mp_short_seqno) {
4752         proto_tree_add_bitmask(mp_tree, tvb, 0, hf_mp_frag, ett_mp_flags, mp_short_flags, ENC_NA);
4753         proto_tree_add_item(mp_tree, hf_mp_short_sequence_num, tvb,  0, 2, ENC_BIG_ENDIAN);
4754     } else {
4755         proto_tree_add_bitmask(mp_tree, tvb, 0, hf_mp_frag, ett_mp_flags, mp_flags, ENC_NA);
4756         proto_tree_add_item(mp_tree, hf_mp_sequence_num, tvb,  1, 3,
4757             ENC_BIG_ENDIAN);
4758     }
4759
4760     hdrlen = mp_short_seqno ? 2 : 4;
4761     if (tvb_reported_length_remaining(tvb, hdrlen) > 0) {
4762         next_tvb = tvb_new_subset_remaining(tvb, hdrlen);
4763         dissect_ppp(next_tvb, pinfo, tree);
4764     }
4765 }
4766
4767 /*
4768  * Handles PPP without HDLC framing, just a protocol field (RFC 1661).
4769  */
4770 static void
4771 dissect_ppp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4772 {
4773     proto_item *ti      = NULL;
4774     proto_tree *fh_tree = NULL;
4775
4776     if (tree) {
4777         ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, -1, ENC_NA);
4778         fh_tree = proto_item_add_subtree(ti, ett_ppp);
4779     }
4780
4781     dissect_ppp_common(tvb, pinfo, tree, fh_tree, ti, 0);
4782 }
4783
4784 static void
4785 dissect_ppp_hdlc_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4786 {
4787     proto_item *ti      = NULL;
4788     proto_tree *fh_tree = NULL;
4789     guint8      byte0;
4790     int         proto_offset;
4791     tvbuff_t   *next_tvb;
4792
4793     byte0 = tvb_get_guint8(tvb, 0);
4794
4795     /* PPP HDLC encapsulation */
4796     if (byte0 == 0xff)
4797         proto_offset = 2;
4798     else {
4799         /* address and control are compressed (NULL) */
4800         proto_offset = 0;
4801     }
4802
4803     /* load the top pane info. This should be overwritten by
4804        the next protocol in the stack */
4805     if (tree) {
4806         ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, -1, ENC_NA);
4807         fh_tree = proto_item_add_subtree(ti, ett_ppp);
4808         if (byte0 == 0xff) {
4809             proto_tree_add_item(fh_tree, hf_ppp_address, tvb, 0, 1,
4810                 ENC_BIG_ENDIAN);
4811             proto_tree_add_item(fh_tree, hf_ppp_control, tvb, 1, 1,
4812                 ENC_BIG_ENDIAN);
4813         }
4814     }
4815
4816     next_tvb = decode_fcs(tvb, fh_tree, ppp_fcs_decode, proto_offset);
4817     dissect_ppp_common(next_tvb, pinfo, tree, fh_tree, ti, proto_offset);
4818 }
4819
4820 /*
4821  * Handles link-layer encapsulations where the frame might be
4822  * a PPP in HDLC-like Framing frame (RFC 1662) or a Cisco HDLC frame.
4823  */
4824 static void
4825 dissect_ppp_hdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4826 {
4827     guint8     byte0;
4828
4829     byte0 = tvb_get_guint8(tvb, 0);
4830     if (byte0 == CHDLC_ADDR_UNICAST || byte0 == CHDLC_ADDR_MULTICAST) {
4831         /* Cisco HDLC encapsulation */
4832         call_dissector(chdlc_handle, tvb, pinfo, tree);
4833         return;
4834     }
4835
4836     /*
4837      * XXX - should we have an exported dissector that always dissects PPP,
4838      * for use when we know the packets are PPP, not CHDLC?
4839      */
4840     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP");
4841     switch (pinfo->p2p_dir) {
4842
4843     case P2P_DIR_SENT:
4844         col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
4845         col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
4846         break;
4847
4848     case P2P_DIR_RECV:
4849         col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
4850         col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
4851         break;
4852
4853     default:
4854         col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "N/A");
4855         col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A");
4856         break;
4857     }
4858
4859     dissect_ppp_hdlc_common(tvb, pinfo, tree);
4860 }
4861
4862 static tvbuff_t*
4863 remove_escape_chars(tvbuff_t *tvb, packet_info *pinfo, int offset, int length)
4864 {
4865     guint8    *buff;
4866     int        i;
4867     int        scanned_len = 0;
4868     guint8     octet;
4869     tvbuff_t  *next_tvb;
4870
4871     buff = (guint8 *)wmem_alloc(pinfo->pool, length);
4872     i = 0;
4873     while (scanned_len < length) {
4874         octet = tvb_get_guint8(tvb, offset);
4875         if (octet == 0x7d) {
4876             offset++;
4877             scanned_len++;
4878             if (scanned_len >= length)
4879                 break;
4880             octet = tvb_get_guint8(tvb, offset);
4881             buff[i] = octet ^ 0x20;
4882         } else {
4883             buff[i] = octet;
4884         }
4885         offset++;
4886         scanned_len++;
4887         i++;
4888     }
4889     if (i == 0) {
4890         return NULL;
4891     }
4892     next_tvb = tvb_new_child_real_data(tvb, buff, i, i);
4893
4894     return next_tvb;
4895 }
4896
4897 /*
4898  * Handles link-layer encapsulations where we have a raw RFC 1662
4899  * HDLC-like asynchronous framing byte stream, and have to
4900  * break the byte stream into frames and remove escapes.
4901  */
4902 static void
4903 dissect_ppp_raw_hdlc( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
4904 {
4905     proto_item *ti;
4906     proto_tree *bs_tree = NULL;
4907     gint        offset, end_offset, data_offset;
4908     int         length, data_length;
4909     tvbuff_t   *ppp_tvb;
4910     gboolean    first   = TRUE;
4911
4912     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP");
4913
4914     if (tree) {
4915         ti = proto_tree_add_item(tree, proto_ppp_hdlc, tvb, 0, -1, ENC_NA);
4916         bs_tree = proto_item_add_subtree(ti, ett_ppp_hdlc_data);
4917     }
4918
4919     /*
4920      * XXX - this needs to handle a PPP frame split over multiple higher-level
4921      * packets.
4922      */
4923
4924     /*
4925      * Look for a frame delimiter.
4926      */
4927     offset = tvb_find_guint8(tvb, 0, -1, 0x7e);
4928     if (offset == -1) {
4929         /*
4930          * None found - this is presumably continued from an earlier
4931          * packet and continued in a later packet.
4932          */
4933         col_set_str(pinfo->cinfo, COL_INFO, "PPP Fragment");
4934         proto_tree_add_item(bs_tree, hf_ppp_hdlc_fragment, tvb, offset, -1, ENC_NA);
4935         offset++;
4936         length = tvb_length_remaining(tvb,offset);
4937         ppp_tvb = remove_escape_chars(tvb, pinfo, offset,length);
4938         if (ppp_tvb != NULL) {
4939             add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
4940             call_dissector(data_handle, ppp_tvb, pinfo, tree);
4941         }
4942         return;
4943     }
4944     if (offset != 0) {
4945         /*
4946          * We have some data preceding the first PPP packet;
4947          * mark it as a PPP fragment.
4948          */
4949         col_set_str(pinfo->cinfo, COL_INFO, "PPP Fragment");
4950         length = offset;
4951         proto_tree_add_item(bs_tree, hf_ppp_hdlc_fragment, tvb, 0, length, ENC_NA);
4952         if (length != 0) {
4953             ppp_tvb = remove_escape_chars(tvb, pinfo, 0, length - 1);
4954             if (ppp_tvb != NULL) {
4955                 add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
4956                 call_dissector(data_handle, ppp_tvb, pinfo, tree);
4957             }
4958         }
4959     }
4960     while (tvb_reported_length_remaining(tvb, offset) > 0) {
4961         /*
4962          * Look for the next frame delimiter.
4963          */
4964         end_offset = tvb_find_guint8(tvb, offset + 1, -1, 0x7e);
4965         if (end_offset == -1) {
4966             /*
4967              * We didn't find one.  This is probably continued in a later
4968              * packet.
4969              */
4970             if (first)
4971                 col_set_str(pinfo->cinfo, COL_INFO, "PPP Fragment");
4972             proto_tree_add_item(bs_tree, hf_ppp_hdlc_fragment, tvb, offset, -1, ENC_NA);
4973             offset++;
4974             length = tvb_length_remaining(tvb, offset);
4975             ppp_tvb = remove_escape_chars(tvb, pinfo, offset, length);
4976             if (ppp_tvb != NULL) {
4977                 add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
4978                 call_dissector(data_handle, ppp_tvb, pinfo, tree);
4979             }
4980             return;
4981         }
4982
4983         data_offset = offset + 1;     /* skip starting frame delimiter */
4984         data_length = end_offset - data_offset;
4985
4986         /*
4987          * Is that frame delimiter immediately followed by another one?
4988          * Some PPP implementations put a frame delimiter at the
4989          * beginning and the end of each frame, although RFC 1662
4990          * appears only to require that there be one frame delimiter
4991          * between adjacent frames:
4992          *
4993          *  Each frame begins and ends with a Flag Sequence, which is the
4994          *  binary sequence 01111110 (hexadecimal 0x7e).  All implementations
4995          *  continuously check for this flag, which is used for frame
4996          *  synchronization.
4997          *
4998          *  Only one Flag Sequence is required between two frames.  Two
4999          *  consecutive Flag Sequences constitute an empty frame, which is
5000          *  silently discarded, and not counted as a FCS error.
5001          *
5002          * If the delimiter at the end of this frame is followed by
5003          * another delimiter, we consider the first delimiter part
5004          * of this frame.
5005          */
5006         if (tvb_offset_exists(tvb, end_offset + 1) &&
5007             tvb_get_guint8(tvb, end_offset+1) == 0x7e) {
5008             end_offset++;
5009         }
5010         length = end_offset - offset;
5011         proto_tree_add_item(bs_tree, hf_ppp_hdlc_data, tvb, offset, length, ENC_NA);
5012         if (length > 1) {
5013             ppp_tvb = remove_escape_chars(tvb, pinfo, data_offset, data_length);
5014             if (ppp_tvb != NULL) {
5015                 add_new_data_source(pinfo, ppp_tvb, "PPP Message");
5016                 dissect_ppp_hdlc_common(ppp_tvb, pinfo, tree);
5017                 first = FALSE;
5018             }
5019         }
5020         offset = end_offset;
5021     }
5022 }
5023
5024 /*
5025  * At least for the PPP/USB captures I've seen, the data either starts with
5026  * 0x7eff03 or 0x7eff7d23 or 0xff03, so this function performs that heuristic
5027  * matching first before calling dissect_ppp_raw_hdlc().  Otherwise, if we call
5028  * it directly for USB captures, some captures like the following will not be
5029  * dissected correctly:
5030  * http://wiki.wireshark.org/SampleCaptures#head-886e340c31ca977f321c921f81cbec4c21bb7738
5031  *
5032  * NOTE: I don't know if these heuristics are sufficient.  Time will tell ...
5033  */
5034 static gboolean
5035 dissect_ppp_usb( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ )
5036 {
5037     /*
5038      * In some cases, the 0x03 normally in byte 3 is escaped so we must look
5039      * for the 2 byte sequence of 0x7d23 instead of 0x03.  The 0x23 is
5040      * generated by 0x20^0x03 per section 4.2 of:
5041      * http://tools.ietf.org/html/rfc1662.html.
5042      */
5043     const guchar buf1[3] = {0x7e, 0xff, 0x03};
5044     const guchar buf2[4] = {0x7e, 0xff, 0x7d, 0x23};
5045     tvbuff_t *next_tvb;
5046
5047     if ((tvb_memeql(tvb, 0, buf2, sizeof(buf2)) == 0) ||
5048         (tvb_memeql(tvb, 0, buf1, sizeof(buf1)) == 0)) {
5049         dissect_ppp_raw_hdlc(tvb, pinfo, tree);
5050     } else if ((tvb_memeql(tvb, 0, &buf1[1], sizeof(buf1) - 1) == 0) ||
5051         (tvb_memeql(tvb, 0, &buf2[1], sizeof(buf2) - 1) == 0)) {
5052         /* It's missing the 0x7e framing character.  What TODO?
5053          * Should we try faking it by sticking 0x7e in front?  Or try telling
5054          * dissect_ppp_raw_hdlc() NOT to look for the 0x7e frame deliminator?
5055          * Or is this a bug in libpcap (used 1.1.0)?
5056          * Or a bug in the Linux kernel (tested with 2.6.24.4)  Or a bug in
5057          * usbmon?  Or is the data we're looking at really just part of the
5058          * payload and not control data?  Well, at least in my case it's
5059          * definitely not, but not sure if this is always the case. Is this
5060          * issue applicable only to PPP/USB or PPP/XYZ, in which case a more
5061          * general solution should be found?
5062          */
5063         /* For now, just try skipping the framing I guess??? */
5064         if (tvb_get_guint8(tvb, 1) == 0x03)
5065             next_tvb = tvb_new_subset_remaining(tvb, 2);
5066         else
5067             next_tvb = tvb_new_subset_remaining(tvb, 3);
5068         dissect_ppp(next_tvb, pinfo, tree);
5069     } else if (tvb_get_guint8(tvb, 0) == 0x7e) {
5070         /* Well, let's guess that since the 1st byte is 0x7e that it really is
5071          * a PPP frame, and the address and control bytes are compressed (NULL)
5072          * per http://tools.ietf.org/html/rfc1662, section 3.2. */
5073         next_tvb = tvb_new_subset_remaining(tvb, 1);
5074         dissect_ppp_hdlc_common(next_tvb, pinfo, tree);
5075     } else
5076         return (FALSE);
5077     return (TRUE);
5078 }
5079
5080 void
5081 proto_register_ppp_raw_hdlc(void)
5082 {
5083     static hf_register_info hf[] = {
5084       /* Generated from convert_proto_tree_add_text.pl */
5085       { &hf_ppp_hdlc_fragment, { "PPP Fragment", "ppp_hdlc.fragment", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5086       { &hf_ppp_hdlc_data, { "PPP Data", "ppp_hdlc.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5087     };
5088
5089     static gint *ett[] = {
5090         &ett_ppp_hdlc_data
5091     };
5092
5093     proto_ppp_hdlc = proto_register_protocol("PPP In HDLC-Like Framing",
5094         "PPP-HDLC", "ppp_hdlc");
5095     proto_register_subtree_array(ett, array_length(ett));
5096     proto_register_field_array(proto_ppp_hdlc, hf, array_length(hf));
5097 }
5098
5099 void
5100 proto_reg_handoff_ppp_raw_hdlc(void)
5101 {
5102     dissector_handle_t ppp_raw_hdlc_handle;
5103
5104     ppp_raw_hdlc_handle = create_dissector_handle(dissect_ppp_raw_hdlc,
5105         proto_ppp);
5106     dissector_add_uint("gre.proto", ETHERTYPE_CDMA2000_A10_UBS,
5107         ppp_raw_hdlc_handle);
5108     dissector_add_uint("gre.proto", ETHERTYPE_3GPP2, ppp_raw_hdlc_handle);
5109
5110     heur_dissector_add("usb.bulk", dissect_ppp_usb, proto_ppp);
5111 }
5112
5113 /*
5114  * Handles PAP just as a protocol field
5115  */
5116 static void
5117 dissect_pap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5118 {
5119     proto_item *ti, *data_ti;
5120     proto_tree *fh_tree, *data_tree = NULL;
5121     guint8      code;
5122     gchar      *peer_id, *password, *message;
5123     guint8      peer_id_length, password_length, message_length;
5124     int         offset              = 0;
5125
5126     code = tvb_get_guint8(tvb, 0);
5127
5128     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP PAP");
5129     col_set_str(pinfo->cinfo, COL_INFO,
5130                 val_to_str_const(code, pap_vals, "Unknown"));
5131
5132     ti = proto_tree_add_item(tree, proto_pap, tvb, 0, -1, ENC_NA);
5133     fh_tree = proto_item_add_subtree(ti, ett_pap);
5134
5135     proto_tree_add_item(fh_tree, hf_pap_code, tvb, offset, 1,
5136                         ENC_BIG_ENDIAN);
5137     offset++;
5138
5139     proto_tree_add_item(fh_tree, hf_pap_identifier, tvb, offset, 1,
5140                         ENC_BIG_ENDIAN);
5141     offset++;
5142
5143     proto_tree_add_item(fh_tree, hf_pap_length, tvb, offset, 2,
5144                         ENC_BIG_ENDIAN);
5145     offset += 2;
5146
5147     data_ti = proto_tree_add_item(fh_tree, hf_pap_data, tvb, offset, -1,
5148                                   ENC_NA);
5149     data_tree = proto_item_add_subtree(data_ti, ett_pap_data);
5150
5151     switch (code) {
5152     case CONFREQ:
5153         proto_tree_add_item(data_tree, hf_pap_peer_id_length, tvb, offset,
5154                             1, ENC_BIG_ENDIAN);
5155         peer_id_length = tvb_get_guint8(tvb, offset);
5156         offset++;
5157
5158         proto_tree_add_item(data_tree, hf_pap_peer_id, tvb, offset,
5159                             peer_id_length, ENC_ASCII|ENC_NA);
5160         peer_id = tvb_format_text(tvb, offset, peer_id_length);
5161         offset += peer_id_length;
5162
5163         proto_tree_add_item(data_tree, hf_pap_password_length, tvb, offset,
5164                             1, ENC_BIG_ENDIAN);
5165         password_length = tvb_get_guint8(tvb, offset);
5166         offset++;
5167
5168         proto_tree_add_item(data_tree, hf_pap_password, tvb, offset,
5169                             password_length, ENC_ASCII|ENC_NA);
5170         password = tvb_format_text(tvb, offset, password_length);
5171
5172         col_append_fstr(pinfo->cinfo, COL_INFO,
5173                         " (Peer-ID='%s', Password='%s')", peer_id, password);
5174         break;
5175
5176     case CONFACK:
5177     case CONFNAK:
5178         proto_tree_add_item(data_tree, hf_pap_message_length, tvb, offset,
5179                             1, ENC_BIG_ENDIAN);
5180         message_length = tvb_get_guint8(tvb, offset);
5181         offset +=1;
5182
5183         proto_tree_add_item(data_tree, hf_pap_message, tvb, offset,
5184                             message_length, ENC_ASCII|ENC_NA);
5185         message = tvb_format_text(tvb, offset, message_length);
5186
5187         col_append_fstr(pinfo->cinfo, COL_INFO, " (Message='%s')",
5188                         message);
5189         break;
5190
5191     default:
5192         proto_tree_add_item(data_tree, hf_pap_stuff, tvb, offset, -1,
5193                             ENC_NA);
5194         break;
5195     }
5196 }
5197
5198 /*
5199  * RFC 1994
5200  * Handles CHAP just as a protocol field
5201  */
5202 static void
5203 dissect_chap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5204 {
5205     proto_item *ti      = NULL;
5206     proto_tree *fh_tree = NULL;
5207     proto_item *tf;
5208     proto_tree *field_tree;
5209     guint8      code, value_size;
5210     guint32     length;
5211     int         offset;
5212
5213     code = tvb_get_guint8(tvb, 0);
5214     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP CHAP");
5215     col_set_str(pinfo->cinfo, COL_INFO,
5216         val_to_str_const(code, chap_vals, "Unknown"));
5217
5218     if (tree) {
5219         /* Create CHAP protocol tree */
5220         ti = proto_tree_add_item(tree, proto_chap, tvb, 0, -1, ENC_NA);
5221         fh_tree = proto_item_add_subtree(ti, ett_chap);
5222
5223         proto_tree_add_item(fh_tree, hf_chap_code, tvb, 0, 1, ENC_BIG_ENDIAN);
5224         proto_tree_add_item(fh_tree, hf_chap_identifier, tvb, 1, 1,
5225             ENC_BIG_ENDIAN);
5226     }
5227
5228     /* Length - make sure it's valid */
5229     length = tvb_get_ntohs(tvb, 2);
5230     if (length < 4) {
5231         proto_tree_add_uint_format_value(fh_tree, hf_chap_length, tvb, 2, 2,
5232                 length, "%u (invalid, must be >= 4)", length);
5233         return;
5234     }
5235     proto_item_set_len(ti, length);
5236     if (tree) {
5237         proto_tree_add_item(fh_tree, hf_chap_length, tvb, 2, 2,
5238             ENC_BIG_ENDIAN);
5239     }
5240
5241     offset = 4;     /* Offset moved to after length field */
5242     length -= 4;    /* Length includes previous 4 bytes, subtract */
5243
5244     switch (code) {
5245     /* Challenge or Response data */
5246     case CHAP_CHAL:
5247     case CHAP_RESP:
5248         if (length > 0) {
5249             guint value_offset = 0;
5250             guint name_offset  = 0, name_size = 0;
5251
5252             /* Create data subtree */
5253             tf = proto_tree_add_item(fh_tree, hf_chap_data, tvb, offset,
5254                                      length, ENC_NA);
5255             field_tree = proto_item_add_subtree(tf, ett_chap_data);
5256             length--;
5257
5258             /* Value size */
5259             value_size = tvb_get_guint8(tvb, offset);
5260             if (value_size > length) {
5261                 proto_tree_add_uint_format_value(field_tree, hf_chap_value_size, tvb, offset, 1,
5262                                     value_size, "%d byte%s (invalid, must be <= %u)",
5263                                     value_size, plurality(value_size, "", "s"), length);
5264                 return;
5265             }
5266             proto_tree_add_item(field_tree, hf_chap_value_size, tvb,
5267                                 offset, 1, ENC_BIG_ENDIAN);
5268             offset++;
5269
5270             /* Value */
5271             if (length > 0) {
5272                 value_offset = offset;
5273                 proto_tree_add_item(field_tree, hf_chap_value, tvb, offset,
5274                                     value_size, ENC_NA);
5275
5276                 /* Move along value_size bytes */
5277                 offset += value_size;
5278                 length -= value_size;
5279
5280                 /* Find name in remaining bytes */
5281                 if (length > 0) {
5282                     tvb_ensure_bytes_exist(tvb, offset, length);
5283                     proto_tree_add_item(field_tree, hf_chap_name, tvb,
5284                                         offset, length, ENC_ASCII|ENC_NA);
5285                     name_offset = offset;
5286                     name_size = length;
5287                 }
5288
5289                 /* Show name and value in info column */
5290                 col_append_fstr(pinfo->cinfo, COL_INFO,
5291                                 " (NAME='%s%s', VALUE=0x%s)",
5292                                 tvb_format_text(tvb, name_offset,
5293                                                 (name_size > 20) ? 20 : name_size),
5294                                 (name_size > 20) ? "..." : "",
5295                                 tvb_bytes_to_ep_str(tvb, value_offset, value_size));
5296             }
5297         }
5298         break;
5299
5300     /* Success or Failure data */
5301     case CHAP_SUCC:
5302     case CHAP_FAIL:
5303         if (tree) {
5304             if (length > 0) {
5305                 proto_tree_add_item(fh_tree, hf_chap_message, tvb, offset,
5306                     length, ENC_ASCII|ENC_NA);
5307             }
5308         }
5309
5310         /* Show message in info column */
5311         col_append_fstr(pinfo->cinfo, COL_INFO, " (MESSAGE='%s')",
5312             tvb_format_text(tvb, offset, length));
5313         break;
5314
5315     /* Code from unknown code type... */
5316     default:
5317         if (length > 0)
5318             proto_tree_add_item(fh_tree, hf_chap_stuff, tvb, offset, length, ENC_NA);
5319         break;
5320     }
5321 }
5322
5323 /*
5324  * RFC 2472.
5325  */
5326 static void
5327 dissect_ipv6cp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5328 {
5329     dissect_cp(tvb, proto_ipv6cp, ett_ipv6cp, cp_vals, ett_ipv6cp_options,
5330         ipv6cp_opts, N_IPV6CP_OPTS, pinfo, tree);
5331 }
5332
5333 static void
5334 dissect_ipv6cp_if_id_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb, int offset,
5335     guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
5336 {
5337     proto_tree_add_bytes_format_value(tree, hf_ipv6cp_interface_identifier, tvb, offset+2, length-2,
5338         NULL, "%s", tvb_bytes_to_ep_str_punct(tvb, offset+2, 8, ':'));
5339 }
5340
5341 void
5342 proto_register_ppp(void)
5343 {
5344     static hf_register_info hf[] = {
5345         { &hf_ppp_direction,
5346             { "Direction", "ppp.direction", FT_UINT8, BASE_DEC,
5347                 VALS(ppp_direction_vals), 0x0, "PPP direction", HFILL }},
5348         { &hf_ppp_address,
5349             { "Address", "ppp.address", FT_UINT8, BASE_HEX,
5350                 NULL, 0x0, NULL, HFILL }},
5351         { &hf_ppp_control,
5352             { "Control", "ppp.control", FT_UINT8, BASE_HEX,
5353                 NULL, 0x0, NULL, HFILL }},
5354         { &hf_ppp_protocol,
5355             { "Protocol", "ppp.protocol", FT_UINT16, BASE_HEX|BASE_EXT_STRING,
5356                 &ppp_vals_ext, 0x0, NULL, HFILL }},
5357         { &hf_ppp_code,
5358             { "Code", "ppp.code", FT_UINT8, BASE_DEC,
5359                 NULL, 0x0, NULL, HFILL }},
5360         { &hf_ppp_identifier,
5361             { "Identifier", "ppp.identifier", FT_UINT8, BASE_DEC_HEX,
5362                 NULL, 0x0, NULL, HFILL }},
5363         { &hf_ppp_length,
5364             { "Length", "ppp.length", FT_UINT16, BASE_DEC,
5365                 NULL, 0x0, NULL, HFILL }},
5366         { &hf_ppp_magic_number,
5367             { "Magic Number", "ppp.magic_number", FT_UINT32, BASE_HEX,
5368                 NULL, 0x0, NULL, HFILL }},
5369         { &hf_ppp_oui,
5370             { "OUI", "ppp.oui", FT_UINT24, BASE_HEX,
5371                 VALS(oui_vals), 0x0, NULL, HFILL }},
5372         { &hf_ppp_kind,
5373             { "Kind", "ppp.kind", FT_UINT8, BASE_DEC_HEX,
5374                 NULL, 0x0, NULL, HFILL }},
5375         { &hf_ppp_data,
5376             { "Data", "ppp.data", FT_BYTES, BASE_NONE,
5377                 NULL, 0x0, NULL, HFILL }},
5378         { &hf_ppp_opt_type,
5379             { "Type", "ppp.opt.type", FT_UINT8, BASE_DEC,
5380                 NULL, 0x0, NULL, HFILL}},
5381         { &hf_ppp_opt_type_copy,
5382             { "Copy on fragmentation", "ppp.opt.type.copy", FT_BOOLEAN, 8,
5383                 TFS(&tfs_yes_no), IPOPT_COPY_MASK, NULL, HFILL}},
5384         { &hf_ppp_opt_type_class,
5385             { "Class", "ppp.opt.type.class", FT_UINT8, BASE_DEC,
5386                 VALS(ipopt_type_class_vals), IPOPT_CLASS_MASK, NULL, HFILL}},
5387         { &hf_ppp_opt_type_number,
5388             { "Number", "ppp.opt.type.number", FT_UINT8, BASE_DEC,
5389                 VALS(ipopt_type_number_vals), IPOPT_NUMBER_MASK, NULL, HFILL}},
5390       /* Generated from convert_proto_tree_add_text.pl */
5391       { &hf_ppp_fcs_16, { "FCS 16", "ppp.fcs_16", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5392       { &hf_ppp_fcs_32, { "FCS 32", "ppp.fcs_32", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5393     };
5394     static gint *ett[] = {
5395         &ett_ppp,
5396         &ett_ppp_opt_type
5397     };
5398     static ei_register_info ei[] = {
5399         { &ei_ppp_opt_len_invalid, { "ppp.opt.len.invalid", PI_PROTOCOL, PI_WARN, "Invalid length for option", EXPFILL }},
5400     };
5401
5402     module_t *ppp_module;
5403     expert_module_t* expert_ppp;
5404
5405     proto_ppp = proto_register_protocol("Point-to-Point Protocol", "PPP",
5406         "ppp");
5407     proto_register_field_array(proto_ppp, hf, array_length(hf));
5408     proto_register_subtree_array(ett, array_length(ett));
5409     expert_ppp = expert_register_protocol(proto_ppp);
5410     expert_register_field_array(expert_ppp, ei, array_length(ei));
5411
5412     /* subdissector code */
5413     ppp_subdissector_table = register_dissector_table("ppp.protocol",
5414         "PPP protocol", FT_UINT16, BASE_HEX);
5415
5416     register_dissector("ppp_hdlc", dissect_ppp_hdlc, proto_ppp);
5417     register_dissector("ppp_lcp_options", dissect_lcp_options, proto_ppp);
5418     register_dissector("ppp", dissect_ppp, proto_ppp);
5419
5420     /* Register the preferences for the ppp protocol */
5421     ppp_module = prefs_register_protocol(proto_ppp, NULL);
5422
5423     prefs_register_enum_preference(ppp_module, "fcs_type",
5424         "PPP Frame Checksum Type",
5425         "The type of PPP frame checksum (none, 16-bit, 32-bit)",
5426         &ppp_fcs_decode, fcs_options, FALSE);
5427     prefs_register_bool_preference(ppp_module, "decompress_vj",
5428         "Decompress Van Jacobson-compressed frames",
5429         "Whether Van Jacobson-compressed PPP frames should be decompressed",
5430         &ppp_vj_decomp);
5431     prefs_register_uint_preference(ppp_module, "default_proto_id",
5432         "PPPMuxCP Default PID (in hex)",
5433         "Default Protocol ID to be used for PPPMuxCP",
5434         16, &pppmux_def_prot_id);
5435 }
5436
5437 void
5438 proto_reg_handoff_ppp(void)
5439 {
5440     dissector_handle_t ppp_hdlc_handle, ppp_handle;
5441
5442     /*
5443      * Get a handle for the CHDLC dissector.
5444      */
5445     chdlc_handle = find_dissector("chdlc");
5446     data_handle = find_dissector("data");
5447
5448     ppp_handle = find_dissector("ppp");
5449     dissector_add_uint("fr.nlpid", NLPID_PPP, ppp_handle);
5450
5451     ppp_hdlc_handle = find_dissector("ppp_hdlc");
5452     dissector_add_uint("wtap_encap", WTAP_ENCAP_PPP, ppp_hdlc_handle);
5453     dissector_add_uint("wtap_encap", WTAP_ENCAP_PPP_WITH_PHDR,
5454         ppp_hdlc_handle);
5455     dissector_add_uint("sll.ltype", LINUX_SLL_P_PPPHDLC, ppp_hdlc_handle);
5456     dissector_add_uint("osinl.excl", NLPID_PPP, ppp_handle);
5457     dissector_add_uint("gre.proto", ETHERTYPE_PPP, ppp_hdlc_handle);
5458     dissector_add_uint("juniper.proto", JUNIPER_PROTO_PPP, ppp_handle);
5459         dissector_add_uint("sflow_245.header_protocol", SFLOW_245_HEADER_PPP, ppp_hdlc_handle);
5460 }
5461
5462 void
5463 proto_register_mp(void)
5464 {
5465     static hf_register_info hf[] = {
5466         { &hf_mp_frag,
5467             { "Fragment", "mp.frag", FT_UINT8, BASE_HEX,
5468                 VALS(mp_frag_vals), MP_FRAG_MASK, NULL, HFILL }},
5469         { &hf_mp_frag_first,
5470             { "First fragment", "mp.first", FT_BOOLEAN, 8,
5471                 TFS(&tfs_yes_no), MP_FRAG_FIRST, NULL, HFILL }},
5472         { &hf_mp_frag_last,
5473             { "Last fragment", "mp.last", FT_BOOLEAN, 8,
5474                 TFS(&tfs_yes_no), MP_FRAG_LAST, NULL, HFILL }},
5475         { &hf_mp_sequence_num,
5476             { "Sequence number", "mp.seq", FT_UINT24, BASE_DEC,
5477                 NULL, 0x0, NULL, HFILL }},
5478         { &hf_mp_sequence_num_reserved,
5479             { "Reserved", "mp.sequence_num_reserved", FT_BOOLEAN, 8,
5480                 NULL, MP_FRAG_RESERVED, NULL, HFILL }},
5481         { &hf_mp_short_sequence_num,
5482             { "Short Sequence number", "mp.sseq", FT_UINT16, BASE_DEC,
5483                 NULL, 0x0FFF, NULL, HFILL }},
5484         { &hf_mp_short_sequence_num_reserved,
5485             { "Reserved", "mp.short_sequence_num_reserved", FT_BOOLEAN, 8,
5486                 NULL, MP_FRAG_RESERVED_SHORT, NULL, HFILL }},
5487     };
5488     static gint *ett[] = {
5489         &ett_mp,
5490         &ett_mp_flags
5491     };
5492
5493     module_t *mp_module;
5494
5495     proto_mp = proto_register_protocol("PPP Multilink Protocol", "PPP MP",
5496         "mp");
5497     proto_register_field_array(proto_mp, hf, array_length(hf));
5498     proto_register_subtree_array(ett, array_length(ett));
5499
5500     /* Register the preferences for the PPP multilink protocol */
5501     mp_module = prefs_register_protocol(proto_mp, NULL);
5502
5503     prefs_register_bool_preference(mp_module, "short_seqno",
5504         "Short sequence numbers",
5505         "Whether PPP Multilink frames use 12-bit sequence numbers",
5506         &mp_short_seqno);
5507 }
5508
5509 void
5510 proto_reg_handoff_mp(void)
5511 {
5512     dissector_handle_t mp_handle;
5513
5514     mp_handle = create_dissector_handle(dissect_mp, proto_mp);
5515     dissector_add_uint("ppp.protocol", PPP_MP, mp_handle);
5516 }
5517
5518 void
5519 proto_register_lcp(void)
5520 {
5521     static hf_register_info hf[] = {
5522         { &hf_lcp_magic_number,
5523             { "Magic Number", "lcp.magic_number", FT_UINT32, BASE_HEX,
5524                 NULL, 0x0, NULL, HFILL }},
5525         { &hf_lcp_data,
5526             { "Data", "lcp.data", FT_BYTES, BASE_NONE,
5527                 NULL, 0x0, NULL, HFILL }},
5528         { &hf_lcp_message,
5529             { "Message", "lcp.message", FT_STRING, BASE_NONE,
5530                 NULL, 0x0, NULL, HFILL }},
5531         { &hf_lcp_secs_remaining,
5532             { "Seconds Remaining", "lcp.secs_remaining", FT_UINT32, BASE_DEC,
5533                 NULL, 0x0, NULL, HFILL }},
5534         { &hf_lcp_rej_proto,
5535             { "Rejected Protocol", "lcp.rej_proto", FT_UINT16,
5536                 BASE_HEX | BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
5537         { &hf_lcp_opt_type,
5538             { "Type", "lcp.opt.type", FT_UINT8, BASE_DEC,
5539                 NULL, 0x0, NULL, HFILL }},
5540         { &hf_lcp_opt_length,
5541             { "Length", "lcp.opt.length", FT_UINT8, BASE_DEC,
5542                 NULL, 0x0, NULL, HFILL }},
5543         { &hf_lcp_opt_oui,
5544             { "OUI", "lcp.opt.oui", FT_UINT24, BASE_HEX,
5545                 NULL, 0x0, NULL, HFILL }},
5546         { &hf_lcp_opt_kind,
5547             { "Kind", "lcp.opt.kind", FT_UINT8, BASE_DEC_HEX,
5548                 NULL, 0x0, NULL, HFILL }},
5549         { &hf_lcp_opt_data,
5550             { "Data", "lcp.opt.data", FT_BYTES, BASE_NONE,
5551                 NULL, 0x0, NULL, HFILL }},
5552         { &hf_lcp_opt_mru,
5553             { "Maximum Receive Unit", "lcp.opt.mru", FT_UINT16, BASE_DEC,
5554                 NULL, 0x0, NULL, HFILL }},
5555         { &hf_lcp_opt_asyncmap,
5556             { "Async Control Character Map", "lcp.opt.asyncmap", FT_UINT32,
5557                 BASE_HEX, NULL, 0x0, NULL, HFILL }},
5558         { &hf_lcp_opt_asyncmap_nul,
5559             { "NUL", "lcp.opt.asyncmap.nul", FT_BOOLEAN, 32,
5560                 NULL, 0x00000001, NULL, HFILL }},
5561         { &hf_lcp_opt_asyncmap_soh,
5562             { "SOH", "lcp.opt.asyncmap.soh", FT_BOOLEAN, 32,
5563                 NULL, 0x00000002, NULL, HFILL }},
5564         { &hf_lcp_opt_asyncmap_stx,
5565             { "STX", "lcp.opt.asyncmap.stx", FT_BOOLEAN, 32,
5566                 NULL, 0x00000004, NULL, HFILL }},
5567         { &hf_lcp_opt_asyncmap_etx,
5568             { "ETX", "lcp.opt.asyncmap.etx", FT_BOOLEAN, 32,
5569                 NULL, 0x00000008, NULL, HFILL }},
5570         { &hf_lcp_opt_asyncmap_eot,
5571             { "EOT", "lcp.opt.asyncmap.eot", FT_BOOLEAN, 32,
5572                 NULL, 0x00000010, NULL, HFILL }},
5573         { &hf_lcp_opt_asyncmap_enq,
5574             { "ENQ", "lcp.opt.asyncmap.enq", FT_BOOLEAN, 32,
5575                 NULL, 0x00000020, NULL, HFILL }},
5576         { &hf_lcp_opt_asyncmap_ack,
5577             { "ACK", "lcp.opt.asyncmap.ack", FT_BOOLEAN, 32,
5578                 NULL, 0x00000040, NULL, HFILL }},
5579         { &hf_lcp_opt_asyncmap_bel,
5580             { "BEL", "lcp.opt.asyncmap.bel", FT_BOOLEAN, 32,
5581                 NULL, 0x00000080, NULL, HFILL }},
5582         { &hf_lcp_opt_asyncmap_bs,
5583             { "BS", "lcp.opt.asyncmap.bs", FT_BOOLEAN, 32,
5584                 NULL, 0x00000100, NULL, HFILL }},
5585         { &hf_lcp_opt_asyncmap_ht,
5586             { "HT", "lcp.opt.asyncmap.ht", FT_BOOLEAN, 32,
5587                 NULL, 0x00000200, NULL, HFILL }},
5588         { &hf_lcp_opt_asyncmap_lf,
5589             { "LF", "lcp.opt.asyncmap.lf", FT_BOOLEAN, 32,
5590                 NULL, 0x00000400, NULL, HFILL }},
5591         { &hf_lcp_opt_asyncmap_vt,
5592             { "VT", "lcp.opt.asyncmap.vt", FT_BOOLEAN, 32,
5593                 NULL, 0x00000800, NULL, HFILL }},
5594         { &hf_lcp_opt_asyncmap_ff,
5595             { "FF", "lcp.opt.asyncmap.ff", FT_BOOLEAN, 32,
5596                 NULL, 0x00001000, NULL, HFILL }},
5597         { &hf_lcp_opt_asyncmap_cr,
5598             { "CR", "lcp.opt.asyncmap.cr", FT_BOOLEAN, 32,
5599                 NULL, 0x00002000, NULL, HFILL }},
5600         { &hf_lcp_opt_asyncmap_so,
5601             { "SO", "lcp.opt.asyncmap.so", FT_BOOLEAN, 32,
5602                 NULL, 0x00004000, NULL, HFILL }},
5603         { &hf_lcp_opt_asyncmap_si,
5604             { "SI", "lcp.opt.asyncmap.si", FT_BOOLEAN, 32,
5605                 NULL, 0x00008000, NULL, HFILL }},
5606         { &hf_lcp_opt_asyncmap_dle,
5607             { "DLE", "lcp.opt.asyncmap.dle", FT_BOOLEAN, 32,
5608                 NULL, 0x00010000, NULL, HFILL }},
5609         { &hf_lcp_opt_asyncmap_dc1,
5610             { "DC1 (XON)", "lcp.opt.asyncmap.dc1", FT_BOOLEAN, 32,
5611                 NULL, 0x00020000, NULL, HFILL }},
5612         { &hf_lcp_opt_asyncmap_dc2,
5613             { "DC2", "lcp.opt.asyncmap.dc2", FT_BOOLEAN, 32,
5614                 NULL, 0x00040000, NULL, HFILL }},
5615         { &hf_lcp_opt_asyncmap_dc3,
5616             { "DC3 (XOFF)", "lcp.opt.asyncmap.dc3", FT_BOOLEAN, 32,
5617                 NULL, 0x00080000, NULL, HFILL }},
5618         { &hf_lcp_opt_asyncmap_dc4,
5619             { "DC4", "lcp.opt.asyncmap.dc4", FT_BOOLEAN, 32,
5620                 NULL, 0x00100000, NULL, HFILL }},
5621         { &hf_lcp_opt_asyncmap_nak,
5622             { "NAK", "lcp.opt.asyncmap.nak", FT_BOOLEAN, 32,
5623                 NULL, 0x00200000, NULL, HFILL }},
5624         { &hf_lcp_opt_asyncmap_syn,
5625             { "SYN", "lcp.opt.asyncmap.syn", FT_BOOLEAN, 32,
5626                 NULL, 0x00400000, NULL, HFILL }},
5627         { &hf_lcp_opt_asyncmap_etb,
5628             { "ETB", "lcp.opt.asyncmap.etb", FT_BOOLEAN, 32,
5629                 NULL, 0x00800000, NULL, HFILL }},
5630         { &hf_lcp_opt_asyncmap_can,
5631             { "CAN", "lcp.opt.asyncmap.can", FT_BOOLEAN, 32,
5632                 NULL, 0x01000000, NULL, HFILL }},
5633         { &hf_lcp_opt_asyncmap_em,
5634             { "EM", "lcp.opt.asyncmap.em", FT_BOOLEAN, 32,
5635                 NULL, 0x02000000, NULL, HFILL }},
5636         { &hf_lcp_opt_asyncmap_sub,
5637             { "SUB", "lcp.opt.asyncmap.sub", FT_BOOLEAN, 32,
5638                 NULL, 0x04000000, NULL, HFILL }},
5639         { &hf_lcp_opt_asyncmap_esc,
5640             { "ESC", "lcp.opt.asyncmap.esc", FT_BOOLEAN, 32,
5641                 NULL, 0x08000000, NULL, HFILL }},
5642         { &hf_lcp_opt_asyncmap_fs,
5643             { "FS", "lcp.opt.asyncmap.fs", FT_BOOLEAN, 32,
5644                 NULL, 0x10000000, NULL, HFILL }},
5645         { &hf_lcp_opt_asyncmap_gs,
5646             { "GS", "lcp.opt.asyncmap.gs", FT_BOOLEAN, 32,
5647                 NULL, 0x20000000, NULL, HFILL }},
5648         { &hf_lcp_opt_asyncmap_rs,
5649             { "RS", "lcp.opt.asyncmap.rs", FT_BOOLEAN, 32,
5650                 NULL, 0x40000000, NULL, HFILL }},
5651         { &hf_lcp_opt_asyncmap_us,
5652             { "US", "lcp.opt.asyncmap.us", FT_BOOLEAN, 32,
5653                 NULL, 0x80000000, NULL, HFILL }},
5654         { &hf_lcp_opt_auth_protocol,
5655             { "Authentication Protocol", "lcp.opt.auth_protocol", FT_UINT16,
5656                 BASE_HEX | BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
5657         { &hf_lcp_opt_algorithm,
5658             { "Algorithm", "lcp.opt.algorithm", FT_UINT8,
5659                 BASE_DEC | BASE_RANGE_STRING, &chap_alg_rvals,
5660                 0x0, NULL, HFILL }},
5661         { &hf_lcp_opt_quality_protocol,
5662             { "Quality Protocol", "lcp.opt.quality_protocol", FT_UINT16,
5663                 BASE_HEX | BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
5664         { &hf_lcp_opt_magic_number,
5665             { "Magic Number", "lcp.opt.magic_number", FT_UINT32, BASE_HEX,
5666                 NULL, 0x0, NULL, HFILL }},
5667         { &hf_lcp_opt_reportingperiod,
5668             { "Reporting Period", "lcp.opt.reporting_period", FT_UINT32,
5669                 BASE_DEC, NULL, 0x0,
5670                 "Maximum time in micro-seconds that the remote end should "
5671                 "wait between transmission of LCP Link-Quality-Report packets",
5672                 HFILL }},
5673         { &hf_lcp_opt_fcs_alternatives,
5674             { "FCS Alternatives", "lcp.opt.fcs_alternatives", FT_UINT8,
5675                 BASE_HEX, NULL, 0x0, NULL, HFILL }},
5676         { &hf_lcp_opt_fcs_alternatives_null,
5677             { "NULL FCS", "lcp.opt.fcs_alternatives.null", FT_BOOLEAN, 8,
5678                 NULL, 0x01, NULL, HFILL }},
5679         { &hf_lcp_opt_fcs_alternatives_ccitt16,
5680             { "CCITT 16-bit", "lcp.opt.fcs_alternatives.ccitt16", FT_BOOLEAN,
5681                 8, NULL, 0x02, NULL, HFILL }},
5682         { &hf_lcp_opt_fcs_alternatives_ccitt32,
5683             { "CCITT 32-bit", "lcp.opt.fcs_alternatives.ccitt32", FT_BOOLEAN,
5684                 8, NULL, 0x04, NULL, HFILL }},
5685         { &hf_lcp_opt_maximum,
5686             { "Maximum", "lcp.opt.maximum", FT_UINT8, BASE_DEC, NULL, 0x0,
5687                 "The largest number of padding octets which may be added "
5688                 "to the frame.", HFILL }},
5689         { &hf_lcp_opt_window,
5690             { "Window", "lcp.opt.window", FT_UINT8, BASE_DEC, NULL, 0x0,
5691                 "The number of frames the receiver will buffer.", HFILL }},
5692         { &hf_lcp_opt_hdlc_address,
5693             { "Address", "lcp.opt.hdlc_address", FT_BYTES, BASE_NONE, NULL,
5694                 0x0, "An HDLC Address as specified in ISO 3309.", HFILL }},
5695         { &hf_lcp_opt_operation,
5696             { "Operation", "lcp.opt.operation", FT_UINT8, BASE_DEC,
5697                 VALS(callback_op_vals), 0x0, NULL, HFILL }},
5698         { &hf_lcp_opt_message,
5699             { "Message", "lcp.opt.message", FT_BYTES, BASE_NONE,
5700                 NULL, 0x0, NULL, HFILL }},
5701         { &hf_lcp_opt_mrru,
5702             { "MRRU", "lcp.opt.mrru", FT_UINT16, BASE_DEC, NULL, 0x0,
5703                 "Maximum Receive Reconstructed Unit", HFILL }},
5704         { &hf_lcp_opt_ep_disc_class,
5705             { "Class", "lcp.opt.ep_disc_class", FT_UINT8, BASE_DEC,
5706                 VALS(multilink_ep_disc_class_vals), 0x0, NULL, HFILL }},
5707         { &hf_lcp_opt_ip_address,
5708             { "IP Address", "lcp.opt.ip_address", FT_IPv4, BASE_NONE,
5709                 NULL, 0x0, NULL, HFILL }},
5710         { &hf_lcp_opt_802_1_address,
5711             { "IEEE 802.1 Address", "lcp.opt.802_1_address", FT_ETHER,
5712                 BASE_NONE, NULL, 0x0, NULL, HFILL }},
5713         { &hf_lcp_opt_magic_block,
5714             { "PPP Magic-Number Block", "lcp.opt.magic_block", FT_BYTES,
5715                 BASE_NONE, NULL, 0x0, NULL, HFILL }},
5716         { &hf_lcp_opt_psndn,
5717             { "Public Switched Network Directory Number", "lcp.opt.psndn",
5718                 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5719         { &hf_lcp_opt_mode,
5720             { "Mode", "lcp.opt.mode", FT_UINT8, BASE_DEC,
5721                 VALS(dce_id_mode_vals), 0x0, NULL, HFILL }},
5722         { &hf_lcp_opt_unused,
5723             { "Unused", "lcp.opt.unused", FT_BYTES, BASE_NONE,
5724                 NULL, 0x0, NULL, HFILL }},
5725         { &hf_lcp_opt_link_discrim,
5726             { "Link Discriminator", "lcp.opt.link_discrim", FT_UINT16,
5727                 BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }},
5728         { &hf_lcp_opt_id,
5729             { "Identification", "lcp.opt.id", FT_UINT_BYTES, BASE_NONE,
5730                 NULL, 0x0, NULL, HFILL }},
5731         { &hf_lcp_opt_cobs_flags,
5732             { "Flags", "lcp.opt.flags", FT_UINT8, BASE_HEX,
5733                 NULL, 0x0, NULL, HFILL }},
5734         { &hf_lcp_opt_cobs_flags_res,
5735             { "Reserved", "lcp.opt.flags.reserved", FT_UINT8, BASE_HEX,
5736                 NULL, 0xFC, NULL, HFILL }},
5737         { &hf_lcp_opt_cobs_flags_pre,
5738             { "PRE", "lcp.opt.flags.pre", FT_BOOLEAN, 8,
5739                 NULL, 0x02, "Preemption", HFILL }},
5740         { &hf_lcp_opt_cobs_flags_zxe,
5741             { "ZXE", "lcp.opt.flags.zxe", FT_BOOLEAN, 8,
5742                 NULL, 0x01, "Zero pair/run elimination", HFILL }},
5743         { &hf_lcp_opt_class,
5744             { "Class", "lcp.opt.class", FT_UINT8, BASE_DEC,
5745                 NULL, 0x0, NULL, HFILL }},
5746         { &hf_lcp_opt_prefix,
5747             { "Prefix", "lcp.opt.prefix", FT_UINT_BYTES, BASE_NONE,
5748                 NULL, 0x0, NULL, HFILL }},
5749         { &hf_lcp_opt_code,
5750             { "Code", "lcp.opt.code", FT_UINT8, BASE_DEC,
5751                 VALS(ml_hdr_fmt_code_vals), 0x0, NULL, HFILL }},
5752         { &hf_lcp_opt_max_susp_classes,
5753             { "Max suspendable classes", "lcp.opt.max_susp_classes",
5754                 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
5755         { &hf_lcp_opt_MIBenum,
5756             { "MIBenum", "lcp.opt.MIBenum", FT_UINT32,
5757                 BASE_DEC | BASE_EXT_STRING, &charset_vals_ext, 0x0,
5758                 "A unique integer value identifying a charset", HFILL }},
5759         { &hf_lcp_opt_language_tag,
5760             { "Language-Tag", "lcp.opt.language_tag", FT_STRING, BASE_NONE,
5761                 NULL, 0x0, NULL, HFILL }}
5762     };
5763
5764     static gint *ett[] = {
5765         &ett_lcp,
5766         &ett_lcp_options,
5767         &ett_lcp_vendor_opt,
5768         &ett_lcp_mru_opt,
5769         &ett_lcp_asyncmap_opt,
5770         &ett_lcp_authprot_opt,
5771         &ett_lcp_qualprot_opt,
5772         &ett_lcp_magicnumber_opt,
5773         &ett_lcp_linkqualmon_opt,
5774         &ett_lcp_pcomp_opt,
5775         &ett_lcp_acccomp_opt,
5776         &ett_lcp_fcs_alternatives_opt,
5777         &ett_lcp_self_desc_pad_opt,
5778         &ett_lcp_numbered_mode_opt,
5779         &ett_lcp_callback_opt,
5780         &ett_lcp_compound_frames_opt,
5781         &ett_lcp_nomdataencap_opt,
5782         &ett_lcp_multilink_mrru_opt,
5783         &ett_lcp_multilink_ssnh_opt,
5784         &ett_lcp_multilink_ep_disc_opt,
5785         &ett_lcp_magic_block,
5786         &ett_lcp_dce_identifier_opt,
5787         &ett_lcp_multilink_pp_opt,
5788         &ett_lcp_bacp_link_discrim_opt,
5789         &ett_lcp_auth_opt,
5790         &ett_lcp_cobs_opt,
5791         &ett_lcp_prefix_elision_opt,
5792         &ett_multilink_hdr_fmt_opt,
5793         &ett_lcp_internationalization_opt,
5794         &ett_lcp_simple_opt
5795     };
5796
5797     proto_lcp = proto_register_protocol("PPP Link Control Protocol", "PPP LCP",
5798         "lcp");
5799     proto_register_field_array(proto_lcp, hf, array_length(hf));
5800     proto_register_subtree_array(ett, array_length(ett));
5801 }
5802
5803 void
5804 proto_reg_handoff_lcp(void)
5805 {
5806     dissector_handle_t lcp_handle;
5807
5808     lcp_handle = create_dissector_handle(dissect_lcp, proto_lcp);
5809     dissector_add_uint("ppp.protocol", PPP_LCP, lcp_handle);
5810
5811     /*
5812      * NDISWAN on Windows translates Ethernet frames from higher-level
5813      * protocols into PPP frames to hand to the PPP driver, and translates
5814      * PPP frames from the PPP driver to hand to the higher-level protocols.
5815      *
5816      * Apparently the PPP driver, on at least some versions of Windows,
5817      * passes frames for internal-to-PPP protocols up through NDISWAN;
5818      * the protocol type field appears to be passed through unchanged
5819      * (unlike what's done with, for example, the protocol type field
5820      * for IP, which is mapped from its PPP value to its Ethernet value).
5821      *
5822      * This means that we may see, on Ethernet captures, frames for
5823      * protocols internal to PPP, so we register PPP_LCP with the
5824      * "ethertype" dissector table as well as the PPP protocol dissector
5825      * table.
5826      */
5827     dissector_add_uint("ethertype", PPP_LCP, lcp_handle);
5828
5829     /*
5830      * for GSM-A / MobileL3 / GPRS SM / PCO
5831      */
5832     dissector_add_uint("sm_pco.protocol", PPP_LCP, lcp_handle);
5833 }
5834
5835 void
5836 proto_register_vsncp(void)
5837 {
5838     static hf_register_info hf[] = {
5839       /* Generated from convert_proto_tree_add_text.pl */
5840       { &hf_vsncp_pdn_identifier, { "PDN Identifier", "vsncp.pdn_identifier", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5841       { &hf_vsncp_attach_type, { "Attach Type", "vsncp.attach_type", FT_UINT8, BASE_HEX, VALS(vsncp_attach_vals), 0x0, NULL, HFILL }},
5842       { &hf_vsncp_pdn_type, { "PDN Type", "vsncp.pdn_type", FT_UINT8, BASE_HEX, VALS(vsncp_pdntype_vals), 0x0, NULL, HFILL }},
5843       { &hf_vsncp_error_code, { "Error Code", "vsncp.error_code", FT_UINT8, BASE_HEX, VALS(vsncp_errorcode_vals), 0x0, NULL, HFILL }},
5844       { &hf_vsncp_pdn_ipv4, { "PDN IPv4", "vsncp.pdn_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5845       { &hf_vsncp_pdn_ipv6, { "PDN IPv6", "vsncp.pdn_ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5846       { &hf_vsncp_default_router_address, { "IPv4 Default Router Address", "vsncp.default_router_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5847       { &hf_vsncp_access_point_name, { "Access Point Name Label", "vsncp.access_point_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5848       { &hf_vsncp_address_allocation_cause, { "Address Allocation Cause", "vsncp.address_allocation_cause", FT_UINT8, BASE_HEX, VALS(vsncp_alloc_vals), 0x0, NULL, HFILL }},
5849       { &hf_vsncp_ambr_data, { "AMBR Data", "vsncp.ambr_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5850       { &hf_vsncp_ipv6_interface_identifier, { "IPv6 interface identifier", "vsncp.ipv6_interface_identifier", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5851       { &hf_vsncp_protocol, { "Protocol", "vsncp.protocol", FT_UINT16, BASE_HEX, VALS(vsncp_pco_vals), 0x0, NULL, HFILL }},
5852       { &hf_vsncp_protocol_configuration_length, { "Length", "vsncp.protocol_configuration_length", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5853       { &hf_vsncp_protocol_configuration_data, { "Data", "vsncp.protocol_configuration_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5854       { &hf_vsncp_code, { "Code", "vsncp.code", FT_UINT8, BASE_HEX, VALS(cp_vals), 0x0, NULL, HFILL }},
5855       { &hf_vsncp_identifier, { "Identifier", "vsncp.identifier", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
5856       { &hf_vsncp_length, { "Length", "vsncp.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
5857     };
5858
5859     static gint *ett[] = {
5860         &ett_vsncp,
5861         &ett_vsncp_options
5862     };
5863
5864     proto_vsncp = proto_register_protocol("Vendor Specific Control Protocol",
5865         "VSNCP", "vsncp");
5866     proto_register_subtree_array(ett, array_length(ett));
5867     proto_register_field_array(proto_vsncp, hf, array_length(hf));
5868 }
5869
5870 void
5871 proto_reg_handoff_vsncp(void)
5872 {
5873     dissector_handle_t vsncp_handle;
5874
5875     vsncp_handle = create_dissector_handle(dissect_vsncp, proto_vsncp);
5876     dissector_add_uint("ppp.protocol", PPP_VSNCP, vsncp_handle);
5877 }
5878
5879 void
5880 proto_register_vsnp(void)
5881 {
5882     static gint *ett[] = {
5883         &ett_vsnp
5884     };
5885
5886     static hf_register_info hf[] = {
5887         { &hf_vsnp_pdnid,
5888             { "PDN ID", "vsnp.pdnid", FT_UINT8, BASE_HEX,
5889                 NULL, 0x0, NULL, HFILL }}
5890     };
5891
5892     proto_vsnp = proto_register_protocol("Vendor Specific Network Protocol",
5893         "PPP VSNP", "vsnp");
5894     proto_register_subtree_array(ett, array_length(ett));
5895     proto_register_field_array(proto_vsnp, hf, array_length(hf));
5896 }
5897
5898 void
5899 proto_reg_handoff_vsnp(void)
5900 {
5901     dissector_handle_t vsnp_handle;
5902
5903     vsnp_handle = create_dissector_handle(dissect_vsnp, proto_vsnp);
5904     dissector_add_uint("ppp.protocol", PPP_VSNP, vsnp_handle);
5905 }
5906
5907 void
5908 proto_register_ipcp(void)
5909 {
5910     static hf_register_info hf[] = {
5911         { &hf_ipcp_opt_type,
5912             { "Type", "ipcp.opt.type", FT_UINT8, BASE_DEC,
5913                 NULL, 0x0, NULL, HFILL }},
5914         { &hf_ipcp_opt_length,
5915             { "Length", "ipcp.opt.length", FT_UINT8, BASE_DEC,
5916                 NULL, 0x0, NULL, HFILL }},
5917         { &hf_ipcp_opt_src_address,
5918             { "Source IP Address", "ipcp.opt.src_address", FT_IPv4, BASE_NONE,
5919                 NULL, 0x0, NULL, HFILL }},
5920         { &hf_ipcp_opt_dst_address,
5921             { "Destination IP Address", "ipcp.opt.dst_address", FT_IPv4,
5922                 BASE_NONE, NULL, 0x0, NULL, HFILL }},
5923         { &hf_ipcp_opt_compress_proto,
5924             { "IP Compression Protocol", "ipcp.opt.compress_proto", FT_UINT16,
5925                 BASE_HEX, VALS(ipcp_compress_proto_vals), 0x0, NULL, HFILL }},
5926         { &hf_ipcp_opt_max_cid,
5927             { "Max CID", "ipcp.opt.max_cid", FT_UINT16, BASE_DEC,
5928                 NULL, 0x0, "Maximum value of a context identifier", HFILL }},
5929         { &hf_ipcp_opt_mrru,
5930             { "MRRU", "ipcp.opt.mrru", FT_UINT16, BASE_DEC,
5931                 NULL, 0x0, "Maximum Reconstructed Reception Unit", HFILL }},
5932         { &hf_ipcp_opt_max_slot_id,
5933             { "Max Slot ID", "ipcp.opt.max_slot_id", FT_UINT8, BASE_DEC,
5934                 NULL, 0x0, NULL, HFILL }},
5935         { &hf_ipcp_opt_comp_slot_id,
5936             { "Comp Slot ID", "ipcp.opt.comp_slot_id", FT_BOOLEAN, 8,
5937                 TFS(&tfs_comp_slot_id), 0x01, NULL, HFILL }},
5938         { &hf_ipcp_opt_tcp_space,
5939             { "TCP Space", "ipcp.opt.tcp_space", FT_UINT16, BASE_DEC,
5940                 NULL, 0x0, NULL, HFILL }},
5941         { &hf_ipcp_opt_non_tcp_space,
5942             { "Non TCP Space", "ipcp.opt.non_tcp_space", FT_UINT16, BASE_DEC,
5943                 NULL, 0x0, NULL, HFILL }},
5944         { &hf_ipcp_opt_f_max_period,
5945             { "F Max Period", "ipcp.opt.f_max_period", FT_UINT16, BASE_DEC,
5946                 NULL, 0x0, "Maximum interval between full headers", HFILL }},
5947         { &hf_ipcp_opt_f_max_time,
5948             { "F Max Time", "ipcp.opt.f_max_time", FT_UINT16, BASE_DEC, NULL,
5949                 0x0, "Maximum time interval between full headers", HFILL }},
5950         { &hf_ipcp_opt_max_header,
5951             { "Max Header", "ipcp.opt.max_header", FT_UINT16, BASE_DEC, NULL,
5952                 0x0,
5953                 "The largest header size in octets that may be compressed",
5954                 HFILL }},
5955         { &hf_ipcp_data,
5956             { "Data", "ipcp.data", FT_BYTES, BASE_NONE,
5957                 NULL, 0x0, NULL, HFILL }},
5958         { &hf_ipcp_opt_ip_address,
5959             { "IP Address", "ipcp.opt.ip_address", FT_IPv4, BASE_NONE,
5960                 NULL, 0x0, NULL, HFILL }},
5961         { &hf_ipcp_opt_mobilenodehomeaddr,
5962             { "Mobile Node's Home Address", "ipcp.opt.mobilenodehomeaddress",
5963                 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5964         { &hf_ipcp_opt_pri_dns_address,
5965             { "Primary DNS Address", "ipcp.opt.pri_dns_address",
5966                 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5967         { &hf_ipcp_opt_pri_nbns_address,
5968             { "Primary NBNS Address", "ipcp.opt.pri_nbns_address",
5969                 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5970         { &hf_ipcp_opt_sec_dns_address,
5971             { "Secondary DNS Address", "ipcp.opt.sec_dns_address",
5972                 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5973         { &hf_ipcp_opt_sec_nbns_address,
5974             { "Secondary NBNS Address", "ipcp.opt.sec_nbns_address",
5975                 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5976         { &hf_ipcp_opt_rohc_type,
5977             { "Type", "ipcp.opt.rohc.type", FT_UINT8, BASE_DEC,
5978                 NULL, 0x0, NULL, HFILL }},
5979         { &hf_ipcp_opt_rohc_length,
5980             { "Length", "ipcp.opt.rohc.length", FT_UINT8, BASE_DEC,
5981                 NULL, 0x0, NULL, HFILL }},
5982         { &hf_ipcp_opt_rohc_profile,
5983             { "Profile", "ipcp.opt.rohc.profile", FT_UINT16, BASE_HEX,
5984                 VALS(ipcp_rohc_profile_vals), 0x0, NULL, HFILL }},
5985         { &hf_ipcp_opt_iphc_type,
5986             { "Type", "ipcp.opt.iphc.type", FT_UINT8, BASE_DEC,
5987                 NULL, 0x0, NULL, HFILL }},
5988         { &hf_ipcp_opt_iphc_length,
5989             { "Length", "ipcp.opt.iphc.length", FT_UINT8, BASE_DEC,
5990                 NULL, 0x0, NULL, HFILL }},
5991         { &hf_ipcp_opt_iphc_param,
5992             { "Parameter", "ipcp.opt.iphc.param", FT_UINT8, BASE_DEC,
5993                 VALS(ipcp_iphc_parameter_vals), 0x0, NULL, HFILL }}
5994     };
5995
5996     static gint *ett[] = {
5997         &ett_ipcp,
5998         &ett_ipcp_options,
5999         &ett_ipcp_ipaddrs_opt,
6000         &ett_ipcp_compress_opt,
6001         &ett_ipcp_ipaddr_opt,
6002         &ett_ipcp_mobileipv4_opt,
6003         &ett_ipcp_pridns_opt,
6004         &ett_ipcp_secdns_opt,
6005         &ett_ipcp_prinbns_opt,
6006         &ett_ipcp_secnbns_opt,
6007         &ett_ipcp_iphc_rtp_compress_opt,
6008         &ett_ipcp_iphc_enhanced_rtp_compress_opt,
6009         &ett_ipcp_iphc_neghdrcomp_opt,
6010         &ett_ipcp_rohc_profiles_opt
6011     };
6012
6013     proto_ipcp = proto_register_protocol("PPP IP Control Protocol", "PPP IPCP",
6014         "ipcp");
6015     proto_register_field_array(proto_ipcp, hf, array_length(hf));
6016     proto_register_subtree_array(ett, array_length(ett));
6017 }
6018
6019 void
6020 proto_reg_handoff_ipcp(void)
6021 {
6022     dissector_handle_t ipcp_handle;
6023
6024     ipcp_handle = create_dissector_handle(dissect_ipcp, proto_ipcp);
6025     dissector_add_uint("ppp.protocol", PPP_IPCP, ipcp_handle);
6026
6027     /*
6028      * See above comment about NDISWAN for an explanation of why we're
6029      * registering with the "ethertype" dissector table.
6030      */
6031     dissector_add_uint("ethertype", PPP_IPCP, ipcp_handle);
6032
6033     /*
6034      * for GSM-A / MobileL3 / GPRS SM / PCO
6035      */
6036     dissector_add_uint("sm_pco.protocol", PPP_IPCP, ipcp_handle);
6037 }
6038
6039 void
6040 proto_register_bcp(void)
6041 {
6042     static hf_register_info hf[] = {
6043         { &hf_bcp_flags,
6044             { "Flags", "bcp.flags", FT_UINT8, BASE_HEX,
6045                 NULL, 0x0, NULL, HFILL }},
6046         { &hf_bcp_fcs_present,
6047             { "LAN FCS present", "bcp.flags.fcs_present", FT_BOOLEAN, 8,
6048                 TFS(&tfs_yes_no), BCP_FCS_PRESENT, NULL, HFILL }},
6049         { &hf_bcp_zeropad,
6050             { "802.3 pad zero-filled", "bcp.flags.zeropad", FT_BOOLEAN, 8,
6051                 TFS(&tfs_yes_no), BCP_ZEROPAD, NULL, HFILL }},
6052         { &hf_bcp_bcontrol,
6053             { "Bridge control", "bcp.flags.bcontrol", FT_BOOLEAN, 8,
6054                 TFS(&tfs_yes_no), BCP_IS_BCONTROL, NULL, HFILL }},
6055         { &hf_bcp_pads,
6056             { "Pads", "bcp.pads", FT_UINT8, BASE_DEC,
6057                 NULL, BCP_PADS_MASK, NULL, HFILL }},
6058         { &hf_bcp_mac_type,
6059             { "MAC Type", "bcp.mac_type", FT_UINT8, BASE_DEC,
6060                 VALS(bcp_mac_type_vals), 0x0, NULL, HFILL }},
6061         { &hf_bcp_pad,
6062             { "Pad", "bcp.pad", FT_BYTES, BASE_NONE,
6063                 NULL, 0x0, NULL, HFILL }},
6064     };
6065
6066     static gint *ett[] = {
6067         &ett_bcp,
6068         &ett_bcp_flags
6069     };
6070
6071     proto_bcp = proto_register_protocol("PPP Bridging Control Protocol",
6072         "PPP BCP", "bcp");
6073     proto_register_field_array(proto_bcp, hf, array_length(hf));
6074     proto_register_subtree_array(ett, array_length(ett));
6075 }
6076
6077 void
6078 proto_register_osinlcp(void)
6079 {
6080     static hf_register_info hf[] = {
6081         { &hf_osinlcp_opt_type,
6082             { "Type", "osinlcp.opt.type", FT_UINT8, BASE_DEC,
6083                 NULL, 0x0, NULL, HFILL }},
6084         { &hf_osinlcp_opt_length,
6085             { "Length", "osinlcp.opt.length", FT_UINT8, BASE_DEC,
6086                 NULL, 0x0, NULL, HFILL }},
6087         { &hf_osinlcp_opt_alignment,
6088             { "Alignment", "osinlcp.opt.alignment", FT_UINT8, BASE_DEC,
6089                 NULL, 0x0, NULL, HFILL }}
6090     };
6091
6092     static gint *ett[] = {
6093         &ett_osinlcp,
6094         &ett_osinlcp_options,
6095         &ett_osinlcp_align_npdu_opt
6096     };
6097
6098     proto_osinlcp = proto_register_protocol(
6099         "PPP OSI Network Layer Control Protocol", "PPP OSINLCP", "osinlcp");
6100     proto_register_field_array(proto_osinlcp, hf, array_length(hf));
6101     proto_register_subtree_array(ett, array_length(ett));
6102 }
6103
6104 void
6105 proto_reg_handoff_bcp(void)
6106 {
6107     dissector_handle_t bcp_handle;
6108
6109     eth_withfcs_handle    = find_dissector("eth_withfcs");
6110     eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
6111
6112     bcp_handle = create_dissector_handle(dissect_bcp, proto_bcp);
6113     dissector_add_uint("ppp.protocol", PPP_BCP, bcp_handle);
6114 }
6115
6116 void
6117 proto_reg_handoff_osinlcp(void)
6118 {
6119     dissector_handle_t osinlcp_handle;
6120
6121     osinlcp_handle = create_dissector_handle(dissect_osinlcp, proto_osinlcp);
6122     dissector_add_uint("ppp.protocol", PPP_OSINLCP, osinlcp_handle);
6123
6124     /*
6125      * See above comment about NDISWAN for an explanation of why we're
6126      * registering with the "ethertype" dissector table.
6127      */
6128     dissector_add_uint("ethertype", PPP_OSINLCP, osinlcp_handle);
6129 }
6130
6131 void
6132 proto_register_ccp(void)
6133 {
6134     static hf_register_info hf[] = {
6135         { &hf_ccp_opt_type,
6136             { "Type", "ccp.opt.type", FT_UINT8, BASE_DEC,
6137                 NULL, 0x0, NULL, HFILL }},
6138         { &hf_ccp_opt_length,
6139             { "Length", "ccp.opt.length", FT_UINT8, BASE_DEC,
6140                 NULL, 0x0, NULL, HFILL }},
6141         { &hf_ccp_opt_oui,
6142             { "OUI", "ccp.opt.oui", FT_UINT24, BASE_HEX,
6143                 NULL, 0x0, NULL, HFILL }},
6144         { &hf_ccp_opt_subtype,
6145             { "Subtype", "ccp.opt.subtype", FT_UINT8, BASE_DEC_HEX,
6146                 NULL, 0x0, NULL, HFILL }},
6147         { &hf_ccp_opt_history_count,
6148             { "History Count", "ccp.opt.history_count", FT_UINT16, BASE_DEC,
6149                 NULL, 0x0, "The maximum number of compression histories",
6150                 HFILL }},
6151         { &hf_ccp_opt_cm,
6152             { "Check Mode Field", "ccp.opt.cm", FT_UINT8, BASE_DEC,
6153                 NULL, 0x0, NULL, HFILL }},
6154         { &hf_ccp_opt_cm_reserved,
6155             { "Reserved", "ccp.opt.cm.reserved", FT_UINT8, BASE_DEC,
6156                 NULL, 0xF8, NULL, HFILL }},
6157         { &hf_ccp_opt_cm_check_mode,
6158             { "Check Mode", "ccp.opt.cm.check_mode", FT_UINT8, BASE_DEC,
6159                 VALS(stac_checkmode_vals), 0x07, NULL, HFILL }},
6160         { &hf_ccp_opt_supported_bits,
6161             { "Supported Bits", "ccp.opt.supported_bits", FT_UINT32, BASE_HEX,
6162                 NULL, 0x0, NULL, HFILL }},
6163         { &hf_ccp_opt_supported_bits_h,
6164             { "H", "ccp.opt.supported_bits.h", FT_BOOLEAN, 32,
6165                 TFS(&ccp_mppe_h_tfs), MPPE_SUPPORTED_BITS_H, NULL, HFILL }},
6166         { &hf_ccp_opt_supported_bits_m,
6167             { "M", "ccp.opt.supported_bits.m", FT_BOOLEAN, 32,
6168                 TFS(&ccp_mppe_m_tfs), MPPE_SUPPORTED_BITS_M, NULL, HFILL }},
6169         { &hf_ccp_opt_supported_bits_s,
6170             { "S", "ccp.opt.supported_bits.s", FT_BOOLEAN, 32,
6171                 TFS(&ccp_mppe_s_tfs), MPPE_SUPPORTED_BITS_S, NULL, HFILL }},
6172         { &hf_ccp_opt_supported_bits_l,
6173             { "L", "ccp.opt.supported_bits.l", FT_BOOLEAN, 32,
6174                 TFS(&ccp_mppe_l_tfs), MPPE_SUPPORTED_BITS_L, NULL, HFILL }},
6175         { &hf_ccp_opt_supported_bits_d,
6176             { "D", "ccp.opt.supported_bits.d", FT_BOOLEAN, 32,
6177                 TFS(&ccp_mppe_d_tfs), MPPE_SUPPORTED_BITS_D, NULL, HFILL }},
6178         { &hf_ccp_opt_supported_bits_c,
6179             { "C", "ccp.opt.supported_bits.c", FT_BOOLEAN, 32,
6180                 TFS(&ccp_mppe_c_tfs), MPPC_SUPPORTED_BITS_C, NULL, HFILL }},
6181         { &hf_ccp_opt_history,
6182             { "History", "ccp.opt.history", FT_UINT8, BASE_DEC, NULL, 0x0,
6183                 "Maximum size of the compression history in powers of 2",
6184                 HFILL }},
6185         { &hf_ccp_opt_version,
6186             { "Version", "ccp.opt.version", FT_BYTES, BASE_NONE,
6187                 NULL, 0x0, NULL, HFILL }},
6188         { &hf_ccp_opt_vd,
6189             { "Vers/Dict", "ccp.opt.vd", FT_UINT8, BASE_HEX,
6190                 NULL, 0x0, NULL, HFILL }},
6191         { &hf_ccp_opt_vd_vers,
6192             { "Vers", "ccp.opt.vd.vers", FT_UINT8, BASE_DEC,
6193                 NULL, 0xE0, NULL, HFILL }},
6194         { &hf_ccp_opt_vd_dict,
6195             { "Dict", "ccp.opt.vd.dict", FT_UINT8, BASE_DEC, NULL,
6196                 0x1F, "The size in bits of the largest code used", HFILL }},
6197         { &hf_ccp_opt_check_mode,
6198             { "Check Mode", "ccp.opt.check_mode", FT_UINT8, BASE_DEC,
6199                 VALS(lzsdcp_checkmode_vals), 0x0, NULL, HFILL }},
6200         { &hf_ccp_opt_process_mode,
6201             { "Process Mode", "ccp.opt.process_mode", FT_UINT8, BASE_DEC,
6202                 VALS(lzsdcp_processmode_vals), 0x0, NULL, HFILL }},
6203         { &hf_ccp_opt_fe,
6204             { "Features", "ccp.opt.fe", FT_UINT8, BASE_DEC,
6205                 NULL, 0xC0, NULL, HFILL }},
6206         { &hf_ccp_opt_p,
6207             { "Packet by Packet flag", "ccp.opt.p", FT_BOOLEAN, 8,
6208                 TFS(&tfs_enabled_disabled), 0x20, NULL, HFILL }},
6209         { &hf_ccp_opt_History,
6210             { "History", "ccp.opt.History", FT_UINT8, BASE_DEC,
6211                 NULL, 0x1F, NULL, HFILL }},
6212         { &hf_ccp_opt_contexts,
6213             { "# Contexts", "ccp.opt.contexts", FT_UINT8, BASE_DEC,
6214                 NULL, 0x0, NULL, HFILL }},
6215         { &hf_ccp_opt_mode,
6216             { "Mode", "ccp.opt.mode", FT_UINT8, BASE_DEC,
6217                 VALS(dce_mode_vals), 0x0, NULL, HFILL }},
6218         { &hf_ccp_opt_window,
6219             { "Window", "ccp.opt.window", FT_UINT8, BASE_DEC,
6220                 NULL, 0xF0, NULL, HFILL }},
6221         { &hf_ccp_opt_method,
6222             { "Method", "ccp.opt.method", FT_UINT8, BASE_DEC,
6223                 VALS(deflate_method_vals), 0x0F, NULL, HFILL }},
6224         { &hf_ccp_opt_mbz,
6225             { "MBZ", "ccp.opt.mbz", FT_UINT8, BASE_DEC,
6226                 NULL, 0xFC, NULL, HFILL }},
6227         { &hf_ccp_opt_chk,
6228             { "Chk", "ccp.opt.chk", FT_UINT8, BASE_DEC,
6229                 VALS(deflate_chk_vals), 0x03, NULL, HFILL }},
6230         { &hf_ccp_opt_mode_dictcount,
6231             { "Mode/Dictionary Count", "ccp.opt.mode_dictcount", FT_UINT16,
6232                 BASE_DEC | BASE_RANGE_STRING, RVALS(v44lzjh_mode_dict_rvals),
6233                 0x0, NULL, HFILL }},
6234         { &hf_ccp_opt_dict_size,
6235             { "Dictionary Size", "ccp.opt.dict_size", FT_UINT16, BASE_DEC,
6236                 NULL, 0x0, NULL, HFILL }},
6237         { &hf_ccp_opt_history_length,
6238             { "History Length", "ccp.opt.history_length", FT_UINT16, BASE_DEC,
6239                 NULL, 0x0, NULL, HFILL }},
6240         { &hf_ccp_opt_data,
6241             { "Data", "ccp.opt.data", FT_BYTES, BASE_NONE,
6242                 NULL, 0x0, NULL, HFILL }},
6243     };
6244     static gint *ett[] = {
6245         &ett_ccp,
6246         &ett_ccp_options,
6247         &ett_ccp_oui_opt,
6248         &ett_ccp_predict1_opt,
6249         &ett_ccp_predict2_opt,
6250         &ett_ccp_puddle_opt,
6251         &ett_ccp_hpppc_opt,
6252         &ett_ccp_stac_opt,
6253         &ett_ccp_stac_opt_check_mode,
6254         &ett_ccp_mppe_opt,
6255         &ett_ccp_mppe_opt_supp_bits,
6256         &ett_ccp_gfza_opt,
6257         &ett_ccp_v42bis_opt,
6258         &ett_ccp_bsdcomp_opt,
6259         &ett_ccp_lzsdcp_opt,
6260         &ett_ccp_mvrca_opt,
6261         &ett_ccp_dce_opt,
6262         &ett_ccp_deflate_opt,
6263         &ett_ccp_v44lzjh_opt
6264     };
6265
6266     proto_ccp = proto_register_protocol("PPP Compression Control Protocol",
6267         "PPP CCP", "ccp");
6268     proto_register_field_array(proto_ccp, hf, array_length(hf));
6269     proto_register_subtree_array(ett, array_length(ett));
6270 }
6271
6272 void
6273 proto_reg_handoff_ccp(void)
6274 {
6275     dissector_handle_t ccp_handle;
6276
6277     ccp_handle = create_dissector_handle(dissect_ccp, proto_ccp);
6278     dissector_add_uint("ppp.protocol", PPP_CCP, ccp_handle);
6279
6280     /*
6281      * See above comment about NDISWAN for an explanation of why we're
6282      * registering with the "ethertype" dissector table.
6283      */
6284     dissector_add_uint("ethertype", PPP_CCP, ccp_handle);
6285 }
6286
6287 void
6288 proto_register_cbcp(void)
6289 {
6290     static hf_register_info hf[] = {
6291       /* Generated from convert_proto_tree_add_text.pl */
6292       { &hf_cbcp_callback_delay, { "Callback delay", "cbcp.callback_delay", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
6293       { &hf_cbcp_address_type, { "Address Type", "cbcp.address_type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
6294       { &hf_cbcp_address, { "Address", "cbcp.address", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6295       { &hf_cbcp_no_callback, { "No callback", "cbcp.no_callback", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6296     };
6297
6298     static gint *ett[] = {
6299         &ett_cbcp,
6300         &ett_cbcp_options,
6301         &ett_cbcp_callback_opt,
6302         &ett_cbcp_callback_opt_addr
6303     };
6304
6305     static ei_register_info ei[] = {
6306         { &ei_cbcp_address, { "cbcp.address.malformed", PI_MALFORMED, PI_ERROR, "Address runs past end of option", EXPFILL }},
6307     };
6308
6309     expert_module_t* expert_cbcp;
6310
6311     proto_cbcp = proto_register_protocol("PPP Callback Control Protocol",
6312         "PPP CBCP", "cbcp");
6313     proto_register_field_array(proto_cbcp, hf, array_length(hf));
6314     proto_register_subtree_array(ett, array_length(ett));
6315     expert_cbcp = expert_register_protocol(proto_cbcp);
6316     expert_register_field_array(expert_cbcp, ei, array_length(ei));
6317 }
6318
6319 void
6320 proto_reg_handoff_cbcp(void)
6321 {
6322     dissector_handle_t cbcp_handle;
6323
6324     cbcp_handle = create_dissector_handle(dissect_cbcp, proto_cbcp);
6325     dissector_add_uint("ppp.protocol", PPP_CBCP, cbcp_handle);
6326
6327     /*
6328      * See above comment about NDISWAN for an explanation of why we're
6329      * registering with the "ethertype" dissector table.
6330      */
6331     dissector_add_uint("ethertype", PPP_CBCP, cbcp_handle);
6332 }
6333
6334 void
6335 proto_register_bacp(void)
6336 {
6337     static hf_register_info hf[] = {
6338       /* Generated from convert_proto_tree_add_text.pl */
6339       { &hf_bacp_magic_number, { "Magic number", "bacp.magic_number", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
6340       { &hf_bacp_link_speed, { "Link Speed", "bacp.link_speed", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
6341       { &hf_bacp_link_type, { "Link Type", "bacp.link_type", FT_UINT8, BASE_DEC, VALS(bap_link_type_vals), 0x0, NULL, HFILL }},
6342     };
6343
6344     static gint *ett[] = {
6345         &ett_bacp,
6346         &ett_bacp_options,
6347         &ett_bacp_favored_peer_opt
6348     };
6349
6350     proto_bacp = proto_register_protocol(
6351         "PPP Bandwidth Allocation Control Protocol", "PPP BACP", "bacp");
6352     proto_register_field_array(proto_bacp, hf, array_length(hf));
6353     proto_register_subtree_array(ett, array_length(ett));
6354 }
6355
6356 void
6357 proto_reg_handoff_bacp(void)
6358 {
6359     dissector_handle_t bacp_handle;
6360
6361     bacp_handle = create_dissector_handle(dissect_bacp, proto_bacp);
6362     dissector_add_uint("ppp.protocol", PPP_BACP, bacp_handle);
6363
6364     /*
6365      * See above comment about NDISWAN for an explanation of why we're
6366      * registering with the "ethertype" dissector table.
6367      */
6368     dissector_add_uint("ethertype", PPP_BACP, bacp_handle);
6369 }
6370
6371 void
6372 proto_register_bap(void)
6373 {
6374     static hf_register_info hf[] = {
6375       /* Generated from convert_proto_tree_add_text.pl */
6376       { &hf_bap_sub_option_type, { "Sub-Option Type", "bap.sub_option_type", FT_UINT8, BASE_DEC, VALS(bap_phone_delta_subopt_vals), 0x0, NULL, HFILL }},
6377       { &hf_bap_sub_option_length, { "Sub-Option Length", "bap.sub_option_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
6378       { &hf_bap_unique_digit, { "Unique Digit", "bap.unique_digit", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
6379       { &hf_bap_subscriber_number, { "Subscriber Number", "bap.subscriber_number", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6380       { &hf_bap_phone_number_sub_address, { "Phone Number Sub Address", "bap.phone_number_sub_address", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6381       { &hf_bap_unknown_option_data, { "Unknown", "bap.unknown_option_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6382       { &hf_bap_reason, { "Reason", "bap.reason", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6383       { &hf_bap_link_descriminator, { "Link Discriminator", "bap.link_descriminator", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
6384       { &hf_bap_call_status, { "Status", "bap.call_status", FT_UINT8, BASE_HEX|BASE_EXT_STRING, &q931_cause_code_vals_ext, 0x0, NULL, HFILL }},
6385       { &hf_bap_call_action, { "Action", "bap.call_action", FT_UINT8, BASE_HEX, VALS(bap_call_status_opt_action_vals), 0x0, NULL, HFILL }},
6386       { &hf_bap_type, { "Type", "bap.type", FT_UINT8, BASE_HEX, VALS(bap_vals), 0x0, NULL, HFILL }},
6387       { &hf_bap_identifier, { "Identifier", "bap.identifier", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
6388       { &hf_bap_length, { "Length", "bap.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
6389       { &hf_bap_response_code, { "Response Code", "bap.response_code", FT_UINT8, BASE_HEX, VALS(bap_resp_code_vals), 0x0, NULL, HFILL }},
6390     };
6391
6392     static gint *ett[] = {
6393         &ett_bap,
6394         &ett_bap_options,
6395         &ett_bap_link_type_opt,
6396         &ett_bap_phone_delta_opt,
6397         &ett_bap_phone_delta_subopt,
6398         &ett_bap_call_status_opt
6399     };
6400
6401     static ei_register_info ei[] = {
6402         { &ei_bap_sub_option_length, { "bap.sub_option_length.invalid", PI_PROTOCOL, PI_WARN, "Invalid length", EXPFILL }},
6403     };
6404
6405     expert_module_t* expert_bap;
6406
6407     proto_bap = proto_register_protocol("PPP Bandwidth Allocation Protocol", "PPP BAP", "bap");
6408     proto_register_field_array(proto_bap, hf, array_length(hf));
6409     proto_register_subtree_array(ett, array_length(ett));
6410     expert_bap = expert_register_protocol(proto_bap);
6411     expert_register_field_array(expert_bap, ei, array_length(ei));
6412 }
6413
6414 void
6415 proto_reg_handoff_bap(void)
6416 {
6417     dissector_handle_t bap_handle;
6418
6419     bap_handle = create_dissector_handle(dissect_bap, proto_bap);
6420     dissector_add_uint("ppp.protocol", PPP_BAP, bap_handle);
6421
6422     /*
6423      * See above comment about NDISWAN for an explanation of why we're
6424      * registering with the "ethertype" dissector table.
6425      */
6426     dissector_add_uint("ethertype", PPP_BAP, bap_handle);
6427 }
6428
6429 void
6430 proto_register_comp_data(void)
6431 {
6432 #if 0 /* See dissect_comp_data() */
6433     static gint *ett[] = {
6434         &ett_comp_data
6435     };
6436 #endif
6437
6438     proto_comp_data = proto_register_protocol("PPP Compressed Datagram",
6439         "PPP Comp", "comp_data");
6440 #if 0
6441     proto_register_subtree_array(ett, array_length(ett));
6442 #endif
6443 }
6444
6445 void
6446 proto_reg_handoff_comp_data(void)
6447 {
6448     dissector_handle_t comp_data_handle;
6449
6450     comp_data_handle = create_dissector_handle(dissect_comp_data,
6451         proto_comp_data);
6452     dissector_add_uint("ppp.protocol", PPP_COMP, comp_data_handle);
6453
6454     /*
6455      * See above comment about NDISWAN for an explanation of why we're
6456      * registering with the "ethertype" dissector table.
6457      */
6458     dissector_add_uint("ethertype", PPP_COMP, comp_data_handle);
6459 }
6460
6461 void
6462 proto_register_pap(void)
6463 {
6464     static gint *ett[] = {
6465         &ett_pap,
6466         &ett_pap_data
6467     };
6468
6469     static hf_register_info hf[] = {
6470         { &hf_pap_code,
6471             { "Code", "pap.code", FT_UINT8, BASE_DEC, VALS(pap_vals), 0x0,
6472                 "The Code field is one octet and identifies the type of PAP "
6473                 "packet", HFILL }},
6474         { &hf_pap_identifier,
6475             { "Identifier", "pap.identifier", FT_UINT8, BASE_DEC, NULL, 0x0,
6476                 "The Identifier field is one octet and aids in matching "
6477                 "requests and replies.", HFILL }},
6478         { &hf_pap_length,
6479             { "Length", "pap.length", FT_UINT16, BASE_DEC, NULL, 0x0,
6480                 "The Length field is two octets and indicates the length of "
6481                 "the PAP packet", HFILL }},
6482         { &hf_pap_data,
6483             { "Data", "pap.data", FT_NONE, BASE_NONE, NULL, 0x0,
6484                 "The format of the Data field is determined by the Code field",
6485                 HFILL }},
6486         { &hf_pap_peer_id_length,
6487             { "Peer-ID-Length", "pap.peer_id.length",
6488                 FT_UINT8, BASE_DEC, NULL, 0x0,
6489                 "The Peer-ID-Length field is one octet and indicates the "
6490                 "length of the Peer-ID field", HFILL }},
6491         { &hf_pap_peer_id,
6492             { "Peer-ID", "pap.peer_id", FT_STRING, BASE_NONE, NULL, 0x0,
6493                 "The Peer-ID field is zero or more octets and indicates the "
6494                 "name of the peer to be authenticated", HFILL }},
6495         { &hf_pap_password_length,
6496             { "Password-Length", "pap.password.length",
6497                 FT_UINT8, BASE_DEC, NULL, 0x0,
6498                 "The Password-Length field is one octet and indicates the "
6499                 "length of the Password field", HFILL }},
6500         { &hf_pap_password,
6501             { "Password", "pap.password", FT_STRING, BASE_NONE, NULL, 0x0,
6502                 "The Password field is zero or more octets and indicates the "
6503                 "password to be used for authentication", HFILL }},
6504         { &hf_pap_message_length,
6505             { "Message-Length", "pap.message.length",
6506                 FT_UINT8, BASE_DEC, NULL, 0x0,
6507                 "The Message-Length field is one octet and indicates the "
6508                 "length of the Message field", HFILL }},
6509         { &hf_pap_message,
6510             { "Message", "pap.message", FT_STRING, BASE_NONE, NULL, 0x0,
6511                 "The Message field is zero or more octets, and its contents "
6512                 "are implementation dependent.", HFILL }},
6513         { &hf_pap_stuff,
6514             { "stuff", "pap.stuff", FT_BYTES, BASE_NONE,
6515                 NULL, 0x0, NULL, HFILL }}
6516     };
6517
6518     proto_pap = proto_register_protocol("PPP Password Authentication Protocol",
6519         "PPP PAP", "pap");
6520     proto_register_field_array(proto_pap, hf, array_length(hf));
6521     proto_register_subtree_array(ett, array_length(ett));
6522 }
6523
6524 void
6525 proto_reg_handoff_pap(void)
6526 {
6527     dissector_handle_t pap_handle;
6528
6529     pap_handle = create_dissector_handle(dissect_pap, proto_pap);
6530     dissector_add_uint("ppp.protocol", PPP_PAP, pap_handle);
6531
6532     /*
6533      * See above comment about NDISWAN for an explanation of why we're
6534      * registering with the "ethertype" dissector table.
6535      */
6536     dissector_add_uint("ethertype", PPP_PAP, pap_handle);
6537
6538     /*
6539      * for GSM-A / MobileL3 / GPRS SM / PCO
6540      */
6541     dissector_add_uint("sm_pco.protocol", PPP_PAP, pap_handle);
6542 }
6543
6544 void
6545 proto_register_chap(void)
6546 {
6547     static gint *ett[] = {
6548         &ett_chap,
6549         &ett_chap_data
6550     };
6551
6552     static hf_register_info hf[] = {
6553         { &hf_chap_code,
6554             { "Code", "chap.code", FT_UINT8, BASE_DEC, VALS(chap_vals), 0x0,
6555                 "CHAP code", HFILL }},
6556         { &hf_chap_identifier,
6557             { "Identifier", "chap.identifier", FT_UINT8, BASE_DEC, NULL, 0x0,
6558                 "CHAP identifier", HFILL }},
6559         { &hf_chap_length,
6560             { "Length", "chap.length", FT_UINT16, BASE_DEC, NULL, 0x0,
6561                 "CHAP length", HFILL  }},
6562         { &hf_chap_data,
6563             { "Data", "chap.data", FT_NONE, BASE_NONE, NULL, 0x0,
6564                 "CHAP Data", HFILL }},
6565          { &hf_chap_value_size,
6566             { "Value Size", "chap.value_size", FT_UINT8, BASE_DEC, NULL, 0x0,
6567                 "CHAP value size", HFILL }},
6568         { &hf_chap_value,
6569             { "Value", "chap.value", FT_BYTES, BASE_NONE, NULL, 0x0,
6570                 "CHAP value data", HFILL }},
6571         { &hf_chap_name,
6572             { "Name", "chap.name", FT_STRING, BASE_NONE, NULL, 0x0,
6573                 "CHAP name", HFILL }},
6574         { &hf_chap_message,
6575             { "Message", "chap.message", FT_STRING, BASE_NONE, NULL, 0x0,
6576                 "CHAP message", HFILL }},
6577         { &hf_chap_stuff,
6578             { "Stuff", "chap.stuff", FT_BYTES, BASE_NONE, NULL, 0x0,
6579                 NULL, HFILL }},
6580         };
6581
6582     proto_chap = proto_register_protocol(
6583         "PPP Challenge Handshake Authentication Protocol", "PPP CHAP", "chap");
6584     proto_register_field_array(proto_chap, hf, array_length(hf));
6585     proto_register_subtree_array(ett, array_length(ett));
6586 }
6587
6588 void
6589 proto_reg_handoff_chap(void)
6590 {
6591     dissector_handle_t chap_handle = create_dissector_handle(dissect_chap,
6592         proto_chap);
6593     dissector_add_uint("ppp.protocol", PPP_CHAP, chap_handle);
6594
6595     /*
6596      * See above comment about NDISWAN for an explanation of why we're
6597      * registering with the "ethertype" dissector table.
6598      */
6599     dissector_add_uint("ethertype", PPP_CHAP, chap_handle);
6600
6601     /*
6602      * for GSM-A / MobileL3 / GPRS SM / PCO
6603      */
6604     dissector_add_uint("sm_pco.protocol", PPP_CHAP, chap_handle);
6605 }
6606
6607 void
6608 proto_register_pppmuxcp(void)
6609 {
6610     static hf_register_info hf[] = {
6611         { &hf_pppmux_flags_pid,
6612             { "PID", "pppmuxcp.flags.pid", FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x80,
6613                 NULL, HFILL }},
6614         { &hf_pppmux_flags_field_length,
6615             { "Length field", "pppmuxcp.flags.field_length", FT_BOOLEAN, 8, TFS(&tfs_pppmux_length_field), 0x40,
6616                 NULL, HFILL }},
6617         /* Generated from convert_proto_tree_add_text.pl */
6618         { &hf_pppmux_flags, { "PFF/LXT", "pppmuxcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
6619         { &hf_pppmux_sub_frame_length, { "Sub-frame Length", "pppmuxcp.sub_frame_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
6620         { &hf_pppmux_def_prot_id, { "Default Protocol ID", "pppmuxcp.def_prot_id", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
6621         };
6622
6623     static gint *ett[] = {
6624         &ett_pppmuxcp,
6625         &ett_pppmuxcp_options
6626     };
6627
6628     proto_pppmuxcp = proto_register_protocol("PPPMux Control Protocol",
6629         "PPP PPPMuxCP", "pppmuxcp");
6630     proto_register_field_array(proto_pppmuxcp, hf, array_length(hf));
6631     proto_register_subtree_array(ett, array_length(ett));
6632 }
6633
6634
6635 void
6636 proto_reg_handoff_pppmuxcp(void)
6637 {
6638     dissector_handle_t muxcp_handle;
6639
6640     muxcp_handle = create_dissector_handle(dissect_pppmuxcp, proto_pppmuxcp);
6641     dissector_add_uint("ppp.protocol", PPP_MUXCP, muxcp_handle);
6642
6643     /*
6644      * See above comment about NDISWAN for an explanation of why we're
6645      * registering with the "ethertype" dissector table.
6646      */
6647     dissector_add_uint("ethertype", PPP_MUXCP, muxcp_handle);
6648 }
6649
6650
6651 void
6652 proto_register_pppmux(void)
6653 {
6654     static hf_register_info hf[] = {
6655         { &hf_pppmux_protocol,
6656             { "Protocol", "pppmux.protocol", FT_UINT16,
6657                 BASE_HEX|BASE_EXT_STRING, &ppp_vals_ext, 0x0,
6658                 "The protocol of the sub-frame.", HFILL }}
6659     };
6660
6661     static gint *ett[] = {
6662         &ett_pppmux,
6663         &ett_pppmux_subframe,
6664         &ett_pppmux_subframe_hdr,
6665         &ett_pppmux_subframe_flags,
6666         &ett_pppmux_subframe_info
6667     };
6668
6669     proto_pppmux = proto_register_protocol("PPP Multiplexing", "PPP PPPMux",
6670         "pppmux");
6671     proto_register_field_array(proto_pppmux, hf, array_length(hf));
6672     proto_register_subtree_array(ett, array_length(ett));
6673 }
6674
6675 void
6676 proto_reg_handoff_pppmux(void)
6677 {
6678     dissector_handle_t pppmux_handle;
6679
6680     pppmux_handle = create_dissector_handle(dissect_pppmux, proto_pppmux);
6681     dissector_add_uint("ppp.protocol", PPP_MUX, pppmux_handle);
6682
6683     /*
6684      * See above comment about NDISWAN for an explanation of why we're
6685      * registering with the "ethertype" dissector table.
6686      */
6687     dissector_add_uint("ethertype", PPP_MUX, pppmux_handle);
6688 }
6689
6690 void
6691 proto_register_mplscp(void)
6692 {
6693     static gint *ett[] = {
6694         &ett_mplscp,
6695         &ett_mplscp_options
6696     };
6697
6698     proto_mplscp = proto_register_protocol("PPP MPLS Control Protocol",
6699         "PPP MPLSCP", "mplscp");
6700     proto_register_subtree_array(ett, array_length(ett));
6701 }
6702
6703 void
6704 proto_reg_handoff_mplscp(void)
6705 {
6706     dissector_handle_t mplscp_handle;
6707
6708     mplscp_handle = create_dissector_handle(dissect_mplscp, proto_mplscp);
6709     dissector_add_uint("ppp.protocol", PPP_MPLSCP, mplscp_handle);
6710
6711     /*
6712      * See above comment about NDISWAN for an explanation of why we're
6713      * registering with the "ethertype" dissector table.
6714      */
6715     dissector_add_uint("ethertype", PPP_MPLSCP, mplscp_handle);
6716 }
6717
6718 void
6719 proto_register_cdpcp(void)
6720 {
6721     static gint *ett[] = {
6722         &ett_cdpcp,
6723         &ett_cdpcp_options
6724     };
6725
6726     proto_cdpcp = proto_register_protocol("PPP CDP Control Protocol",
6727         "PPP CDPCP", "cdpcp");
6728     proto_register_subtree_array(ett, array_length(ett));
6729 }
6730
6731 void
6732 proto_reg_handoff_cdpcp(void)
6733 {
6734     dissector_handle_t cdpcp_handle;
6735
6736     cdpcp_handle = create_dissector_handle(dissect_cdpcp, proto_cdpcp);
6737     dissector_add_uint("ppp.protocol", PPP_CDPCP, cdpcp_handle);
6738
6739     /*
6740      * See above comment about NDISWAN for an explanation of why we're
6741      * registering with the "ethertype" dissector table.
6742      */
6743     dissector_add_uint("ethertype", PPP_CDPCP, cdpcp_handle);
6744 }
6745
6746 void
6747 proto_register_ipv6cp(void)
6748 {
6749     static hf_register_info hf[] = {
6750       /* Generated from convert_proto_tree_add_text.pl */
6751       { &hf_ipv6cp_interface_identifier, { "Interface Identifier", "ipv6cp.interface_identifier", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6752     };
6753     static gint *ett[] = {
6754         &ett_ipv6cp,
6755         &ett_ipv6cp_options,
6756         &ett_ipv6cp_if_id_opt,
6757         &ett_ipv6cp_compress_opt
6758     };
6759
6760     proto_ipv6cp = proto_register_protocol("PPP IPv6 Control Protocol",
6761         "PPP IPV6CP", "ipv6cp");
6762     proto_register_field_array(proto_ipv6cp, hf, array_length(hf));
6763     proto_register_subtree_array(ett, array_length(ett));
6764 }
6765
6766 void
6767 proto_reg_handoff_ipv6cp(void)
6768 {
6769     dissector_handle_t ipv6cp_handle;
6770
6771     ipv6cp_handle = create_dissector_handle(dissect_ipv6cp, proto_ipv6cp);
6772     dissector_add_uint("ppp.protocol", PPP_IPV6CP, ipv6cp_handle);
6773
6774     /*
6775      * See above comment about NDISWAN for an explanation of why we're
6776      * registering with the "ethertype" dissector table.
6777      */
6778     dissector_add_uint("ethertype", PPP_IPV6CP, ipv6cp_handle);
6779
6780     /*
6781      * for GSM-A / MobileL3 / GPRS SM / PCO
6782      */
6783     dissector_add_uint("sm_pco.protocol", PPP_IPV6CP, ipv6cp_handle);
6784 }
6785
6786 void
6787 proto_register_iphc_crtp(void)
6788 {
6789     static hf_register_info hf[] = {
6790         { &hf_iphc_crtp_cid16,
6791             { "Context Id", "crtp.cid", FT_UINT16, BASE_DEC, NULL, 0x0,
6792                 "The context identifier of the compressed packet.", HFILL }},
6793         { &hf_iphc_crtp_cid8,
6794             { "Context Id", "crtp.cid", FT_UINT8, BASE_DEC, NULL, 0x0,
6795                 "The context identifier of the compressed packet.", HFILL }},
6796         { &hf_iphc_crtp_gen,
6797             { "Generation", "crtp.gen", FT_UINT8, BASE_DEC, NULL, 0x3f,
6798                 "The generation of the compressed packet.", HFILL }},
6799         { &hf_iphc_crtp_seq,
6800             { "Sequence", "crtp.seq", FT_UINT8, BASE_DEC, NULL, 0x0f,
6801                 "The sequence of the compressed packet.", HFILL }},
6802         { &hf_iphc_crtp_fh_flags,
6803             { "Flags", "crtp.fh_flags", FT_UINT8, BASE_HEX, VALS(iphc_crtp_fh_flags),
6804                 0xc0, "The flags of the full header packet.", HFILL }},
6805         { &hf_iphc_crtp_cs_flags,
6806             { "Flags", "crtp.cs_flags", FT_UINT8, BASE_DEC, VALS(iphc_crtp_cs_flags),
6807                 0x0, "The flags of the context state packet.", HFILL }},
6808         { &hf_iphc_crtp_cs_cnt,
6809             { "Count", "crtp.cnt", FT_UINT8, BASE_DEC, NULL, 0x0,
6810                 "The count of the context state packet.", HFILL }},
6811         { &hf_iphc_crtp_cs_invalid,
6812             { "Invalid", "crtp.invalid", FT_BOOLEAN, 8, NULL, 0x80,
6813                 "The invalid bit of the context state packet.", HFILL }},
6814         { &hf_iphc_crtp_data,
6815             { "Data", "crtp.data", FT_BYTES, BASE_NONE, NULL, 0x0,
6816                 NULL, HFILL }},
6817         };
6818
6819     static gint *ett[] = {
6820         &ett_iphc_crtp,
6821         &ett_iphc_crtp_hdr,
6822         &ett_iphc_crtp_info
6823     };
6824
6825     static ei_register_info ei[] = {
6826         { &ei_iphc_crtp_ip_version, { "crtp.ip_version_unsupported", PI_PROTOCOL, PI_WARN, "IP version is unsupported", EXPFILL }},
6827         { &ei_iphc_crtp_next_protocol, { "crtp.next_protocol_unsupported", PI_PROTOCOL, PI_WARN, "Next protocol is unsupported", EXPFILL }},
6828     };
6829
6830     expert_module_t* expert_iphc_crtp;
6831
6832     proto_iphc_crtp = proto_register_protocol("CRTP", "CRTP", "crtp");
6833     proto_register_field_array(proto_iphc_crtp, hf, array_length(hf));
6834     proto_register_subtree_array(ett, array_length(ett));
6835     expert_iphc_crtp = expert_register_protocol(proto_iphc_crtp);
6836     expert_register_field_array(expert_iphc_crtp, ei, array_length(ei));
6837 }
6838
6839 void
6840 proto_reg_handoff_iphc_crtp(void)
6841 {
6842     dissector_handle_t fh_handle;
6843     dissector_handle_t cudp16_handle;
6844     dissector_handle_t cudp8_handle;
6845     dissector_handle_t cs_handle;
6846
6847     fh_handle = create_dissector_handle(dissect_iphc_crtp_fh, proto_iphc_crtp);
6848     dissector_add_uint("ppp.protocol", PPP_RTP_FH, fh_handle);
6849
6850     cudp16_handle = create_dissector_handle(dissect_iphc_crtp_cudp16,
6851         proto_iphc_crtp);
6852     dissector_add_uint("ppp.protocol", PPP_RTP_CUDP16, cudp16_handle);
6853
6854     cudp8_handle = create_dissector_handle(dissect_iphc_crtp_cudp8,
6855         proto_iphc_crtp);
6856     dissector_add_uint("ppp.protocol", PPP_RTP_CUDP8, cudp8_handle);
6857
6858     cs_handle = create_dissector_handle(dissect_iphc_crtp_cs, proto_iphc_crtp);
6859     dissector_add_uint("ppp.protocol", PPP_RTP_CS, cs_handle);
6860
6861     /*
6862      * See above comment about NDISWAN for an explanation of why we're
6863      * registering with the "ethertype" dissector table.
6864      */
6865     dissector_add_uint("ethertype", PPP_RTP_FH, fh_handle);
6866     dissector_add_uint("ethertype", PPP_RTP_CUDP16, cudp16_handle);
6867     dissector_add_uint("ethertype", PPP_RTP_CUDP8, cudp16_handle);
6868     dissector_add_uint("ethertype", PPP_RTP_CS, cs_handle);
6869 }
6870
6871 /*
6872  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
6873  *
6874  * Local variables:
6875  * c-basic-offset: 4
6876  * tab-width: 8
6877  * indent-tabs-mode: nil
6878  * End:
6879  *
6880  * vi: set shiftwidth=4 tabstop=8 expandtab:
6881  * :indentSize=4:tabSize=8:noTabs=true:
6882  */