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