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