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