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