As the gtk2 directory is no longer needed (GTK1 and 2 are using the same sources...
[obnox/wireshark/wip.git] / packet-ppp.c
1 /* packet-ppp.c
2  * Routines for ppp packet disassembly
3  * RFC 1661, RFC 1662
4  *
5  * $Id$
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  *
10  * This file created and by Mike Hall <mlh@io.com>
11  * Copyright 1998
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <string.h>
33 #include <glib.h>
34 #include "prefs.h"
35 #include <epan/packet.h>
36 #include "packet-ppp.h"
37 #include "ppptypes.h"
38 #include "etypes.h"
39 #include "ip_opts.h"
40 #include <epan/atalk-utils.h>
41 #include "packet-chdlc.h"
42 #include "packet-ip.h"
43 #include "packet-ipx.h"
44 #include "packet-vines.h"
45 #include "nlpid.h"
46 #include "crc16.h"
47 #include "crc32.h"
48
49 #define ppp_min(a, b)  ((a<b) ? a : b)
50
51 static int proto_ppp = -1;
52 static int hf_ppp_address = -1;
53 static int hf_ppp_control = -1;
54 static int hf_ppp_protocol = -1;
55
56 static gint ett_ppp = -1;
57
58 static int proto_lcp = -1;
59
60 static gint ett_lcp = -1;
61 static gint ett_lcp_options = -1;
62 static gint ett_lcp_authprot_opt = -1;
63 static gint ett_lcp_qualprot_opt = -1;
64 static gint ett_lcp_fcs_alternatives_opt = -1;
65 static gint ett_lcp_numbered_mode_opt = -1;
66 static gint ett_lcp_callback_opt = -1;
67 static gint ett_lcp_multilink_ep_disc_opt = -1;
68 static gint ett_lcp_internationalization_opt = -1;
69
70 static int proto_ipcp = -1;
71
72 static gint ett_ipcp = -1;
73 static gint ett_ipcp_options = -1;
74 static gint ett_ipcp_ipaddrs_opt = -1;
75 static gint ett_ipcp_compressprot_opt = -1;
76
77 static int proto_osicp = -1;
78
79 static gint ett_osicp = -1;
80 static gint ett_osicp_options = -1;
81 static gint ett_osicp_align_npdu_opt = -1;
82
83 static int proto_ccp = -1;
84
85 static gint ett_ccp = -1;
86 static gint ett_ccp_options = -1;
87 static gint ett_ccp_stac_opt = -1;
88 static gint ett_ccp_mppc_opt = -1;
89 static gint ett_ccp_bsdcomp_opt = -1;
90 static gint ett_ccp_lzsdcp_opt = -1;
91 static gint ett_ccp_mvrca_opt = -1;
92 static gint ett_ccp_deflate_opt = -1;
93
94 static int proto_cbcp = -1;
95
96 static gint ett_cbcp = -1;
97 static gint ett_cbcp_options = -1;
98 static gint ett_cbcp_callback_opt = -1;
99 static gint ett_cbcp_callback_opt_addr = -1;
100
101 static int proto_bacp = -1;
102
103 static gint ett_bacp = -1;
104 static gint ett_bacp_options = -1;
105 static gint ett_bacp_favored_peer_opt = -1;
106
107 static int proto_bap = -1;
108
109 static gint ett_bap = -1;
110 static gint ett_bap_options = -1;
111 static gint ett_bap_link_type_opt = -1;
112 static gint ett_bap_phone_delta_opt = -1;
113 static gint ett_bap_phone_delta_subopt = -1;
114 static gint ett_bap_call_status_opt = -1;
115
116 static int proto_comp_data = -1;
117
118 static gint ett_comp_data = -1;
119
120 static int proto_pppmuxcp = -1;
121
122 static gint ett_pppmuxcp = -1;
123 static gint ett_pppmuxcp_options = -1;
124
125 static int proto_pppmux = -1;
126
127 static gint ett_pppmux = -1;
128 static gint ett_pppmux_subframe = -1;
129 static gint ett_pppmux_subframe_hdr = -1;
130 static gint ett_pppmux_subframe_flags = -1;
131 static gint ett_pppmux_subframe_info = -1;
132
133 static int proto_mp = -1;
134 static int hf_mp_frag_first = -1;
135 static int hf_mp_frag_last = -1;
136 static int hf_mp_sequence_num = -1;
137
138 static int ett_mp = -1;
139 static int ett_mp_flags = -1;
140
141 static int proto_mplscp = -1;
142 static gint ett_mplscp = -1;
143 static gint ett_mplscp_options = -1;
144
145 static int proto_cdpcp = -1;
146 static gint ett_cdpcp = -1;
147 static gint ett_cdpcp_options = -1;
148
149 static int proto_pap                    = -1;           /* PAP vars */
150 static gint ett_pap                     = -1;
151 static gint ett_pap_data                = -1;
152 static gint ett_pap_peer_id             = -1;
153 static gint ett_pap_password            = -1;
154 static gint ett_pap_message             = -1;
155
156 static int proto_chap                   = -1;           /* CHAP vars */
157 static gint ett_chap                    = -1;
158 static gint ett_chap_data               = -1;
159 static gint ett_chap_value              = -1;
160 static gint ett_chap_name               = -1;
161 static gint ett_chap_message            = -1;
162
163 static int proto_ipv6cp = -1;  /* IPv6CP vars */
164
165 static gint ett_ipv6cp = -1;
166 static gint ett_ipv6cp_options = -1;
167 static gint ett_ipv6cp_if_id_opt = -1;
168 static gint ett_ipv6cp_compressprot_opt = -1;  
169
170 static dissector_table_t ppp_subdissector_table;
171 static dissector_handle_t chdlc_handle;
172 static dissector_handle_t data_handle;
173
174 /* options */
175 static gint ppp_fcs_decode = 0; /* 0 = No FCS, 1 = 16 bit FCS, 2 = 32 bit FCS */
176 #define NO_FCS 0
177 #define FCS_16 1
178 #define FCS_32 2
179
180 const enum_val_t fcs_options[] = {
181   {"none", "None", NO_FCS},
182   {"16-bit", "16-Bit", FCS_16},
183   {"32-bit", "32-Bit", FCS_32},
184   {NULL, NULL, -1}
185 };
186
187 gboolean ppp_vj_decomp = TRUE; /* Default to VJ header decompression */
188
189 /*
190  * For Default Protocol ID negotiated with PPPMuxCP. We need to
191  * this ID so that if the first subframe doesn't have protocol
192  * ID, we can use it
193  */
194
195 static guint pppmux_def_prot_id = 0;
196
197 /* PPP definitions */
198
199 /*
200  * Used by the GTP dissector as well.
201  */
202 const value_string ppp_vals[] = {
203         {PPP_PADDING,   "Padding Protocol" },
204         {PPP_ROHC_SCID, "ROHC small-CID" },
205         {PPP_ROHC_LCID, "ROHC large-CID" },
206         {PPP_IP,        "IP"             },
207         {PPP_OSI,       "OSI"            },
208         {PPP_DEC4,      "DECnet Phase IV" },
209         {PPP_AT,        "Appletalk"      },
210         {PPP_IPX,       "Netware IPX/SPX"},
211         {PPP_VJC_COMP,  "VJ compressed TCP"},
212         {PPP_VJC_UNCOMP,"VJ uncompressed TCP"},
213         {PPP_BPDU,      "Bridging PDU"},
214         {PPP_ST,        "Stream Protocol (ST-II)" },
215         {PPP_VINES,     "Vines"          },
216         {PPP_AT_EDDP,   "AppleTalk EDDP" },
217         {PPP_AT_SB,     "AppleTalk SmartBuffered" },
218         {PPP_MP,        "Multilink"},
219         {PPP_NB,        "NETBIOS Framing" },
220         {PPP_CISCO,     "Cisco Systems" },
221         {PPP_ASCOM,     "Ascom Timeplex" },
222         {PPP_LBLB,      "Fujitsu Link Backup and Load Balancing" },
223         {PPP_RL,        "DCA Remote Lan" },
224         {PPP_SDTP,      "Serial Data Transport Protocol" },
225         {PPP_LLC,       "SNA over LLC" },
226         {PPP_SNA,       "SNA" },
227         {PPP_IPV6HC,    "IPv6 Header Compression " },
228         {PPP_KNX,       "KNX Bridging Data" },
229         {PPP_ENCRYPT,   "Encryption" },
230         {PPP_ILE,       "Individual Link Encryption" },
231         {PPP_IPV6,      "IPv6"           },
232         {PPP_MUX,       "PPP Multiplexing"},
233         {PPP_RTP_FH,    "RTP IPHC Full Header" },
234         {PPP_RTP_CTCP,  "RTP IPHC Compressed TCP" },
235         {PPP_RTP_CNTCP, "RTP IPHC Compressed Non TCP" },
236         {PPP_RTP_CUDP8, "RTP IPHC Compressed UDP 8" },
237         {PPP_RTP_CRTP8, "RTP IPHC Compressed RTP 8" },
238         {PPP_STAMPEDE,  "Stampede Bridging" },
239         {PPP_MPPLUS,    "MP+ Protocol" },
240         {PPP_NTCITS_IPI,"NTCITS IPI" },
241         {PPP_ML_SLCOMP, "single link compression in multilink" },
242         {PPP_COMP,      "compressed packet" },
243         {PPP_STP_HELLO, "802.1d Hello Packet" },
244         {PPP_IBM_SR,    "IBM Source Routing BPDU" },
245         {PPP_DEC_LB,    "DEC LANBridge100 Spanning Tree"},
246         {PPP_CDP,       "Cisco Discovery Protocol" },
247         {PPP_NETCS,     "Netcs Twin Routing" },
248         {PPP_STP,       "Scheduled Transfer Protocol" },
249         {PPP_EDP,       "Extreme Discovery Protocol" },
250         {PPP_OSCP,      "Optical Supervisory Channel Protocol" },
251         {PPP_OSCP2,     "Optical Supervisory Channel Protocol" },
252         {PPP_LUXCOM,    "Luxcom" },
253         {PPP_SIGMA,     "Sigma Network Systems" },
254         {PPP_ACSP,      "Apple Client Server Protocol" },
255         {PPP_MPLS_UNI,  "MPLS Unicast"},
256         {PPP_MPLS_MULTI, "MPLS Multicast"},
257         {PPP_P12844,    "IEEE p1284.4 standard - data packets" },
258         {PPP_ETSI,      "ETSI TETRA Networks Procotol Type 1" },
259         {PPP_MFTP,      "Multichannel Flow Treatment Protocol" },
260         {PPP_RTP_CTCPND,"RTP IPHC Compressed TCP No Delta" },
261         {PPP_RTP_CS,    "RTP IPHC Context State" },
262         {PPP_RTP_CUDP16,"RTP IPHC Compressed UDP 16" },
263         {PPP_RTP_CRDP16,"RTP IPHC Compressed RTP 16" },
264         {PPP_CCCP,      "Cray Communications Control Protocol" },
265         {PPP_CDPD_MNRP, "CDPD Mobile Network Registration Protocol" },
266         {PPP_EXPANDAP,  "Expand accelarator protocol" },
267         {PPP_ODSICP,    "ODSICP NCP" },
268         {PPP_DOCSIS,    "DOCSIS DLL" },
269         {PPP_LZS,       "Stacker LZS" },
270         {PPP_REFTEK,    "RefTek Protocol" },
271         {PPP_FC,        "Fibre Channel" },
272         {PPP_EMIT,      "EMIT Protocols" },
273         {PPP_IPCP,      "IP Control Protocol" },
274         {PPP_OSICP,     "OSI Control Protocol" },
275         {PPP_XNSIDPCP,  "Xerox NS IDP Control Protocol" },
276         {PPP_DECNETCP,  "DECnet Phase IV Control Protocol" },
277         {PPP_ATCP,      "AppleTalk Control Protocol" },
278         {PPP_IPXCP,     "IPX Control Protocol" },
279         {PPP_BRIDGENCP, "Bridging NCP" },
280         {PPP_SPCP,      "Stream Protocol Control Protocol" },
281         {PPP_BVCP,      "Banyan Vines Control Protocol" },
282         {PPP_MLCP,      "Multi-Link Control Protocol" },
283         {PPP_NBCP,      "NETBIOS Framing Control Protocol" },
284         {PPP_CISCOCP,   "Cisco Systems Control Protocol" },
285         {PPP_ASCOMCP,   "Ascom Timeplex" },
286         {PPP_LBLBCP,    "Fujitsu LBLB Control Protocol" },
287         {PPP_RLNCP,     "DCA Remote Lan Network Control Protocol" },
288         {PPP_SDCP,      "Serial Data Control Protocol" },
289         {PPP_LLCCP,     "SNA over LLC Control Protocol" },
290         {PPP_SNACP,     "SNA Control Protocol" },
291         {PPP_KNXCP,     "KNX Bridging Control Protocol" },
292         {PPP_ECP,       "Encryption Control Protocol" },
293         {PPP_ILECP,     "Individual Encryption Control Protocol" },
294         {PPP_IPV6CP,    "IPv6 Control Protocol" },
295         {PPP_MUXCP,     "PPPMux Control Protocol"},
296         {PPP_STAMPEDECP,"Stampede Bridging Control Protocol" },
297         {PPP_MPPCP,     "MP+ Contorol Protocol" },
298         {PPP_IPICP,     "NTCITS IPI Control Protocol" },
299         {PPP_SLCC,      "single link compression in multilink control" },
300         {PPP_CCP,       "Compression Control Protocol" },
301         {PPP_CDPCP,     "CDP Control Protocol" },
302         {PPP_NETCSCP,   "Netcs Twin Routing" },
303         {PPP_STPCP,     "STP - Control Protocol" },
304         {PPP_EDPCP,     "EDP Control Protocol" },
305         {PPP_ACSPC,     "Apple Client Server Protocol Control" },
306         {PPP_MPLSCP,    "MPLS Control Protocol" },
307         {PPP_P12844CP,  "IEEE p1284.4 standard - Protocol Control" },
308         {PPP_ETSICP,    "ETSI TETRA TNP1 Control Protocol" },
309         {PPP_MFTPCP,    "Multichannel Flow Treatment Protocol" },
310         {PPP_LCP,       "Link Control Protocol" },
311         {PPP_PAP,       "Password Authentication Protocol"  },
312         {PPP_LQR,       "Link Quality Report protocol" },
313         {PPP_SPAP,      "Shiva Password Authentication Protocol" },
314         {PPP_CBCP,      "Callback Control Protocol" },
315         {PPP_BACP,      "Bandwidth Allocation Control Protocol" },
316         {PPP_BAP,       "Bandwidth Allocation Protocol" },
317         {PPP_CONTCP,    "Container Control Protocol" },
318         {PPP_CHAP,      "Challenge Handshake Authentication Protocol" },
319         {PPP_RSAAP,     "RSA Authentication Protocol" },
320         {PPP_EAP,       "Extensible Authentication Protocol" },
321         {PPP_SIEP,      "Mitsubishi Security Information Exchange Protocol"},
322         {PPP_SBAP,      "Stampede Bridging Authorization Protocol" },
323         {PPP_PRPAP,     "Proprietary Authentication Protocol" },
324         {PPP_PRPAP2,    "Proprietary Authentication Protocol" },
325         {PPP_PRPNIAP,   "Proprietary Node ID Authentication Protocol" },
326         {0,             NULL            }
327 };
328
329 /* CP (LCP, IPCP, etc.) codes.
330  * from pppd fsm.h
331  */
332 #define CONFREQ    1  /* Configuration Request */
333 #define CONFACK    2  /* Configuration Ack */
334 #define CONFNAK    3  /* Configuration Nak */
335 #define CONFREJ    4  /* Configuration Reject */
336 #define TERMREQ    5  /* Termination Request */
337 #define TERMACK    6  /* Termination Ack */
338 #define CODEREJ    7  /* Code Reject */
339
340 static const value_string cp_vals[] = {
341         {CONFREQ,    "Configuration Request" },
342         {CONFACK,    "Configuration Ack" },
343         {CONFNAK,    "Configuration Nak" },
344         {CONFREJ,    "Configuration Reject" },
345         {TERMREQ,    "Termination Request" },
346         {TERMACK,    "Termination Ack" },
347         {CODEREJ,    "Code Reject" },
348         {0,          NULL            } };
349
350 /*
351  * LCP-specific packet types.
352  */
353 #define PROTREJ    8  /* Protocol Reject */
354 #define ECHOREQ    9  /* Echo Request */
355 #define ECHOREP    10 /* Echo Reply */
356 #define DISCREQ    11 /* Discard Request */
357 #define IDENT      12 /* Identification */
358 #define TIMEREMAIN 13 /* Time remaining */
359
360 /*
361  * CCP-specific packet types.
362  */
363 #define RESETREQ   14  /* Reset Request */
364 #define RESETACK   15  /* Reset Ack */
365
366 /*
367  * CBCP-specific packet types.
368  */
369 #define CBREQ      1  /* Callback Request */
370 #define CBRES      2  /* Callback Response */
371 #define CBACK      3  /* Callback Ack */
372
373 #define CBCP_OPT  6 /* Use callback control protocol */
374
375 /*
376  * BAP-specific packet types.
377  */
378 #define BAP_CREQ   1  /* Call Request */
379 #define BAP_CRES   2  /* Call Response */
380 #define BAP_CBREQ  3  /* Callback Request */
381 #define BAP_CBRES  4  /* Callback Response */
382 #define BAP_LDQREQ 5  /* Link Drop Query Request */
383 #define BAP_LDQRES 6  /* Link Drop Query Response */
384 #define BAP_CSI    7  /* Call Status Indication */
385 #define BAP_CSRES  8  /* Call Status Response */
386
387 static const value_string lcp_vals[] = {
388         {CONFREQ,    "Configuration Request" },
389         {CONFACK,    "Configuration Ack" },
390         {CONFNAK,    "Configuration Nak" },
391         {CONFREJ,    "Configuration Reject" },
392         {TERMREQ,    "Termination Request" },
393         {TERMACK,    "Termination Ack" },
394         {CODEREJ,    "Code Reject" },
395         {PROTREJ,    "Protocol Reject" },
396         {ECHOREQ,    "Echo Request" },
397         {ECHOREP,    "Echo Reply" },
398         {DISCREQ,    "Discard Request" },
399         {IDENT,      "Identification" },
400         {TIMEREMAIN, "Time Remaining" },
401         {0,          NULL }
402 };
403
404 static const value_string ccp_vals[] = {
405         {CONFREQ,    "Configuration Request" },
406         {CONFACK,    "Configuration Ack" },
407         {CONFNAK,    "Configuration Nak" },
408         {CONFREJ,    "Configuration Reject" },
409         {TERMREQ,    "Termination Request" },
410         {TERMACK,    "Termination Ack" },
411         {CODEREJ,    "Code Reject" },
412         {RESETREQ,   "Reset Request" },
413         {RESETACK,   "Reset Ack" },
414         {0,          NULL }
415 };
416
417 static const value_string cbcp_vals[] = {
418         {CBREQ,      "Callback Request" },
419         {CBRES,      "Callback Response" },
420         {CBACK,      "Callback Ack" },
421         {0,          NULL }
422 };
423
424 static const value_string bap_vals[] = {
425         {BAP_CREQ,      "Call Request" },
426         {BAP_CRES,      "Call Response" },
427         {BAP_CBREQ,     "Callback Request" },
428         {BAP_CBRES,     "Callback Response" },
429         {BAP_LDQREQ,    "Link Drop Query Request" },
430         {BAP_LDQRES,    "Link Drop Query Response" },
431         {BAP_CSI,       "Call Status Indication" },
432         {BAP_CSRES,     "Call Status Response" },
433         {0,             NULL }
434 };
435
436 #define BAP_RESP_CODE_REQACK    0x00
437 #define BAP_RESP_CODE_REQNAK    0x01
438 #define BAP_RESP_CODE_REQREJ    0x02
439 #define BAP_RESP_CODE_REQFULLNAK        0x03
440 static const value_string bap_resp_code_vals[] = {
441         {BAP_RESP_CODE_REQACK,  "Request Ack" },
442         {BAP_RESP_CODE_REQNAK,  "Request Nak" },
443         {BAP_RESP_CODE_REQREJ,  "Request Rej" },
444         {BAP_RESP_CODE_REQFULLNAK,      "Request Full Nak" },
445         {0,                     NULL }
446 };
447
448 #define BAP_LINK_TYPE_ISDN      0       /* ISDN */
449 #define BAP_LINK_TYPE_X25       1       /* X.25 */
450 #define BAP_LINK_TYPE_ANALOG    2       /* Analog */
451 #define BAP_LINK_TYPE_SD        3       /* Switched Digital (non-ISDN) */
452 #define BAP_LINK_TYPE_ISDNOV    4       /* ISDN data over voice */
453 #define BAP_LINK_TYPE_RESV5     5       /* Reserved */
454 #define BAP_LINK_TYPE_RESV6     6       /* Reserved */
455 #define BAP_LINK_TYPE_RESV7     7       /* Reserved */
456 static const value_string bap_link_type_vals[] = {
457         {BAP_LINK_TYPE_ISDN,    "ISDN" },
458         {BAP_LINK_TYPE_X25,     "X.25" },
459         {BAP_LINK_TYPE_ANALOG,  "Analog" },
460         {BAP_LINK_TYPE_SD,      "Switched Digital (non-ISDN)" },
461         {BAP_LINK_TYPE_ISDNOV,  "ISDN data over voice" },
462         {BAP_LINK_TYPE_RESV5,   "Reserved" },
463         {BAP_LINK_TYPE_RESV6,   "Reserved" },
464         {BAP_LINK_TYPE_RESV7,   "Reserved" },
465         {0,                     NULL }
466 };
467
468 #define BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT       1       /* Unique Digit */
469 #define BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM        2       /* Subscriber Number */
470 #define BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR 3 /* Phone Number Sub Address */
471 static const value_string bap_phone_delta_subopt_vals[] = {
472         {BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT,     "Unique Digit" },
473         {BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM,      "Subscriber Number" },
474         {BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR, "Phone Number Sub Address" },
475         {0,                                     NULL }
476 };
477
478 /*
479  * Cause codes for Cause.
480  *
481  * The following code table is taken from packet-q931.c but is slightly
482  * adapted to BAP protocol.
483  */
484 static const value_string q931_cause_code_vals[] = {
485         { 0x00, "Call successful" },
486         { 0x01, "Unallocated (unassigned) number" },
487         { 0x02, "No route to specified transit network" },
488         { 0x03, "No route to destination" },
489         { 0x04, "Send special information tone" },
490         { 0x05, "Misdialled trunk prefix" },
491         { 0x06, "Channel unacceptable" },
492         { 0x07, "Call awarded and being delivered in an established channel" },
493         { 0x08, "Prefix 0 dialed but not allowed" },
494         { 0x09, "Prefix 1 dialed but not allowed" },
495         { 0x0A, "Prefix 1 dialed but not required" },
496         { 0x0B, "More digits received than allowed, call is proceeding" },
497         { 0x10, "Normal call clearing" },
498         { 0x11, "User busy" },
499         { 0x12, "No user responding" },
500         { 0x13, "No answer from user (user alerted)" },
501         { 0x14, "Subscriber absent" },
502         { 0x15, "Call rejected" },
503         { 0x16, "Number changed" },
504         { 0x17, "Reverse charging rejected" },
505         { 0x18, "Call suspended" },
506         { 0x19, "Call resumed" },
507         { 0x1A, "Non-selected user clearing" },
508         { 0x1B, "Destination out of order" },
509         { 0x1C, "Invalid number format (incomplete number)" },
510         { 0x1D, "Facility rejected" },
511         { 0x1E, "Response to STATUS ENQUIRY" },
512         { 0x1F, "Normal unspecified" },
513         { 0x21, "Circuit out of order" },
514         { 0x22, "No circuit/channel available" },
515         { 0x23, "Destination unattainable" },
516         { 0x25, "Degraded service" },
517         { 0x26, "Network out of order" },
518         { 0x27, "Transit delay range cannot be achieved" },
519         { 0x28, "Throughput range cannot be achieved" },
520         { 0x29, "Temporary failure" },
521         { 0x2A, "Switching equipment congestion" },
522         { 0x2B, "Access information discarded" },
523         { 0x2C, "Requested circuit/channel not available" },
524         { 0x2D, "Pre-empted" },
525         { 0x2E, "Precedence call blocked" },
526         { 0x2F, "Resources unavailable, unspecified" },
527         { 0x31, "Quality of service unavailable" },
528         { 0x32, "Requested facility not subscribed" },
529         { 0x33, "Reverse charging not allowed" },
530         { 0x34, "Outgoing calls barred" },
531         { 0x35, "Outgoing calls barred within CUG" },
532         { 0x36, "Incoming calls barred" },
533         { 0x37, "Incoming calls barred within CUG" },
534         { 0x38, "Call waiting not subscribed" },
535         { 0x39, "Bearer capability not authorized" },
536         { 0x3A, "Bearer capability not presently available" },
537         { 0x3E, "Inconsistency in designated outgoing access information and subscriber class" },
538         { 0x3F, "Service or option not available, unspecified" },
539         { 0x41, "Bearer capability not implemented" },
540         { 0x42, "Channel type not implemented" },
541         { 0x43, "Transit network selection not implemented" },
542         { 0x44, "Message not implemented" },
543         { 0x45, "Requested facility not implemented" },
544         { 0x46, "Only restricted digital information bearer capability is available" },
545         { 0x4F, "Service or option not implemented, unspecified" },
546         { 0x51, "Invalid call reference value" },
547         { 0x52, "Identified channel does not exist" },
548         { 0x53, "Call identity does not exist for suspended call" },
549         { 0x54, "Call identity in use" },
550         { 0x55, "No call suspended" },
551         { 0x56, "Call having the requested call identity has been cleared" },
552         { 0x57, "Called user not member of CUG" },
553         { 0x58, "Incompatible destination" },
554         { 0x59, "Non-existent abbreviated address entry" },
555         { 0x5A, "Destination address missing, and direct call not subscribed" },
556         { 0x5B, "Invalid transit network selection (national use)" },
557         { 0x5C, "Invalid facility parameter" },
558         { 0x5D, "Mandatory information element is missing" },
559         { 0x5F, "Invalid message, unspecified" },
560         { 0x60, "Mandatory information element is missing" },
561         { 0x61, "Message type non-existent or not implemented" },
562         { 0x62, "Message not compatible with call state or message type non-existent or not implemented" },
563         { 0x63, "Information element nonexistant or not implemented" },
564         { 0x64, "Invalid information element contents" },
565         { 0x65, "Message not compatible with call state" },
566         { 0x66, "Recovery on timer expiry" },
567         { 0x67, "Parameter non-existent or not implemented - passed on" },
568         { 0x6E, "Message with unrecognized parameter discarded" },
569         { 0x6F, "Protocol error, unspecified" },
570         { 0x7F, "Internetworking, unspecified" },
571         { 0xFF, "Non-specific failure" },
572         { 0,    NULL }
573 };
574
575 static const value_string bap_call_status_opt_action_vals[] = {
576         {0,     "No retry" },
577         {1,     "Retry" },
578         {0,     NULL }
579 };
580
581 #define STAC_CM_NONE            0
582 #define STAC_CM_LCB             1
583 #define STAC_CM_CRC             2
584 #define STAC_CM_SN              3
585 #define STAC_CM_EXTMODE         4
586 static const value_string stac_checkmode_vals[] = {
587         {STAC_CM_NONE,          "None" },
588         {STAC_CM_LCB,           "LCB" },
589         {STAC_CM_CRC,           "CRC" },
590         {STAC_CM_SN,            "Sequence Number" },
591         {STAC_CM_EXTMODE,       "Extended Mode" },
592         {0,                     NULL }
593 };
594
595 #define LZSDCP_CM_NONE          0
596 #define LZSDCP_CM_LCB           1
597 #define LZSDCP_CM_SN            2
598 #define LZSDCP_CM_SN_LCB        3
599 static const value_string lzsdcp_checkmode_vals[] = {
600         {LZSDCP_CM_NONE,        "None" },
601         {LZSDCP_CM_LCB,         "LCB" },
602         {LZSDCP_CM_SN,          "Sequence Number" },
603         {LZSDCP_CM_SN_LCB,      "Sequence Number + LCB" },
604         {0,                     NULL }
605 };
606
607 #define LZSDCP_PM_NONE          0
608 #define LZSDCP_PM_PROC_UNCOMP   1
609 static const value_string lzsdcp_processmode_vals[] = {
610         {LZSDCP_PM_NONE,        "None" },
611         {LZSDCP_PM_PROC_UNCOMP, "Process-Uncompressed" },
612         {0,                     NULL }
613 };
614
615 /*
616  * Options.  (LCP)
617  */
618 #define CI_MRU                  1       /* Maximum Receive Unit */
619 #define CI_ASYNCMAP             2       /* Async Control Character Map */
620 #define CI_AUTHTYPE             3       /* Authentication Type */
621 #define CI_QUALITY              4       /* Quality Protocol */
622 #define CI_MAGICNUMBER          5       /* Magic Number */
623 #define CI_PCOMPRESSION         7       /* Protocol Field Compression */
624 #define CI_ACCOMPRESSION        8       /* Address/Control Field Compression */
625 #define CI_FCS_ALTERNATIVES     9       /* FCS Alternatives (RFC 1570) */
626 #define CI_SELF_DESCRIBING_PAD  10      /* Self-Describing Pad (RFC 1570) */
627 #define CI_NUMBERED_MODE        11      /* Numbered Mode (RFC 1663) */
628 #define CI_CALLBACK             13      /* Callback (RFC 1570) */
629 #define CI_COMPOUND_FRAMES      15      /* Compound frames (RFC 1570) */
630 #define CI_MULTILINK_MRRU       17      /* Multilink MRRU (RFC 1717) */
631 #define CI_MULTILINK_SSNH       18      /* Multilink Short Sequence Number
632                                            Header (RFC 1717) */
633 #define CI_MULTILINK_EP_DISC    19      /* Multilink Endpoint Discriminator
634                                            (RFC 1717) */
635 #define CI_DCE_IDENTIFIER       21      /* DCE Identifier */
636 #define CI_MULTILINK_PLUS_PROC  22      /* Multilink Plus Procedure */
637 #define CI_LINK_DISC_FOR_BACP   23      /* Link Discriminator for BACP
638                                            (RFC 2125) */
639 #define CI_LCP_AUTHENTICATION   24      /* LCP Authentication Option */
640 #define CI_COBS                 25      /* Consistent Overhead Byte
641                                            Stuffing */
642 #define CI_PREFIX_ELISION       26      /* Prefix elision */
643 #define CI_MULTILINK_HDR_FMT    27      /* Multilink header format */
644 #define CI_INTERNATIONALIZATION 28      /* Internationalization (RFC 2484) */
645 #define CI_SDL_ON_SONET_SDH     29      /* Simple Data Link on SONET/SDH */
646
647 static void dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
648                         int offset, guint length, packet_info *pinfo,
649                         proto_tree *tree);
650 static void dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
651                         int offset, guint length, packet_info *pinfo,
652                         proto_tree *tree);
653 static void dissect_lcp_protocol_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
654                         int offset, guint length, packet_info *pinfo,
655                         proto_tree *tree);
656 static void dissect_lcp_authprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
657                         int offset, guint length, packet_info *pinfo,
658                         proto_tree *tree);
659 static void dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp,
660                         tvbuff_t *tvb, int offset, guint length,
661                         packet_info *pinfo, proto_tree *tree);
662 static void dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp,
663                         tvbuff_t *tvb, int offset, guint length,
664                         packet_info *pinfo, proto_tree *tree);
665 static void dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp,
666                         tvbuff_t *tvb, int offset, guint length,
667                         packet_info *pinfo, proto_tree *tree);
668 static void dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp,
669                         tvbuff_t *tvb, int offset, guint length,
670                         packet_info *pinfo, proto_tree *tree);
671 static void dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
672                         int offset, guint length, packet_info *pinfo,
673                         proto_tree *tree);
674 static void dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp,
675                         tvbuff_t *tvb, int offset, guint length,
676                         packet_info *pinfo, proto_tree *tree);
677 static void dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp,
678                         tvbuff_t *tvb, int offset, guint length,
679                         packet_info *pinfo, proto_tree *tree);
680 static void dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp,
681                         tvbuff_t *tvb, int offset, guint length,
682                         packet_info *pinfo, proto_tree *tree);
683 static void dissect_lcp_internationalization_opt(const ip_tcp_opt *optp,
684                         tvbuff_t *tvb, int offset, guint length,
685                         packet_info *pinfo, proto_tree *tree);
686 static void dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
687
688 static const ip_tcp_opt lcp_opts[] = {
689         {
690                 CI_MRU,
691                 "Maximum Receive Unit",
692                 NULL,
693                 FIXED_LENGTH,
694                 4,
695                 dissect_lcp_mru_opt
696         },
697         {
698                 CI_ASYNCMAP,
699                 "Async Control Character Map",
700                 NULL,
701                 FIXED_LENGTH,
702                 6,
703                 dissect_lcp_async_map_opt
704         },
705         {
706                 CI_AUTHTYPE,
707                 "Authentication protocol",
708                 &ett_lcp_authprot_opt,
709                 VARIABLE_LENGTH,
710                 4,
711                 dissect_lcp_authprot_opt
712         },
713         {
714                 CI_QUALITY,
715                 "Quality protocol",
716                 &ett_lcp_qualprot_opt,
717                 VARIABLE_LENGTH,
718                 4,
719                 dissect_lcp_protocol_opt
720         },
721         {
722                 CI_MAGICNUMBER,
723                 "Magic number",
724                 NULL,
725                 FIXED_LENGTH,
726                 6,
727                 dissect_lcp_magicnumber_opt
728         },
729         {
730                 CI_PCOMPRESSION,
731                 "Protocol field compression",
732                 NULL,
733                 FIXED_LENGTH,
734                 2,
735                 NULL
736         },
737         {
738                 CI_ACCOMPRESSION,
739                 "Address/control field compression",
740                 NULL,
741                 FIXED_LENGTH,
742                 2,
743                 NULL
744         },
745         {
746                 CI_FCS_ALTERNATIVES,
747                 "FCS alternatives",
748                 &ett_lcp_fcs_alternatives_opt,
749                 FIXED_LENGTH,
750                 3,
751                 dissect_lcp_fcs_alternatives_opt
752         },
753         {
754                 CI_SELF_DESCRIBING_PAD,
755                 "Maximum octets of self-describing padding",
756                 NULL,
757                 FIXED_LENGTH,
758                 3,
759                 dissect_lcp_self_describing_pad_opt
760         },
761         {
762                 CI_NUMBERED_MODE,
763                 "Numbered mode",
764                 &ett_lcp_numbered_mode_opt,
765                 VARIABLE_LENGTH,
766                 4,
767                 dissect_lcp_numbered_mode_opt
768         },
769         {
770                 CI_CALLBACK,
771                 "Callback",
772                 &ett_lcp_callback_opt,
773                 VARIABLE_LENGTH,
774                 3,
775                 dissect_lcp_callback_opt,
776         },
777         {
778                 CI_COMPOUND_FRAMES,
779                 "Compound frames",
780                 NULL,
781                 FIXED_LENGTH,
782                 2,
783                 NULL
784         },
785         {
786                 CI_MULTILINK_MRRU,
787                 "Multilink MRRU",
788                 NULL,
789                 FIXED_LENGTH,
790                 4,
791                 dissect_lcp_multilink_mrru_opt
792         },
793         {
794                 CI_MULTILINK_SSNH,
795                 "Use short sequence number headers",
796                 NULL,
797                 FIXED_LENGTH,
798                 2,
799                 NULL
800         },
801         {
802                 CI_MULTILINK_EP_DISC,
803                 "Multilink endpoint discriminator",
804                 &ett_lcp_multilink_ep_disc_opt,
805                 VARIABLE_LENGTH,
806                 3,
807                 dissect_lcp_multilink_ep_disc_opt,
808         },
809         {
810                 CI_DCE_IDENTIFIER,
811                 "DCE identifier",
812                 NULL,
813                 VARIABLE_LENGTH,
814                 2,
815                 NULL
816         },
817         {
818                 CI_MULTILINK_PLUS_PROC,
819                 "Multilink Plus Procedure",
820                 NULL,
821                 VARIABLE_LENGTH,
822                 2,
823                 NULL
824         },
825         {
826                 CI_LINK_DISC_FOR_BACP,
827                 "Link discriminator for BAP",
828                 NULL,
829                 FIXED_LENGTH,
830                 4,
831                 dissect_lcp_bap_link_discriminator_opt
832         },
833         {
834                 CI_LCP_AUTHENTICATION,
835                 "LCP authentication",
836                 NULL,
837                 VARIABLE_LENGTH,
838                 2,
839                 NULL
840         },
841         {
842                 CI_COBS,
843                 "Consistent Overhead Byte Stuffing",
844                 NULL,
845                 VARIABLE_LENGTH,
846                 2,
847                 NULL
848         },
849         {
850                 CI_PREFIX_ELISION,
851                 "Prefix elision",
852                 NULL,
853                 VARIABLE_LENGTH,
854                 2,
855                 NULL
856         },
857         {
858                 CI_MULTILINK_HDR_FMT,
859                 "Multilink header format",
860                 NULL,
861                 VARIABLE_LENGTH,
862                 2,
863                 NULL
864         },
865         {
866                 CI_INTERNATIONALIZATION,
867                 "Internationalization",
868                 &ett_lcp_internationalization_opt,
869                 VARIABLE_LENGTH,
870                 7,
871                 dissect_lcp_internationalization_opt
872         },
873         {
874                 CI_SDL_ON_SONET_SDH,
875                 "Simple data link on SONET/SDH",
876                 NULL,
877                 VARIABLE_LENGTH,
878                 2,
879                 NULL
880         }
881 };
882
883 #define N_LCP_OPTS      (sizeof lcp_opts / sizeof lcp_opts[0])
884
885 /*
886  * CHAP Algorithms
887  */
888 #define CHAP_ALG_MD5    0x05    /* CHAP with MD5 */
889 #define CHAP_ALG_MSV1   0x80    /* MS-CHAPv1 */
890 #define CHAP_ALG_MSV2   0x81    /* MS-CHAPv2 */
891
892 static const value_string chap_alg_vals[] = {
893         {CHAP_ALG_MD5,  "CHAP with MD5" },
894         {CHAP_ALG_MSV1, "MS-CHAP" },
895         {CHAP_ALG_MSV2, "MS-CHAP-2" },
896         {0,             NULL }
897 };
898
899
900 /*
901  * Options.  (IPCP)
902  */
903 #define CI_ADDRS        1       /* IP Addresses (deprecated) (RFC 1172) */
904 #define CI_COMPRESSTYPE 2       /* Compression Type (RFC 1332) */
905 #define CI_ADDR         3       /* IP Address (RFC 1332) */
906 #define CI_MOBILE_IPv4  4       /* Mobile IPv4 (RFC 2290) */
907 #define CI_MS_DNS1      129     /* Primary DNS value (RFC 1877) */
908 #define CI_MS_WINS1     130     /* Primary WINS value (RFC 1877) */
909 #define CI_MS_DNS2      131     /* Secondary DNS value (RFC 1877) */
910 #define CI_MS_WINS2     132     /* Secondary WINS value (RFC 1877) */
911
912 static void dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
913                         int offset, guint length, packet_info *pinfo,
914                         proto_tree *tree);
915 static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
916                         int offset, guint length, packet_info *pinfo,
917                         proto_tree *tree);
918
919 static const ip_tcp_opt ipcp_opts[] = {
920         {
921                 CI_ADDRS,
922                 "IP addresses (deprecated)",
923                 &ett_ipcp_ipaddrs_opt,
924                 FIXED_LENGTH,
925                 10,
926                 dissect_ipcp_addrs_opt
927         },
928         {
929                 CI_COMPRESSTYPE,
930                 "IP compression protocol",
931                 &ett_ipcp_compressprot_opt,
932                 VARIABLE_LENGTH,
933                 4,
934                 dissect_lcp_protocol_opt
935         },
936         {
937                 CI_ADDR,
938                 "IP address",
939                 NULL,
940                 FIXED_LENGTH,
941                 6,
942                 dissect_ipcp_addr_opt
943         },
944         {
945                 CI_MOBILE_IPv4,
946                 "Mobile node's home IP address",
947                 NULL,
948                 FIXED_LENGTH,
949                 6,
950                 dissect_ipcp_addr_opt
951         },
952         {
953                 CI_MS_DNS1,
954                 "Primary DNS server IP address",
955                 NULL,
956                 FIXED_LENGTH,
957                 6,
958                 dissect_ipcp_addr_opt
959         },
960         {
961                 CI_MS_WINS1,
962                 "Primary WINS server IP address",
963                 NULL,
964                 FIXED_LENGTH,
965                 6,
966                 dissect_ipcp_addr_opt
967         },
968         {
969                 CI_MS_DNS2,
970                 "Secondary DNS server IP address",
971                 NULL,
972                 FIXED_LENGTH,
973                 6,
974                 dissect_ipcp_addr_opt
975         },
976         {
977                 CI_MS_WINS2,
978                 "Secondary WINS server IP address",
979                 NULL,
980                 FIXED_LENGTH,
981                 6,
982                 dissect_ipcp_addr_opt
983         }
984 };
985
986 #define N_IPCP_OPTS     (sizeof ipcp_opts / sizeof ipcp_opts[0])
987
988 /*
989  * Options.  (OSICP)
990  */
991 #define CI_OSICP_ALIGN_NPDU      1       /* Alignment of the OSI NPDU (RFC 1377) */
992
993 static void dissect_osicp_align_npdu_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
994                         int offset, guint length, packet_info *pinfo,
995                         proto_tree *tree);
996
997 static const ip_tcp_opt osicp_opts[] = {
998         {
999                 CI_OSICP_ALIGN_NPDU,
1000                 "Align-NPDU",
1001                 &ett_osicp_align_npdu_opt,
1002                 FIXED_LENGTH,
1003                 3,
1004                 dissect_osicp_align_npdu_opt
1005         }
1006 };
1007
1008 #define N_OSICP_OPTS     (sizeof osicp_opts / sizeof osicp_opts[0])
1009
1010 /*
1011  * Options.  (CCP)
1012  */
1013 #define CI_CCP_OUI      0       /* OUI (RFC1962) */
1014 #define CI_CCP_PREDICT1 1       /* Predictor type 1 (RFC1962) */
1015 #define CI_CCP_PREDICT2 2       /* Predictor type 2 (RFC1962) */
1016 #define CI_CCP_PUDDLE   3       /* Puddle Jumper (RFC1962) */
1017 #define CI_CCP_HPPPC    16      /* Hewlett-Packard PPC (RFC1962) */
1018 #define CI_CCP_STAC     17      /* stac Electronics LZS (RFC1974) */
1019 #define CI_CCP_MPPC     18      /* Microsoft PPC (RFC2218/3078) */
1020 #define CI_CCP_GFZA     19      /* Gandalf FZA (RFC1962) */
1021 #define CI_CCP_V42BIS   20      /* V.42bis compression */
1022 #define CI_CCP_BSDLZW   21      /* BSD LZW Compress (RFC1977) */
1023 #define CI_CCP_LZSDCP   23      /* LZS-DCP (RFC1967) */
1024 #define CI_CCP_MVRCA    24      /* MVRCA (Magnalink) (RFC1975) */
1025 #define CI_CCP_DEFLATE  26      /* Deflate (RFC1979) */
1026 #define CI_CCP_RESERVED 255     /* Reserved (RFC1962) */
1027
1028 /*
1029  * Microsoft Point-To-Point Compression (MPPC) and Encryption (MPPE)
1030  * supported bits.
1031  */
1032 #define MPPC_SUPPORTED_BITS_C   0x00000001      /* MPPC negotiation */
1033 #define MPPE_SUPPORTED_BITS_D   0x00000010      /* Obsolete */
1034 #define MPPE_SUPPORTED_BITS_L   0x00000020      /* 40-bit encryption */
1035 #define MPPE_SUPPORTED_BITS_S   0x00000040      /* 128-bit encryption */
1036 #define MPPE_SUPPORTED_BITS_M   0x00000080      /* 56-bit encryption */
1037 #define MPPE_SUPPORTED_BITS_H   0x01000000      /* stateless mode */
1038
1039 static void dissect_ccp_stac_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1040                         int offset, guint length, packet_info *pinfo,
1041                         proto_tree *tree);
1042
1043 static void dissect_ccp_mppc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1044                         int offset, guint length, packet_info *pinfo,
1045                         proto_tree *tree);
1046
1047 static void dissect_ccp_bsdcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1048                         int offset, guint length, packet_info *pinfo,
1049                         proto_tree *tree);
1050
1051 static void dissect_ccp_lzsdcp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1052                         int offset, guint length, packet_info *pinfo,
1053                         proto_tree *tree);
1054
1055 static void dissect_ccp_mvrca_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1056                         int offset, guint length, packet_info *pinfo,
1057                         proto_tree *tree);
1058
1059 static void dissect_ccp_deflate_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1060                         int offset, guint length, packet_info *pinfo,
1061                         proto_tree *tree);
1062
1063 static const ip_tcp_opt ccp_opts[] = {
1064         {
1065                 CI_CCP_STAC,
1066                 "Stac Electronics LZS",
1067                 &ett_ccp_stac_opt,
1068                 VARIABLE_LENGTH,
1069                 5,
1070                 /* In RFC 1974, this is a fixed-length field of size 5,
1071                    but in Ascend Proprietary STAC compression this field
1072                    is 6 octets. Sigh... */
1073                 dissect_ccp_stac_opt
1074         },
1075         {
1076                 CI_CCP_MPPC,
1077                 "Microsoft PPC",
1078                 &ett_ccp_mppc_opt,
1079                 FIXED_LENGTH,
1080                 6,
1081                 dissect_ccp_mppc_opt
1082         },
1083         {
1084                 CI_CCP_BSDLZW,
1085                 "BSD Compress",
1086                 &ett_ccp_bsdcomp_opt,
1087                 FIXED_LENGTH,
1088                 3,
1089                 dissect_ccp_bsdcomp_opt
1090         },
1091         {
1092                 CI_CCP_LZSDCP,
1093                 "LZS-DCP",
1094                 &ett_ccp_lzsdcp_opt,
1095                 FIXED_LENGTH,
1096                 6,
1097                 dissect_ccp_lzsdcp_opt
1098         },
1099         {
1100                 CI_CCP_MVRCA,
1101                 "MVRCA (Magnalink)",
1102                 &ett_ccp_mvrca_opt,
1103                 FIXED_LENGTH,
1104                 4,
1105                 dissect_ccp_mvrca_opt
1106         },
1107         {
1108                 CI_CCP_DEFLATE,
1109                 "Deflate",
1110                 &ett_ccp_deflate_opt,
1111                 FIXED_LENGTH,
1112                 4,   /* RFC1979 says the length is 3 but it's actually 4. */
1113                 dissect_ccp_deflate_opt
1114         },
1115 };
1116
1117 #define N_CCP_OPTS      (sizeof ccp_opts / sizeof ccp_opts[0])
1118
1119 /*
1120  * Options.  (CBCP)
1121  */
1122 #define CI_CBCP_NO_CALLBACK     1  /* No callback */
1123 #define CI_CBCP_CB_USER         2  /* Callback to a user-specified number */
1124 #define CI_CBCP_CB_PRE          3  /* Callback to a pre-specified or
1125                                             administrator specified number */
1126 #define CI_CBCP_CB_ANY          4  /* Callback to any of a list of numbers */
1127
1128 static void dissect_cbcp_no_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1129                         int offset, guint length, packet_info *pinfo,
1130                         proto_tree *tree);
1131
1132 static void dissect_cbcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1133                         int offset, guint length, packet_info *pinfo,
1134                         proto_tree *tree);
1135
1136 static const ip_tcp_opt cbcp_opts[] = {
1137         {
1138                 CI_CBCP_NO_CALLBACK,
1139                 "No callback",
1140                 NULL,
1141                 FIXED_LENGTH,
1142                 2,
1143                 dissect_cbcp_no_callback_opt
1144         },
1145         {
1146                 CI_CBCP_CB_USER,
1147                 "Callback to a user-specified number",
1148                 &ett_cbcp_callback_opt,
1149                 VARIABLE_LENGTH,
1150                 4,
1151                 dissect_cbcp_callback_opt
1152         },
1153         {
1154                 CI_CBCP_CB_PRE,
1155                 "Callback to a pre-specified or admin-specified number",
1156                 &ett_cbcp_callback_opt,
1157                 FIXED_LENGTH,
1158                 3,
1159                 dissect_cbcp_callback_opt
1160         },
1161         {
1162                 CI_CBCP_CB_ANY,
1163                 "Callback to any of a list of numbers",
1164                 &ett_cbcp_callback_opt,
1165                 VARIABLE_LENGTH,
1166                 4,
1167                 dissect_cbcp_callback_opt
1168         }
1169
1170 };
1171
1172 #define N_CBCP_OPTS     (sizeof cbcp_opts / sizeof cbcp_opts[0])
1173
1174 /*
1175  * Options.  (BACP)
1176  */
1177 #define CI_BACP_FAVORED_PEER    1  /* Favored-Peer */
1178
1179 static void dissect_bacp_favored_peer_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1180                         int offset, guint length, packet_info *pinfo,
1181                         proto_tree *tree);
1182
1183 static const ip_tcp_opt bacp_opts[] = {
1184         {
1185                 CI_BACP_FAVORED_PEER,
1186                 "Favored-Peer",
1187                 &ett_bacp_favored_peer_opt,
1188                 FIXED_LENGTH,
1189                 6,
1190                 dissect_bacp_favored_peer_opt
1191         }
1192 };
1193
1194 #define N_BACP_OPTS     (sizeof bacp_opts / sizeof bacp_opts[0])
1195
1196 /*
1197  * Options.  (BAP)
1198  */
1199 #define CI_BAP_LINK_TYPE        1  /* Link Type */
1200 #define CI_BAP_PHONE_DELTA      2  /* Phone-Delta */
1201 #define CI_BAP_NO_PHONE_NUM_NEEDED      3  /* No Phone Number Needed */
1202 #define CI_BAP_REASON           4  /* Reason */
1203 #define CI_BAP_LINK_DISC        5  /* Link Discriminator */
1204 #define CI_BAP_CALL_STATUS      6  /* Call Status */
1205
1206 static void dissect_bap_link_type_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1207                         int offset, guint length, packet_info *pinfo,
1208                         proto_tree *tree);
1209
1210 static void dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1211                         int offset, guint length, packet_info *pinfo,
1212                         proto_tree *tree);
1213
1214 static void dissect_bap_link_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1215                         int offset, guint length, packet_info *pinfo,
1216                         proto_tree *tree);
1217
1218 static void dissect_bap_reason_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1219                         int offset, guint length, packet_info *pinfo,
1220                         proto_tree *tree);
1221
1222 static void dissect_bap_call_status_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1223                         int offset, guint length, packet_info *pinfo,
1224                         proto_tree *tree);
1225
1226 static const ip_tcp_opt bap_opts[] = {
1227         {
1228                 CI_BAP_LINK_TYPE,
1229                 "Link Type",
1230                 &ett_bap_link_type_opt,
1231                 FIXED_LENGTH,
1232                 5,
1233                 dissect_bap_link_type_opt
1234         },
1235         {
1236                 CI_BAP_PHONE_DELTA,
1237                 "Phone Delta",
1238                 &ett_bap_phone_delta_opt,
1239                 VARIABLE_LENGTH,
1240                 4,
1241                 dissect_bap_phone_delta_opt
1242         },
1243         {
1244                 CI_BAP_NO_PHONE_NUM_NEEDED,
1245                 "No Phone Number Needed",
1246                 NULL,
1247                 FIXED_LENGTH,
1248                 2,
1249                 NULL
1250         },
1251         {
1252                 CI_BAP_REASON,
1253                 "Reason",
1254                 NULL,
1255                 VARIABLE_LENGTH,
1256                 2,
1257                 dissect_bap_reason_opt
1258         },
1259         {
1260                 CI_BAP_LINK_DISC,
1261                 "Link Discriminator",
1262                 NULL,
1263                 FIXED_LENGTH,
1264                 4,
1265                 dissect_bap_link_disc_opt
1266         },
1267         {
1268                 CI_BAP_CALL_STATUS,
1269                 "Call Status",
1270                 &ett_bap_call_status_opt,
1271                 FIXED_LENGTH,
1272                 4,
1273                 dissect_bap_call_status_opt
1274         }
1275 };
1276
1277 #define N_BAP_OPTS      (sizeof bap_opts / sizeof bap_opts[0])
1278
1279 static void dissect_ppp(tvbuff_t *tvb, packet_info *pinfo,
1280     proto_tree *tree);
1281
1282 static const value_string pap_vals[] = {
1283         {CONFREQ,    "Authenticate-Request" },
1284         {CONFACK,    "Authenticate-Ack" },
1285         {CONFNAK,    "Authenticate-Nak" },
1286         {0,          NULL            } };
1287
1288 static void dissect_pap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1289
1290 #define CHAP_CHAL  1  /* CHAP Challenge */
1291 #define CHAP_RESP  2  /* CHAP Response */
1292 #define CHAP_SUCC  3  /* CHAP Success */
1293 #define CHAP_FAIL  4  /* CHAP Failure */
1294
1295 static const value_string chap_vals[] = {
1296         {CHAP_CHAL,  "Challenge" },
1297         {CHAP_RESP,  "Response" },
1298         {CHAP_SUCC,  "Success" },
1299         {CHAP_FAIL,  "Failure" },
1300         {0,          NULL            } };
1301
1302 static void dissect_chap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1303
1304 static const value_string pppmuxcp_vals[] = {
1305         {CONFREQ,    "Configuration Request" },
1306         {CONFACK,    "Configuration Ack" },
1307         {0,          NULL}
1308 };
1309
1310 /*
1311  * PPPMuxCP options
1312  */
1313
1314 #define CI_DEFAULT_PID   1
1315
1316 static void dissect_pppmuxcp_def_pid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1317                         int offset, guint length, packet_info *pinfo, proto_tree *tree);
1318
1319
1320 static const ip_tcp_opt pppmuxcp_opts[] = {
1321         {
1322                 CI_DEFAULT_PID,
1323                 "Default Protocol ID",
1324                 NULL,
1325                 FIXED_LENGTH,
1326                 4,
1327                 dissect_pppmuxcp_def_pid_opt
1328         }
1329 };
1330
1331 #define N_PPPMUXCP_OPTS (sizeof pppmuxcp_opts / sizeof pppmuxcp_opts[0])
1332
1333 /*
1334  * Options.  (IPv6CP)
1335  */
1336 #define CI_IPV6CP_IF_ID         1       /* Interface Identifier (RFC 2472) */
1337 #define CI_IPV6CP_COMPRESSTYPE  2       /* Compression Type (RFC 2472) */
1338
1339 static void dissect_ipv6cp_if_id_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1340                         int offset, guint length, packet_info *pinfo,
1341                         proto_tree *tree);
1342
1343 static const ip_tcp_opt ipv6cp_opts[] = {
1344         {
1345                 CI_IPV6CP_IF_ID,
1346                 "Interface Identifier",
1347                 &ett_ipv6cp_if_id_opt,
1348                 FIXED_LENGTH,
1349                 10,
1350                 dissect_ipv6cp_if_id_opt
1351         },
1352         {
1353                 CI_COMPRESSTYPE,
1354                 "IPv6 compression protocol",
1355                 &ett_ipcp_compressprot_opt,
1356                 VARIABLE_LENGTH,
1357                 4,
1358                 dissect_lcp_protocol_opt
1359         },
1360 };
1361
1362 #define N_IPV6CP_OPTS   (sizeof ipv6cp_opts / sizeof ipv6cp_opts[0])
1363
1364 /*
1365 *******************************************************************************
1366 * DETAILS : Calculate a new FCS-16 given the current FCS-16 and the new data.
1367 *******************************************************************************
1368 */
1369 static guint16
1370 fcs16(tvbuff_t * tvbuff)
1371 {
1372     guint len = tvb_length(tvbuff)-2;
1373
1374     /* Check for Invalid Length */
1375     if (len == 0)
1376         return (0x0000);
1377     return crc16_ccitt_tvb(tvbuff, len);
1378 }
1379
1380 /*
1381 *******************************************************************************
1382 * DETAILS : Calculate a new FCS-32 given the current FCS-32 and the new data.
1383 *******************************************************************************
1384 */
1385 static guint32
1386 fcs32(tvbuff_t * tvbuff)
1387 {
1388     guint len = tvb_length(tvbuff)-4;
1389
1390     /* Check for invalid Length */
1391     if (len == 0)
1392         return (0x00000000);
1393     return crc32_ccitt_tvb(tvbuff, len);
1394 }
1395
1396 tvbuff_t *
1397 decode_fcs(tvbuff_t *tvb, proto_tree *fh_tree, int fcs_decode, int proto_offset)
1398 {
1399   tvbuff_t   *next_tvb;
1400   gint       len, reported_len;
1401   int        rx_fcs_offset;
1402   guint32    rx_fcs_exp;
1403   guint32    rx_fcs_got;
1404
1405   /*
1406    * Remove the FCS, if any, from the packet data.
1407    */
1408   switch (fcs_decode) {
1409
1410   case NO_FCS:
1411     next_tvb = tvb_new_subset(tvb, proto_offset, -1, -1);
1412     break;
1413
1414   case FCS_16:
1415     /*
1416      * Do we have the entire packet, and does it include a 2-byte FCS?
1417      */
1418     len = tvb_length_remaining(tvb, proto_offset);
1419     reported_len = tvb_reported_length_remaining(tvb, proto_offset);
1420     if (reported_len < 2 || len < 0) {
1421       /*
1422        * The packet is claimed not to even have enough data for a 2-byte FCS,
1423        * or we're already past the end of the captured data.
1424        * Don't slice anything off.
1425        */
1426       next_tvb = tvb_new_subset(tvb, proto_offset, -1, -1);
1427     } else if (len < reported_len) {
1428       /*
1429        * The packet is claimed to have enough data for a 2-byte FCS, but
1430        * we didn't capture all of the packet.
1431        * Slice off the 2-byte FCS from the reported length, and trim the
1432        * captured length so it's no more than the reported length; that
1433        * will slice off what of the FCS, if any, is in the captured
1434        * length.
1435        */
1436       reported_len -= 2;
1437       if (len > reported_len)
1438         len = reported_len;
1439       next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1440     } else {
1441       /*
1442        * We have the entire packet, and it includes a 2-byte FCS.
1443        * Slice it off.
1444        */
1445       len -= 2;
1446       reported_len -= 2;
1447       next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1448
1449       /*
1450        * Compute the FCS and put it into the tree.
1451        */
1452       rx_fcs_offset = proto_offset + len;
1453       rx_fcs_exp = fcs16(tvb);
1454       rx_fcs_got = tvb_get_letohs(tvb, rx_fcs_offset);
1455       if (rx_fcs_got != rx_fcs_exp) {
1456         proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 2,
1457                             "FCS 16: 0x%04x (incorrect, should be 0x%04x)",
1458                             rx_fcs_got, rx_fcs_exp);
1459       } else {
1460         proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 2,
1461                             "FCS 16: 0x%04x (correct)",
1462                             rx_fcs_got);
1463       }
1464     }
1465     break;
1466
1467   case FCS_32:
1468     /*
1469      * Do we have the entire packet, and does it include a 4-byte FCS?
1470      */
1471     len = tvb_length_remaining(tvb, proto_offset);
1472     reported_len = tvb_reported_length_remaining(tvb, proto_offset);
1473     if (reported_len < 4) {
1474       /*
1475        * The packet is claimed not to even have enough data for a 4-byte FCS.
1476        * Just pass on the tvbuff as is.
1477        */
1478       next_tvb = tvb_new_subset(tvb, proto_offset, -1, -1);
1479     } else if (len < reported_len) {
1480       /*
1481        * The packet is claimed to have enough data for a 4-byte FCS, but
1482        * we didn't capture all of the packet.
1483        * Slice off the 4-byte FCS from the reported length, and trim the
1484        * captured length so it's no more than the reported length; that
1485        * will slice off what of the FCS, if any, is in the captured
1486        * length.
1487        */
1488       reported_len -= 4;
1489       if (len > reported_len)
1490         len = reported_len;
1491       next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1492     } else {
1493       /*
1494        * We have the entire packet, and it includes a 4-byte FCS.
1495        * Slice it off.
1496        */
1497       len -= 4;
1498       reported_len -= 4;
1499       next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1500
1501       /*
1502        * Compute the FCS and put it into the tree.
1503        */
1504       rx_fcs_offset = proto_offset + len;
1505       rx_fcs_exp = fcs32(tvb);
1506       rx_fcs_got = tvb_get_letohl(tvb, rx_fcs_offset);
1507       if (rx_fcs_got != rx_fcs_exp) {
1508         proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 4,
1509                             "FCS 32: 0x%08x (incorrect, should be 0x%08x)",
1510                             rx_fcs_got, rx_fcs_exp);
1511       } else {
1512         proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 4,
1513                             "FCS 32: 0x%08x (correct)",
1514                             rx_fcs_got);
1515       }
1516     }
1517     break;
1518
1519   default:
1520    g_assert_not_reached();
1521    next_tvb = NULL;
1522   }
1523
1524   return next_tvb;
1525 }
1526
1527 void
1528 capture_ppp_hdlc( const guchar *pd, int offset, int len, packet_counts *ld ) {
1529   if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
1530     ld->other++;
1531     return;
1532   }
1533   if (pd[0] == CHDLC_ADDR_UNICAST || pd[0] == CHDLC_ADDR_MULTICAST) {
1534     capture_chdlc(pd, offset, len, ld);
1535     return;
1536   }
1537   if (!BYTES_ARE_IN_FRAME(offset, len, 4)) {
1538     ld->other++;
1539     return;
1540   }
1541   switch (pntohs(&pd[offset + 2])) {
1542     case PPP_IP:
1543       capture_ip(pd, offset + 4, len, ld);
1544       break;
1545     case PPP_IPX:
1546       capture_ipx(ld);
1547       break;
1548     case PPP_VINES:
1549       capture_vines(ld);
1550       break;
1551     default:
1552       ld->other++;
1553       break;
1554   }
1555 }
1556
1557 static void
1558 dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1559                         guint length, packet_info *pinfo _U_,
1560                         proto_tree *tree)
1561 {
1562   proto_tree_add_text(tree, tvb, offset, length, "%s: %u", optp->name,
1563                         tvb_get_ntohs(tvb, offset + 2));
1564 }
1565
1566 static void
1567 dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1568                         guint length, packet_info *pinfo _U_,
1569                         proto_tree *tree)
1570 {
1571   guint32 map;
1572   char *mapstr;
1573   static const char *ctrlchars[32] = {
1574     "NUL", "SOH",       "STX", "ETX",        "EOT",      "ENQ", "ACK", "BEL",
1575     "BS",  "HT",        "NL",  "VT",         "NP (FF)",  "CR",  "SO",  "SI",
1576     "DLE", "DC1 (XON)", "DC2", "DC3 (XOFF)", "DC4",      "NAK", "SYN", "ETB",
1577     "CAN", "EM",        "SUB", "ESC",        "FS",       "GS",  "RS",  "US"
1578   };
1579   char mapbuf[32*(10+2)+1];
1580   char *mapp;
1581   int i;
1582
1583   /*
1584    * XXX - walk through the map and show the characters to map?
1585    * Put them in a subtree of this item, and have the top-level item
1586    * either say "None", "All", or give a list of the characters?)
1587    */
1588   map = tvb_get_ntohl(tvb, offset + 2);
1589   if (map == 0x00000000)
1590     mapstr = "None";    /* don't map any control characters */
1591   else if (map == 0xffffffff)
1592     mapstr = "All";     /* map all control characters */
1593   else {
1594     /*
1595      * Show the names of the control characters being mapped.
1596      */
1597     mapp = &mapbuf[0];
1598     for (i = 0; i < 32; i++) {
1599       if (map & (1 << i)) {
1600         if (mapp != &mapbuf[0]) {
1601           strcpy(mapp, ", ");
1602           mapp += 2;
1603         }
1604         strcpy(mapp, ctrlchars[i]);
1605         mapp += strlen(ctrlchars[i]);
1606       }
1607     }
1608     mapstr = mapbuf;
1609   }
1610   proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%08x (%s)", optp->name,
1611                       map, mapstr);
1612 }
1613
1614 static void
1615 dissect_lcp_protocol_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1616                         guint length, packet_info *pinfo _U_,
1617                         proto_tree *tree)
1618 {
1619   guint16 protocol;
1620   proto_item *tf;
1621   proto_tree *field_tree = NULL;
1622
1623   tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
1624           optp->name, length, plurality(length, "", "s"));
1625   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1626   offset += 2;
1627   length -= 2;
1628   protocol = tvb_get_ntohs(tvb, offset);
1629   proto_tree_add_text(field_tree, tvb, offset, 2, "%s: %s (0x%02x)", optp->name,
1630                 val_to_str(protocol, ppp_vals, "Unknown"), protocol);
1631   offset += 2;
1632   length -= 2;
1633   if (length > 0)
1634     proto_tree_add_text(field_tree, tvb, offset, length, "Data (%d byte%s)", length,
1635                         plurality(length, "", "s"));
1636 }
1637
1638 static void
1639 dissect_lcp_authprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1640                          guint length, packet_info *pinfo _U_,
1641                          proto_tree *tree)
1642 {
1643   guint16 protocol;
1644   guint8 algorithm;
1645   proto_item *tf;
1646   proto_tree *field_tree = NULL;
1647
1648   tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
1649           optp->name, length, plurality(length, "", "s"));
1650   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1651   offset += 2;
1652   length -= 2;
1653   protocol = tvb_get_ntohs(tvb, offset);
1654   proto_tree_add_text(field_tree, tvb, offset, 2, "%s: %s (0x%02x)", optp->name,
1655                 val_to_str(protocol, ppp_vals, "Unknown"), protocol);
1656   offset += 2;
1657   length -= 2;
1658   if (length > 0) {
1659     if (protocol == PPP_CHAP) {
1660       algorithm = tvb_get_guint8(tvb, offset);
1661       proto_tree_add_text(field_tree, tvb, offset, length,
1662                           "Algorithm: %s (0x%02x)",
1663                           val_to_str(algorithm, chap_alg_vals, "Unknown"),
1664                           algorithm);
1665       offset++;
1666     } else {
1667       proto_tree_add_text(field_tree, tvb, offset, length, "Data (%d byte%s)", length,
1668                         plurality(length, "", "s"));
1669     }
1670   }
1671 }
1672
1673 static void
1674 dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1675                         int offset, guint length, packet_info *pinfo _U_,
1676                         proto_tree *tree)
1677 {
1678   proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%08x", optp->name,
1679                         tvb_get_ntohl(tvb, offset + 2));
1680 }
1681
1682 static void
1683 dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1684                         int offset, guint length, packet_info *pinfo _U_,
1685                         proto_tree *tree)
1686 {
1687   proto_item *tf;
1688   proto_tree *field_tree = NULL;
1689   guint8 alternatives;
1690
1691   alternatives = tvb_get_guint8(tvb, offset + 2);
1692   tf = proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%02x",
1693           optp->name, alternatives);
1694   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1695   offset += 2;
1696   if (alternatives & 0x1)
1697     proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s",
1698        decode_boolean_bitfield(alternatives, 0x1, 8, "Null FCS", NULL));
1699   if (alternatives & 0x2)
1700     proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s",
1701        decode_boolean_bitfield(alternatives, 0x2, 8, "CCITT 16-bit FCS", NULL));
1702   if (alternatives & 0x4)
1703     proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s",
1704        decode_boolean_bitfield(alternatives, 0x4, 8, "CCITT 32-bit FCS", NULL));
1705 }
1706
1707 static void
1708 dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1709                         int offset, guint length, packet_info *pinfo _U_,
1710                         proto_tree *tree)
1711 {
1712   proto_tree_add_text(tree, tvb, offset, length, "%s: %u", optp->name,
1713                         tvb_get_guint8(tvb, offset + 2));
1714 }
1715
1716 static void
1717 dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1718                         int offset, guint length, packet_info *pinfo _U_,
1719                         proto_tree *tree)
1720 {
1721   proto_item *tf;
1722   proto_tree *field_tree = NULL;
1723
1724   tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
1725           optp->name, length, plurality(length, "", "s"));
1726   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1727   offset += 2;
1728   length -= 2;
1729   proto_tree_add_text(field_tree, tvb, offset, 1, "Window: %u",
1730                         tvb_get_guint8(tvb, offset));
1731   offset += 1;
1732   length -= 1;
1733   if (length > 0)
1734     proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s)",
1735                         length, plurality(length, "", "s"));
1736 }
1737
1738 static const value_string callback_op_vals[] = {
1739         {0, "Location is determined by user authentication" },
1740         {1, "Message is dialing string" },
1741         {2, "Message is location identifier" },
1742         {3, "Message is E.164" },
1743         {4, "Message is distinguished name" },
1744         {5, "unassigned"},
1745         {6, "Location is determined during CBCP negotiation" },
1746         {0, NULL }
1747 };
1748
1749 static void
1750 dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1751                         guint length, packet_info *pinfo _U_,
1752                         proto_tree *tree)
1753 {
1754   proto_item *tf;
1755   proto_tree *field_tree = NULL;
1756   guint8 operation;
1757
1758   tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
1759           optp->name, length, plurality(length, "", "s"));
1760   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1761   offset += 2;
1762   length -= 2;
1763   operation = tvb_get_guint8(tvb, offset);
1764   proto_tree_add_text(field_tree, tvb, offset, 1, "Operation: %s (0x%02x)",
1765                 val_to_str(operation, callback_op_vals, "Unknown"),
1766                 operation);
1767   offset += 1;
1768   length -= 1;
1769   if (length > 0)
1770     proto_tree_add_text(field_tree, tvb, offset, length, "Message (%d byte%s)",
1771                         length, plurality(length, "", "s"));
1772 }
1773
1774 static void
1775 dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1776                         int offset, guint length, packet_info *pinfo _U_,
1777                         proto_tree *tree)
1778 {
1779   proto_tree_add_text(tree, tvb, offset, length, "%s: %u", optp->name,
1780                         tvb_get_ntohs(tvb, offset + 2));
1781 }
1782
1783 #define CLASS_NULL                      0
1784 #define CLASS_LOCAL                     1
1785 #define CLASS_IP                        2
1786 #define CLASS_IEEE_802_1                3
1787 #define CLASS_PPP_MAGIC_NUMBER          4
1788 #define CLASS_PSDN_DIRECTORY_NUMBER     5
1789
1790 static const value_string multilink_ep_disc_class_vals[] = {
1791         {CLASS_NULL,                  "Null" },
1792         {CLASS_LOCAL,                 "Locally assigned address" },
1793         {CLASS_IP,                    "IP address" },
1794         {CLASS_IEEE_802_1,            "IEEE 802.1 globally assigned MAC address" },
1795         {CLASS_PPP_MAGIC_NUMBER,      "PPP magic-number block" },
1796         {CLASS_PSDN_DIRECTORY_NUMBER, "Public switched network directory number" },
1797         {0,                           NULL }
1798 };
1799
1800 static void
1801 dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1802                         int offset, guint length, packet_info *pinfo _U_,
1803                         proto_tree *tree)
1804 {
1805   proto_item *tf;
1806   proto_tree *field_tree = NULL;
1807   guint8 ep_disc_class;
1808
1809   tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
1810           optp->name, length, plurality(length, "", "s"));
1811   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1812   offset += 2;
1813   length -= 2;
1814   ep_disc_class = tvb_get_guint8(tvb, offset);
1815   proto_tree_add_text(field_tree, tvb, offset, 1, "Class: %s (%u)",
1816                 val_to_str(ep_disc_class, multilink_ep_disc_class_vals, "Unknown"),
1817                 ep_disc_class);
1818   offset += 1;
1819   length -= 1;
1820   if (length > 0) {
1821     switch (ep_disc_class) {
1822
1823     case CLASS_NULL:
1824       proto_tree_add_text(field_tree, tvb, offset, length,
1825                         "Address (%d byte%s), should have been empty",
1826                         length, plurality(length, "", "s"));
1827       break;
1828
1829     case CLASS_LOCAL:
1830       if (length > 20) {
1831         proto_tree_add_text(field_tree, tvb, offset, length,
1832                         "Address (%d byte%s), should have been <20",
1833                         length, plurality(length, "", "s"));
1834       } else {
1835         proto_tree_add_text(field_tree, tvb, offset, length,
1836                         "Address (%d byte%s)",
1837                         length, plurality(length, "", "s"));
1838       }
1839       break;
1840
1841     case CLASS_IP:
1842       if (length != 4) {
1843         proto_tree_add_text(field_tree, tvb, offset, length,
1844                         "Address (%d byte%s), should have been 4",
1845                         length, plurality(length, "", "s"));
1846       } else {
1847         proto_tree_add_text(field_tree, tvb, offset, length,
1848                         "Address: %s", ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1849       }
1850       break;
1851
1852     case CLASS_IEEE_802_1:
1853       if (length != 6) {
1854         proto_tree_add_text(field_tree, tvb, offset, length,
1855                         "Address (%d byte%s), should have been 6",
1856                         length, plurality(length, "", "s"));
1857       } else {
1858         proto_tree_add_text(field_tree, tvb, offset, length,
1859                         "Address: %s", ether_to_str(tvb_get_ptr(tvb, offset, 6)));
1860       }
1861       break;
1862
1863     case CLASS_PPP_MAGIC_NUMBER:
1864       /* XXX - dissect as 32-bit magic numbers */
1865       if (length > 20) {
1866         proto_tree_add_text(field_tree, tvb, offset, length,
1867                         "Address (%d byte%s), should have been <20",
1868                         length, plurality(length, "", "s"));
1869       } else {
1870         proto_tree_add_text(field_tree, tvb, offset, length,
1871                         "Address (%d byte%s)",
1872                         length, plurality(length, "", "s"));
1873       }
1874       break;
1875
1876     case CLASS_PSDN_DIRECTORY_NUMBER:
1877       if (length > 15) {
1878         proto_tree_add_text(field_tree, tvb, offset, length,
1879                         "Address (%d byte%s), should have been <20",
1880                         length, plurality(length, "", "s"));
1881       } else {
1882         proto_tree_add_text(field_tree, tvb, offset, length,
1883                         "Address (%d byte%s)",
1884                         length, plurality(length, "", "s"));
1885       }
1886       break;
1887
1888     default:
1889       proto_tree_add_text(field_tree, tvb, offset, length,
1890                         "Address (%d byte%s)",
1891                         length, plurality(length, "", "s"));
1892       break;
1893     }
1894   }
1895 }
1896
1897 static void
1898 dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1899                         int offset, guint length, packet_info *pinfo _U_,
1900                         proto_tree *tree)
1901 {
1902   proto_tree_add_text(tree, tvb, offset, length,
1903                         "%s: 0x%04x", optp->name,
1904                         tvb_get_ntohs(tvb, offset + 2));
1905 }
1906
1907 /* Character set numbers from the IANA charset registry. */
1908 static const value_string charset_num_vals[] = {
1909         {105, "UTF-8" },
1910         {0,   NULL }
1911 };
1912
1913 static void
1914 dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1915                         int offset, guint length, packet_info *pinfo _U_,
1916                         proto_tree *tree)
1917 {
1918   proto_item *tf;
1919   proto_tree *field_tree = NULL;
1920   guint32 charset;
1921
1922   tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
1923           optp->name, length, plurality(length, "", "s"));
1924   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1925   offset += 2;
1926   length -= 2;
1927   charset = tvb_get_ntohl(tvb, offset);
1928   proto_tree_add_text(field_tree, tvb, offset, 4, "Character set: %s (0x%04x)",
1929                 val_to_str(charset, charset_num_vals, "Unknown"),
1930                 charset);
1931   offset += 4;
1932   length -= 4;
1933   if (length > 0) {
1934     /* XXX - should be displayed as an ASCII string */
1935     proto_tree_add_text(field_tree, tvb, offset, length, "Language tag (%d byte%s)",
1936                         length, plurality(length, "", "s"));
1937   }
1938 }
1939
1940 static void
1941 dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1942                         int offset, guint length, packet_info *pinfo _U_,
1943                         proto_tree *tree)
1944 {
1945   proto_item *tf;
1946   proto_tree *field_tree = NULL;
1947
1948   tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
1949           optp->name, length, plurality(length, "", "s"));
1950   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1951   offset += 2;
1952   length -= 2;
1953   proto_tree_add_text(field_tree, tvb, offset, 4,
1954                         "Source IP address: %s",
1955                         ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1956   offset += 4;
1957   length -= 4;
1958   proto_tree_add_text(field_tree, tvb, offset, 4,
1959                         "Destination IP address: %s",
1960                         ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1961 }
1962
1963 static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1964                         int offset, guint length, packet_info *pinfo _U_,
1965                         proto_tree *tree)
1966 {
1967   proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
1968                         ip_to_str(tvb_get_ptr(tvb, offset + 2, 4)));
1969 }
1970
1971 static void dissect_osicp_align_npdu_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1972                         int offset, guint length, packet_info *pinfo _U_,
1973                         proto_tree *tree)
1974 {
1975   proto_item *tf;
1976   proto_tree *field_tree;
1977   guint8 alignment;
1978
1979   tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
1980   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1981
1982   alignment = tvb_get_guint8(tvb, offset + 2);
1983   proto_tree_add_text(field_tree, tvb, offset + 2, 1,
1984       "Alignment: %u", alignment);
1985 }
1986
1987 static void dissect_pppmuxcp_def_pid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1988                         int offset, guint length, packet_info *pinfo _U_,
1989                         proto_tree *tree)
1990 {
1991   pppmux_def_prot_id = tvb_get_ntohs(tvb, offset + 2);
1992   proto_tree_add_text(tree, tvb, offset + 2, length - 2, "%s: %s (0x%02x)",optp->name,
1993                       val_to_str(pppmux_def_prot_id, ppp_vals, "Unknown"), pppmux_def_prot_id);
1994 }
1995
1996
1997 static void
1998 dissect_ccp_stac_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1999                         int offset, guint length, packet_info *pinfo _U_,
2000                         proto_tree *tree)
2001 {
2002   proto_item *tf;
2003   proto_tree *field_tree;
2004   guint8 check_mode;
2005
2006   if (length == 6) {
2007     proto_tree_add_text(tree, tvb, offset, length,
2008                         "%s (Ascend Proprietary version)", optp->name);
2009     /* We don't know how to decode the following 4 octets, since
2010        there's no public document that describe their usage. */
2011   } else {
2012     tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2013     field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2014
2015     proto_tree_add_text(field_tree, tvb, offset + 2, 2,
2016                         "History Count: %u", tvb_get_ntohs(tvb, offset + 2));
2017     check_mode = tvb_get_guint8(tvb, offset + 4);
2018     proto_tree_add_text(field_tree, tvb, offset + 4, 1,
2019                         "Check Mode: %s (0x%02X)",
2020                         val_to_str(check_mode, stac_checkmode_vals, "Unknown"),
2021                         check_mode);
2022   }
2023 }
2024
2025 static void
2026 dissect_ccp_mppc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2027                         int offset, guint length, packet_info *pinfo _U_,
2028                         proto_tree *tree)
2029 {
2030   proto_item *tf;
2031   proto_tree *flags_tree;
2032   guint32 supported_bits;
2033
2034   supported_bits = tvb_get_ntohl(tvb, offset + 2);
2035   tf = proto_tree_add_text(tree, tvb, offset, length,
2036               "%s: Supported Bits: 0x%08X", optp->name, supported_bits);
2037   flags_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2038   proto_tree_add_text(flags_tree, tvb, offset + 2, 4, "%s",
2039       decode_boolean_bitfield(supported_bits, MPPC_SUPPORTED_BITS_C, 8*4,
2040       "Desire to negotiate MPPC", "NO Desire to negotiate MPPC"));
2041   proto_tree_add_text(flags_tree, tvb, offset + 2, 4, "%s",
2042       decode_boolean_bitfield(supported_bits, MPPE_SUPPORTED_BITS_D, 8*4,
2043       "Obsolete (should NOT be 1)", "Obsolete (should ALWAYS be 0)"));
2044   proto_tree_add_text(flags_tree, tvb, offset + 2, 4, "%s",
2045       decode_boolean_bitfield(supported_bits, MPPE_SUPPORTED_BITS_L, 8*4,
2046       "40-bit encryption ON", "40-bit encryption OFF"));
2047   proto_tree_add_text(flags_tree, tvb, offset + 2, 4, "%s",
2048       decode_boolean_bitfield(supported_bits, MPPE_SUPPORTED_BITS_S, 8*4,
2049       "128-bit encryption ON", "128-bit encryption OFF"));
2050   proto_tree_add_text(flags_tree, tvb, offset + 2, 4, "%s",
2051       decode_boolean_bitfield(supported_bits, MPPE_SUPPORTED_BITS_M, 8*4,
2052       "56-bit encryption ON", "56-bit encryption OFF"));
2053   proto_tree_add_text(flags_tree, tvb, offset + 2, 4, "%s",
2054       decode_boolean_bitfield(supported_bits, MPPE_SUPPORTED_BITS_H, 8*4,
2055       "Stateless mode ON", "Stateless mode OFF"));
2056 }
2057
2058 static void
2059 dissect_ccp_bsdcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2060                         int offset, guint length, packet_info *pinfo _U_,
2061                         proto_tree *tree)
2062 {
2063   proto_item *tf;
2064   proto_tree *field_tree;
2065
2066   tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2067   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2068
2069   proto_tree_add_text(field_tree, tvb, offset + 2, 1,
2070                       "Version: %u", tvb_get_guint8(tvb, offset + 2) >> 5);
2071   proto_tree_add_text(field_tree, tvb, offset + 2, 1,
2072                       "Dict: %u bits",
2073                       tvb_get_guint8(tvb, offset + 2) & 0x1f);
2074 }
2075
2076 static void
2077 dissect_ccp_lzsdcp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2078                         int offset, guint length, packet_info *pinfo _U_,
2079                         proto_tree *tree)
2080 {
2081   proto_item *tf;
2082   proto_tree *field_tree;
2083   guint8 check_mode;
2084   guint8 process_mode;
2085
2086   tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2087   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2088
2089   proto_tree_add_text(field_tree, tvb, offset + 2, 2,
2090                       "History Count: %u", tvb_get_ntohs(tvb, offset + 2));
2091   check_mode = tvb_get_guint8(tvb, offset + 4);
2092   proto_tree_add_text(field_tree, tvb, offset + 4, 1,
2093                       "Check Mode: %s (0x%02X)",
2094                       val_to_str(check_mode, lzsdcp_checkmode_vals, "Unknown"),
2095                       check_mode);
2096   process_mode = tvb_get_guint8(tvb, offset + 5);
2097   proto_tree_add_text(field_tree, tvb, offset + 5, 1,
2098                       "Process Mode: %s (0x%02X)",
2099                       val_to_str(process_mode, lzsdcp_processmode_vals, "Unkown"),
2100                       process_mode);
2101 }
2102
2103 static void
2104 dissect_ccp_mvrca_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2105                         int offset, guint length, packet_info *pinfo _U_,
2106                         proto_tree *tree)
2107 {
2108   proto_item *tf;
2109   proto_tree *field_tree;
2110
2111   tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2112   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2113
2114   proto_tree_add_text(field_tree, tvb, offset + 2, 1,
2115                       "Features: %u", tvb_get_guint8(tvb, offset + 2) >> 5);
2116   proto_tree_add_text(field_tree, tvb, offset + 2, 1,
2117                       "Packet by Packet flag: %s",
2118                       tvb_get_guint8(tvb, offset + 2) & 0x20 ? "true" : "false");
2119   proto_tree_add_text(field_tree, tvb, offset + 2, 1,
2120                       "History: %u", tvb_get_guint8(tvb, offset + 2) & 0x20);
2121   proto_tree_add_text(field_tree, tvb, offset + 3, 1,
2122                       "Number of contexts: %u", tvb_get_guint8(tvb, offset + 3));
2123 }
2124
2125 static void
2126 dissect_ccp_deflate_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2127                         int offset, guint length, packet_info *pinfo _U_,
2128                         proto_tree *tree)
2129 {
2130   proto_item *tf;
2131   proto_tree *field_tree;
2132   guint8 method;
2133
2134   tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2135   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2136
2137   proto_tree_add_text(field_tree, tvb, offset + 2, 1,
2138                       "Window: %u", hi_nibble(tvb_get_guint8(tvb, offset + 2)));
2139   method = lo_nibble(tvb_get_guint8(tvb, offset + 2));
2140   proto_tree_add_text(field_tree, tvb, offset + 2, 1,
2141                       "Method: %s (0x%02x)",
2142                       method == 0x08 ?  "zlib compression" : "other", method);
2143   proto_tree_add_text(field_tree, tvb, offset + 3, 1,
2144                       "Sequence number check method: %u",
2145                       tvb_get_guint8(tvb, offset + 2) & 0x03);
2146 }
2147
2148 static void
2149 dissect_cbcp_no_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2150                         int offset, guint length, packet_info *pinfo _U_,
2151                         proto_tree *tree)
2152 {
2153   proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2154 }
2155
2156 static void
2157 dissect_cbcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2158                         int offset, guint length, packet_info *pinfo _U_,
2159                         proto_tree *tree)
2160 {
2161   proto_item *tf;
2162   proto_tree *field_tree;
2163   proto_item *ta;
2164   proto_tree *addr_tree;
2165   guint8 addr_type;
2166   guint addr_len;
2167
2168   tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2169   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2170
2171   proto_tree_add_text(field_tree, tvb, offset + 2, 1,
2172                       "Callback delay: %u", tvb_get_guint8(tvb, offset + 2));
2173   offset += 3;
2174   length -= 3;
2175
2176   while (length > 0) {
2177     ta = proto_tree_add_text(field_tree, tvb, offset, length,
2178                              "Callback Address");
2179     addr_type = tvb_get_guint8(tvb, offset);
2180     addr_tree = proto_item_add_subtree(tf, ett_cbcp_callback_opt_addr);
2181     proto_tree_add_text(addr_tree, tvb, offset, 1,
2182                         "Address Type: %s (%u)",
2183                         ((addr_type == 1) ? "PSTN/ISDN" : "Other"), addr_type);
2184     offset++;
2185     length--;
2186     addr_len = tvb_strsize(tvb, offset);
2187     proto_tree_add_text(addr_tree, tvb, offset, addr_len,
2188                         "Address: %s",
2189                         tvb_format_text(tvb, offset, addr_len - 1));
2190     offset += (addr_len + 1);
2191     length -= (addr_len + 1);
2192   }
2193 }
2194
2195 static void
2196 dissect_bacp_favored_peer_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2197                         int offset, guint length, packet_info *pinfo _U_,
2198                         proto_tree *tree)
2199 {
2200   proto_item *tf;
2201   proto_tree *field_tree;
2202
2203   tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2204   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2205
2206   proto_tree_add_text(field_tree, tvb, offset + 2, 4,
2207                       "Magic number: 0x%08x", tvb_get_ntohl(tvb, offset + 2));
2208 }
2209
2210 static void
2211 dissect_bap_link_type_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2212                         int offset, guint length, packet_info *pinfo _U_,
2213                         proto_tree *tree)
2214 {
2215   proto_item *tf;
2216   proto_tree *field_tree;
2217   guint8 link_type;
2218
2219   tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2220   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2221
2222   proto_tree_add_text(field_tree, tvb, offset + 2, 2,
2223               "Link Speed: %u kbps", tvb_get_ntohs(tvb, offset + 2));
2224   link_type = tvb_get_guint8(tvb, offset + 4);
2225   proto_tree_add_text(field_tree, tvb, offset + 4, 1,
2226               "Link Type: %s (%u)", val_to_str(link_type, bap_link_type_vals,
2227                                                 "Unknown"), link_type);
2228 }
2229
2230 static void
2231 dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2232                         int offset, guint length, packet_info *pinfo _U_,
2233                         proto_tree *tree)
2234 {
2235   proto_item *tf;
2236   proto_tree *field_tree;
2237   proto_item *ti;
2238   proto_tree *suboption_tree;
2239   guint8 subopt_type;
2240   guint8 subopt_len;
2241
2242   tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2243   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2244
2245   offset += 2;
2246   length -= 2;
2247
2248   while (length > 0) {
2249     subopt_type = tvb_get_guint8(tvb, offset);
2250     subopt_len = tvb_get_guint8(tvb, offset + 1);
2251     ti = proto_tree_add_text(field_tree, tvb, offset, subopt_len,
2252                 "Sub-Option (%d byte%s)",
2253                 subopt_len, plurality(subopt_len, "", "s"));
2254     suboption_tree = proto_item_add_subtree(ti, ett_bap_phone_delta_subopt);
2255
2256     proto_tree_add_text(suboption_tree, tvb, offset, 1,
2257         "Sub-Option Type: %s (%u)",
2258         val_to_str(subopt_type, bap_phone_delta_subopt_vals, "Unknown"),
2259         subopt_type);
2260
2261     proto_tree_add_text(suboption_tree, tvb, offset + 1, 1,
2262         "Sub-Option Length: %u", subopt_len);
2263
2264     switch (subopt_type) {
2265     case BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT:
2266       proto_tree_add_text(suboption_tree, tvb, offset + 2, 1, "Uniq Digit: %u",
2267                           tvb_get_guint8(tvb, offset + 2));
2268       break;
2269     case BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM:
2270       if (subopt_len > 2) {
2271         proto_tree_add_text(suboption_tree, tvb, offset + 2, subopt_len - 2,
2272                           "Subscriber Number: %s",
2273                           tvb_format_text(tvb, offset + 2, subopt_len - 2));
2274       } else {
2275         proto_tree_add_text(suboption_tree, tvb, offset + 1, 1,
2276                           "Invalid suboption length: %u", subopt_len);
2277       }
2278       break;
2279     case BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR:
2280       if (subopt_len > 2) {
2281         proto_tree_add_text(suboption_tree, tvb, offset + 2, subopt_len - 2,
2282                           "Phone Number Sub Address: %s",
2283                           tvb_format_text(tvb, offset + 2, subopt_len - 2));
2284       }
2285       break;
2286     default:
2287       proto_tree_add_text(suboption_tree, tvb, offset + 2, subopt_len - 2,
2288                           "Unknown");
2289       break;
2290     }
2291     offset += subopt_len;
2292     length -= subopt_len;
2293   }
2294 }
2295
2296 static void
2297 dissect_bap_reason_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2298                         int offset, guint length, packet_info *pinfo _U_,
2299                         proto_tree *tree)
2300 {
2301   if (length > 2) {
2302     proto_tree_add_text(tree, tvb, offset, length, "%s: %s",
2303                            optp->name,
2304                            tvb_format_text(tvb, offset + 2, length - 2));
2305   }
2306 }
2307
2308 static void
2309 dissect_bap_link_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2310                         int offset, guint length, packet_info *pinfo _U_,
2311                         proto_tree *tree)
2312 {
2313   proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%04x",
2314                       optp->name, tvb_get_ntohs(tvb, offset + 2));
2315 }
2316
2317 static void
2318 dissect_bap_call_status_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2319                         int offset, guint length, packet_info *pinfo _U_,
2320                         proto_tree *tree)
2321 {
2322   proto_item *tf;
2323   proto_tree *field_tree;
2324   guint8 status, action;
2325
2326   tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2327   field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2328
2329   status = tvb_get_guint8(tvb, offset + 2);
2330   proto_tree_add_text(field_tree, tvb, offset + 2, 1,
2331       "Status: %s (0x%02x)",
2332       val_to_str(status, q931_cause_code_vals, "Unknown"), status);
2333
2334   action = tvb_get_guint8(tvb, offset + 3);
2335   proto_tree_add_text(field_tree, tvb, offset + 3, 1,
2336       "Action: %s (0x%02x)",
2337       val_to_str(action, bap_call_status_opt_action_vals, "Unknown"), action);
2338 }
2339
2340 static void
2341 dissect_cp( tvbuff_t *tvb, int proto_id, int proto_subtree_index,
2342         const value_string *proto_vals, int options_subtree_index,
2343         const ip_tcp_opt *opts, int nopts, packet_info *pinfo,
2344         proto_tree *tree )
2345 {
2346   proto_item *ti;
2347   proto_tree *fh_tree = NULL;
2348   proto_item *tf;
2349   proto_tree *field_tree;
2350
2351   guint8 code;
2352   guint8 id;
2353   int length, offset;
2354   guint16 protocol;
2355
2356   code = tvb_get_guint8(tvb, 0);
2357   id = tvb_get_guint8(tvb, 1);
2358   length = tvb_get_ntohs(tvb, 2);
2359
2360   if(check_col(pinfo->cinfo, COL_PROTOCOL))
2361     col_set_str(pinfo->cinfo, COL_PROTOCOL,
2362                 proto_get_protocol_short_name(find_protocol_by_id(proto_id)));
2363
2364   if(check_col(pinfo->cinfo, COL_INFO))
2365         col_add_str(pinfo->cinfo, COL_INFO,
2366                 val_to_str(code, proto_vals, "Unknown"));
2367
2368   if(tree) {
2369     ti = proto_tree_add_item(tree, proto_id, tvb, 0, length, FALSE);
2370     fh_tree = proto_item_add_subtree(ti, proto_subtree_index);
2371     proto_tree_add_text(fh_tree, tvb, 0, 1, "Code: %s (0x%02x)",
2372       val_to_str(code, proto_vals, "Unknown"), code);
2373     proto_tree_add_text(fh_tree, tvb, 1, 1, "Identifier: 0x%02x",
2374                         id);
2375     proto_tree_add_text(fh_tree, tvb, 2, 2, "Length: %u",
2376                         length);
2377   }
2378   offset = 4;
2379   length -= 4;
2380
2381   switch (code) {
2382     case CONFREQ:
2383     case CONFACK:
2384     case CONFNAK:
2385     case CONFREJ:
2386       if(tree) {
2387         if (length > 0) {
2388           tf = proto_tree_add_text(fh_tree, tvb, offset, length,
2389             "Options: (%d byte%s)", length, plurality(length, "", "s"));
2390           field_tree = proto_item_add_subtree(tf, options_subtree_index);
2391           dissect_ip_tcp_options(tvb, offset, length, opts, nopts, -1,
2392                                  pinfo, field_tree);
2393         }
2394       }
2395       break;
2396
2397     case ECHOREQ:
2398     case ECHOREP:
2399     case DISCREQ:
2400     case IDENT:
2401       if(tree) {
2402         proto_tree_add_text(fh_tree, tvb, offset, 4, "Magic number: 0x%08x",
2403                         tvb_get_ntohl(tvb, offset));
2404         offset += 4;
2405         length -= 4;
2406         if (length > 0)
2407           proto_tree_add_text(fh_tree, tvb, offset, length, "Message (%d byte%s)",
2408                                 length, plurality(length, "", "s"));
2409       }
2410       break;
2411
2412     case TIMEREMAIN:
2413       if(tree) {
2414         proto_tree_add_text(fh_tree, tvb, offset, 4, "Magic number: 0x%08x",
2415                         tvb_get_ntohl(tvb, offset));
2416         offset += 4;
2417         length -= 4;
2418         proto_tree_add_text(fh_tree, tvb, offset, 4, "Seconds remaining: %u",
2419                         tvb_get_ntohl(tvb, offset));
2420         offset += 4;
2421         length -= 4;
2422         if (length > 0)
2423           proto_tree_add_text(fh_tree, tvb, offset, length, "Message (%d byte%s)",
2424                                 length, plurality(length, "", "s"));
2425       }
2426       break;
2427
2428     case PROTREJ:
2429       if(tree) {
2430         gboolean save_in_error_pkt;
2431         tvbuff_t *next_tvb;
2432
2433         protocol = tvb_get_ntohs(tvb, offset);
2434         proto_tree_add_text(fh_tree, tvb, offset, 2,
2435                             "Rejected protocol: %s (0x%04x)",
2436                             val_to_str(protocol, ppp_vals, "Unknown"),
2437                             protocol);
2438         offset += 2;
2439         length -= 2;
2440         if (length > 0) {
2441           proto_tree_add_text(fh_tree, tvb, offset, length,
2442                               "Rejected packet (%d byte%s)",
2443                               length, plurality(length, "", "s"));
2444
2445           /* Save the current value of the "we're inside an error packet"
2446              flag, and set that flag; subdissectors may treat packets
2447              that are the payload of error packets differently from
2448              "real" packets. */
2449           save_in_error_pkt = pinfo->in_error_pkt;
2450           pinfo->in_error_pkt = TRUE;
2451
2452           /* Decode the rejected packet. */
2453           next_tvb = tvb_new_subset(tvb, offset, length, length);
2454           if (!dissector_try_port(ppp_subdissector_table, protocol,
2455                                   next_tvb, pinfo, fh_tree)) {
2456             call_dissector(data_handle, next_tvb, pinfo, fh_tree);
2457           }
2458
2459           /* Restore the "we're inside an error packet" flag. */
2460           pinfo->in_error_pkt = save_in_error_pkt;
2461         }
2462       }
2463       break;
2464
2465     case CODEREJ:
2466                 /* decode the rejected LCP packet here. */
2467       if (length > 0)
2468         proto_tree_add_text(fh_tree, tvb, offset, length, "Rejected packet (%d byte%s)",
2469                                 length, plurality(length, "", "s"));
2470       break;
2471
2472     case TERMREQ:
2473     case TERMACK:
2474       if (length > 0)
2475         proto_tree_add_text(fh_tree, tvb, offset, length, "Data (%d byte%s)",
2476                                 length, plurality(length, "", "s"));
2477       break;
2478
2479     default:
2480       if (length > 0)
2481         proto_tree_add_text(fh_tree, tvb, offset, length, "Stuff (%d byte%s)",
2482                                 length, plurality(length, "", "s"));
2483       break;
2484   }
2485 }
2486
2487 /* Protocol field compression */
2488 #define PFC_BIT 0x01
2489
2490 static void
2491 dissect_ppp_common( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2492                 proto_tree *fh_tree, proto_item *ti )
2493 {
2494   guint16 ppp_prot;
2495   int     proto_len;
2496   tvbuff_t      *next_tvb;
2497
2498   ppp_prot = tvb_get_guint8(tvb, 0);
2499   if (ppp_prot & PFC_BIT) {
2500     /* Compressed protocol field - just the byte we fetched. */
2501     proto_len = 1;
2502   } else {
2503     /* Uncompressed protocol field - fetch all of it. */
2504     ppp_prot = tvb_get_ntohs(tvb, 0);
2505     proto_len = 2;
2506   }
2507
2508   /* If "ti" is not null, it refers to the top-level "proto_ppp" item
2509      for PPP, and was given a length equal to the length of any
2510      stuff in the header preceding the protocol type, e.g. an HDLC
2511      header; add the length of the protocol type field to it. */
2512   if (ti != NULL)
2513     proto_item_set_len(ti, proto_item_get_len(ti) + proto_len);
2514
2515   if (tree)
2516     proto_tree_add_uint(fh_tree, hf_ppp_protocol, tvb, 0, proto_len, ppp_prot);
2517
2518   next_tvb = tvb_new_subset(tvb, proto_len, -1, -1);
2519
2520   /* do lookup with the subdissector table */
2521   if (!dissector_try_port(ppp_subdissector_table, ppp_prot, next_tvb, pinfo, tree)) {
2522     if (check_col(pinfo->cinfo, COL_PROTOCOL))
2523       col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", ppp_prot);
2524     if (check_col(pinfo->cinfo, COL_INFO))
2525       col_add_fstr(pinfo->cinfo, COL_INFO, "PPP %s (0x%04x)",
2526                    val_to_str(ppp_prot, ppp_vals, "Unknown"), ppp_prot);
2527     call_dissector(data_handle,next_tvb, pinfo, tree);
2528   }
2529 }
2530
2531 static void
2532 dissect_lcp_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2533 {
2534   dissect_ip_tcp_options(tvb, 0, tvb_reported_length(tvb), lcp_opts, N_LCP_OPTS, 
2535             -1, pinfo, tree);
2536 }
2537
2538 /*
2539  * RFC 1661.
2540  */
2541 static void
2542 dissect_lcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2543 {
2544   dissect_cp(tvb, proto_lcp, ett_lcp, lcp_vals, ett_lcp_options,
2545              lcp_opts, N_LCP_OPTS, pinfo, tree);
2546 }
2547
2548 /*
2549  * RFC 1332.
2550  */
2551 static void
2552 dissect_ipcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2553 {
2554   dissect_cp(tvb, proto_ipcp, ett_ipcp, cp_vals, ett_ipcp_options,
2555              ipcp_opts, N_IPCP_OPTS, pinfo, tree);
2556 }
2557
2558 /*
2559  * RFC 1377.
2560  */
2561 static void
2562 dissect_osicp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2563 {
2564   dissect_cp(tvb, proto_osicp, ett_osicp, cp_vals, ett_osicp_options,
2565              osicp_opts, N_OSICP_OPTS, pinfo, tree);
2566 }
2567
2568 /*
2569  * RFC 1962.
2570  */
2571 static void
2572 dissect_ccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2573 {
2574   dissect_cp(tvb, proto_ccp, ett_ccp, ccp_vals, ett_ccp_options,
2575              ccp_opts, N_CCP_OPTS, pinfo, tree);
2576 }
2577
2578 /*
2579  * Callback Control Protocol - see
2580  *
2581  *      http://www.linet.gr.jp/~manabe/PPxP/doc/Standards/draft-gidwani-ppp-callback-cp-00.txt
2582  */
2583 static void
2584 dissect_cbcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2585 {
2586   dissect_cp(tvb, proto_cbcp, ett_cbcp, cbcp_vals, ett_cbcp_options,
2587              cbcp_opts, N_CBCP_OPTS, pinfo, tree);
2588 }
2589
2590 /*
2591  * RFC 2125 (BACP and BAP).
2592  */
2593 static void
2594 dissect_bacp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2595 {
2596   dissect_cp(tvb, proto_bacp, ett_bacp, cp_vals, ett_bacp_options,
2597              bacp_opts, N_BACP_OPTS, pinfo, tree);
2598 }
2599
2600 static void
2601 dissect_bap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2602 {
2603   proto_item *ti;
2604   proto_tree *fh_tree = NULL;
2605   proto_item *tf;
2606   proto_tree *field_tree;
2607
2608   guint8 type;
2609   guint8 id;
2610   int length, offset;
2611   guint8 resp_code;
2612
2613   type = tvb_get_guint8(tvb, 0);
2614   id = tvb_get_guint8(tvb, 1);
2615   length = tvb_get_ntohs(tvb, 2);
2616
2617   if(check_col(pinfo->cinfo, COL_PROTOCOL))
2618     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP BAP");
2619
2620   if(check_col(pinfo->cinfo, COL_INFO))
2621         col_add_str(pinfo->cinfo, COL_INFO,
2622                 val_to_str(type, bap_vals, "Unknown"));
2623
2624   if(tree) {
2625     ti = proto_tree_add_item(tree, proto_bap, tvb, 0, length, FALSE);
2626     fh_tree = proto_item_add_subtree(ti, ett_bap_options);
2627     proto_tree_add_text(fh_tree, tvb, 0, 1, "Type: %s (0x%02x)",
2628       val_to_str(type, bap_vals, "Unknown"), type);
2629     proto_tree_add_text(fh_tree, tvb, 1, 1, "Identifier: 0x%02x",
2630                         id);
2631     proto_tree_add_text(fh_tree, tvb, 2, 2, "Length: %u",
2632                         length);
2633   }
2634   offset = 4;
2635   length -= 4;
2636
2637   if (type == BAP_CRES || type == BAP_CBRES ||
2638       type == BAP_LDQRES || type == BAP_CSRES) {
2639     resp_code = tvb_get_guint8(tvb, offset);
2640     proto_tree_add_text(fh_tree, tvb, offset, 1, "Response Code: %s (0x%02x)",
2641         val_to_str(resp_code, bap_resp_code_vals, "Unknown"), resp_code);
2642     offset++;
2643     length--;
2644   }
2645
2646   if(tree) {
2647     if (length > 0) {
2648       tf = proto_tree_add_text(fh_tree, tvb, offset, length,
2649                "Data (%d byte%s)", length, plurality(length, "", "s"));
2650       field_tree = proto_item_add_subtree(tf, ett_bap_options);
2651       dissect_ip_tcp_options(tvb, offset, length, bap_opts, N_BAP_OPTS, -1,
2652                              pinfo, field_tree);
2653     }
2654   }
2655 }
2656
2657 static void
2658 dissect_comp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2659 {
2660   proto_item *ti;
2661   proto_tree *comp_data_tree;
2662
2663   if (check_col(pinfo->cinfo, COL_PROTOCOL))
2664     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP Comp");
2665
2666   if(check_col(pinfo->cinfo, COL_INFO))
2667     col_set_str(pinfo->cinfo, COL_INFO, "Compressed data");
2668
2669   if (tree) {
2670     ti = proto_tree_add_item(tree, proto_comp_data, tvb, 0, -1, FALSE);
2671     comp_data_tree = proto_item_add_subtree(ti, ett_comp_data);
2672   }
2673 }
2674
2675 /*
2676  * RFC 3153 (both PPPMuxCP and PPPMux).
2677  */
2678 static void
2679 dissect_pppmuxcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2680 {
2681   dissect_cp(tvb,proto_pppmuxcp,ett_pppmuxcp,pppmuxcp_vals,
2682              ett_pppmuxcp_options,pppmuxcp_opts,N_PPPMUXCP_OPTS,pinfo,tree);
2683 }
2684
2685 #define PPPMUX_FLAGS_MASK          0xc0
2686 #define PPPMUX_PFF_BIT_SET         0x80
2687 #define PPPMUX_LXT_BIT_SET         0x40
2688
2689 static void
2690 dissect_pppmux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2691 {
2692   proto_tree *mux_tree, *hdr_tree, *sub_tree, *flag_tree;
2693   proto_tree *info_tree;
2694   proto_item *ti = NULL,*sub_ti = NULL;
2695   guint8 flags, byte;
2696   guint16 length;
2697   static guint16 pid;
2698   tvbuff_t *next_tvb;
2699   int offset = 0, length_remaining;
2700   int length_field = 0, pid_field = 0,hdr_length = 0;
2701
2702   if (check_col(pinfo->cinfo, COL_PROTOCOL))
2703     col_set_str(pinfo->cinfo,COL_PROTOCOL, "PPP PPPMux");
2704
2705   if (check_col(pinfo->cinfo, COL_INFO))
2706     col_set_str(pinfo->cinfo, COL_INFO, "PPP Multiplexing");
2707
2708   length_remaining = tvb_reported_length(tvb);
2709
2710   if (tree) {
2711     ti = proto_tree_add_item(tree, proto_pppmux, tvb, 0, -1, FALSE);
2712     mux_tree = proto_item_add_subtree(ti,ett_pppmux);
2713
2714     while (length_remaining > 0) {
2715
2716       flags = tvb_get_guint8(tvb,offset) & PPPMUX_FLAGS_MASK;
2717
2718       if (flags && PPPMUX_LXT_BIT_SET ) {
2719         length = tvb_get_ntohs(tvb,offset) & 0x3fff;
2720         length_field = 2;
2721       } else {
2722         length = tvb_get_guint8(tvb,offset) & 0x3f;
2723         length_field = 1;
2724       }
2725
2726       if (flags && PPPMUX_PFF_BIT_SET) {
2727         byte = tvb_get_guint8(tvb,offset + length_field);
2728         if (byte && PFC_BIT) {            /* Compressed PID field*/
2729           pid = byte;
2730           pid_field = 1;
2731         } else {                  /*PID field is 2 bytes*/
2732           pid = tvb_get_ntohs(tvb,offset + length_field);
2733           pid_field = 2;
2734         }
2735       } else {
2736         if (!pid){       /*No Last PID, hence use the default */
2737           if (pppmux_def_prot_id)
2738             pid = pppmux_def_prot_id;
2739         }
2740       }
2741
2742       hdr_length = length_field + pid_field;
2743
2744       ti = proto_tree_add_text(mux_tree, tvb, offset, length + length_field,
2745                                "PPPMux Sub-frame");
2746       sub_tree = proto_item_add_subtree(ti,ett_pppmux_subframe);
2747       sub_ti = proto_tree_add_text(sub_tree, tvb, offset,
2748                                    hdr_length,"Header field");
2749
2750       hdr_tree = proto_item_add_subtree(sub_ti,ett_pppmux_subframe_hdr);
2751       ti = proto_tree_add_text(hdr_tree, tvb, offset, length_field, "PFF/LXT: 0x%02X",
2752                                flags);
2753
2754       flag_tree = proto_item_add_subtree(ti,ett_pppmux_subframe_flags);
2755       proto_tree_add_text(flag_tree,tvb,offset,length_field,"%s",
2756                           decode_boolean_bitfield(flags,0x80,8,"PID Present","PID not present"));
2757       proto_tree_add_text(flag_tree,tvb,offset,length_field,"%s",
2758                           decode_boolean_bitfield(flags,0x40,8,"2 bytes ength field ","1 byte length field"));
2759
2760       ti = proto_tree_add_text(hdr_tree,tvb,offset,length_field,"Sub-frame Length = %u",length);
2761
2762       if (flags && PPPMUX_PFF_BIT_SET)
2763         proto_tree_add_text(hdr_tree,tvb,offset + length_field,pid_field,"%s: %s(0x%02x)",
2764                             "Protocol ID",val_to_str(pid,ppp_vals,"Unknown"), pid);
2765
2766       offset += hdr_length;
2767       length_remaining -= hdr_length;
2768       length -= pid_field;
2769
2770       sub_ti = proto_tree_add_text(sub_tree,tvb,offset,length,"Information Field");
2771       info_tree = proto_item_add_subtree(sub_ti,ett_pppmux_subframe_info);
2772
2773       next_tvb = tvb_new_subset(tvb,offset,length,-1);
2774
2775       if (!dissector_try_port(ppp_subdissector_table, pid, next_tvb, pinfo, info_tree)) {
2776         call_dissector(data_handle, next_tvb, pinfo, info_tree);
2777       }
2778       offset += length;
2779       length_remaining -= length;
2780     }  /* While length_remaining */
2781     pid = 0;
2782   } /* if tree */
2783 }
2784
2785 /*
2786  * RFC 3032.
2787  */
2788 static void
2789 dissect_mplscp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2790 {
2791   dissect_cp(tvb, proto_mplscp, ett_mplscp, cp_vals, ett_mplscp_options,
2792              NULL, 0, pinfo, tree);
2793 }
2794
2795 /*
2796  * Cisco Discovery Protocol Control Protocol.
2797  * XXX - where is this documented?
2798  */
2799 static void
2800 dissect_cdpcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2801 {
2802   dissect_cp(tvb, proto_cdpcp, ett_cdpcp, cp_vals, ett_cdpcp_options,
2803              NULL, 0, pinfo, tree);
2804 }
2805
2806 #define MP_FRAG_MASK     0xC0
2807 #define MP_FRAG(bits)    ((bits) & MP_FRAG_MASK)
2808 #define MP_FRAG_FIRST    0x80
2809 #define MP_FRAG_LAST     0x40
2810 #define MP_FRAG_RESERVED 0x3f
2811
2812 static const true_false_string frag_truth = {
2813   "Yes",
2814   "No"
2815 };
2816
2817 /* According to RFC 1717, the length the MP header isn't indicated anywhere
2818    in the header itself.  It starts out at four bytes and can be
2819    negotiated down to two using LCP.  We currently assume that all
2820    headers are four bytes.  - gcc
2821  */
2822 static void
2823 dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2824 {
2825   proto_tree *mp_tree, *hdr_tree;
2826   proto_item *ti = NULL;
2827   guint8      flags;
2828   gchar      *flag_str;
2829   tvbuff_t   *next_tvb;
2830
2831   if (check_col(pinfo->cinfo, COL_PROTOCOL))
2832     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP MP");
2833
2834   if (check_col(pinfo->cinfo, COL_INFO))
2835     col_set_str(pinfo->cinfo, COL_INFO, "PPP Multilink");
2836
2837   flags = tvb_get_guint8(tvb, 0);
2838
2839   if (tree) {
2840     switch (flags) {
2841       case MP_FRAG_FIRST:
2842         flag_str = "First";
2843         break;
2844       case MP_FRAG_LAST:
2845         flag_str = "Last";
2846         break;
2847       case MP_FRAG_FIRST|MP_FRAG_LAST:
2848         flag_str = "First, Last";
2849         break;
2850       default:
2851         flag_str = "Unknown";
2852         break;
2853     }
2854     ti = proto_tree_add_item(tree, proto_mp, tvb, 0, 4, FALSE);
2855     mp_tree = proto_item_add_subtree(ti, ett_mp);
2856     ti = proto_tree_add_text(mp_tree, tvb, 0, 1, "Fragment: 0x%2X (%s)",
2857       flags, flag_str);
2858     hdr_tree = proto_item_add_subtree(ti, ett_mp_flags);
2859     proto_tree_add_boolean(hdr_tree, hf_mp_frag_first, tvb, 0, 1, flags);
2860     proto_tree_add_boolean(hdr_tree, hf_mp_frag_last, tvb, 0, 1, flags),
2861     proto_tree_add_text(hdr_tree, tvb, 0, 1, "%s",
2862       decode_boolean_bitfield(flags, MP_FRAG_RESERVED, sizeof(flags) * 8,
2863         "reserved", "reserved"));
2864     proto_tree_add_item(mp_tree, hf_mp_sequence_num, tvb,  1, 3, FALSE);
2865   }
2866
2867   if (tvb_reported_length_remaining(tvb, 4) > 0) {
2868     next_tvb = tvb_new_subset(tvb, 4, -1, -1);
2869     dissect_ppp(next_tvb, pinfo, tree);
2870   }
2871 }
2872
2873 /*
2874  * Handles PPP without HDLC framing, just a protocol field (RFC 1661).
2875  */
2876 static void
2877 dissect_ppp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
2878   proto_item *ti = NULL;
2879   proto_tree *fh_tree = NULL;
2880
2881   if(tree) {
2882     ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, -1, FALSE);
2883     fh_tree = proto_item_add_subtree(ti, ett_ppp);
2884   }
2885
2886   dissect_ppp_common(tvb, pinfo, tree, fh_tree, ti);
2887 }
2888
2889 /*
2890  * Handles link-layer encapsulations where the frame might be
2891  * a PPP in HDLC-like Framing frame (RFC 1662) or a Cisco HDLC frame.
2892  */
2893 static void
2894 dissect_ppp_hdlc( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
2895 {
2896   proto_item *ti = NULL;
2897   proto_tree *fh_tree = NULL;
2898   guint8     byte0;
2899   int        proto_offset;
2900   tvbuff_t  *next_tvb;
2901
2902   byte0 = tvb_get_guint8(tvb, 0);
2903   if (byte0 == CHDLC_ADDR_UNICAST || byte0 == CHDLC_ADDR_MULTICAST) {
2904     /* Cisco HDLC encapsulation */
2905     call_dissector(chdlc_handle, tvb, pinfo, tree);
2906     return;
2907   }
2908
2909   /*
2910    * XXX - should we have a routine that always dissects PPP, for use
2911    * when we know the packets are PPP, not CHDLC?
2912    */
2913
2914   /* PPP HDLC encapsulation */
2915   if (byte0 == 0xff)
2916     proto_offset = 2;
2917   else {
2918     /* address and control are compressed (NULL) */
2919     proto_offset = 0;
2920   }
2921
2922   /* load the top pane info. This should be overwritten by
2923      the next protocol in the stack */
2924
2925   if(check_col(pinfo->cinfo, COL_PROTOCOL))
2926     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP" );
2927
2928   switch (pinfo->p2p_dir) {
2929
2930   case P2P_DIR_SENT:
2931     if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
2932       col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
2933     if(check_col(pinfo->cinfo, COL_RES_DL_DST))
2934       col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
2935     break;
2936
2937   case P2P_DIR_RECV:
2938     if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
2939       col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
2940     if(check_col(pinfo->cinfo, COL_RES_DL_DST))
2941       col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
2942     break;
2943
2944   default:
2945     if(check_col(pinfo->cinfo, COL_RES_DL_SRC))
2946       col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "N/A");
2947     if(check_col(pinfo->cinfo, COL_RES_DL_DST))
2948       col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A");
2949     break;
2950   }
2951
2952   if(tree) {
2953     ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, proto_offset, FALSE);
2954     fh_tree = proto_item_add_subtree(ti, ett_ppp);
2955     if (byte0 == 0xff) {
2956       proto_tree_add_item(fh_tree, hf_ppp_address, tvb, 0, 1, FALSE);
2957       proto_tree_add_item(fh_tree, hf_ppp_control, tvb, 1, 1, FALSE);
2958     }
2959   }
2960
2961   next_tvb = decode_fcs(tvb, fh_tree, ppp_fcs_decode, proto_offset);
2962
2963   dissect_ppp_common(next_tvb, pinfo, tree, fh_tree, ti);
2964 }
2965
2966 /*
2967  * Handles PAP just as a protocol field
2968  */
2969 static void
2970 dissect_pap( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
2971   proto_item *ti;
2972   proto_tree *fh_tree = NULL;
2973   proto_item *tf;
2974   proto_tree *field_tree;
2975   proto_item *tm;
2976   proto_tree *message_tree;
2977   proto_item *tp;
2978   proto_tree *peer_id_tree;
2979   proto_item *tpw;
2980   proto_tree *passwd_tree;
2981
2982   guint8 code;
2983   guint8 id, peer_id_length, password_length, msg_length;
2984   int length, offset;
2985
2986   code = tvb_get_guint8(tvb, 0);
2987   id = tvb_get_guint8(tvb, 1);
2988   length = tvb_get_ntohs(tvb, 2);
2989
2990   if(check_col(pinfo->cinfo, COL_PROTOCOL))
2991     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP PAP");
2992
2993   if(check_col(pinfo->cinfo, COL_INFO))
2994         col_add_str(pinfo->cinfo, COL_INFO,
2995                 val_to_str(code, pap_vals, "Unknown"));
2996
2997   if(tree) {
2998     ti = proto_tree_add_item(tree, proto_pap, tvb, 0, length, FALSE);
2999     fh_tree = proto_item_add_subtree(ti, ett_pap);
3000     proto_tree_add_text(fh_tree, tvb, 0, 1, "Code: %s (0x%02x)",
3001       val_to_str(code, pap_vals, "Unknown"), code);
3002     proto_tree_add_text(fh_tree, tvb, 1, 1, "Identifier: 0x%02x",
3003                         id);
3004     proto_tree_add_text(fh_tree, tvb, 2, 2, "Length: %u",
3005                         length);
3006   }
3007   offset = 4;
3008   length -= 4;
3009
3010   switch (code) {
3011     case CONFREQ:
3012       if(tree) {
3013         if (length > 0) {
3014           tf = proto_tree_add_text(fh_tree, tvb, offset, length,
3015             "Data (%d byte%s)", length, plurality(length, "", "s"));
3016           field_tree = proto_item_add_subtree(tf, ett_pap_data);
3017                   peer_id_length = tvb_get_guint8(tvb, offset);
3018                   tp = proto_tree_add_text(field_tree, tvb, offset,      1,
3019               "Peer ID length: %d byte%s", peer_id_length, plurality(peer_id_length, "", "s"));
3020                   if (--length > 0) {
3021                           peer_id_tree = proto_item_add_subtree(tp, ett_pap_peer_id);
3022                           proto_tree_add_text(peer_id_tree, tvb, ++offset, ppp_min(peer_id_length, length),
3023               "Peer-ID (%d byte%s)", peer_id_length, plurality(peer_id_length, "", "s"));
3024                           offset+=peer_id_length;
3025                           length-=peer_id_length;
3026                           if (length > 0) {
3027                                 password_length = tvb_get_guint8(tvb, offset);
3028                                 if (--length > 0) {
3029                                         tpw = proto_tree_add_text(field_tree, tvb, offset,      1,
3030                                                 "Password length: %d byte%s", password_length, plurality(password_length, "", "s"));
3031                                         passwd_tree = proto_item_add_subtree(tpw, ett_pap_password);
3032                                         proto_tree_add_text(passwd_tree, tvb, ++offset, ppp_min(password_length, length),
3033                                                 "Password (%d byte%s)", password_length, plurality(password_length, "", "s"));
3034                                 }
3035                           }
3036                   }
3037         }
3038       }
3039       break;
3040
3041     case CONFACK:
3042     case CONFNAK:
3043       if(tree) {
3044         if (length > 0) {
3045           tf = proto_tree_add_text(fh_tree, tvb, offset, length,
3046             "Data (%d byte%s)", length, plurality(length, "", "s"));
3047           field_tree = proto_item_add_subtree(tf, ett_pap_data);
3048                   msg_length = tvb_get_guint8(tvb, offset);
3049                   tm = proto_tree_add_text(field_tree, tvb, offset,      1,
3050               "Message length: %d byte%s", msg_length, plurality(msg_length, "", "s"));
3051                   if (--length > 0) {
3052                         message_tree = proto_item_add_subtree(tm, ett_pap_message);
3053                     proto_tree_add_text(message_tree, tvb, ++offset, ppp_min(msg_length, length),
3054               "Message (%d byte%s)", msg_length, plurality(msg_length, "", "s"));
3055                   }
3056         }
3057       }
3058       break;
3059     default:
3060       if (length > 0)
3061         proto_tree_add_text(fh_tree, tvb, offset, length, "Stuff (%d byte%s)",
3062                                 length, plurality(length, "", "s"));
3063       break;
3064   }
3065 }
3066
3067 /*
3068  * Handles CHAP just as a protocol field
3069  */
3070 static void
3071 dissect_chap( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
3072   proto_item *ti;
3073   proto_tree *fh_tree = NULL;
3074   proto_item *tf;
3075   proto_tree *field_tree;
3076   proto_item *tv;
3077   proto_tree *value_tree;
3078
3079   guint8 code, id, value_size;
3080   guint16 length;
3081   int offset;
3082   int name_length;
3083
3084   code = tvb_get_guint8(tvb, 0);
3085   id = tvb_get_guint8(tvb, 1);
3086   length = tvb_get_ntohs(tvb, 2);
3087
3088   if(check_col(pinfo->cinfo, COL_PROTOCOL))
3089     col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP CHAP");
3090
3091   if(check_col(pinfo->cinfo, COL_INFO))
3092         col_add_str(pinfo->cinfo, COL_INFO,
3093                 val_to_str(code, chap_vals, "Unknown"));
3094
3095   if(tree) {
3096     ti = proto_tree_add_item(tree, proto_chap, tvb, 0, length, FALSE);
3097     fh_tree = proto_item_add_subtree(ti, ett_chap);
3098     proto_tree_add_text(fh_tree, tvb, 0, 1, "Code: %s (0x%02x)",
3099       val_to_str(code, chap_vals, "Unknown"), code);
3100     proto_tree_add_text(fh_tree, tvb, 1, 1, "Identifier: 0x%02x",
3101                         id);
3102     proto_tree_add_text(fh_tree, tvb, 2, 2, "Length: %u",
3103                         length);
3104   }
3105   offset = 4;
3106   length -= 4;
3107
3108   switch (code) {
3109     case CHAP_CHAL:
3110     case CHAP_RESP:
3111       if(tree) {
3112         if (length > 0) {
3113           tf = proto_tree_add_text(fh_tree, tvb, offset, length,
3114                                    "Data (%d byte%s)", length,
3115                                    plurality(length, "", "s"));
3116           field_tree = proto_item_add_subtree(tf, ett_chap_data);
3117           value_size = tvb_get_guint8(tvb, offset);
3118           name_length = length - value_size - 1;
3119           tv = proto_tree_add_text(field_tree, tvb, offset, 1,
3120                                    "Value Size: %d byte%s",
3121                                    value_size, plurality(value_size, "", "s"));
3122           if (--length > 0) {
3123             value_tree = proto_item_add_subtree(tv, ett_chap_value);
3124             proto_tree_add_text(value_tree, tvb, ++offset,
3125                                 ppp_min(value_size, length),
3126                                 "Value (%d byte%s)",
3127                                 value_size, plurality(value_size, "", "s"));
3128             offset+=value_size;
3129             length-=value_size;
3130             if (length > 0) {
3131               proto_tree_add_text(field_tree, tvb, offset,
3132                                   ppp_min(name_length, length),
3133                                   "Name (%d byte%s)", name_length,
3134                                   plurality(name_length, "", "s"));
3135             }
3136           }
3137         }
3138       }
3139       break;
3140
3141     case CHAP_SUCC:
3142     case CHAP_FAIL:
3143       if(tree) {
3144         if (length > 0) {
3145           tf = proto_tree_add_text(fh_tree, tvb, offset, length,
3146                                    "Data (%d byte%s)", length,
3147                                    plurality(length, "", "s"));
3148           field_tree = proto_item_add_subtree(tf, ett_chap_data);
3149           tv = proto_tree_add_text(field_tree, tvb, offset, length,
3150                                    "Message: %d byte%s",
3151                                    length, plurality(length, "", "s"));
3152         }
3153       }
3154       break;
3155     default:
3156       if (length > 0)
3157         proto_tree_add_text(fh_tree, tvb, offset, length, "Stuff (%d byte%s)",
3158                                 length, plurality(length, "", "s"));
3159       break;
3160   }
3161 }
3162
3163 /*
3164  * RFC 2472.
3165  */
3166 static void
3167 dissect_ipv6cp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3168 {
3169   dissect_cp(tvb, proto_ipv6cp, ett_ipv6cp, cp_vals, ett_ipv6cp_options,
3170              ipv6cp_opts, N_IPV6CP_OPTS, pinfo, tree);
3171 }
3172
3173 static void dissect_ipv6cp_if_id_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3174                         int offset, guint length, packet_info *pinfo _U_,
3175                         proto_tree *tree)
3176 {
3177   proto_tree_add_text(tree, tvb, offset, length, "%s: %02x%02x:%02x%02x:%02x%x:%02x%02x",
3178                       optp->name,
3179                       tvb_get_guint8(tvb, offset + 2),
3180                       tvb_get_guint8(tvb, offset + 3),
3181                       tvb_get_guint8(tvb, offset + 4),
3182                       tvb_get_guint8(tvb, offset + 5),
3183                       tvb_get_guint8(tvb, offset + 6),
3184                       tvb_get_guint8(tvb, offset + 7),
3185                       tvb_get_guint8(tvb, offset + 8),
3186                       tvb_get_guint8(tvb, offset + 9)
3187                       );
3188 }
3189
3190 void
3191 proto_register_ppp(void)
3192 {
3193   static hf_register_info hf[] = {
3194     { &hf_ppp_address,
3195     { "Address", "ppp.address", FT_UINT8, BASE_HEX,
3196         NULL, 0x0, "", HFILL }},
3197
3198     { &hf_ppp_control,
3199     { "Control", "ppp.control", FT_UINT8, BASE_HEX,
3200         NULL, 0x0, "", HFILL }},
3201
3202     { &hf_ppp_protocol,
3203     { "Protocol", "ppp.protocol", FT_UINT16, BASE_HEX,
3204         VALS(ppp_vals), 0x0, "", HFILL }},
3205   };
3206   static gint *ett[] = {
3207     &ett_ppp,
3208   };
3209
3210   module_t *ppp_module;
3211
3212   proto_ppp = proto_register_protocol("Point-to-Point Protocol", "PPP", "ppp");
3213   proto_register_field_array(proto_ppp, hf, array_length(hf));
3214   proto_register_subtree_array(ett, array_length(ett));
3215
3216 /* subdissector code */
3217   ppp_subdissector_table = register_dissector_table("ppp.protocol",
3218         "PPP protocol", FT_UINT16, BASE_HEX);
3219
3220   register_dissector("ppp_hdlc", dissect_ppp_hdlc, proto_ppp);
3221   register_dissector("ppp_lcp_options", dissect_lcp_options, proto_ppp);
3222   register_dissector("ppp", dissect_ppp, proto_ppp);
3223
3224   /* Register the preferences for the ppp protocol */
3225   ppp_module = prefs_register_protocol(proto_ppp, NULL);
3226
3227   prefs_register_enum_preference(ppp_module,
3228         "fcs_type",
3229         "PPP Frame Checksum Type",
3230         "The type of PPP frame checksum (none, 16-bit, 32-bit)",
3231         &ppp_fcs_decode,
3232         fcs_options, FALSE);
3233   prefs_register_bool_preference(ppp_module,
3234         "decompress_vj",
3235         "Decompress Van Jacobson-compressed frames",
3236         "Whether Van Jacobson-compressed PPP frames should be decompressed",
3237         &ppp_vj_decomp);
3238   prefs_register_uint_preference(ppp_module,
3239         "default_proto_id",
3240         "PPPMuxCP Default PID",
3241         "Default Protocol ID to be used for PPPMuxCP",
3242         16, &pppmux_def_prot_id);
3243 }
3244
3245 void
3246 proto_reg_handoff_ppp(void)
3247 {
3248   dissector_handle_t ppp_hdlc_handle, ppp_handle;
3249
3250   /*
3251    * Get a handle for the CHDLC dissector.
3252    */
3253   chdlc_handle = find_dissector("chdlc");
3254   data_handle = find_dissector("data");
3255
3256   ppp_hdlc_handle = find_dissector("ppp_hdlc");
3257   ppp_handle = find_dissector("ppp");
3258   dissector_add("wtap_encap", WTAP_ENCAP_PPP, ppp_hdlc_handle);
3259   dissector_add("wtap_encap", WTAP_ENCAP_PPP_WITH_PHDR, ppp_hdlc_handle);
3260   dissector_add("fr.ietf", NLPID_PPP, ppp_handle);
3261   dissector_add("gre.proto", ETHERTYPE_PPP, ppp_hdlc_handle);
3262 }
3263
3264 void
3265 proto_register_mp(void)
3266 {
3267   static hf_register_info hf[] = {
3268     { &hf_mp_frag_first,
3269     { "First fragment",         "mp.first",     FT_BOOLEAN, 8,
3270         TFS(&frag_truth), MP_FRAG_FIRST, "", HFILL }},
3271
3272     { &hf_mp_frag_last,
3273     { "Last fragment",          "mp.last",      FT_BOOLEAN, 8,
3274         TFS(&frag_truth), MP_FRAG_LAST, "", HFILL }},
3275
3276     { &hf_mp_sequence_num,
3277     { "Sequence number",        "mp.seq",       FT_UINT24, BASE_DEC, NULL, 0x0,
3278         "", HFILL }}
3279   };
3280   static gint *ett[] = {
3281     &ett_mp,
3282     &ett_mp_flags,
3283   };
3284
3285   proto_mp = proto_register_protocol("PPP Multilink Protocol", "PPP MP", "mp");
3286   proto_register_field_array(proto_mp, hf, array_length(hf));
3287   proto_register_subtree_array(ett, array_length(ett));
3288 }
3289
3290 void
3291 proto_reg_handoff_mp(void)
3292 {
3293   dissector_handle_t mp_handle;
3294
3295   mp_handle = create_dissector_handle(dissect_mp, proto_mp);
3296   dissector_add("ppp.protocol", PPP_MP, mp_handle);
3297 }
3298
3299 void
3300 proto_register_lcp(void)
3301 {
3302   static gint *ett[] = {
3303     &ett_lcp,
3304     &ett_lcp_options,
3305     &ett_lcp_authprot_opt,
3306     &ett_lcp_qualprot_opt,
3307     &ett_lcp_fcs_alternatives_opt,
3308     &ett_lcp_numbered_mode_opt,
3309     &ett_lcp_callback_opt,
3310     &ett_lcp_multilink_ep_disc_opt,
3311     &ett_lcp_internationalization_opt,
3312   };
3313
3314   proto_lcp = proto_register_protocol("PPP Link Control Protocol", "PPP LCP",
3315                                       "lcp");
3316   proto_register_subtree_array(ett, array_length(ett));
3317 }
3318
3319 void
3320 proto_reg_handoff_lcp(void)
3321 {
3322   dissector_handle_t lcp_handle;
3323
3324   lcp_handle = create_dissector_handle(dissect_lcp, proto_lcp);
3325   dissector_add("ppp.protocol", PPP_LCP, lcp_handle);
3326
3327   /*
3328    * NDISWAN on Windows translates Ethernet frames from higher-level
3329    * protocols into PPP frames to hand to the PPP driver, and translates
3330    * PPP frames from the PPP driver to hand to the higher-level protocols.
3331    *
3332    * Apparently the PPP driver, on at least some versions of Windows,
3333    * passes frames for internal-to-PPP protocols up through NDISWAN;
3334    * the protocol type field appears to be passed through unchanged
3335    * (unlike what's done with, for example, the protocol type field
3336    * for IP, which is mapped from its PPP value to its Ethernet value).
3337    *
3338    * This means that we may see, on Ethernet captures, frames for
3339    * protocols internal to PPP, so we register PPP_LCP with the
3340    * "ethertype" dissector table as well as the PPP protocol dissector
3341    * table.
3342    */
3343   dissector_add("ethertype", PPP_LCP, lcp_handle);
3344 }
3345
3346 void
3347 proto_register_ipcp(void)
3348 {
3349   static gint *ett[] = {
3350     &ett_ipcp,
3351     &ett_ipcp_options,
3352     &ett_ipcp_ipaddrs_opt,
3353     &ett_ipcp_compressprot_opt,
3354   };
3355
3356   proto_ipcp = proto_register_protocol("PPP IP Control Protocol", "PPP IPCP",
3357                                       "ipcp");
3358   proto_register_subtree_array(ett, array_length(ett));
3359 }
3360
3361 void
3362 proto_reg_handoff_ipcp(void)
3363 {
3364   dissector_handle_t ipcp_handle;
3365
3366   ipcp_handle = create_dissector_handle(dissect_ipcp, proto_ipcp);
3367   dissector_add("ppp.protocol", PPP_IPCP, ipcp_handle);
3368
3369   /*
3370    * See above comment about NDISWAN for an explanation of why we're
3371    * registering with the "ethertype" dissector table.
3372    */
3373   dissector_add("ethertype", PPP_IPCP, ipcp_handle);
3374 }
3375
3376 void
3377 proto_register_osicp(void)
3378 {
3379   static gint *ett[] = {
3380     &ett_osicp,
3381     &ett_osicp_options,
3382     &ett_osicp_align_npdu_opt,
3383   };
3384
3385   proto_osicp = proto_register_protocol("PPP OSI Control Protocol", "PPP OSICP",
3386                                       "osicp");
3387   proto_register_subtree_array(ett, array_length(ett));
3388 }
3389
3390 void
3391 proto_reg_handoff_osicp(void)
3392 {
3393   dissector_handle_t osicp_handle;
3394
3395   osicp_handle = create_dissector_handle(dissect_osicp, proto_osicp);
3396   dissector_add("ppp.protocol", PPP_OSICP, osicp_handle);
3397
3398   /*
3399    * See above comment about NDISWAN for an explanation of why we're
3400    * registering with the "ethertype" dissector table.
3401    */
3402   dissector_add("ethertype", PPP_OSICP, osicp_handle);
3403 }
3404
3405 void
3406 proto_register_ccp(void)
3407 {
3408   static gint *ett[] = {
3409     &ett_ccp,
3410     &ett_ccp_options,
3411     &ett_ccp_stac_opt,
3412     &ett_ccp_mppc_opt,
3413     &ett_ccp_bsdcomp_opt,
3414     &ett_ccp_lzsdcp_opt,
3415     &ett_ccp_mvrca_opt,
3416     &ett_ccp_deflate_opt,
3417   };
3418
3419   proto_ccp = proto_register_protocol("PPP Compression Control Protocol",
3420                                       "PPP CCP", "ccp");
3421   proto_register_subtree_array(ett, array_length(ett));
3422 }
3423
3424 void
3425 proto_reg_handoff_ccp(void)
3426 {
3427   dissector_handle_t ccp_handle;
3428
3429   ccp_handle = create_dissector_handle(dissect_ccp, proto_ccp);
3430   dissector_add("ppp.protocol", PPP_CCP, ccp_handle);
3431
3432   /*
3433    * See above comment about NDISWAN for an explanation of why we're
3434    * registering with the "ethertype" dissector table.
3435    */
3436   dissector_add("ethertype", PPP_CCP, ccp_handle);
3437 }
3438
3439 void
3440 proto_register_cbcp(void)
3441 {
3442   static gint *ett[] = {
3443     &ett_cbcp,
3444     &ett_cbcp_options,
3445     &ett_cbcp_callback_opt,
3446     &ett_cbcp_callback_opt_addr
3447   };
3448
3449   proto_cbcp = proto_register_protocol("PPP Callback Control Protocol",
3450                                       "PPP CBCP", "cbcp");
3451   proto_register_subtree_array(ett, array_length(ett));
3452 }
3453
3454 void
3455 proto_reg_handoff_cbcp(void)
3456 {
3457   dissector_handle_t cbcp_handle;
3458
3459   cbcp_handle = create_dissector_handle(dissect_cbcp, proto_cbcp);
3460   dissector_add("ppp.protocol", PPP_CBCP, cbcp_handle);
3461
3462   /*
3463    * See above comment about NDISWAN for an explanation of why we're
3464    * registering with the "ethertype" dissector table.
3465    */
3466   dissector_add("ethertype", PPP_CBCP, cbcp_handle);
3467 }
3468
3469 void
3470 proto_register_bacp(void)
3471 {
3472   static gint *ett[] = {
3473     &ett_bacp,
3474     &ett_bacp_options,
3475     &ett_bacp_favored_peer_opt
3476   };
3477
3478   proto_bacp = proto_register_protocol("PPP Bandwidth Allocation Control Protocol",
3479                                       "PPP BACP", "bacp");
3480   proto_register_subtree_array(ett, array_length(ett));
3481 }
3482
3483 void
3484 proto_reg_handoff_bacp(void)
3485 {
3486   dissector_handle_t bacp_handle;
3487
3488   bacp_handle = create_dissector_handle(dissect_bacp, proto_bacp);
3489   dissector_add("ppp.protocol", PPP_BACP, bacp_handle);
3490
3491   /*
3492    * See above comment about NDISWAN for an explanation of why we're
3493    * registering with the "ethertype" dissector table.
3494    */
3495   dissector_add("ethertype", PPP_BACP, bacp_handle);
3496 }
3497
3498 void
3499 proto_register_bap(void)
3500 {
3501   static gint *ett[] = {
3502     &ett_bap,
3503     &ett_bap_options,
3504     &ett_bap_link_type_opt,
3505     &ett_bap_phone_delta_opt,
3506     &ett_bap_phone_delta_subopt,
3507     &ett_bap_call_status_opt
3508   };
3509
3510   proto_bap = proto_register_protocol("PPP Bandwidth Allocation Protocol",
3511                                       "PPP BAP", "bap");
3512   proto_register_subtree_array(ett, array_length(ett));
3513 }
3514
3515 void
3516 proto_reg_handoff_bap(void)
3517 {
3518   dissector_handle_t bap_handle;
3519
3520   bap_handle = create_dissector_handle(dissect_bap, proto_bap);
3521   dissector_add("ppp.protocol", PPP_BAP, bap_handle);
3522
3523   /*
3524    * See above comment about NDISWAN for an explanation of why we're
3525    * registering with the "ethertype" dissector table.
3526    */
3527   dissector_add("ethertype", PPP_BAP, bap_handle);
3528 }
3529
3530 void
3531 proto_register_comp_data(void)
3532 {
3533   static gint *ett[] = {
3534     &ett_comp_data
3535   };
3536
3537   proto_comp_data = proto_register_protocol("PPP Compressed Datagram",
3538                                       "PPP Comp", "comp_data");
3539   proto_register_subtree_array(ett, array_length(ett));
3540 }
3541
3542 void
3543 proto_reg_handoff_comp_data(void)
3544 {
3545   dissector_handle_t comp_data_handle;
3546
3547   comp_data_handle = create_dissector_handle(dissect_comp_data,
3548                                         proto_comp_data);
3549   dissector_add("ppp.protocol", PPP_COMP, comp_data_handle);
3550
3551   /*
3552    * See above comment about NDISWAN for an explanation of why we're
3553    * registering with the "ethertype" dissector table.
3554    */
3555   dissector_add("ethertype", PPP_COMP, comp_data_handle);
3556 }
3557
3558 void
3559 proto_register_pap(void)
3560 {
3561   static gint *ett[] = {
3562     &ett_pap,
3563     &ett_pap_data,
3564     &ett_pap_peer_id,
3565     &ett_pap_password,
3566     &ett_pap_message,
3567   };
3568
3569   proto_pap = proto_register_protocol("PPP Password Authentication Protocol", "PPP PAP",
3570                                       "pap");
3571   proto_register_subtree_array(ett, array_length(ett));
3572 }
3573
3574 void
3575 proto_reg_handoff_pap(void)
3576 {
3577   dissector_handle_t pap_handle;
3578
3579   pap_handle = create_dissector_handle(dissect_pap, proto_pap);
3580   dissector_add("ppp.protocol", PPP_PAP, pap_handle);
3581
3582   /*
3583    * See above comment about NDISWAN for an explanation of why we're
3584    * registering with the "ethertype" dissector table.
3585    */
3586   dissector_add("ethertype", PPP_PAP, pap_handle);
3587 }
3588
3589 void
3590 proto_register_chap(void)
3591 {
3592   static gint *ett[] = {
3593     &ett_chap,
3594     &ett_chap_data,
3595     &ett_chap_value,
3596     &ett_chap_name,
3597     &ett_chap_message,
3598   };
3599
3600   proto_chap = proto_register_protocol("PPP Challenge Handshake Authentication Protocol", "PPP CHAP",
3601                                       "chap");
3602   proto_register_subtree_array(ett, array_length(ett));
3603 }
3604
3605 void
3606 proto_reg_handoff_chap(void)
3607 {
3608   dissector_handle_t chap_handle;
3609
3610   chap_handle = create_dissector_handle(dissect_chap, proto_chap);
3611   dissector_add("ppp.protocol", PPP_CHAP, chap_handle);
3612
3613   /*
3614    * See above comment about NDISWAN for an explanation of why we're
3615    * registering with the "ethertype" dissector table.
3616    */
3617   dissector_add("ethertype", PPP_CHAP, chap_handle);
3618 }
3619
3620 void
3621 proto_register_pppmuxcp(void)
3622 {
3623   static gint *ett[] = {
3624     &ett_pppmuxcp,
3625     &ett_pppmuxcp_options,
3626   };
3627
3628   proto_pppmuxcp = proto_register_protocol("PPPMux Control Protocol",
3629                                        "PPP PPPMuxCP",
3630                                       "pppmuxcp");
3631   proto_register_subtree_array(ett, array_length(ett));
3632 }
3633
3634
3635 void
3636 proto_reg_handoff_pppmuxcp(void)
3637 {
3638   dissector_handle_t muxcp_handle;
3639
3640   muxcp_handle = create_dissector_handle(dissect_pppmuxcp, proto_pppmuxcp);
3641   dissector_add("ppp.protocol", PPP_MUXCP, muxcp_handle);
3642
3643   /*
3644    * See above comment about NDISWAN for an explanation of why we're
3645    * registering with the "ethertype" dissector table.
3646    */
3647   dissector_add("ethertype", PPP_MUXCP, muxcp_handle);
3648 }
3649
3650
3651 void
3652 proto_register_pppmux(void)
3653 {
3654   static gint *ett[] = {
3655     &ett_pppmux,
3656     &ett_pppmux_subframe,
3657     &ett_pppmux_subframe_hdr,
3658     &ett_pppmux_subframe_flags,
3659     &ett_pppmux_subframe_info,
3660   };
3661
3662   proto_pppmux = proto_register_protocol("PPP Multiplexing",
3663                                        "PPP PPPMux",
3664                                       "pppmux");
3665   proto_register_subtree_array(ett, array_length(ett));
3666 }
3667
3668 void
3669 proto_reg_handoff_pppmux(void)
3670 {
3671   dissector_handle_t pppmux_handle;
3672
3673   pppmux_handle = create_dissector_handle(dissect_pppmux, proto_pppmux);
3674   dissector_add("ppp.protocol", PPP_MUX, pppmux_handle);
3675
3676   /*
3677    * See above comment about NDISWAN for an explanation of why we're
3678    * registering with the "ethertype" dissector table.
3679    */
3680   dissector_add("ethertype", PPP_MUX, pppmux_handle);
3681 }
3682
3683 void
3684 proto_register_mplscp(void)
3685 {
3686   static gint *ett[] = {
3687     &ett_mplscp,
3688     &ett_mplscp_options,
3689   };
3690
3691   proto_mplscp = proto_register_protocol("PPP MPLS Control Protocol",
3692                                          "PPP MPLSCP", "mplscp");
3693   proto_register_subtree_array(ett, array_length(ett));
3694 }
3695
3696 void
3697 proto_reg_handoff_mplscp(void)
3698 {
3699   dissector_handle_t mplscp_handle;
3700
3701   mplscp_handle = create_dissector_handle(dissect_mplscp, proto_mplscp);
3702   dissector_add("ppp.protocol", PPP_MPLSCP, mplscp_handle);
3703
3704   /*
3705    * See above comment about NDISWAN for an explanation of why we're
3706    * registering with the "ethertype" dissector table.
3707    */
3708   dissector_add("ethertype", PPP_MPLSCP, mplscp_handle);
3709 }
3710
3711 void
3712 proto_register_cdpcp(void)
3713 {
3714   static gint *ett[] = {
3715     &ett_cdpcp,
3716     &ett_cdpcp_options,
3717   };
3718
3719   proto_cdpcp = proto_register_protocol("PPP CDP Control Protocol",
3720                                          "PPP CDPCP", "cdpcp");
3721   proto_register_subtree_array(ett, array_length(ett));
3722 }
3723
3724 void
3725 proto_reg_handoff_cdpcp(void)
3726 {
3727   dissector_handle_t cdpcp_handle;
3728
3729   cdpcp_handle = create_dissector_handle(dissect_cdpcp, proto_cdpcp);
3730   dissector_add("ppp.protocol", PPP_CDPCP, cdpcp_handle);
3731
3732   /*
3733    * See above comment about NDISWAN for an explanation of why we're
3734    * registering with the "ethertype" dissector table.
3735    */
3736   dissector_add("ethertype", PPP_CDPCP, cdpcp_handle);
3737 }
3738
3739 void
3740 proto_register_ipv6cp(void)
3741 {
3742   static gint *ett[] = {
3743     &ett_ipv6cp,
3744     &ett_ipv6cp_options,
3745     &ett_ipv6cp_if_id_opt,
3746     &ett_ipv6cp_compressprot_opt,
3747   };
3748
3749   proto_ipv6cp = proto_register_protocol("PPP IPv6 Control Protocol",
3750                                          "PPP IPV6CP", "ipv6cp");
3751   proto_register_subtree_array(ett, array_length(ett));
3752 }
3753
3754 void
3755 proto_reg_handoff_ipv6cp(void)
3756 {
3757   dissector_handle_t ipv6cp_handle;
3758
3759   ipv6cp_handle = create_dissector_handle(dissect_ipv6cp, proto_ipv6cp);
3760   dissector_add("ppp.protocol", PPP_IPV6CP, ipv6cp_handle);
3761
3762   /*
3763    * See above comment about NDISWAN for an explanation of why we're
3764    * registering with the "ethertype" dissector table.
3765    */
3766   dissector_add("ethertype", PPP_IPV6CP, ipv6cp_handle);
3767 }