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