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