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