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