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