MSWSP: add ids for another unknown Property Set
[wireshark-wip.git] / epan / dissectors / packet-ppp.c
blob4c4887c45943ff5664e3f5feca4899d5baf64c8d
1 /* packet-ppp.c
2 * Routines for ppp packet disassembly
3 * RFC 1661, RFC 1662
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
10 * This file created and by Mike Hall <mlh@io.com>
11 * Copyright 1998
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "config.h"
30 #include <glib.h>
31 #include <epan/packet.h>
32 #include <wsutil/pint.h>
33 #include <epan/prefs.h>
34 #include <epan/wmem/wmem.h>
35 #include "packet-ppp.h"
36 #include <epan/ppptypes.h>
37 #include <epan/etypes.h>
38 #include <epan/expert.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-tvb.h>
47 #include <epan/crc32-tvb.h>
48 #include <epan/ipproto.h>
49 #include <epan/addr_resolv.h>
50 #include <epan/oui.h>
51 #include "packet-usb.h"
52 #include "packet-sll.h"
55 static int proto_ppp = -1;
56 static int hf_ppp_direction = -1;
57 static int hf_ppp_address = -1;
58 static int hf_ppp_control = -1;
59 static int hf_ppp_protocol = -1;
60 static int hf_ppp_code = -1;
61 static int hf_ppp_identifier = -1;
62 static int hf_ppp_length = -1;
63 static int hf_ppp_magic_number = -1;
64 static int hf_ppp_oui = -1;
65 static int hf_ppp_kind = -1;
66 static int hf_ppp_data = -1;
67 static int hf_ppp_opt_type = -1;
68 static int hf_ppp_opt_type_copy = -1;
69 static int hf_ppp_opt_type_class = -1;
70 static int hf_ppp_opt_type_number = -1;
72 static gint ett_ppp = -1;
73 static gint ett_ppp_opt_type = -1;
75 static expert_field ei_ppp_opt_len_invalid = EI_INIT;
77 static int proto_ppp_hdlc = -1;
79 static gint ett_ppp_hdlc_data = -1;
81 static int proto_lcp = -1;
83 static gint ett_lcp = -1;
84 static gint ett_lcp_options = -1;
85 static gint ett_lcp_vendor_opt = -1;
86 static gint ett_lcp_mru_opt = -1;
87 static gint ett_lcp_asyncmap_opt = -1;
88 static gint ett_lcp_authprot_opt = -1;
89 static gint ett_lcp_qualprot_opt = -1;
90 static gint ett_lcp_magicnumber_opt = -1;
91 static gint ett_lcp_linkqualmon_opt = -1;
92 static gint ett_lcp_pcomp_opt = -1;
93 static gint ett_lcp_acccomp_opt = -1;
94 static gint ett_lcp_fcs_alternatives_opt = -1;
95 static gint ett_lcp_self_desc_pad_opt = -1;
96 static gint ett_lcp_numbered_mode_opt = -1;
97 static gint ett_lcp_callback_opt = -1;
98 static gint ett_lcp_compound_frames_opt = -1;
99 static gint ett_lcp_nomdataencap_opt = -1;
100 static gint ett_lcp_multilink_mrru_opt = -1;
101 static gint ett_lcp_multilink_ssnh_opt = -1;
102 static gint ett_lcp_multilink_ep_disc_opt = -1;
103 static gint ett_lcp_magic_block = -1;
104 static gint ett_lcp_dce_identifier_opt = -1;
105 static gint ett_lcp_multilink_pp_opt = -1;
106 static gint ett_lcp_bacp_link_discrim_opt = -1;
107 static gint ett_lcp_auth_opt = -1;
108 static gint ett_lcp_cobs_opt = -1;
109 static gint ett_lcp_prefix_elision_opt = -1;
110 static gint ett_multilink_hdr_fmt_opt = -1;
111 static gint ett_lcp_internationalization_opt = -1;
112 static gint ett_lcp_simple_opt = -1;
114 static int proto_ipcp = -1;
116 static gint ett_ipcp = -1;
117 static gint ett_ipcp_options = -1;
118 static gint ett_ipcp_ipaddrs_opt = -1;
119 static gint ett_ipcp_compress_opt = -1;
120 static gint ett_ipcp_ipaddr_opt = -1;
121 static gint ett_ipcp_mobileipv4_opt = -1;
122 static gint ett_ipcp_pridns_opt = -1;
123 static gint ett_ipcp_secdns_opt = -1;
124 static gint ett_ipcp_prinbns_opt = -1;
125 static gint ett_ipcp_secnbns_opt = -1;
127 static gint ett_ipcp_iphc_rtp_compress_opt = -1;
128 static gint ett_ipcp_iphc_enhanced_rtp_compress_opt = -1;
129 static gint ett_ipcp_iphc_neghdrcomp_opt = -1;
130 static gint ett_ipcp_rohc_profiles_opt = -1;
132 static int proto_vsncp = -1;
134 static gint ett_vsncp = -1;
135 static gint ett_vsncp_options = -1;
137 static int proto_vsnp = -1;
138 static gint hf_vsnp_pdnid = -1;
140 static gint ett_vsnp =-1;
142 static int proto_osinlcp = -1;
144 static gint ett_osinlcp = -1;
145 static gint ett_osinlcp_options = -1;
146 static gint ett_osinlcp_align_npdu_opt = -1;
148 static int proto_bcp = -1;
149 static int hf_bcp_flags = -1;
150 static int hf_bcp_fcs_present = -1;
151 static int hf_bcp_zeropad = -1;
152 static int hf_bcp_bcontrol = -1;
153 static int hf_bcp_pads = -1;
154 static int hf_bcp_mac_type = -1;
156 static gint ett_bcp = -1;
157 static gint ett_bcp_flags = -1;
159 static int proto_ccp = -1;
161 static gint ett_ccp = -1;
162 static gint ett_ccp_options = -1;
163 static gint ett_ccp_oui_opt = -1;
164 static gint ett_ccp_predict1_opt = -1;
165 static gint ett_ccp_predict2_opt = -1;
166 static gint ett_ccp_puddle_opt = -1;
167 static gint ett_ccp_hpppc_opt = -1;
168 static gint ett_ccp_stac_opt = -1;
169 static gint ett_ccp_stac_opt_check_mode = -1;
170 static gint ett_ccp_mppe_opt = -1;
171 static gint ett_ccp_mppe_opt_supp_bits = -1;
172 static gint ett_ccp_gfza_opt = -1;
173 static gint ett_ccp_v42bis_opt = -1;
174 static gint ett_ccp_bsdcomp_opt = -1;
175 static gint ett_ccp_lzsdcp_opt = -1;
176 static gint ett_ccp_mvrca_opt = -1;
177 static gint ett_ccp_dce_opt = -1;
178 static gint ett_ccp_deflate_opt = -1;
179 static gint ett_ccp_v44lzjh_opt = -1;
181 static int proto_cbcp = -1;
183 static gint ett_cbcp = -1;
184 static gint ett_cbcp_options = -1;
185 static gint ett_cbcp_callback_opt = -1;
186 static gint ett_cbcp_callback_opt_addr = -1;
188 static int proto_bacp = -1;
190 static gint ett_bacp = -1;
191 static gint ett_bacp_options = -1;
192 static gint ett_bacp_favored_peer_opt = -1;
194 static int proto_bap = -1;
196 static gint ett_bap = -1;
197 static gint ett_bap_options = -1;
198 static gint ett_bap_link_type_opt = -1;
199 static gint ett_bap_phone_delta_opt = -1;
200 static gint ett_bap_phone_delta_subopt = -1;
201 static gint ett_bap_call_status_opt = -1;
203 static int proto_comp_data = -1;
205 #if 0 /* see dissect_comp_data() */
206 static gint ett_comp_data = -1;
207 #endif
208 static int proto_pppmuxcp = -1;
210 static int hf_pppmux_flags_pid = -1;
211 static int hf_pppmux_flags_field_length = -1;
213 static gint ett_pppmuxcp = -1;
214 static gint ett_pppmuxcp_options = -1;
216 static int proto_pppmux = -1;
217 static int hf_pppmux_protocol = -1;
219 static gint ett_pppmux = -1;
220 static gint ett_pppmux_subframe = -1;
221 static gint ett_pppmux_subframe_hdr = -1;
222 static gint ett_pppmux_subframe_flags = -1;
223 static gint ett_pppmux_subframe_info = -1;
225 static int proto_mp = -1;
226 static int hf_mp_frag_first = -1;
227 static int hf_mp_frag_last = -1;
228 static int hf_mp_short_sequence_num_reserved = -1;
229 static int hf_mp_sequence_num = -1;
230 static int hf_mp_sequence_num_reserved = -1;
231 static int hf_mp_short_sequence_num = -1;
233 static int ett_mp = -1;
234 static int ett_mp_flags = -1;
236 static int proto_mplscp = -1;
237 static gint ett_mplscp = -1;
238 static gint ett_mplscp_options = -1;
240 static int proto_cdpcp = -1;
241 static gint ett_cdpcp = -1;
242 static gint ett_cdpcp_options = -1;
244 static int proto_pap = -1; /* PAP vars */
245 static gint ett_pap = -1;
246 static gint ett_pap_data = -1;
248 static gint hf_pap_code = -1;
249 static gint hf_pap_identifier = -1;
250 static gint hf_pap_length = -1;
251 static gint hf_pap_data = -1;
252 static gint hf_pap_peer_id = -1;
253 static gint hf_pap_peer_id_length = -1;
254 static gint hf_pap_password = -1;
255 static gint hf_pap_password_length = -1;
256 static gint hf_pap_message = -1;
257 static gint hf_pap_message_length = -1;
258 static gint hf_pap_stuff = -1;
260 static int proto_chap = -1; /* CHAP vars */
261 static gint ett_chap = -1;
262 static gint ett_chap_data = -1;
265 static gint hf_chap_code = -1;
266 static gint hf_chap_identifier = -1;
267 static gint hf_chap_length = -1;
268 static gint hf_chap_data = -1;
269 static gint hf_chap_value_size = -1;
270 static gint hf_chap_value = -1;
271 static gint hf_chap_name = -1;
272 static gint hf_chap_message = -1;
275 static int proto_ipv6cp = -1; /* IPv6CP vars */
277 static gint ett_ipv6cp = -1;
278 static gint ett_ipv6cp_options = -1;
279 static gint ett_ipv6cp_if_id_opt = -1;
280 static gint ett_ipv6cp_compress_opt = -1;
282 static int proto_iphc_crtp = -1; /* CRTP vars */
283 static int hf_iphc_crtp_cid8 = -1;
284 static int hf_iphc_crtp_cid16 = -1;
285 static int hf_iphc_crtp_gen = -1;
286 static int hf_iphc_crtp_seq = -1;
287 static int hf_iphc_crtp_fh_flags = -1;
288 static int hf_iphc_crtp_cs_flags = -1;
289 static int hf_iphc_crtp_cs_cnt = -1;
290 static int hf_iphc_crtp_cs_invalid = -1;
292 static gint ett_iphc_crtp = -1;
293 static gint ett_iphc_crtp_hdr = -1;
294 static gint ett_iphc_crtp_info = -1;
296 static dissector_table_t ppp_subdissector_table;
297 static dissector_handle_t chdlc_handle;
298 static dissector_handle_t data_handle;
299 static dissector_handle_t eth_withfcs_handle;
300 static dissector_handle_t eth_withoutfcs_handle;
302 static const value_string ppp_direction_vals[] = {
303 {P2P_DIR_RECV, "DCE->DTE"},
304 {P2P_DIR_SENT, "DTE->DCE"},
305 {0, NULL}
308 /* options */
309 static gint ppp_fcs_decode = 0; /* 0 = No FCS, 1 = 16 bit FCS, 2 = 32 bit FCS */
310 #define NO_FCS 0
311 #define FCS_16 1
312 #define FCS_32 2
314 const enum_val_t fcs_options[] = {
315 {"none", "None", NO_FCS},
316 {"16-bit", "16-Bit", FCS_16},
317 {"32-bit", "32-Bit", FCS_32},
318 {NULL, NULL, -1}
321 gboolean ppp_vj_decomp = TRUE; /* Default to VJ header decompression */
324 * For Default Protocol ID negotiated with PPPMuxCP. We need to
325 * this ID so that if the first subframe doesn't have protocol
326 * ID, we can use it
329 static guint pppmux_def_prot_id = 0;
331 /* PPP definitions */
334 * Used by the GTP dissector as well.
335 * www.iana.org/assignments/ppp-numbers
337 static const value_string ppp_vals[] = {
338 {PPP_PADDING, "Padding Protocol"},
339 {PPP_ROHC_SCID, "ROHC small-CID"},
340 {PPP_ROHC_LCID, "ROHC large-CID"},
341 {PPP_IP, "Internet Protocol version 4"},
342 {PPP_OSI, "OSI Network Layer"},
343 {PPP_XNSIDP, "Xerox NS IDP"},
344 {PPP_DEC4, "DECnet Phase IV"},
345 {PPP_AT, "Appletalk"},
346 {PPP_IPX, "Novell IPX"},
347 {PPP_VJC_COMP, "Van Jacobson Compressed TCP/IP"},
348 {PPP_VJC_UNCOMP, "Van Jacobson Uncompressed TCP/IP"},
349 {PPP_BCP, "Bridging PDU"},
350 {PPP_ST, "Stream Protocol (ST-II)"},
351 {PPP_VINES, "Banyan Vines"},
352 {PPP_AT_EDDP, "AppleTalk EDDP"},
353 {PPP_AT_SB, "AppleTalk SmartBuffered"},
354 {PPP_MP, "Multi-Link"},
355 {PPP_NB, "NETBIOS Framing"},
356 {PPP_CISCO, "Cisco Systems"},
357 {PPP_ASCOM, "Ascom Timeplex"},
358 {PPP_LBLB, "Fujitsu Link Backup and Load Balancing (LBLB)"},
359 {PPP_RL, "DCA Remote Lan"},
360 {PPP_SDTP, "Serial Data Transport Protocol (PPP-SDTP)"},
361 {PPP_LLC, "SNA over 802.2"},
362 {PPP_SNA, "SNA"},
363 {PPP_IPV6HC, "IPv6 Header Compression "},
364 {PPP_KNX, "KNX Bridging Data"},
365 {PPP_ENCRYPT, "Encryption"},
366 {PPP_ILE, "Individual Link Encryption"},
367 {PPP_IPV6, "Internet Protocol version 6"},
368 {PPP_MUX, "PPP Muxing"},
369 {PPP_VSNP, "Vendor-Specific Network Protocol (VSNP)"},
370 {PPP_TNP, "TRILL Network Protocol (TNP)"},
371 {PPP_RTP_FH, "RTP IPHC Full Header"},
372 {PPP_RTP_CTCP, "RTP IPHC Compressed TCP"},
373 {PPP_RTP_CNTCP, "RTP IPHC Compressed Non TCP"},
374 {PPP_RTP_CUDP8, "RTP IPHC Compressed UDP 8"},
375 {PPP_RTP_CRTP8, "RTP IPHC Compressed RTP 8"},
376 {PPP_STAMPEDE, "Stampede Bridging"},
377 {PPP_MPPLUS, "MP+ Protocol"},
378 {PPP_NTCITS_IPI, "NTCITS IPI"},
379 {PPP_ML_SLCOMP, "Single link compression in multilink"},
380 {PPP_COMP, "Compressed datagram"},
381 {PPP_STP_HELLO, "802.1d Hello Packets"},
382 {PPP_IBM_SR, "IBM Source Routing BPDU"},
383 {PPP_DEC_LB, "DEC LANBridge100 Spanning Tree"},
384 {PPP_CDP, "Cisco Discovery Protocol"},
385 {PPP_NETCS, "Netcs Twin Routing"},
386 {PPP_STP, "STP - Scheduled Transfer Protocol"},
387 {PPP_EDP, "EDP - Extreme Discovery Protocol"},
388 {PPP_OSCP, "Optical Supervisory Channel Protocol (OSCP)"},
389 {PPP_OSCP2, "Optical Supervisory Channel Protocol (OSCP)"},
390 {PPP_LUXCOM, "Luxcom"},
391 {PPP_SIGMA, "Sigma Network Systems"},
392 {PPP_ACSP, "Apple Client Server Protocol"},
393 {PPP_MPLS_UNI, "MPLS Unicast"},
394 {PPP_MPLS_MULTI, "MPLS Multicast"},
395 {PPP_P12844, "IEEE p1284.4 standard - data packets"},
396 {PPP_TETRA, "ETSI TETRA Network Protocol Type 1"},
397 {PPP_MFTP, "Multichannel Flow Treatment Protocol"},
398 {PPP_RTP_CTCPND, "RTP IPHC Compressed TCP No Delta"},
399 {PPP_RTP_CS, "RTP IPHC Context State"},
400 {PPP_RTP_CUDP16, "RTP IPHC Compressed UDP 16"},
401 {PPP_RTP_CRDP16, "RTP IPHC Compressed RTP 16"},
402 {PPP_CCCP, "Cray Communications Control Protocol"},
403 {PPP_CDPD_MNRP, "CDPD Mobile Network Registration Protocol"},
404 {PPP_EXPANDAP, "Expand accelerator protocol"},
405 {PPP_ODSICP, "ODSICP NCP"},
406 {PPP_DOCSIS, "DOCSIS DLL"},
407 {PPP_CETACEANNDP, "Cetacean Network Detection Protocol"},
408 {PPP_LZS, "Stacker LZS"},
409 {PPP_REFTEK, "RefTek Protocol"},
410 {PPP_FC, "Fibre Channel"},
411 {PPP_EMIT, "EMIT Protocols"},
412 {PPP_VSP, "Vendor-Specific Protocol (VSP)"},
413 {PPP_TLSP, "TRILL Link State Protocol (TLSP)"},
414 {PPP_IPCP, "Internet Protocol Control Protocol"},
415 {PPP_OSINLCP, "OSI Network Layer Control Protocol"},
416 {PPP_XNSIDPCP, "Xerox NS IDP Control Protocol"},
417 {PPP_DECNETCP, "DECnet Phase IV Control Protocol"},
418 {PPP_ATCP, "AppleTalk Control Protocol"},
419 {PPP_IPXCP, "Novell IPX Control Protocol"},
420 {PPP_BRIDGENCP, "Bridging NCP"},
421 {PPP_SPCP, "Stream Protocol Control Protocol"},
422 {PPP_BVCP, "Banyan Vines Control Protocol"},
423 {PPP_MLCP, "Multi-Link Control Protocol"},
424 {PPP_NBCP, "NETBIOS Framing Control Protocol"},
425 {PPP_CISCOCP, "Cisco Systems Control Protocol"},
426 {PPP_ASCOMCP, "Ascom Timeplex"},
427 {PPP_LBLBCP, "Fujitsu LBLB Control Protocol"},
428 {PPP_RLNCP, "DCA Remote Lan Network Control Protocol (RLNCP)"},
429 {PPP_SDCP, "Serial Data Control Protocol (PPP-SDCP)"},
430 {PPP_LLCCP, "SNA over 802.2 Control Protocol"},
431 {PPP_SNACP, "SNA Control Protocol"},
432 {PPP_IP6HCCP, "IP6 Header Compression Control Protocol"},
433 {PPP_KNXCP, "KNX Bridging Control Protocol"},
434 {PPP_ECP, "Encryption Control Protocol"},
435 {PPP_ILECP, "Individual Link Encryption Control Protocol"},
436 {PPP_IPV6CP, "IPv6 Control Protocol"},
437 {PPP_MUXCP, "PPP Muxing Control Protocol"},
438 {PPP_VSNCP, "Vendor-Specific Network Control Protocol (VSNCP)"},
439 {PPP_TNCP, "TRILL Network Control Protocol"},
440 {PPP_STAMPEDECP, "Stampede Bridging Control Protocol"},
441 {PPP_MPPCP, "MP+ Control Protocol"},
442 {PPP_IPICP, "NTCITS IPI Control Protocol"},
443 {PPP_SLCC, "Single link compression in multilink control"},
444 {PPP_CCP, "Compression Control Protocol"},
445 {PPP_CDPCP, "Cisco Discovery Protocol Control Protocol"},
446 {PPP_NETCSCP, "Netcs Twin Routing"},
447 {PPP_STPCP, "STP - Control Protocol"},
448 {PPP_EDPCP, "EDPCP - Extreme Discovery Protocol Control Protocol"},
449 {PPP_ACSPC, "Apple Client Server Protocol Control"},
450 {PPP_MPLSCP, "MPLS Control Protocol"},
451 {PPP_P12844CP, "IEEE p1284.4 standard - Protocol Control"},
452 {PPP_TETRACP, "ETSI TETRA TNP1 Control Protocol"},
453 {PPP_MFTPCP, "Multichannel Flow Treatment Protocol"},
454 {PPP_LCP, "Link Control Protocol"},
455 {PPP_PAP, "Password Authentication Protocol"},
456 {PPP_LQR, "Link Quality Report"},
457 {PPP_SPAP, "Shiva Password Authentication Protocol"},
458 {PPP_CBCP, "Callback Control Protocol (CBCP)"},
459 {PPP_BACP, "BACP Bandwidth Allocation Control Protocol"},
460 {PPP_BAP, "BAP Bandwidth Allocation Protocol"},
461 {PPP_VSAP, "Vendor-Specific Authentication Protocol (VSAP)"},
462 {PPP_CONTCP, "Container Control Protocol"},
463 {PPP_CHAP, "Challenge Handshake Authentication Protocol"},
464 {PPP_RSAAP, "RSA Authentication Protocol"},
465 {PPP_EAP, "Extensible Authentication Protocol"},
466 {PPP_SIEP, "Mitsubishi Security Information Exchange Protocol (SIEP)"},
467 {PPP_SBAP, "Stampede Bridging Authorization Protocol"},
468 {PPP_PRPAP, "Proprietary Authentication Protocol"},
469 {PPP_PRPAP2, "Proprietary Authentication Protocol"},
470 {PPP_PRPNIAP, "Proprietary Node ID Authentication Protocol"},
471 {0, NULL}
473 value_string_ext ppp_vals_ext = VALUE_STRING_EXT_INIT(ppp_vals);
475 /* CP (LCP, CCP, IPCP, etc.) codes.
476 * from pppd fsm.h
478 #define VNDRSPCFC 0 /* Vendor Specific: RFC 2153 */
479 #define CONFREQ 1 /* Configuration Request */
480 #define CONFACK 2 /* Configuration Ack */
481 #define CONFNAK 3 /* Configuration Nak */
482 #define CONFREJ 4 /* Configuration Reject */
483 #define TERMREQ 5 /* Termination Request */
484 #define TERMACK 6 /* Termination Ack */
485 #define CODEREJ 7 /* Code Reject */
487 static const value_string cp_vals[] = {
488 {VNDRSPCFC, "Vendor Specific"},
489 {CONFREQ, "Configuration Request"},
490 {CONFACK, "Configuration Ack"},
491 {CONFNAK, "Configuration Nak"},
492 {CONFREJ, "Configuration Reject"},
493 {TERMREQ, "Termination Request"},
494 {TERMACK, "Termination Ack"},
495 {CODEREJ, "Code Reject"},
496 {0, NULL}
500 * LCP-specific packet types.
502 #define PROTREJ 8 /* Protocol Reject */
503 #define ECHOREQ 9 /* Echo Request */
504 #define ECHOREP 10 /* Echo Reply */
505 #define DISCREQ 11 /* Discard Request */
506 #define IDENT 12 /* Identification */
507 #define TIMEREMAIN 13 /* Time remaining */
510 * CCP-specific packet types.
512 #define RESETREQ 14 /* Reset Request */
513 #define RESETACK 15 /* Reset Ack */
516 * CBCP-specific packet types.
518 #define CBREQ 1 /* Callback Request */
519 #define CBRES 2 /* Callback Response */
520 #define CBACK 3 /* Callback Ack */
522 #define CBCP_OPT 6 /* Use callback control protocol */
525 * BAP-specific packet types.
527 #define BAP_CREQ 1 /* Call Request */
528 #define BAP_CRES 2 /* Call Response */
529 #define BAP_CBREQ 3 /* Callback Request */
530 #define BAP_CBRES 4 /* Callback Response */
531 #define BAP_LDQREQ 5 /* Link Drop Query Request */
532 #define BAP_LDQRES 6 /* Link Drop Query Response */
533 #define BAP_CSI 7 /* Call Status Indication */
534 #define BAP_CSRES 8 /* Call Status Response */
536 static const value_string lcp_vals[] = {
537 {VNDRSPCFC, "Vendor Specific"},
538 {CONFREQ, "Configuration Request"},
539 {CONFACK, "Configuration Ack"},
540 {CONFNAK, "Configuration Nak"},
541 {CONFREJ, "Configuration Reject"},
542 {TERMREQ, "Termination Request"},
543 {TERMACK, "Termination Ack"},
544 {CODEREJ, "Code Reject"},
545 {PROTREJ, "Protocol Reject"},
546 {ECHOREQ, "Echo Request"},
547 {ECHOREP, "Echo Reply"},
548 {DISCREQ, "Discard Request"},
549 {IDENT, "Identification"},
550 {TIMEREMAIN, "Time Remaining"},
551 {0, NULL}
554 static const value_string ccp_vals[] = {
555 {VNDRSPCFC, "Vendor Specific"},
556 {CONFREQ, "Configuration Request"},
557 {CONFACK, "Configuration Ack"},
558 {CONFNAK, "Configuration Nak"},
559 {CONFREJ, "Configuration Reject"},
560 {TERMREQ, "Termination Request"},
561 {TERMACK, "Termination Ack"},
562 {CODEREJ, "Code Reject"},
563 {RESETREQ, "Reset Request"},
564 {RESETACK, "Reset Ack"},
565 {0, NULL}
568 static const value_string cbcp_vals[] = {
569 {CBREQ, "Callback Request"},
570 {CBRES, "Callback Response"},
571 {CBACK, "Callback Ack"},
572 {0, NULL}
575 static const value_string bap_vals[] = {
576 {BAP_CREQ, "Call Request"},
577 {BAP_CRES, "Call Response"},
578 {BAP_CBREQ, "Callback Request"},
579 {BAP_CBRES, "Callback Response"},
580 {BAP_LDQREQ, "Link Drop Query Request"},
581 {BAP_LDQRES, "Link Drop Query Response"},
582 {BAP_CSI, "Call Status Indication"},
583 {BAP_CSRES, "Call Status Response"},
584 {0, NULL}
587 #define BAP_RESP_CODE_REQACK 0x00
588 #define BAP_RESP_CODE_REQNAK 0x01
589 #define BAP_RESP_CODE_REQREJ 0x02
590 #define BAP_RESP_CODE_REQFULLNAK 0x03
591 static const value_string bap_resp_code_vals[] = {
592 {BAP_RESP_CODE_REQACK, "Request Ack"},
593 {BAP_RESP_CODE_REQNAK, "Request Nak"},
594 {BAP_RESP_CODE_REQREJ, "Request Rej"},
595 {BAP_RESP_CODE_REQFULLNAK, "Request Full Nak"},
596 {0, NULL}
599 #define BAP_LINK_TYPE_ISDN 0 /* ISDN */
600 #define BAP_LINK_TYPE_X25 1 /* X.25 */
601 #define BAP_LINK_TYPE_ANALOG 2 /* Analog */
602 #define BAP_LINK_TYPE_SD 3 /* Switched Digital (non-ISDN) */
603 #define BAP_LINK_TYPE_ISDNOV 4 /* ISDN data over voice */
604 #define BAP_LINK_TYPE_RESV5 5 /* Reserved */
605 #define BAP_LINK_TYPE_RESV6 6 /* Reserved */
606 #define BAP_LINK_TYPE_RESV7 7 /* Reserved */
607 static const value_string bap_link_type_vals[] = {
608 {BAP_LINK_TYPE_ISDN, "ISDN"},
609 {BAP_LINK_TYPE_X25, "X.25"},
610 {BAP_LINK_TYPE_ANALOG, "Analog"},
611 {BAP_LINK_TYPE_SD, "Switched Digital (non-ISDN)"},
612 {BAP_LINK_TYPE_ISDNOV, "ISDN data over voice"},
613 {BAP_LINK_TYPE_RESV5, "Reserved"},
614 {BAP_LINK_TYPE_RESV6, "Reserved"},
615 {BAP_LINK_TYPE_RESV7, "Reserved"},
616 {0, NULL}
619 #define BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT 1 /* Unique Digit */
620 #define BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM 2 /* Subscriber Number */
621 #define BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR 3 /* Phone Number Sub Address */
622 static const value_string bap_phone_delta_subopt_vals[] = {
623 {BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT, "Unique Digit"},
624 {BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM, "Subscriber Number"},
625 {BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR, "Phone Number Sub Address"},
626 {0, NULL}
630 * Cause codes for Cause.
632 * The following code table is taken from packet-q931.c but is slightly
633 * adapted to BAP protocol.
635 static const value_string q931_cause_code_vals[] = {
636 {0x00, "Call successful"},
637 {0x01, "Unallocated (unassigned) number"},
638 {0x02, "No route to specified transit network"},
639 {0x03, "No route to destination"},
640 {0x04, "Send special information tone"},
641 {0x05, "Misdialled trunk prefix"},
642 {0x06, "Channel unacceptable"},
643 {0x07, "Call awarded and being delivered in an established channel"},
644 {0x08, "Prefix 0 dialed but not allowed"},
645 {0x09, "Prefix 1 dialed but not allowed"},
646 {0x0A, "Prefix 1 dialed but not required"},
647 {0x0B, "More digits received than allowed, call is proceeding"},
648 {0x10, "Normal call clearing"},
649 {0x11, "User busy"},
650 {0x12, "No user responding"},
651 {0x13, "No answer from user (user alerted)"},
652 {0x14, "Subscriber absent"},
653 {0x15, "Call rejected"},
654 {0x16, "Number changed"},
655 {0x17, "Reverse charging rejected"},
656 {0x18, "Call suspended"},
657 {0x19, "Call resumed"},
658 {0x1A, "Non-selected user clearing"},
659 {0x1B, "Destination out of order"},
660 {0x1C, "Invalid number format (incomplete number)"},
661 {0x1D, "Facility rejected"},
662 {0x1E, "Response to STATUS ENQUIRY"},
663 {0x1F, "Normal unspecified"},
664 {0x21, "Circuit out of order"},
665 {0x22, "No circuit/channel available"},
666 {0x23, "Destination unattainable"},
667 {0x25, "Degraded service"},
668 {0x26, "Network out of order"},
669 {0x27, "Transit delay range cannot be achieved"},
670 {0x28, "Throughput range cannot be achieved"},
671 {0x29, "Temporary failure"},
672 {0x2A, "Switching equipment congestion"},
673 {0x2B, "Access information discarded"},
674 {0x2C, "Requested circuit/channel not available"},
675 {0x2D, "Pre-empted"},
676 {0x2E, "Precedence call blocked"},
677 {0x2F, "Resources unavailable, unspecified"},
678 {0x31, "Quality of service unavailable"},
679 {0x32, "Requested facility not subscribed"},
680 {0x33, "Reverse charging not allowed"},
681 {0x34, "Outgoing calls barred"},
682 {0x35, "Outgoing calls barred within CUG"},
683 {0x36, "Incoming calls barred"},
684 {0x37, "Incoming calls barred within CUG"},
685 {0x38, "Call waiting not subscribed"},
686 {0x39, "Bearer capability not authorized"},
687 {0x3A, "Bearer capability not presently available"},
688 {0x3E, "Inconsistency in designated outgoing access information and subscriber class"},
689 {0x3F, "Service or option not available, unspecified"},
690 {0x41, "Bearer capability not implemented"},
691 {0x42, "Channel type not implemented"},
692 {0x43, "Transit network selection not implemented"},
693 {0x44, "Message not implemented"},
694 {0x45, "Requested facility not implemented"},
695 {0x46, "Only restricted digital information bearer capability is available"},
696 {0x4F, "Service or option not implemented, unspecified"},
697 {0x51, "Invalid call reference value"},
698 {0x52, "Identified channel does not exist"},
699 {0x53, "Call identity does not exist for suspended call"},
700 {0x54, "Call identity in use"},
701 {0x55, "No call suspended"},
702 {0x56, "Call having the requested call identity has been cleared"},
703 {0x57, "Called user not member of CUG"},
704 {0x58, "Incompatible destination"},
705 {0x59, "Non-existent abbreviated address entry"},
706 {0x5A, "Destination address missing, and direct call not subscribed"},
707 {0x5B, "Invalid transit network selection (national use)"},
708 {0x5C, "Invalid facility parameter"},
709 {0x5D, "Mandatory information element is missing"},
710 {0x5F, "Invalid message, unspecified"},
711 {0x60, "Mandatory information element is missing"},
712 {0x61, "Message type non-existent or not implemented"},
713 {0x62, "Message not compatible with call state or message type non-existent or not implemented"},
714 {0x63, "Information element non-existent or not implemented"},
715 {0x64, "Invalid information element contents"},
716 {0x65, "Message not compatible with call state"},
717 {0x66, "Recovery on timer expiry"},
718 {0x67, "Parameter non-existent or not implemented - passed on"},
719 {0x6E, "Message with unrecognized parameter discarded"},
720 {0x6F, "Protocol error, unspecified"},
721 {0x7F, "Internetworking, unspecified"},
722 {0xFF, "Non-specific failure"},
723 {0, NULL}
725 static value_string_ext q931_cause_code_vals_ext = VALUE_STRING_EXT_INIT(q931_cause_code_vals);
727 static const value_string bap_call_status_opt_action_vals[] = {
728 {0, "No retry"},
729 {1, "Retry"},
730 {0, NULL}
733 #define STAC_CM_NONE 0
734 #define STAC_CM_LCB 1
735 #define STAC_CM_CRC 2
736 #define STAC_CM_SN 3
737 #define STAC_CM_EXTMODE 4
738 static const value_string stac_checkmode_vals[] = {
739 {STAC_CM_NONE, "None"},
740 {STAC_CM_LCB, "LCB"},
741 {STAC_CM_CRC, "CRC"},
742 {STAC_CM_SN, "Sequence Number"},
743 {STAC_CM_EXTMODE, "Extended Mode"},
744 {0, NULL}
747 #define LZSDCP_CM_NONE 0
748 #define LZSDCP_CM_LCB 1
749 #define LZSDCP_CM_SN 2
750 #define LZSDCP_CM_SN_LCB 3
751 static const value_string lzsdcp_checkmode_vals[] = {
752 {LZSDCP_CM_NONE, "None"},
753 {LZSDCP_CM_LCB, "LCB"},
754 {LZSDCP_CM_SN, "Sequence Number"},
755 {LZSDCP_CM_SN_LCB, "Sequence Number + LCB (default)"},
756 {0, NULL}
759 #define LZSDCP_PM_NONE 0
760 #define LZSDCP_PM_PROC_UNCOMP 1
761 static const value_string lzsdcp_processmode_vals[] = {
762 {LZSDCP_PM_NONE, "None (default)"},
763 {LZSDCP_PM_PROC_UNCOMP, "Process-Uncompressed"},
764 {0, NULL}
767 #define DCE_MODE_1 1
768 #define DCE_MODE_2 2
769 static const value_string dce_mode_vals[] = {
770 {DCE_MODE_1, "No Additional Negotiation"},
771 {DCE_MODE_2, "Full PPP Negotiation and State Machine"},
772 {0, NULL}
776 * Options. (LCP)
778 #define CI_VENDORSPECIFIC 0 /* Vendor Specific [RFC2153] */
779 #define CI_MRU 1 /* Maximum Receive Unit [RFC1661] */
780 #define CI_ASYNCMAP 2 /* Async Control Character Map */
781 #define CI_AUTHPROT 3 /* Authentication Protocol [RFC1661] */
782 #define CI_QUALITY 4 /* Quality Protocol [RFC1661] */
783 #define CI_MAGICNUMBER 5 /* Magic Number [RFC1661] */
784 #define CI_LINKQUALMON 6 /* DEPRECATED (Quality Protocol) [RFC1172] */
785 #define CI_PCOMPRESSION 7 /* Protocol Field Compression [RFC1661] */
786 #define CI_ACCOMPRESSION 8 /* Address/Control Field Compression
787 [RFC1661] */
788 #define CI_FCS_ALTERNATIVES 9 /* FCS Alternatives [RFC1570] */
789 #define CI_SELF_DESCRIBING_PAD 10 /* Self-Describing Pad [RFC1570] */
790 #define CI_NUMBERED_MODE 11 /* Numbered Mode [RFC1663] */
791 #define CI_MULTILINK_PROC 12 /* DEPRECATED (Multi-Link Procedure) */
792 #define CI_CALLBACK 13 /* Callback [RFC1570] */
793 #define CI_CONNECTTIME 14 /* DEPRECATED (Connect Time) */
794 #define CI_COMPOUND_FRAMES 15 /* DEPRECATED (Compound Frames) [RFC1570] */
795 #define CI_NOMDATAENCAP 16 /* DEPRECATED (Nominal Data Encapsulation) */
796 /* NOTE: IANA lists CI_NOMDATAENCAP as 16, but it is listed as 14 in
797 * http://tools.ietf.org/html/draft-ietf-pppext-dataencap-03.
798 * Which is correct is anyone's guess. */
799 #define CI_MULTILINK_MRRU 17 /* Multilink MRRU [RFC1990] */
800 #define CI_MULTILINK_SSNH 18 /* Multilink Short Sequence Number Header
801 [RFC1990] */
802 #define CI_MULTILINK_EP_DISC 19 /* Multilink Endpoint Discriminator
803 [RFC1990] */
804 #define CI_PROP_KEN 20 /* Proprietary [Ken Culbert] ken@funk.com */
805 #define CI_DCE_IDENTIFIER 21 /* DCE Identifier [RFC1976]: Warning:
806 Option type 25 in the RFC is incorrect */
807 #define CI_MULTILINK_PLUS_PROC 22 /* Multilink Plus Procedure [RFC1934] */
808 #define CI_LINK_DISC_FOR_BACP 23 /* Link Discriminator for BACP [RFC2125] */
809 #define CI_LCP_AUTHENTICATION 24 /* LCP Authentication Option [Culbert] */
810 #define CI_COBS 25 /* Consistent Overhead Byte Stuffing (COBS)
811 [Carlson] */
812 #define CI_PREFIX_ELISION 26 /* Prefix elision [RFC2686][RFC2687] */
813 #define CI_MULTILINK_HDR_FMT 27 /* Multilink header format
814 [RFC2686][RFC2687] */
815 #define CI_INTERNATIONALIZATION 28 /* Internationalization [RFC2484] */
816 #define CI_SDL_ON_SONET_SDH 29 /* Simple Data Link on SONET/SDH
817 [RFC2823] */
818 #define CI_UNASSIGNED 30 /* Unassigned ... but so are 31-255, so
819 why do they bother specifically
820 mentioning this one, I wonder? */
822 static int hf_lcp_magic_number = -1;
823 static int hf_lcp_data = -1;
824 static int hf_lcp_message = -1;
825 static int hf_lcp_secs_remaining = -1;
826 static int hf_lcp_rej_proto = -1;
827 static int hf_lcp_opt_type = -1;
828 static int hf_lcp_opt_length = -1;
829 static int hf_lcp_opt_oui = -1;
830 static int hf_lcp_opt_kind = -1;
831 static int hf_lcp_opt_data = -1;
832 static int hf_lcp_opt_mru = -1;
833 static int hf_lcp_opt_asyncmap = -1;
834 static int hf_lcp_opt_asyncmap_nul = -1;
835 static int hf_lcp_opt_asyncmap_soh = -1;
836 static int hf_lcp_opt_asyncmap_stx = -1;
837 static int hf_lcp_opt_asyncmap_etx = -1;
838 static int hf_lcp_opt_asyncmap_eot = -1;
839 static int hf_lcp_opt_asyncmap_enq = -1;
840 static int hf_lcp_opt_asyncmap_ack = -1;
841 static int hf_lcp_opt_asyncmap_bel = -1;
842 static int hf_lcp_opt_asyncmap_bs = -1;
843 static int hf_lcp_opt_asyncmap_ht = -1;
844 static int hf_lcp_opt_asyncmap_lf = -1;
845 static int hf_lcp_opt_asyncmap_vt = -1;
846 static int hf_lcp_opt_asyncmap_ff = -1;
847 static int hf_lcp_opt_asyncmap_cr = -1;
848 static int hf_lcp_opt_asyncmap_so = -1;
849 static int hf_lcp_opt_asyncmap_si = -1;
850 static int hf_lcp_opt_asyncmap_dle = -1;
851 static int hf_lcp_opt_asyncmap_dc1 = -1;
852 static int hf_lcp_opt_asyncmap_dc2 = -1;
853 static int hf_lcp_opt_asyncmap_dc3 = -1;
854 static int hf_lcp_opt_asyncmap_dc4 = -1;
855 static int hf_lcp_opt_asyncmap_nak = -1;
856 static int hf_lcp_opt_asyncmap_syn = -1;
857 static int hf_lcp_opt_asyncmap_etb = -1;
858 static int hf_lcp_opt_asyncmap_can = -1;
859 static int hf_lcp_opt_asyncmap_em = -1;
860 static int hf_lcp_opt_asyncmap_sub = -1;
861 static int hf_lcp_opt_asyncmap_esc = -1;
862 static int hf_lcp_opt_asyncmap_fs = -1;
863 static int hf_lcp_opt_asyncmap_gs = -1;
864 static int hf_lcp_opt_asyncmap_rs = -1;
865 static int hf_lcp_opt_asyncmap_us = -1;
866 static int hf_lcp_opt_auth_protocol = -1;
867 static int hf_lcp_opt_algorithm = -1;
868 static int hf_lcp_opt_quality_protocol = -1;
869 static int hf_lcp_opt_magic_number = -1;
870 static int hf_lcp_opt_reportingperiod = -1;
871 static int hf_lcp_opt_fcs_alternatives = -1;
872 static int hf_lcp_opt_fcs_alternatives_null = -1;
873 static int hf_lcp_opt_fcs_alternatives_ccitt16 = -1;
874 static int hf_lcp_opt_fcs_alternatives_ccitt32 = -1;
875 static int hf_lcp_opt_maximum = -1;
876 static int hf_lcp_opt_window = -1;
877 static int hf_lcp_opt_hdlc_address = -1;
878 static int hf_lcp_opt_operation = -1;
879 static int hf_lcp_opt_message = -1;
880 static int hf_lcp_opt_mrru = -1;
881 static int hf_lcp_opt_ep_disc_class = -1;
882 static int hf_lcp_opt_ip_address = -1;
883 static int hf_lcp_opt_802_1_address = -1;
884 static int hf_lcp_opt_magic_block = -1;
885 static int hf_lcp_opt_psndn = -1;
886 static int hf_lcp_opt_mode = -1;
887 static int hf_lcp_opt_unused = -1;
888 static int hf_lcp_opt_link_discrim = -1;
889 static int hf_lcp_opt_id = -1;
890 static int hf_lcp_opt_cobs_flags = -1;
891 static int hf_lcp_opt_cobs_flags_res = -1;
892 static int hf_lcp_opt_cobs_flags_pre = -1;
893 static int hf_lcp_opt_cobs_flags_zxe = -1;
894 static int hf_lcp_opt_class = -1;
895 static int hf_lcp_opt_prefix = -1;
896 static int hf_lcp_opt_code = -1;
897 static int hf_lcp_opt_max_susp_classes = -1;
898 static int hf_lcp_opt_MIBenum = -1;
899 static int hf_lcp_opt_language_tag = -1;
901 static void dissect_lcp_vendor_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
902 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
903 static void dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
904 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
905 static void dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
906 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
907 static void dissect_lcp_authprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
908 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
909 static void dissect_lcp_qualprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
910 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
911 static void dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
912 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
913 static void dissect_lcp_linkqualmon_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
914 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
915 static void dissect_lcp_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
916 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
917 static void dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp,
918 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
919 proto_tree *tree, void *data _U_);
920 static void dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp,
921 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
922 proto_tree *tree, void *data _U_);
923 static void dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp,
924 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
925 proto_tree *tree, void *data _U_);
926 static void dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
927 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
928 static void dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp,
929 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
930 proto_tree *tree, void *data _U_);
931 static void dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp,
932 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
933 proto_tree *tree, void *data _U_);
934 static void dissect_lcp_dce_identifier_opt(const ip_tcp_opt *optp,
935 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
936 proto_tree *tree, void *data _U_);
937 static void dissect_lcp_multilink_pp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
938 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
939 static void dissect_lcp_bacp_link_discriminator_opt(const ip_tcp_opt *optp,
940 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
941 proto_tree *tree, void *data _U_);
942 static void dissect_lcp_auth_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
943 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
944 static void dissect_lcp_cobs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
945 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
946 static void dissect_lcp_prefix_elision_opt(const ip_tcp_opt *optp,
947 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
948 proto_tree *tree, void *data _U_);
949 static void dissect_lcp_multilink_hdr_fmt_opt(const ip_tcp_opt *optp,
950 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
951 proto_tree *tree, void *data _U_);
952 static void dissect_lcp_internationalization_opt(const ip_tcp_opt *optp,
953 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
954 proto_tree *tree, void *data _U_);
955 static void dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
957 static const ip_tcp_opt lcp_opts[] = {
958 {CI_VENDORSPECIFIC, "Vendor Specific", &ett_lcp_vendor_opt,
959 OPT_LEN_VARIABLE_LENGTH, 6, dissect_lcp_vendor_opt},
960 {CI_MRU, "Maximum Receive Unit", &ett_lcp_mru_opt,
961 OPT_LEN_FIXED_LENGTH, 4, dissect_lcp_mru_opt},
962 {CI_ASYNCMAP, "Async Control Character Map", &ett_lcp_asyncmap_opt,
963 OPT_LEN_FIXED_LENGTH, 6, dissect_lcp_async_map_opt},
964 {CI_AUTHPROT, "Authentication Protocol", &ett_lcp_authprot_opt,
965 OPT_LEN_VARIABLE_LENGTH, 4, dissect_lcp_authprot_opt},
966 {CI_QUALITY, "Quality Protocol", &ett_lcp_qualprot_opt,
967 OPT_LEN_VARIABLE_LENGTH, 4, dissect_lcp_qualprot_opt},
968 {CI_MAGICNUMBER, "Magic Number", &ett_lcp_magicnumber_opt,
969 OPT_LEN_FIXED_LENGTH, 6, dissect_lcp_magicnumber_opt},
970 {CI_LINKQUALMON, "Link Quality Monitoring", &ett_lcp_linkqualmon_opt,
971 OPT_LEN_FIXED_LENGTH, 6, dissect_lcp_linkqualmon_opt},
972 {CI_PCOMPRESSION, "Protocol Field Compression", &ett_lcp_pcomp_opt,
973 OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt},
974 {CI_ACCOMPRESSION, "Address and Control Field Compression", &ett_lcp_acccomp_opt,
975 OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt},
976 {CI_FCS_ALTERNATIVES, "FCS Alternatives", &ett_lcp_fcs_alternatives_opt,
977 OPT_LEN_FIXED_LENGTH, 3, dissect_lcp_fcs_alternatives_opt},
978 {CI_SELF_DESCRIBING_PAD, "Self Describing Pad", &ett_lcp_self_desc_pad_opt,
979 OPT_LEN_FIXED_LENGTH, 3, dissect_lcp_self_describing_pad_opt},
980 {CI_NUMBERED_MODE, "Numbered Mode", &ett_lcp_numbered_mode_opt,
981 OPT_LEN_VARIABLE_LENGTH, 4, dissect_lcp_numbered_mode_opt},
982 /* TODO? CI_MULTILINK_PROC */
983 {CI_CALLBACK, "Callback", &ett_lcp_callback_opt,
984 OPT_LEN_VARIABLE_LENGTH, 3, dissect_lcp_callback_opt},
985 /* TODO? CI_CONNECTTIME */
986 {CI_COMPOUND_FRAMES, "Compound Frames (Deprecated)", &ett_lcp_compound_frames_opt,
987 OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt},
988 {CI_NOMDATAENCAP, "Nominal Data Encapsulation (Deprecated)", &ett_lcp_nomdataencap_opt,
989 OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt},
990 {CI_MULTILINK_MRRU, "Multilink MRRU", &ett_lcp_multilink_mrru_opt,
991 OPT_LEN_FIXED_LENGTH, 4, dissect_lcp_multilink_mrru_opt},
992 {CI_MULTILINK_SSNH, "Multilink Short Sequence Number Header", &ett_lcp_multilink_ssnh_opt,
993 OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt},
994 {CI_MULTILINK_EP_DISC, "Multilink Endpoint Discriminator", &ett_lcp_multilink_ep_disc_opt,
995 OPT_LEN_VARIABLE_LENGTH, 3, dissect_lcp_multilink_ep_disc_opt},
996 /* TODO? CI_PROP_KEN: ken@funk.com: www.funk.com => www.juniper.net */
997 {CI_DCE_IDENTIFIER, "DCE Identifier", &ett_lcp_dce_identifier_opt,
998 OPT_LEN_FIXED_LENGTH, 3, dissect_lcp_dce_identifier_opt},
999 {CI_MULTILINK_PLUS_PROC, "Multi Link Plus Procedure", &ett_lcp_multilink_pp_opt,
1000 OPT_LEN_FIXED_LENGTH, 4, dissect_lcp_multilink_pp_opt},
1001 {CI_LINK_DISC_FOR_BACP, "Link Discriminator for BACP", &ett_lcp_bacp_link_discrim_opt,
1002 OPT_LEN_FIXED_LENGTH, 4, dissect_lcp_bacp_link_discriminator_opt},
1003 {CI_LCP_AUTHENTICATION, "LCP Authentication Option", &ett_lcp_auth_opt,
1004 OPT_LEN_VARIABLE_LENGTH, 3, dissect_lcp_auth_opt},
1005 {CI_COBS, "Consistent Overhead Byte Stuffing (COBS)", &ett_lcp_cobs_opt,
1006 OPT_LEN_FIXED_LENGTH, 3, dissect_lcp_cobs_opt},
1007 {CI_PREFIX_ELISION, "Prefix Elision", &ett_lcp_prefix_elision_opt,
1008 OPT_LEN_VARIABLE_LENGTH, 2, dissect_lcp_prefix_elision_opt},
1009 {CI_MULTILINK_HDR_FMT, "Multilink header format", &ett_multilink_hdr_fmt_opt,
1010 OPT_LEN_FIXED_LENGTH, 4, dissect_lcp_multilink_hdr_fmt_opt},
1011 {CI_INTERNATIONALIZATION, "Internationalization", &ett_lcp_internationalization_opt,
1012 OPT_LEN_VARIABLE_LENGTH, 7, dissect_lcp_internationalization_opt},
1013 {CI_SDL_ON_SONET_SDH, "Simple Data Link on SONET/SDH", &ett_lcp_simple_opt,
1014 OPT_LEN_FIXED_LENGTH, 2, dissect_lcp_simple_opt}
1015 /* TODO? CI_UNASSIGNED */
1018 #define N_LCP_OPTS (sizeof lcp_opts / sizeof lcp_opts[0])
1020 /* 3GPP2 X.S0057-B v1.0
1021 * 9.1.4.1 3GPP2 VSNCP Configuration Options
1022 * Options. (VSNCP)
1025 #define CI_PDN_IDENTIFIER 1
1026 #define CI_ACCESS_POINT_NM 2
1027 #define CI_PDN_TYPE 3
1028 #define CI_PDN_ADDRESS 4
1029 #define CI_PROTOCOL_CONFIG 5
1030 #define CI_ERROR_CODE 6
1031 #define CI_ATTACH_TYPE 7
1032 #define CI_IPv4DEFAULT_ROUTER 8
1033 #define CI_ADDRESS_ALLOC 9
1034 #define CI_APN_AMBR 10
1035 #define CI_IPv6_HSGW_LLA_IID 11
1037 static void dissect_vsncp_pdnid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1038 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1039 static void dissect_vsncp_apname_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1040 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1041 static void dissect_vsncp_pdntype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1042 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1043 static void dissect_vsncp_pdnaddress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1044 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1045 static void dissect_vsncp_pco_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1046 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1047 static void dissect_vsncp_errorcode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1048 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1049 static void dissect_vsncp_attachtype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1050 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1051 static void dissect_vsncp_ipv4address_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1052 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1053 static void dissect_vsncp_addressalloc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1054 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1055 static void dissect_vsncp_apn_ambr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1056 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1057 static void dissect_vsncp_ipv6_hsgw_lla_iid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1058 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1060 static const ip_tcp_opt vsncp_opts[] = {
1061 {CI_PDN_IDENTIFIER, "PDN Identifier", NULL,
1062 OPT_LEN_FIXED_LENGTH, 3, dissect_vsncp_pdnid_opt},
1063 {CI_ACCESS_POINT_NM, "Access Point Name", NULL,
1064 OPT_LEN_VARIABLE_LENGTH, 2, dissect_vsncp_apname_opt},
1065 {CI_PDN_TYPE, "PDN Type", NULL,
1066 OPT_LEN_FIXED_LENGTH, 3, dissect_vsncp_pdntype_opt},
1067 {CI_PDN_ADDRESS, "PDN Address", NULL,
1068 OPT_LEN_VARIABLE_LENGTH, 3, dissect_vsncp_pdnaddress_opt},
1069 {CI_PROTOCOL_CONFIG, "Protocol Configuration Options", NULL,
1070 OPT_LEN_VARIABLE_LENGTH, 3, dissect_vsncp_pco_opt},
1071 {CI_ERROR_CODE, "Error Code", NULL,
1072 OPT_LEN_FIXED_LENGTH, 3, dissect_vsncp_errorcode_opt},
1073 {CI_ATTACH_TYPE, "Attach Type", NULL,
1074 OPT_LEN_FIXED_LENGTH, 3, dissect_vsncp_attachtype_opt},
1075 {CI_IPv4DEFAULT_ROUTER, "IPv4 Default Router Address", NULL,
1076 OPT_LEN_FIXED_LENGTH, 6, dissect_vsncp_ipv4address_opt},
1077 {CI_ADDRESS_ALLOC, "Address Allocation Cause", NULL,
1078 OPT_LEN_FIXED_LENGTH, 3, dissect_vsncp_addressalloc_opt},
1079 {CI_APN_AMBR, "APN Aggregate Maximum Bit Rate(APN-AMBR)", NULL,
1080 OPT_LEN_VARIABLE_LENGTH, 4, dissect_vsncp_apn_ambr_opt},
1081 {CI_IPv6_HSGW_LLA_IID, "IPv6 HSGW Link Local Address IID", NULL,
1082 OPT_LEN_FIXED_LENGTH, 10, dissect_vsncp_ipv6_hsgw_lla_iid_opt}
1085 #define N_VSNCP_OPTS (sizeof vsncp_opts / sizeof vsncp_opts[0])
1088 * CHAP Algorithms
1090 /* 0-4: Reserved */
1091 #define CHAP_ALG_MD5 5 /* CHAP with MD5 */
1092 #define CHAP_AGL_SHA1 6 /* CHAP with SHA-1 [Black] */
1093 /* 7-127: Unassigned */
1094 #define CHAP_ALG_MSV1 128 /* MS-CHAP */
1095 #define CHAP_ALG_MSV2 129 /* MS-CHAP-2 */
1097 static const range_string chap_alg_rvals[] = {
1098 {0, 4, "Reserved"},
1099 {CHAP_ALG_MD5, CHAP_ALG_MD5, "CHAP with MD5"},
1100 {CHAP_AGL_SHA1, CHAP_AGL_SHA1, "CHAP with SHA-1"},
1101 {CHAP_ALG_MSV1, CHAP_ALG_MSV1, "MS-CHAP"},
1102 {CHAP_ALG_MSV2, CHAP_ALG_MSV2, "MS-CHAP-2"},
1103 {0, 0, NULL}
1108 * Options. (IPCP)
1109 * http://tools.ietf.org/html/rfc1172
1110 * http://tools.ietf.org/html/rfc1332
1111 * http://tools.ietf.org/html/rfc1877
1112 * http://tools.ietf.org/html/rfc2290
1113 * http://tools.ietf.org/html/rfc3241
1114 * http://tools.ietf.org/html/rfc3545
1116 #define CI_ADDRS 1 /* IP Addresses (deprecated) (RFC 1172) */
1117 #define CI_COMPRESS_PROTO 2 /* Compression Protocol (RFC 1332) */
1118 #define CI_ADDR 3 /* IP Address (RFC 1332) */
1119 #define CI_MOBILE_IPv4 4 /* Mobile IPv4 (RFC 2290) */
1120 #define CI_PRI_DNS 129 /* Primary DNS value (RFC 1877) */
1121 #define CI_PRI_NBNS 130 /* Primary NBNS value (RFC 1877) */
1122 #define CI_SEC_DNS 131 /* Secondary DNS value (RFC 1877) */
1123 #define CI_SEC_NBNS 132 /* Secondary NBNS value (RFC 1877) */
1125 static int hf_ipcp_opt_type = -1;
1126 static int hf_ipcp_opt_length = -1;
1127 static int hf_ipcp_opt_src_address = -1;
1128 static int hf_ipcp_opt_dst_address = -1;
1129 static int hf_ipcp_opt_compress_proto = -1;
1130 static int hf_ipcp_opt_max_cid = -1;
1131 static int hf_ipcp_opt_mrru = -1;
1132 static int hf_ipcp_opt_max_slot_id = -1;
1133 static int hf_ipcp_opt_comp_slot_id = -1;
1134 static int hf_ipcp_opt_tcp_space = -1;
1135 static int hf_ipcp_opt_non_tcp_space = -1;
1136 static int hf_ipcp_opt_f_max_period = -1;
1137 static int hf_ipcp_opt_f_max_time = -1;
1138 static int hf_ipcp_opt_max_header = -1;
1139 static int hf_ipcp_data = -1;
1140 static int hf_ipcp_opt_ip_address = -1;
1141 static int hf_ipcp_opt_mobilenodehomeaddr = -1;
1142 static int hf_ipcp_opt_pri_dns_address = -1;
1143 static int hf_ipcp_opt_pri_nbns_address = -1;
1144 static int hf_ipcp_opt_sec_dns_address = -1;
1145 static int hf_ipcp_opt_sec_nbns_address = -1;
1147 static int hf_ipcp_opt_rohc_type = -1;
1148 static int hf_ipcp_opt_rohc_length = -1;
1149 static int hf_ipcp_opt_rohc_profile = -1;
1150 static int hf_ipcp_opt_iphc_type = -1;
1151 static int hf_ipcp_opt_iphc_length = -1;
1152 static int hf_ipcp_opt_iphc_param = -1;
1154 static void dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1155 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1156 static void dissect_ipcp_compress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1157 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1158 static void dissect_ipcp_rohc_profiles_opt(const ip_tcp_opt *optp,
1159 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1160 proto_tree *tree, void *data _U_);
1161 static void dissect_ipcp_iphc_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1162 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1163 static void dissect_ipcp_iphc_neghdrcomp_opt(const ip_tcp_opt *optp,
1164 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo _U_,
1165 proto_tree *tree, void *data _U_);
1166 static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1167 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1168 static void dissect_ipcp_mobileipv4_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1169 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1170 static void dissect_ipcp_pri_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1171 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1172 static void dissect_ipcp_pri_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1173 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1174 static void dissect_ipcp_sec_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1175 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1176 static void dissect_ipcp_sec_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1177 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1179 static const ip_tcp_opt ipcp_opts[] = {
1180 {CI_ADDRS, "IP Addresses (deprecated)", &ett_ipcp_ipaddrs_opt,
1181 OPT_LEN_FIXED_LENGTH, 10, dissect_ipcp_addrs_opt},
1182 {CI_COMPRESS_PROTO, "IP Compression Protocol", &ett_ipcp_compress_opt,
1183 OPT_LEN_VARIABLE_LENGTH, 4, dissect_ipcp_compress_opt},
1184 {CI_ADDR, "IP address", &ett_ipcp_ipaddr_opt,
1185 OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_addr_opt},
1186 {CI_MOBILE_IPv4, "Mobile Node's Home IP Address", &ett_ipcp_mobileipv4_opt,
1187 OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_mobileipv4_opt},
1188 {CI_PRI_DNS, "Primary DNS Server IP Address", &ett_ipcp_pridns_opt,
1189 OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_pri_dns_opt},
1190 {CI_PRI_NBNS, "Primary NBNS Server IP Address", &ett_ipcp_prinbns_opt,
1191 OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_pri_nbns_opt},
1192 {CI_SEC_DNS, "Secondary DNS Server IP Address", &ett_ipcp_secdns_opt,
1193 OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_sec_dns_opt},
1194 {CI_SEC_NBNS, "Secondary NBNS Server IP Address", &ett_ipcp_secnbns_opt,
1195 OPT_LEN_FIXED_LENGTH, 6, dissect_ipcp_sec_nbns_opt}
1198 #define N_IPCP_OPTS (sizeof ipcp_opts / sizeof ipcp_opts[0])
1202 * IP Compression options
1204 #define IPCP_ROHC 0x0003 /* RFC3241 */
1205 #define IPCP_COMPRESS_VJ_1172 0x0037 /* value defined in RFC1172 (typo) */
1206 #define IPCP_COMPRESS_VJ 0x002d /* value defined in RFC1332 (correct) */
1207 #define IPCP_COMPRESS_IPHC 0x0061 /* RFC3544 (and RFC2509) */
1209 static const value_string ipcp_compress_proto_vals[] = {
1210 {IPCP_ROHC, "Robust Header Compression (ROHC)"},
1211 {IPCP_COMPRESS_VJ, "VJ compression"},
1212 {IPCP_COMPRESS_VJ_1172, "VJ compression (RFC1172-typo)"},
1213 {IPCP_COMPRESS_IPHC, "IPHC compression"},
1214 {0, NULL}
1217 /* IPHC suboptions (RFC2508, 3544) */
1218 #define IPCP_IPHC_CRTP 1
1219 #define IPCP_IPHC_ECRTP 2
1220 #define IPCP_IPHC_NEGHC 3
1222 static const value_string ipcp_iphc_parameter_vals[] = {
1223 {1, "The number of contexts for TCP Space is 0"},
1224 {2, "The number of contexts for Non TCP Space is 0"},
1225 {0, NULL}
1228 static const ip_tcp_opt ipcp_iphc_subopts[] = {
1229 {IPCP_IPHC_CRTP, "RTP compression (RFC2508)",
1230 &ett_ipcp_iphc_rtp_compress_opt, OPT_LEN_FIXED_LENGTH, 2,
1231 dissect_ipcp_iphc_simple_opt},
1232 {IPCP_IPHC_ECRTP, "Enhanced RTP compression (RFC3545)",
1233 &ett_ipcp_iphc_enhanced_rtp_compress_opt, OPT_LEN_FIXED_LENGTH, 2,
1234 dissect_ipcp_iphc_simple_opt},
1235 {IPCP_IPHC_NEGHC, "Negotiating header compression (RFC3545)",
1236 &ett_ipcp_iphc_neghdrcomp_opt, OPT_LEN_FIXED_LENGTH, 3,
1237 dissect_ipcp_iphc_neghdrcomp_opt}
1240 #define N_IPCP_IPHC_SUBOPTS (sizeof ipcp_iphc_subopts / sizeof ipcp_iphc_subopts[0])
1243 /* ROHC suboptions */
1244 #define IPCP_ROHC_PROFILES 1
1246 /* From http://tools.ietf.org/html/rfc3095 */
1247 static const value_string ipcp_rohc_profile_vals[] = {
1248 {0x0000, "ROHC uncompressed -- no compression"},
1249 {0x0002, "ROHC UDP -- non-RTP UDP/IP compression"},
1250 {0x0003, "ROHC ESP -- ESP/IP compression"},
1251 {0, NULL}
1254 static const ip_tcp_opt ipcp_rohc_subopts[] = {
1255 {IPCP_ROHC_PROFILES, "Profiles (RFC3241)", &ett_ipcp_rohc_profiles_opt,
1256 OPT_LEN_VARIABLE_LENGTH, 2, dissect_ipcp_rohc_profiles_opt}
1259 #define N_IPCP_ROHC_SUBOPTS (sizeof ipcp_rohc_subopts / sizeof ipcp_rohc_subopts[0])
1261 static ip_tcp_opt_type PPP_OPT_TYPES = {&hf_ppp_opt_type, &ett_ppp_opt_type,
1262 &hf_ppp_opt_type_copy, &hf_ppp_opt_type_class, &hf_ppp_opt_type_number};
1265 * Options. (OSINLCP)
1267 #define CI_OSINLCP_ALIGN_NPDU 1 /* Alignment of the OSI NPDU (RFC 1377) */
1269 static int hf_osinlcp_opt_type = -1;
1270 static int hf_osinlcp_opt_length = -1;
1271 static int hf_osinlcp_opt_alignment = -1;
1273 static void dissect_osinlcp_align_npdu_opt(const ip_tcp_opt *optp,
1274 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo,
1275 proto_tree *tree, void *data _U_);
1277 static const ip_tcp_opt osinlcp_opts[] = {
1278 {CI_OSINLCP_ALIGN_NPDU, "Align-NPDU", &ett_osinlcp_align_npdu_opt,
1279 OPT_LEN_FIXED_LENGTH, 3, dissect_osinlcp_align_npdu_opt}
1282 #define N_OSINLCP_OPTS (sizeof osinlcp_opts / sizeof osinlcp_opts[0])
1285 * Options. (CCP)
1287 #define CI_CCP_OUI 0 /* OUI (RFC1962) */
1288 #define CI_CCP_PREDICT1 1 /* Predictor type 1 (RFC1962) */
1289 #define CI_CCP_PREDICT2 2 /* Predictor type 2 (RFC1962) */
1290 #define CI_CCP_PUDDLE 3 /* Puddle Jumper (RFC1962) */
1291 #define CI_CCP_HPPPC 16 /* Hewlett-Packard PPC (RFC1962) */
1292 #define CI_CCP_STAC 17 /* stac Electronics LZS (RFC1974) */
1293 #define CI_CCP_MPPE 18 /* Microsoft PPE/C (RFC2118/3078) */
1294 #define CI_CCP_GFZA 19 /* Gandalf FZA (RFC1962) */
1295 #define CI_CCP_V42BIS 20 /* V.42bis compression */
1296 #define CI_CCP_BSDLZW 21 /* BSD LZW Compress (RFC1977) */
1297 #define CI_CCP_LZSDCP 23 /* LZS-DCP (RFC1967) */
1298 #define CI_CCP_MVRCA 24 /* MVRCA (Magnalink) (RFC1975) */
1299 #define CI_CCP_DCE 25 /* DCE (RFC1976) */
1300 #define CI_CCP_DEFLATE 26 /* Deflate (RFC1979) */
1301 #define CI_CCP_V44LZJH 27 /* V.44/LZJH (http://www.watersprings.org/pub/id/draft-heath-ppp-v44-01.txt) */
1302 #define CI_CCP_RESERVED 255 /* Reserved (RFC1962) */
1304 static int hf_ccp_opt_type = -1;
1305 static int hf_ccp_opt_length = -1;
1306 static int hf_ccp_opt_oui = -1;
1307 static int hf_ccp_opt_subtype = -1;
1308 static int hf_ccp_opt_data = -1;
1309 static int hf_ccp_opt_history_count = -1;
1310 static int hf_ccp_opt_cm = -1;
1311 static int hf_ccp_opt_cm_reserved = -1;
1312 static int hf_ccp_opt_cm_check_mode = -1;
1313 static int hf_ccp_opt_supported_bits = -1;
1314 static int hf_ccp_opt_supported_bits_h = -1;
1315 static int hf_ccp_opt_supported_bits_m = -1;
1316 static int hf_ccp_opt_supported_bits_s = -1;
1317 static int hf_ccp_opt_supported_bits_l = -1;
1318 static int hf_ccp_opt_supported_bits_d = -1;
1319 static int hf_ccp_opt_supported_bits_c = -1;
1320 static int hf_ccp_opt_history = -1;
1321 static int hf_ccp_opt_version = -1;
1322 static int hf_ccp_opt_vd = -1;
1323 static int hf_ccp_opt_vd_vers = -1;
1324 static int hf_ccp_opt_vd_dict = -1;
1325 static int hf_ccp_opt_check_mode = -1;
1326 static int hf_ccp_opt_process_mode = -1;
1327 static int hf_ccp_opt_fe = -1;
1328 static int hf_ccp_opt_p = -1;
1329 static int hf_ccp_opt_History = -1; /* Different than hf_ccp_opt_history */
1330 static int hf_ccp_opt_contexts = -1;
1331 static int hf_ccp_opt_mode = -1;
1332 static int hf_ccp_opt_window = -1;
1333 static int hf_ccp_opt_method = -1;
1334 static int hf_ccp_opt_mbz = -1;
1335 static int hf_ccp_opt_chk = -1;
1336 static int hf_ccp_opt_mode_dictcount = -1;
1337 static int hf_ccp_opt_dict_size = -1;
1338 static int hf_ccp_opt_history_length = -1;
1340 static void dissect_ccp_oui_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1341 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1342 static void dissect_ccp_other_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1343 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1344 #define dissect_ccp_predict1_opt dissect_ccp_other_opt
1345 #define dissect_ccp_predict2_opt dissect_ccp_other_opt
1346 #define dissect_ccp_puddle_opt dissect_ccp_other_opt
1347 #define dissect_ccp_hpppc_opt dissect_ccp_other_opt
1348 static void dissect_ccp_stac_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1349 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1350 static void dissect_ccp_mppe_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1351 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1352 static void dissect_ccp_gfza_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1353 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1354 #define dissect_ccp_v42bis_opt dissect_ccp_other_opt
1355 static void dissect_ccp_bsdcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1356 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1357 static void dissect_ccp_lzsdcp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1358 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1359 static void dissect_ccp_mvrca_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1360 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1361 static void dissect_ccp_dce_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1362 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1363 static void dissect_ccp_deflate_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1364 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1365 static void dissect_ccp_v44lzjh_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1366 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_);
1368 static const ip_tcp_opt ccp_opts[] = {
1370 {CI_CCP_OUI, "OUI", &ett_ccp_oui_opt,
1371 OPT_LEN_VARIABLE_LENGTH, 6, dissect_ccp_oui_opt},
1372 {CI_CCP_PREDICT1, "Predictor type 1", &ett_ccp_predict1_opt,
1373 OPT_LEN_VARIABLE_LENGTH, 2, dissect_ccp_predict1_opt},
1374 {CI_CCP_PREDICT2, "Predictor type 2", &ett_ccp_predict2_opt,
1375 OPT_LEN_VARIABLE_LENGTH, 2, dissect_ccp_predict2_opt},
1376 {CI_CCP_PUDDLE, "Puddle Jumper", &ett_ccp_puddle_opt,
1377 OPT_LEN_VARIABLE_LENGTH, 2, dissect_ccp_puddle_opt},
1378 {CI_CCP_HPPPC, "Hewlett-Packard PPC", &ett_ccp_hpppc_opt,
1379 OPT_LEN_VARIABLE_LENGTH, 2, dissect_ccp_hpppc_opt},
1380 {CI_CCP_STAC, "Stac Electronics LZS", &ett_ccp_stac_opt,
1381 /* In RFC 1974, this is a fixed-length field of size 5, but in
1382 * Ascend Proprietary STAC compression this field is 6 octets. */
1383 OPT_LEN_VARIABLE_LENGTH, 5, dissect_ccp_stac_opt},
1384 {CI_CCP_MPPE, "Microsoft PPE/PPC", &ett_ccp_mppe_opt,
1385 OPT_LEN_FIXED_LENGTH, 6, dissect_ccp_mppe_opt},
1386 {CI_CCP_GFZA, "Gandalf FZA", &ett_ccp_gfza_opt,
1387 OPT_LEN_VARIABLE_LENGTH, 3, dissect_ccp_gfza_opt},
1388 {CI_CCP_V42BIS, "V.42bis compression", &ett_ccp_v42bis_opt,
1389 OPT_LEN_VARIABLE_LENGTH, 2, dissect_ccp_v42bis_opt},
1390 {CI_CCP_BSDLZW, "BSD LZW Compress", &ett_ccp_bsdcomp_opt,
1391 OPT_LEN_FIXED_LENGTH, 3, dissect_ccp_bsdcomp_opt},
1392 {CI_CCP_LZSDCP, "LZS-DCP", &ett_ccp_lzsdcp_opt,
1393 OPT_LEN_FIXED_LENGTH, 6, dissect_ccp_lzsdcp_opt},
1394 {CI_CCP_MVRCA, "MVRCA (Magnalink)", &ett_ccp_mvrca_opt,
1395 OPT_LEN_FIXED_LENGTH, 4, dissect_ccp_mvrca_opt},
1396 {CI_CCP_DCE,
1397 "PPP for Data Compression in Data Circuit-Terminating Equipment (DCE)",
1398 &ett_ccp_dce_opt,
1399 OPT_LEN_FIXED_LENGTH, 3, dissect_ccp_dce_opt},
1400 {CI_CCP_DEFLATE, "Deflate", &ett_ccp_deflate_opt,
1401 /* RFC1979 says the length is 3 but it's actually 4. */
1402 OPT_LEN_FIXED_LENGTH, 4, dissect_ccp_deflate_opt},
1403 {CI_CCP_V44LZJH, "V.44/LZJH compression", &ett_ccp_v44lzjh_opt,
1404 OPT_LEN_VARIABLE_LENGTH, 4, dissect_ccp_v44lzjh_opt}
1407 #define N_CCP_OPTS (sizeof ccp_opts / sizeof ccp_opts[0])
1410 * Options. (CBCP)
1412 #define CI_CBCP_NO_CALLBACK 1 /* No callback */
1413 #define CI_CBCP_CB_USER 2 /* Callback to a user-specified number */
1414 #define CI_CBCP_CB_PRE 3 /* Callback to a pre-specified or
1415 administrator specified number */
1416 #define CI_CBCP_CB_ANY 4 /* Callback to any of a list of numbers */
1418 static void dissect_cbcp_no_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1419 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1421 static void dissect_cbcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1422 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1424 static const ip_tcp_opt cbcp_opts[] = {
1425 {CI_CBCP_NO_CALLBACK, "No callback", NULL,
1426 OPT_LEN_FIXED_LENGTH, 2, dissect_cbcp_no_callback_opt},
1427 {CI_CBCP_CB_USER, "Callback to a user-specified number", &ett_cbcp_callback_opt,
1428 OPT_LEN_VARIABLE_LENGTH, 4, dissect_cbcp_callback_opt},
1429 {CI_CBCP_CB_PRE, "Callback to a pre-specified or admin-specified number", &ett_cbcp_callback_opt,
1430 OPT_LEN_FIXED_LENGTH, 3, dissect_cbcp_callback_opt},
1431 {CI_CBCP_CB_ANY, "Callback to any of a list of numbers", &ett_cbcp_callback_opt,
1432 OPT_LEN_VARIABLE_LENGTH, 4, dissect_cbcp_callback_opt}
1435 #define N_CBCP_OPTS (sizeof cbcp_opts / sizeof cbcp_opts[0])
1438 * Options. (BACP)
1440 #define CI_BACP_FAVORED_PEER 1 /* Favored-Peer */
1442 static void dissect_bacp_favored_peer_opt(const ip_tcp_opt *optp,
1443 tvbuff_t *tvb, int offset, guint length, packet_info *pinfo,
1444 proto_tree *tree, void *data _U_);
1446 static const ip_tcp_opt bacp_opts[] = {
1447 {CI_BACP_FAVORED_PEER, "Favored-Peer", &ett_bacp_favored_peer_opt,
1448 OPT_LEN_FIXED_LENGTH, 6, dissect_bacp_favored_peer_opt}
1451 #define N_BACP_OPTS (sizeof bacp_opts / sizeof bacp_opts[0])
1454 * Options. (BAP)
1456 #define CI_BAP_LINK_TYPE 1 /* Link Type */
1457 #define CI_BAP_PHONE_DELTA 2 /* Phone-Delta */
1458 #define CI_BAP_NO_PHONE_NUM_NEEDED 3 /* No Phone Number Needed */
1459 #define CI_BAP_REASON 4 /* Reason */
1460 #define CI_BAP_LINK_DISC 5 /* Link Discriminator */
1461 #define CI_BAP_CALL_STATUS 6 /* Call Status */
1463 static void dissect_bap_link_type_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1464 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1465 static void dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1466 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1467 static void dissect_bap_link_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1468 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1469 static void dissect_bap_reason_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1470 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1471 static void dissect_bap_call_status_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1472 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1474 static const ip_tcp_opt bap_opts[] = {
1475 {CI_BAP_LINK_TYPE, "Link Type", &ett_bap_link_type_opt,
1476 OPT_LEN_FIXED_LENGTH, 5, dissect_bap_link_type_opt},
1477 {CI_BAP_PHONE_DELTA, "Phone Delta", &ett_bap_phone_delta_opt,
1478 OPT_LEN_VARIABLE_LENGTH, 4, dissect_bap_phone_delta_opt},
1479 {CI_BAP_NO_PHONE_NUM_NEEDED, "No Phone Number Needed", NULL,
1480 OPT_LEN_FIXED_LENGTH, 2, NULL},
1481 {CI_BAP_REASON, "Reason", NULL,
1482 OPT_LEN_VARIABLE_LENGTH, 2, dissect_bap_reason_opt},
1483 {CI_BAP_LINK_DISC, "Link Discriminator", NULL,
1484 OPT_LEN_FIXED_LENGTH, 4, dissect_bap_link_disc_opt},
1485 {CI_BAP_CALL_STATUS, "Call Status", &ett_bap_call_status_opt,
1486 OPT_LEN_FIXED_LENGTH, 4, dissect_bap_call_status_opt}
1489 #define N_BAP_OPTS (sizeof bap_opts / sizeof bap_opts[0])
1491 static void dissect_ppp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1493 static const value_string pap_vals[] = {
1494 {CONFREQ, "Authenticate-Request"},
1495 {CONFACK, "Authenticate-Ack"},
1496 {CONFNAK, "Authenticate-Nak"},
1497 {0, NULL}
1500 static void dissect_pap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1502 #define CHAP_CHAL 1 /* CHAP Challenge */
1503 #define CHAP_RESP 2 /* CHAP Response */
1504 #define CHAP_SUCC 3 /* CHAP Success */
1505 #define CHAP_FAIL 4 /* CHAP Failure */
1507 static const value_string chap_vals[] = {
1508 {CHAP_CHAL, "Challenge"},
1509 {CHAP_RESP, "Response"},
1510 {CHAP_SUCC, "Success"},
1511 {CHAP_FAIL, "Failure"},
1512 {0, NULL}
1515 static void dissect_chap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
1517 static const value_string pppmuxcp_vals[] = {
1518 {CONFREQ, "Configuration Request"},
1519 {CONFACK, "Configuration Ack"},
1520 {0, NULL}
1524 * PPPMuxCP options
1527 #define CI_DEFAULT_PID 1
1529 static void dissect_pppmuxcp_def_pid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1530 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1533 static const ip_tcp_opt pppmuxcp_opts[] = {
1534 {CI_DEFAULT_PID, "Default Protocol ID", NULL,
1535 OPT_LEN_FIXED_LENGTH, 4, dissect_pppmuxcp_def_pid_opt}
1538 static const true_false_string tfs_pppmux_length_field = { "2 bytes", "1 byte" };
1540 #define N_PPPMUXCP_OPTS (sizeof pppmuxcp_opts / sizeof pppmuxcp_opts[0])
1543 * Options. (IPv6CP)
1545 #define CI_IPV6CP_IF_ID 1 /* Interface Identifier (RFC 2472) */
1546 #define CI_IPV6CP_COMPRESSTYPE 2 /* Compression Type (RFC 2472) */
1548 static void dissect_ipv6cp_if_id_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1549 int offset, guint length, packet_info *pinfo, proto_tree *tree, void *data _U_);
1551 static const ip_tcp_opt ipv6cp_opts[] = {
1552 {CI_IPV6CP_IF_ID, "Interface Identifier", &ett_ipv6cp_if_id_opt,
1553 OPT_LEN_FIXED_LENGTH, 10, dissect_ipv6cp_if_id_opt},
1554 {CI_COMPRESS_PROTO, "IPv6 compression", &ett_ipv6cp_compress_opt,
1555 OPT_LEN_VARIABLE_LENGTH, 4, dissect_ipcp_compress_opt}
1558 #define N_IPV6CP_OPTS (sizeof ipv6cp_opts / sizeof ipv6cp_opts[0])
1561 *******************************************************************************
1562 * DETAILS : Calculate a new FCS-16 given the current FCS-16 and the new data.
1563 *******************************************************************************
1565 static guint16
1566 fcs16(tvbuff_t *tvbuff)
1568 guint len = tvb_length(tvbuff) - 2;
1570 /* Check for Invalid Length */
1571 if (len == 0)
1572 return (0x0000);
1573 return crc16_ccitt_tvb(tvbuff, len);
1577 *******************************************************************************
1578 * DETAILS : Calculate a new FCS-32 given the current FCS-32 and the new data.
1579 *******************************************************************************
1581 static guint32
1582 fcs32(tvbuff_t *tvbuff)
1584 guint len = tvb_length(tvbuff) - 4;
1586 /* Check for invalid Length */
1587 if (len == 0)
1588 return (0x00000000);
1589 return crc32_ccitt_tvb(tvbuff, len);
1592 tvbuff_t *
1593 decode_fcs(tvbuff_t *tvb, proto_tree *fh_tree, int fcs_decode, int proto_offset)
1595 tvbuff_t *next_tvb;
1596 gint len, reported_len;
1597 int rx_fcs_offset;
1598 guint32 rx_fcs_exp;
1599 guint32 rx_fcs_got;
1602 * Remove the FCS, if any, from the packet data.
1604 switch (fcs_decode) {
1606 case NO_FCS:
1607 next_tvb = tvb_new_subset_remaining(tvb, proto_offset);
1608 break;
1610 case FCS_16:
1612 * Do we have the entire packet, and does it include a 2-byte FCS?
1614 len = tvb_length_remaining(tvb, proto_offset);
1615 reported_len = tvb_reported_length_remaining(tvb, proto_offset);
1616 if (reported_len < 2 || len < 0) {
1618 * The packet is claimed not to even have enough data for a 2-byte
1619 * FCS, or we're already past the end of the captured data.
1620 * Don't slice anything off.
1622 next_tvb = tvb_new_subset_remaining(tvb, proto_offset);
1623 } else if (len < reported_len) {
1625 * The packet is claimed to have enough data for a 2-byte FCS, but
1626 * we didn't capture all of the packet.
1627 * Slice off the 2-byte FCS from the reported length, and trim the
1628 * captured length so it's no more than the reported length; that
1629 * will slice off what of the FCS, if any, is in the captured
1630 * length.
1632 reported_len -= 2;
1633 if (len > reported_len)
1634 len = reported_len;
1635 next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1636 } else {
1638 * We have the entire packet, and it includes a 2-byte FCS.
1639 * Slice it off.
1641 len -= 2;
1642 reported_len -= 2;
1643 next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1646 * Compute the FCS and put it into the tree.
1648 rx_fcs_offset = proto_offset + len;
1649 rx_fcs_exp = fcs16(tvb);
1650 rx_fcs_got = tvb_get_letohs(tvb, rx_fcs_offset);
1651 if (rx_fcs_got != rx_fcs_exp) {
1652 proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 2,
1653 "FCS 16: 0x%04x [incorrect, should be 0x%04x]",
1654 rx_fcs_got, rx_fcs_exp);
1655 } else {
1656 proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 2,
1657 "FCS 16: 0x%04x [correct]", rx_fcs_got);
1660 break;
1662 case FCS_32:
1664 * Do we have the entire packet, and does it include a 4-byte FCS?
1666 len = tvb_length_remaining(tvb, proto_offset);
1667 reported_len = tvb_reported_length_remaining(tvb, proto_offset);
1668 if (reported_len < 4) {
1670 * The packet is claimed not to even have enough data for a 4-byte
1671 * FCS. Just pass on the tvbuff as is.
1673 next_tvb = tvb_new_subset_remaining(tvb, proto_offset);
1674 } else if (len < reported_len) {
1676 * The packet is claimed to have enough data for a 4-byte FCS, but
1677 * we didn't capture all of the packet.
1678 * Slice off the 4-byte FCS from the reported length, and trim the
1679 * captured length so it's no more than the reported length; that
1680 * will slice off what of the FCS, if any, is in the captured
1681 * length.
1683 reported_len -= 4;
1684 if (len > reported_len)
1685 len = reported_len;
1686 next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1687 } else {
1689 * We have the entire packet, and it includes a 4-byte FCS.
1690 * Slice it off.
1692 len -= 4;
1693 reported_len -= 4;
1694 next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len);
1697 * Compute the FCS and put it into the tree.
1699 rx_fcs_offset = proto_offset + len;
1700 rx_fcs_exp = fcs32(tvb);
1701 rx_fcs_got = tvb_get_letohl(tvb, rx_fcs_offset);
1702 if (rx_fcs_got != rx_fcs_exp) {
1703 proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 4,
1704 "FCS 32: 0x%08x [incorrect, should be 0x%08x]",
1705 rx_fcs_got, rx_fcs_exp);
1706 } else {
1707 proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 4,
1708 "FCS 32: 0x%08x [correct]", rx_fcs_got);
1711 break;
1713 default:
1714 DISSECTOR_ASSERT_NOT_REACHED();
1715 next_tvb = NULL;
1716 break;
1719 return next_tvb;
1722 void
1723 capture_ppp_hdlc(const guchar *pd, int offset, int len, packet_counts *ld)
1725 if (!BYTES_ARE_IN_FRAME(offset, len, 2)) {
1726 ld->other++;
1727 return;
1729 if (pd[0] == CHDLC_ADDR_UNICAST || pd[0] == CHDLC_ADDR_MULTICAST) {
1730 capture_chdlc(pd, offset, len, ld);
1731 return;
1733 if (!BYTES_ARE_IN_FRAME(offset, len, 4)) {
1734 ld->other++;
1735 return;
1737 switch (pntohs(&pd[offset + 2])) {
1738 case PPP_IP:
1739 capture_ip(pd, offset + 4, len, ld);
1740 break;
1741 case PPP_IPX:
1742 capture_ipx(ld);
1743 break;
1744 case PPP_VINES:
1745 capture_vines(ld);
1746 break;
1747 default:
1748 ld->other++;
1749 break;
1753 static void
1754 dissect_lcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
1755 const char *name)
1757 guint8 type;
1759 type = tvb_get_guint8(tvb, offset);
1760 proto_tree_add_uint_format_value(tree, hf_lcp_opt_type, tvb, offset, 1,
1761 type, "%s (%u)", name, type);
1762 proto_tree_add_item(tree, hf_lcp_opt_length, tvb, offset + 1, 1, ENC_NA);
1765 static void
1766 dissect_lcp_vendor_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1767 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1769 proto_tree *field_tree;
1770 proto_item *tf, *ti;
1771 guint32 oui;
1772 const gchar *manuf;
1774 oui = tvb_get_ntoh24(tvb, offset + 2);
1775 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
1776 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1777 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1778 ti = proto_tree_add_uint_format_value(field_tree, hf_lcp_opt_oui, tvb,
1779 offset + 2, 3, oui, "%02x:%02x:%02x",
1780 (oui >> 16) & 0xff, (oui >> 8) & 0xff, oui & 0xff);
1781 manuf = uint_get_manuf_name_if_known(oui);
1782 if (manuf)
1783 proto_item_append_text(ti, "(%s)", manuf);
1785 proto_tree_add_item(field_tree, hf_lcp_opt_kind, tvb, offset + 5, 1,
1786 ENC_NA);
1787 if (length > 6) {
1788 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset + 6,
1789 length - 6, ENC_NA);
1793 static void
1794 dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1795 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1797 proto_tree *field_tree;
1798 proto_item *tf;
1800 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u", optp->name,
1801 tvb_get_ntohs(tvb, offset + 2));
1802 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1803 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1804 proto_tree_add_item(field_tree, hf_lcp_opt_mru, tvb, offset + 2, 2,
1805 ENC_BIG_ENDIAN);
1808 static void
1809 dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1810 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1812 proto_tree *field_tree;
1813 proto_item *tf, *ti;
1814 static const int *asyncmap_fields[] = {
1815 &hf_lcp_opt_asyncmap_us, &hf_lcp_opt_asyncmap_rs,
1816 &hf_lcp_opt_asyncmap_gs, &hf_lcp_opt_asyncmap_fs,
1817 &hf_lcp_opt_asyncmap_esc, &hf_lcp_opt_asyncmap_sub,
1818 &hf_lcp_opt_asyncmap_em, &hf_lcp_opt_asyncmap_can,
1819 &hf_lcp_opt_asyncmap_etb, &hf_lcp_opt_asyncmap_syn,
1820 &hf_lcp_opt_asyncmap_nak, &hf_lcp_opt_asyncmap_dc4,
1821 &hf_lcp_opt_asyncmap_dc3, &hf_lcp_opt_asyncmap_dc2,
1822 &hf_lcp_opt_asyncmap_dc1, &hf_lcp_opt_asyncmap_dle,
1823 &hf_lcp_opt_asyncmap_si, &hf_lcp_opt_asyncmap_so,
1824 &hf_lcp_opt_asyncmap_cr, &hf_lcp_opt_asyncmap_ff,
1825 &hf_lcp_opt_asyncmap_vt, &hf_lcp_opt_asyncmap_lf,
1826 &hf_lcp_opt_asyncmap_ht, &hf_lcp_opt_asyncmap_bs,
1827 &hf_lcp_opt_asyncmap_bel, &hf_lcp_opt_asyncmap_ack,
1828 &hf_lcp_opt_asyncmap_enq, &hf_lcp_opt_asyncmap_eot,
1829 &hf_lcp_opt_asyncmap_etx, &hf_lcp_opt_asyncmap_stx,
1830 &hf_lcp_opt_asyncmap_soh, &hf_lcp_opt_asyncmap_nul,
1831 NULL
1834 static const char *ctrlchars[32] = {
1835 "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
1836 "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
1837 "DLE", "DC1 (XON)", "DC2", "DC3 (XOFF)", "DC4", "NAK", "SYN", "ETB",
1838 "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
1841 gboolean anyctrlchars;
1842 guint32 map;
1843 int i;
1845 map = tvb_get_ntohl(tvb, offset + 2);
1846 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%08x (",
1847 optp->name, map);
1848 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1849 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1850 ti = proto_tree_add_bitmask(field_tree, tvb, offset + 2,
1851 hf_lcp_opt_asyncmap, *optp->subtree_index, asyncmap_fields,
1852 ENC_BIG_ENDIAN);
1853 if (map == 0x00000000) {
1854 proto_item_append_text(tf, "None)");
1855 proto_item_append_text(ti, " (None)");
1856 } else if (map == 0xffffffff) {
1857 proto_item_append_text(tf, "All)");
1858 proto_item_append_text(ti, " (All)");
1859 } else {
1860 for (anyctrlchars = FALSE, i = 31; i >= 0; i--) {
1861 if (map & (1 << i)) {
1862 if (anyctrlchars)
1863 proto_item_append_text(tf, ", %s", ctrlchars[i]);
1864 else {
1865 anyctrlchars = TRUE;
1866 proto_item_append_text(tf, "%s", ctrlchars[i]);
1870 proto_item_append_text(tf, ")");
1874 static void
1875 dissect_lcp_authprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1876 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1878 proto_tree *field_tree;
1879 proto_item *tf;
1880 guint16 protocol;
1882 protocol = tvb_get_ntohs(tvb, offset + 2);
1883 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s (0x%02x)",
1884 optp->name, val_to_str_ext_const(protocol, &ppp_vals_ext, "Unknown"),
1885 protocol);
1886 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1887 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1888 proto_tree_add_item(field_tree, hf_lcp_opt_auth_protocol, tvb, offset + 2,
1889 2, ENC_BIG_ENDIAN);
1891 if (length > 4) {
1892 offset += 4;
1893 length -= 4;
1894 if (protocol == PPP_CHAP) {
1895 proto_tree_add_item(field_tree, hf_lcp_opt_algorithm, tvb, offset,
1896 1, ENC_NA);
1897 if (length > 1) {
1898 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb,
1899 offset + 1, length - 1, ENC_NA);
1901 } else {
1902 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
1903 length, ENC_NA);
1908 static void
1909 dissect_lcp_qualprot_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1910 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1912 proto_tree *field_tree;
1913 proto_item *tf;
1914 guint16 protocol;
1916 protocol = tvb_get_ntohs(tvb, offset + 2);
1917 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s (0x%02x)",
1918 optp->name, val_to_str_ext_const(protocol, &ppp_vals_ext, "Unknown"),
1919 protocol);
1920 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1921 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1922 proto_tree_add_item(field_tree, hf_lcp_opt_quality_protocol, tvb,
1923 offset + 2, 2, ENC_BIG_ENDIAN);
1925 if (length > 4) {
1926 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset + 4,
1927 length + 4, ENC_NA);
1931 static void
1932 dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1933 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1935 proto_tree *field_tree;
1936 proto_item *tf;
1938 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%08x",
1939 optp->name, tvb_get_ntohl(tvb, offset + 2));
1940 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1941 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1942 proto_tree_add_item(field_tree, hf_lcp_opt_magic_number, tvb, offset + 2,
1943 4, ENC_BIG_ENDIAN);
1946 static void
1947 dissect_lcp_linkqualmon_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1948 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1950 proto_tree *field_tree;
1951 proto_item *tf;
1952 guint32 reportingperiod;
1954 reportingperiod = tvb_get_ntohl(tvb, offset + 2);
1955 tf = proto_tree_add_text(tree, tvb, offset, length,
1956 "%s: %u microsecond%s%s", optp->name, reportingperiod,
1957 plurality(reportingperiod, "", "s"),
1958 reportingperiod ? "" : " [illegal]");
1959 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1960 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1961 proto_tree_add_uint_format_value(field_tree, hf_lcp_opt_reportingperiod,
1962 tvb, offset + 2, 4, reportingperiod, "%u microsecond%s%s",
1963 reportingperiod, plurality(reportingperiod, "", "s"),
1964 reportingperiod ? "" : "[illegal]");
1967 /* Used for:
1968 * Protocol Field Compression
1969 * Address and Control Field Compression
1970 * Compound Frames (Deprecated)
1971 * Nominal Data Encapsulation (Deprecated)
1972 * Multilink Short Sequence Number Header
1973 * Simple Data Link on SONET/SDH
1975 static void
1976 dissect_lcp_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
1977 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
1979 proto_tree *field_tree;
1980 proto_item *tf;
1982 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
1983 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1984 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
1987 static void
1988 dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1989 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
1990 void *data _U_)
1992 proto_tree *field_tree;
1993 proto_item *tf;
1994 static const int *fcs_alternatives_fields[] = {
1995 &hf_lcp_opt_fcs_alternatives_ccitt32,
1996 &hf_lcp_opt_fcs_alternatives_ccitt16,
1997 &hf_lcp_opt_fcs_alternatives_null,
1998 NULL
2001 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%02x",
2002 optp->name, tvb_get_guint8(tvb, offset + 2));
2003 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2004 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2005 proto_tree_add_bitmask(field_tree, tvb, offset + 2,
2006 hf_lcp_opt_fcs_alternatives, *optp->subtree_index,
2007 fcs_alternatives_fields, ENC_NA);
2010 static void
2011 dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2012 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
2013 void *data _U_)
2015 proto_tree *field_tree;
2016 proto_item *tf;
2017 guint8 maximum;
2019 maximum = tvb_get_guint8(tvb, offset + 2);
2020 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u octet%s%s",
2021 optp->name, maximum, plurality(maximum, "", "s"),
2022 maximum ? "" : " [invalid]");
2023 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2024 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2025 proto_tree_add_uint_format_value(field_tree, hf_lcp_opt_maximum, tvb,
2026 offset + 2, 1, maximum, "%u octet%s%s", maximum,
2027 plurality(maximum, "", "s"), maximum ? "" : " [invalid]");
2030 static void
2031 dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2032 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
2033 void *data _U_)
2035 proto_tree *field_tree;
2036 proto_item *tf;
2037 guint8 window;
2039 window = tvb_get_guint8(tvb, offset + 2);
2040 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u frame%s%s",
2041 optp->name, window, plurality(window, "", "s"),
2042 (window == 0 || window > 127) ? " [invalid]" : "");
2043 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2044 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2045 proto_tree_add_uint_format_value(field_tree, hf_lcp_opt_window, tvb,
2046 offset + 2, 1, window, "%u frame%s%s", window,
2047 plurality(window, "", "s"),
2048 (window == 0 || window > 127) ? " [invalid]" : "");
2049 if (length > 3) {
2050 proto_tree_add_item(field_tree, hf_lcp_opt_hdlc_address, tvb,
2051 offset + 3, length - 3, ENC_NA);
2055 /* http://tools.ietf.org/html/rfc1570#section-2.3 only lists 0-4, but
2056 * http://tools.ietf.org/html/draft-ietf-pppext-callback-ds-02 lists 5 as
2057 * "E.165 number", rather than "unassigned", and
2058 * http://msdn.microsoft.com/en-us/library/ff632847%28v=prot.10%29.aspx does
2059 * indicate 6 as below. Since 5 is only mentioned in the draft, leave it as
2060 * "unassigned"?
2062 static const value_string callback_op_vals[] = {
2063 {0, "Location is determined by user authentication"},
2064 {1, "Message is dialing string"},
2065 {2, "Message is location identifier"},
2066 {3, "Message is E.164"},
2067 {4, "Message is distinguished name"},
2068 {5, "unassigned"}, /* "Message is E.165"? */
2069 {6, "Location is determined during CBCP negotiation"},
2070 {0, NULL}
2073 static void
2074 dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2075 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2077 proto_tree *field_tree;
2078 proto_item *tf;
2079 guint8 operation;
2081 operation = tvb_get_guint8(tvb, offset + 2);
2082 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
2083 val_to_str_const(operation, callback_op_vals, "Unknown"));
2084 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2085 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2086 proto_tree_add_item(field_tree, hf_lcp_opt_operation, tvb, offset + 2, 1,
2087 ENC_NA);
2089 if (length > 3) {
2090 proto_tree_add_item(field_tree, hf_lcp_opt_message, tvb, offset + 3,
2091 length - 3, ENC_NA);
2095 /* http://tools.ietf.org/html/rfc1990#section-5.1.1 */
2096 static void
2097 dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2098 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
2099 void *data _U_)
2101 proto_tree *field_tree;
2102 proto_item *tf;
2103 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u", optp->name,
2104 tvb_get_ntohs(tvb, offset + 2));
2105 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2106 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2107 proto_tree_add_item(field_tree, hf_lcp_opt_mrru, tvb, offset + 2, 2,
2108 ENC_BIG_ENDIAN);
2111 #define CLASS_NULL 0
2112 #define CLASS_LOCAL 1
2113 #define CLASS_IP 2
2114 #define CLASS_IEEE_802_1 3
2115 #define CLASS_PPP_MAGIC_NUMBER 4
2116 #define CLASS_PSDN_DIRECTORY_NUMBER 5
2118 static const value_string multilink_ep_disc_class_vals[] = {
2119 {CLASS_NULL, "Null"},
2120 {CLASS_LOCAL, "Locally assigned address"},
2121 {CLASS_IP, "Internet Protocol (IP) address"},
2122 {CLASS_IEEE_802_1, "IEEE 802.1 globally assigned MAC address"},
2123 {CLASS_PPP_MAGIC_NUMBER, "PPP magic-number block"},
2124 {CLASS_PSDN_DIRECTORY_NUMBER, "Public switched network directory number"},
2125 {0, NULL}
2128 static void
2129 dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2130 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree,
2131 void *data _U_)
2133 proto_tree *field_tree;
2134 proto_tree *magic_tree;
2135 proto_item *tf, *tm;
2136 guint8 ep_disc_class;
2138 ep_disc_class = tvb_get_guint8(tvb, offset + 2);
2139 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: Class: %s",
2140 optp->name, val_to_str_const(ep_disc_class,
2141 multilink_ep_disc_class_vals, "Unknown"));
2142 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2143 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2144 proto_tree_add_item(field_tree, hf_lcp_opt_ep_disc_class, tvb, offset + 2,
2145 1, ENC_NA);
2147 if (length <= 3)
2148 return;
2150 length -= 3;
2151 offset += 3;
2152 switch (ep_disc_class) {
2153 case CLASS_NULL:
2154 break;
2156 case CLASS_LOCAL:
2157 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2158 length <= 20 ? length : 20, ENC_NA);
2159 break;
2161 case CLASS_IP:
2162 if (length >= 4) {
2163 proto_tree_add_item(field_tree, hf_lcp_opt_ip_address, tvb, offset,
2164 4, ENC_BIG_ENDIAN);
2165 } else {
2166 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2167 length, ENC_NA);
2169 break;
2171 case CLASS_IEEE_802_1:
2172 if (length >= 6) {
2173 proto_tree_add_item(field_tree, hf_lcp_opt_802_1_address, tvb,
2174 offset, 6, ENC_NA);
2175 } else {
2176 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2177 length, ENC_NA);
2179 break;
2181 case CLASS_PPP_MAGIC_NUMBER:
2182 if (length % 4) {
2183 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2184 length, ENC_NA);
2185 } else {
2186 tm = proto_tree_add_item(field_tree, hf_lcp_opt_magic_block, tvb,
2187 offset, length <= 20 ? length : 20, ENC_NA);
2188 magic_tree = proto_item_add_subtree(tm, ett_lcp_magic_block);
2189 for ( ; length >= 4; length -= 4, offset += 4) {
2190 proto_tree_add_item(magic_tree, hf_lcp_opt_magic_number, tvb,
2191 offset, 4, ENC_BIG_ENDIAN);
2194 break;
2196 case CLASS_PSDN_DIRECTORY_NUMBER:
2197 proto_tree_add_item(field_tree, hf_lcp_opt_psndn, tvb, offset,
2198 length > 15 ? 15 : length, ENC_NA);
2199 break;
2201 default:
2202 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset, length,
2203 ENC_NA);
2204 break;
2208 static const value_string dce_id_mode_vals[] = {
2209 {1, "Mode-1 (No Additional Negotiation)"},
2210 {2, "Mode-2 (Full PPP Negotiation and State Machine)"},
2211 {0, NULL}
2214 static void
2215 dissect_lcp_dce_identifier_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2216 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2218 proto_tree *field_tree;
2219 proto_item *tf;
2220 guint8 mode;
2222 mode = tvb_get_guint8(tvb, offset + 2);
2223 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
2224 val_to_str_const(mode, dce_id_mode_vals, "Unknown"));
2225 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2226 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2227 proto_tree_add_item(field_tree, hf_lcp_opt_mode, tvb, offset + 2, 1,
2228 ENC_NA);
2231 static void
2232 dissect_lcp_multilink_pp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2233 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2235 proto_tree *field_tree;
2236 proto_item *tf;
2238 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2239 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2240 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2241 proto_tree_add_item(field_tree, hf_lcp_opt_unused, tvb, offset + 2, 2,
2242 ENC_NA);
2245 static void
2246 dissect_lcp_bacp_link_discriminator_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2247 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2249 proto_tree *field_tree;
2250 proto_item *tf;
2252 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u (0x%04x)",
2253 optp->name, tvb_get_ntohs(tvb, offset + 2),
2254 tvb_get_ntohs(tvb, offset + 2));
2255 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2256 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2257 proto_tree_add_item(field_tree, hf_lcp_opt_link_discrim, tvb, offset + 2,
2258 2, ENC_BIG_ENDIAN);
2261 /* Assuming it's this one:
2262 * http://tools.ietf.org/html/draft-ietf-pppext-link-negot-00
2264 static void
2265 dissect_lcp_auth_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2266 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2268 proto_tree *field_tree;
2269 proto_item *tf;
2270 guint8 id_len;
2272 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2273 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2274 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2275 proto_tree_add_item(field_tree, hf_lcp_opt_id, tvb, offset + 2, 1, ENC_NA);
2277 if (length > 3) {
2278 id_len = tvb_get_guint8(tvb, offset + 2);
2279 length -= 3;
2280 offset += 3;
2281 if (id_len < length) {
2282 length -= id_len;
2283 offset += id_len;
2284 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2285 length, ENC_NA);
2290 /* Asuming it's this one:
2291 * http://tools.ietf.org/html/draft-ietf-pppext-cobs-00
2293 static void
2294 dissect_lcp_cobs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2295 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2297 proto_tree *field_tree;
2298 proto_item *tf;
2299 static const int *cobs_flags_fields[] = {
2300 &hf_lcp_opt_cobs_flags_res,
2301 &hf_lcp_opt_cobs_flags_pre,
2302 &hf_lcp_opt_cobs_flags_zxe,
2303 NULL
2306 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2307 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2308 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2309 proto_tree_add_bitmask(field_tree, tvb, offset + 2, hf_lcp_opt_cobs_flags,
2310 *optp->subtree_index, cobs_flags_fields, ENC_NA);
2313 static void
2314 dissect_lcp_prefix_elision_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2315 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2317 proto_tree *field_tree;
2318 proto_item *tf;
2319 guint8 pre_len;
2321 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2322 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2323 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2325 if (length > 2) {
2326 length -= 2;
2327 offset += 2;
2328 while (length >= 2) {
2329 proto_tree_add_item(field_tree, hf_lcp_opt_class, tvb, offset, 1,
2330 ENC_NA);
2331 pre_len = tvb_get_guint8(tvb, offset + 1);
2332 if ((guint)(pre_len + 2) <= length) {
2333 proto_tree_add_item(field_tree, hf_lcp_opt_prefix, tvb,
2334 offset + 2, 1, ENC_NA);
2335 length -= (2 + pre_len);
2336 } else {
2337 /* Prefix length doesn't make sense, so bail out */
2338 length = 0;
2344 static const value_string ml_hdr_fmt_code_vals[] = {
2345 {2, "Long sequence number fragment format with classes"},
2346 {6, "Short sequence number fragment format with classes"},
2347 {0, NULL}
2350 static void
2351 dissect_lcp_multilink_hdr_fmt_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2352 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2354 proto_tree *field_tree;
2355 proto_item *tf;
2357 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2358 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2359 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2360 proto_tree_add_item(field_tree, hf_lcp_opt_code, tvb, offset + 2, 1,
2361 ENC_NA);
2362 proto_tree_add_item(field_tree, hf_lcp_opt_max_susp_classes, tvb,
2363 offset + 3, 1, ENC_NA);
2367 /* Character sets from http://www.iana.org/assignments/character-sets. */
2368 static const value_string charset_vals[] = {
2369 {3, "ANSI_X3.4-1968"},
2370 {4, "ISO_8859-1:1987"},
2371 {5, "ISO_8859-2:1987"},
2372 {6, "ISO_8859-3:1988"},
2373 {7, "ISO_8859-4:1988"},
2374 {8, "ISO_8859-5:1988"},
2375 {9, "ISO_8859-6:1987"},
2376 {10, "ISO_8859-7:1987"},
2377 {11, "ISO_8859-8:1988"},
2378 {12, "ISO_8859-9:1989"},
2379 {13, "ISO-8859-10"},
2380 {14, "ISO_6937-2-add"},
2381 {15, "JIS_X0201"},
2382 {16, "JIS_Encoding"},
2383 {17, "Shift_JIS"},
2384 {18, "Extended_UNIX_Code_Packed_Format_for_Japanese"},
2385 {19, "Extended_UNIX_Code_Fixed_Width_for_Japanese"},
2386 {20, "BS_4730"},
2387 {21, "SEN_850200_C"},
2388 {22, "IT"},
2389 {23, "ES"},
2390 {24, "DIN_66003"},
2391 {25, "NS_4551-1"},
2392 {26, "NF_Z_62-010"},
2393 {27, "ISO-10646-UTF-1"},
2394 {28, "ISO_646.basic:1983"},
2395 {29, "INVARIANT"},
2396 {30, "ISO_646.irv:1983"},
2397 {31, "NATS-SEFI"},
2398 {32, "NATS-SEFI-ADD"},
2399 {33, "NATS-DANO"},
2400 {34, "NATS-DANO-ADD"},
2401 {35, "SEN_850200_B"},
2402 {36, "KS_C_5601-1987"},
2403 {37, "ISO-2022-KR"},
2404 {38, "EUC-KR"},
2405 {39, "ISO-2022-JP"},
2406 {40, "ISO-2022-JP-2"},
2407 {41, "JIS_C6220-1969-jp"},
2408 {42, "JIS_C6220-1969-ro"},
2409 {43, "PT"},
2410 {44, "greek7-old"},
2411 {45, "latin-greek"},
2412 {46, "NF_Z_62-010_(1973)"},
2413 {47, "Latin-greek-1"},
2414 {48, "ISO_5427"},
2415 {49, "JIS_C6226-1978"},
2416 {50, "BS_viewdata"},
2417 {51, "INIS"},
2418 {52, "INIS-8"},
2419 {53, "INIS-cyrillic"},
2420 {54, "ISO_5427:1981"},
2421 {55, "ISO_5428:1980"},
2422 {56, "GB_1988-80"},
2423 {57, "GB_2312-80"},
2424 {58, "NS_4551-2"},
2425 {59, "videotex-suppl"},
2426 {60, "PT2"},
2427 {61, "ES2"},
2428 {62, "MSZ_7795.3"},
2429 {63, "JIS_C6226-1983"},
2430 {64, "greek7"},
2431 {65, "ASMO_449"},
2432 {66, "iso-ir-90"},
2433 {67, "JIS_C6229-1984-a"},
2434 {68, "JIS_C6229-1984-b"},
2435 {69, "JIS_C6229-1984-b-add"},
2436 {70, "JIS_C6229-1984-hand"},
2437 {71, "JIS_C6229-1984-hand-add"},
2438 {72, "JIS_C6229-1984-kana"},
2439 {73, "ISO_2033-1983"},
2440 {74, "ANSI_X3.110-1983"},
2441 {75, "T.61-7bit"},
2442 {76, "T.61-8bit"},
2443 {77, "ECMA-cyrillic"},
2444 {78, "CSA_Z243.4-1985-1"},
2445 {79, "CSA_Z243.4-1985-2"},
2446 {80, "CSA_Z243.4-1985-gr"},
2447 {81, "ISO_8859-6-E"},
2448 {82, "ISO_8859-6-I"},
2449 {83, "T.101-G2"},
2450 {84, "ISO_8859-8-E"},
2451 {85, "ISO_8859-8-I"},
2452 {86, "CSN_369103"},
2453 {87, "JUS_I.B1.002"},
2454 {88, "IEC_P27-1"},
2455 {89, "JUS_I.B1.003-serb"},
2456 {90, "JUS_I.B1.003-mac"},
2457 {91, "greek-ccitt"},
2458 {92, "NC_NC00-10:81"},
2459 {93, "ISO_6937-2-25"},
2460 {94, "GOST_19768-74"},
2461 {95, "ISO_8859-supp"},
2462 {96, "ISO_10367-box"},
2463 {97, "latin-lap"},
2464 {98, "JIS_X0212-1990"},
2465 {99, "DS_2089"},
2466 {100, "us-dk"},
2467 {101, "dk-us"},
2468 {102, "KSC5636"},
2469 {103, "UNICODE-1-1-UTF-7"},
2470 {104, "ISO-2022-CN"},
2471 {105, "ISO-2022-CN-EXT"},
2472 {106, "UTF-8"},
2473 {109, "ISO-8859-13"},
2474 {110, "ISO-8859-14"},
2475 {111, "ISO-8859-15"},
2476 {112, "ISO-8859-16"},
2477 {113, "GBK"},
2478 {114, "GB18030"},
2479 {115, "OSD_EBCDIC_DF04_15"},
2480 {116, "OSD_EBCDIC_DF03_IRV"},
2481 {117, "OSD_EBCDIC_DF04_1"},
2482 {118, "ISO-11548-1"},
2483 {119, "KZ-1048"},
2484 {1000, "ISO-10646-UCS-2"},
2485 {1001, "ISO-10646-UCS-4"},
2486 {1002, "ISO-10646-UCS-Basic"},
2487 {1003, "ISO-10646-Unicode-Latin1"},
2488 {1004, "ISO-10646-J-1"},
2489 {1005, "ISO-Unicode-IBM-1261"},
2490 {1006, "ISO-Unicode-IBM-1268"},
2491 {1007, "ISO-Unicode-IBM-1276"},
2492 {1008, "ISO-Unicode-IBM-1264"},
2493 {1009, "ISO-Unicode-IBM-1265"},
2494 {1010, "UNICODE-1-1"},
2495 {1011, "SCSU"},
2496 {1012, "UTF-7"},
2497 {1013, "UTF-16BE"},
2498 {1014, "UTF-16LE"},
2499 {1015, "UTF-16"},
2500 {1016, "CESU-8"},
2501 {1017, "UTF-32"},
2502 {1018, "UTF-32BE"},
2503 {1019, "UTF-32LE"},
2504 {1020, "BOCU-1"},
2505 {2000, "ISO-8859-1-Windows-3.0-Latin-1"},
2506 {2001, "ISO-8859-1-Windows-3.1-Latin-1"},
2507 {2002, "ISO-8859-2-Windows-Latin-2"},
2508 {2003, "ISO-8859-9-Windows-Latin-5"},
2509 {2004, "hp-roman8"},
2510 {2005, "Adobe-Standard-Encoding"},
2511 {2006, "Ventura-US"},
2512 {2007, "Ventura-International"},
2513 {2008, "DEC-MCS"},
2514 {2009, "IBM850"},
2515 {2010, "IBM852"},
2516 {2011, "IBM437"},
2517 {2012, "PC8-Danish-Norwegian"},
2518 {2013, "IBM862"},
2519 {2014, "PC8-Turkish"},
2520 {2015, "IBM-Symbols"},
2521 {2016, "IBM-Thai"},
2522 {2017, "HP-Legal"},
2523 {2018, "HP-Pi-font"},
2524 {2019, "HP-Math8"},
2525 {2020, "Adobe-Symbol-Encoding"},
2526 {2021, "HP-DeskTop"},
2527 {2022, "Ventura-Math"},
2528 {2023, "Microsoft-Publishing"},
2529 {2024, "Windows-31J"},
2530 {2025, "GB2312"},
2531 {2026, "Big5"},
2532 {2027, "macintosh"},
2533 {2028, "IBM037"},
2534 {2029, "IBM038"},
2535 {2030, "IBM273"},
2536 {2031, "IBM274"},
2537 {2032, "IBM275"},
2538 {2033, "IBM277"},
2539 {2034, "IBM278"},
2540 {2035, "IBM280"},
2541 {2036, "IBM281"},
2542 {2037, "IBM284"},
2543 {2038, "IBM285"},
2544 {2039, "IBM290"},
2545 {2040, "IBM297"},
2546 {2041, "IBM420"},
2547 {2042, "IBM423"},
2548 {2043, "IBM424"},
2549 {2044, "IBM500"},
2550 {2045, "IBM851"},
2551 {2046, "IBM855"},
2552 {2047, "IBM857"},
2553 {2048, "IBM860"},
2554 {2049, "IBM861"},
2555 {2050, "IBM863"},
2556 {2051, "IBM864"},
2557 {2052, "IBM865"},
2558 {2053, "IBM868"},
2559 {2054, "IBM869"},
2560 {2055, "IBM870"},
2561 {2056, "IBM871"},
2562 {2057, "IBM880"},
2563 {2058, "IBM891"},
2564 {2059, "IBM903"},
2565 {2060, "IBM904"},
2566 {2061, "IBM905"},
2567 {2062, "IBM918"},
2568 {2063, "IBM1026"},
2569 {2064, "EBCDIC-AT-DE"},
2570 {2065, "EBCDIC-AT-DE-A"},
2571 {2066, "EBCDIC-CA-FR"},
2572 {2067, "EBCDIC-DK-NO"},
2573 {2068, "EBCDIC-DK-NO-A"},
2574 {2069, "EBCDIC-FI-SE"},
2575 {2070, "EBCDIC-FI-SE-A"},
2576 {2071, "EBCDIC-FR"},
2577 {2072, "EBCDIC-IT"},
2578 {2073, "EBCDIC-PT"},
2579 {2074, "EBCDIC-ES"},
2580 {2075, "EBCDIC-ES-A"},
2581 {2076, "EBCDIC-ES-S"},
2582 {2077, "EBCDIC-UK"},
2583 {2078, "EBCDIC-US"},
2584 {2079, "UNKNOWN-8BIT"},
2585 {2080, "MNEMONIC"},
2586 {2081, "MNEM"},
2587 {2082, "VISCII"},
2588 {2083, "VIQR"},
2589 {2084, "KOI8-R"},
2590 {2085, "HZ-GB-2312"},
2591 {2086, "IBM866"},
2592 {2087, "IBM775"},
2593 {2088, "KOI8-U"},
2594 {2089, "IBM00858"},
2595 {2090, "IBM00924"},
2596 {2091, "IBM01140"},
2597 {2092, "IBM01141"},
2598 {2093, "IBM01142"},
2599 {2094, "IBM01143"},
2600 {2095, "IBM01144"},
2601 {2096, "IBM01145"},
2602 {2097, "IBM01146"},
2603 {2098, "IBM01147"},
2604 {2099, "IBM01148"},
2605 {2100, "IBM01149"},
2606 {2101, "Big5-HKSCS"},
2607 {2102, "IBM1047"},
2608 {2103, "PTCP154"},
2609 {2104, "Amiga-1251"},
2610 {2105, "KOI7-switched"},
2611 {2106, "BRF"},
2612 {2107, "TSCII"},
2613 {2108, "CP51932"},
2614 {2109, "windows-874"},
2615 {2250, "windows-1250"},
2616 {2251, "windows-1251"},
2617 {2252, "windows-1252"},
2618 {2253, "windows-1253"},
2619 {2254, "windows-1254"},
2620 {2255, "windows-1255"},
2621 {2256, "windows-1256"},
2622 {2257, "windows-1257"},
2623 {2258, "windows-1258"},
2624 {2259, "TIS-620"},
2625 {2260, "CP50220"},
2626 {0, NULL}
2628 value_string_ext charset_vals_ext = VALUE_STRING_EXT_INIT(charset_vals);
2630 static void
2631 dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2632 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2634 proto_tree *field_tree;
2635 proto_item *tf;
2637 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2638 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2639 dissect_lcp_opt_type_len(tvb, offset, field_tree, optp->name);
2640 proto_tree_add_item(field_tree, hf_lcp_opt_MIBenum, tvb, offset + 2, 4,
2641 ENC_BIG_ENDIAN);
2642 proto_tree_add_item(field_tree, hf_lcp_opt_language_tag, tvb, offset + 6,
2643 length - 6, ENC_NA);
2646 static void
2647 dissect_ipcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2648 const char *name)
2650 guint8 type;
2652 type = tvb_get_guint8(tvb, offset);
2653 proto_tree_add_uint_format_value(tree, hf_ipcp_opt_type, tvb, offset, 1,
2654 type, "%s (%u)", name, type);
2655 proto_tree_add_item(tree, hf_ipcp_opt_length, tvb, offset + 1, 1, ENC_NA);
2658 /* http://tools.ietf.org/html/rfc1172#section-5.1 */
2659 static void
2660 dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2661 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2663 proto_item *tf;
2664 proto_tree *field_tree;
2666 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: Src: %s, Dst: %s",
2667 optp->name, tvb_ip_to_str(tvb, offset + 2),
2668 tvb_ip_to_str(tvb, offset + 6));
2669 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2670 dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2671 proto_tree_add_item(field_tree, hf_ipcp_opt_src_address, tvb, offset + 2,
2672 4, ENC_BIG_ENDIAN);
2673 proto_tree_add_item(field_tree, hf_ipcp_opt_dst_address, tvb, offset + 6,
2674 4, ENC_BIG_ENDIAN);
2677 static const true_false_string tfs_comp_slot_id = {
2678 "The slot identifier may be compressed",
2679 "The slot identifier must not be compressed"
2682 /* http://tools.ietf.org/html/rfc1332#section-3.2 */
2683 static void
2684 dissect_ipcp_compress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2685 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2687 proto_item *tf;
2688 proto_tree *field_tree;
2689 guint16 us;
2691 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
2692 val_to_str_const(tvb_get_ntohs(tvb, offset + 2),
2693 ipcp_compress_proto_vals, "Unknown"));
2694 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2695 dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2696 proto_tree_add_item(field_tree, hf_ipcp_opt_compress_proto, tvb,
2697 offset + 2, 2, ENC_BIG_ENDIAN);
2699 us = tvb_get_ntohs(tvb, offset + 2);
2700 switch (us) {
2701 case IPCP_ROHC:
2702 proto_tree_add_item(field_tree, hf_ipcp_opt_max_cid, tvb, offset + 4,
2703 2, ENC_BIG_ENDIAN);
2704 proto_tree_add_item(field_tree, hf_ipcp_opt_mrru, tvb, offset + 6, 2,
2705 ENC_BIG_ENDIAN);
2706 proto_tree_add_item(field_tree, hf_ipcp_opt_max_header, tvb,
2707 offset + 8, 2, ENC_BIG_ENDIAN);
2709 if (length > 10) {
2710 proto_item *tso;
2711 proto_tree *subopt_tree;
2713 /* suboptions */
2714 offset += 10;
2715 length -= 10;
2716 tso = proto_tree_add_text(field_tree, tvb, offset, length,
2717 "Suboptions: (%u byte%s)", length, plurality(length, "", "s"));
2718 subopt_tree = proto_item_add_subtree(tso, *optp->subtree_index);
2719 dissect_ip_tcp_options(tvb, offset, length, ipcp_rohc_subopts,
2720 N_IPCP_ROHC_SUBOPTS, -1, &PPP_OPT_TYPES, &ei_ppp_opt_len_invalid, pinfo, subopt_tree, NULL, NULL);
2722 break;
2724 case IPCP_COMPRESS_VJ_1172:
2725 case IPCP_COMPRESS_VJ:
2726 proto_tree_add_item(field_tree, hf_ipcp_opt_max_slot_id, tvb,
2727 offset + 4, 1, ENC_NA);
2728 proto_tree_add_item(field_tree, hf_ipcp_opt_comp_slot_id, tvb,
2729 offset + 5, 1, ENC_NA);
2730 break;
2732 case IPCP_COMPRESS_IPHC:
2733 proto_tree_add_item(field_tree, hf_ipcp_opt_tcp_space, tvb, offset + 4,
2734 2, ENC_BIG_ENDIAN);
2735 proto_tree_add_item(field_tree, hf_ipcp_opt_non_tcp_space, tvb,
2736 offset + 6, 2, ENC_BIG_ENDIAN);
2737 us = tvb_get_ntohs(tvb, offset + 8);
2738 proto_tree_add_uint_format_value(field_tree, hf_ipcp_opt_f_max_period,
2739 tvb, offset + 8, 2, us, "%u%s", us,
2740 (us == 0) ? " (infinity)" : "");
2741 us = tvb_get_ntohs(tvb, offset + 10);
2742 proto_tree_add_uint_format_value(field_tree, hf_ipcp_opt_f_max_time,
2743 tvb, offset + 10, 2, us, "%u%s", us,
2744 (us == 0) ? " (infinity)" : "");
2745 proto_tree_add_item(field_tree, hf_ipcp_opt_max_header, tvb,
2746 offset + 12, 2, ENC_BIG_ENDIAN);
2748 if ( length > 14 ) {
2749 proto_item *tso;
2750 proto_tree *subopt_tree;
2752 /* suboptions */
2753 offset += 14;
2754 length -= 14;
2755 tso = proto_tree_add_text(field_tree, tvb, offset, length,
2756 "Suboptions: (%u byte%s)", length, plurality(length, "", "s"));
2757 subopt_tree = proto_item_add_subtree(tso, *optp->subtree_index);
2758 dissect_ip_tcp_options(tvb, offset, length, ipcp_iphc_subopts,
2759 N_IPCP_IPHC_SUBOPTS, -1, &PPP_OPT_TYPES, &ei_ppp_opt_len_invalid, pinfo, subopt_tree, NULL, NULL);
2761 break;
2763 default:
2764 if (length > 4) {
2765 proto_tree_add_item(field_tree, hf_ipcp_data, tvb, offset + 4,
2766 length - 4, ENC_NA);
2768 break;
2772 static void
2773 dissect_ipcp_opt_rohc_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2774 const char *name)
2776 guint8 type;
2778 type = tvb_get_guint8(tvb, offset);
2779 proto_tree_add_uint_format_value(tree, hf_ipcp_opt_rohc_type, tvb, offset,
2780 1, type, "%s (%u)", name, type);
2781 proto_tree_add_item(tree, hf_ipcp_opt_rohc_length, tvb, offset + 1, 1,
2782 ENC_NA);
2785 static void
2786 dissect_ipcp_rohc_profiles_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2787 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2789 proto_tree *field_tree;
2790 proto_item *tf;
2792 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2793 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2794 dissect_ipcp_opt_rohc_type_len(tvb, offset, field_tree, optp->name);
2795 if (length <= 2)
2796 return;
2798 for (offset += 2, length -= 2; length >= 2; length -= 2, offset += 2) {
2799 proto_tree_add_item(field_tree, hf_ipcp_opt_rohc_profile, tvb,
2800 offset, 2, ENC_BIG_ENDIAN);
2804 static void
2805 dissect_ipcp_opt_iphc_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2806 const char *name)
2808 guint8 type;
2810 type = tvb_get_guint8(tvb, offset);
2811 proto_tree_add_uint_format_value(tree, hf_ipcp_opt_iphc_type, tvb, offset,
2812 1, type, "%s (%u)", name, type);
2813 proto_tree_add_item(tree, hf_ipcp_opt_iphc_length, tvb, offset + 1, 1,
2814 ENC_NA);
2817 static void
2818 dissect_ipcp_iphc_simple_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2819 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2821 proto_tree *field_tree;
2822 proto_item *tf;
2824 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2825 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2826 dissect_ipcp_opt_iphc_type_len(tvb, offset, field_tree, optp->name);
2829 static void
2830 dissect_ipcp_iphc_neghdrcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2831 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2833 proto_tree *field_tree;
2834 proto_item *tf;
2836 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2837 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2838 dissect_ipcp_opt_iphc_type_len(tvb, offset, field_tree, optp->name);
2839 proto_tree_add_item(field_tree, hf_ipcp_opt_iphc_param, tvb, offset + 2, 1,
2840 ENC_NA);
2843 static void
2844 dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2845 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2847 proto_item *tf;
2848 proto_tree *field_tree;
2850 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
2851 tvb_ip_to_str(tvb, offset + 2));
2852 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2853 dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2854 proto_tree_add_item(field_tree, hf_ipcp_opt_ip_address, tvb, offset + 2, 4,
2855 ENC_BIG_ENDIAN);
2858 static void
2859 dissect_ipcp_mobileipv4_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2860 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2862 proto_item *tf;
2863 proto_tree *field_tree;
2865 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
2866 tvb_ip_to_str(tvb, offset + 2));
2867 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2868 dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2869 proto_tree_add_item(field_tree, hf_ipcp_opt_mobilenodehomeaddr, tvb,
2870 offset + 2, 4, ENC_BIG_ENDIAN);
2873 static void
2874 dissect_ipcp_pri_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2875 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2877 proto_item *tf;
2878 proto_tree *field_tree;
2880 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
2881 tvb_ip_to_str(tvb, offset + 2));
2882 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2883 dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2884 proto_tree_add_item(field_tree, hf_ipcp_opt_pri_dns_address, tvb,
2885 offset + 2, 4, ENC_BIG_ENDIAN);
2888 static void
2889 dissect_ipcp_pri_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2890 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2892 proto_item *tf;
2893 proto_tree *field_tree;
2895 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
2896 tvb_ip_to_str(tvb, offset + 2));
2897 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2898 dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2899 proto_tree_add_item(field_tree, hf_ipcp_opt_pri_nbns_address, tvb,
2900 offset + 2, 4, ENC_BIG_ENDIAN);
2903 static void
2904 dissect_ipcp_sec_dns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2905 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2907 proto_item *tf;
2908 proto_tree *field_tree;
2910 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
2911 tvb_ip_to_str(tvb, offset + 2));
2912 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2913 dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2914 proto_tree_add_item(field_tree, hf_ipcp_opt_sec_dns_address, tvb,
2915 offset + 2, 4, ENC_BIG_ENDIAN);
2918 static void
2919 dissect_ipcp_sec_nbns_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2920 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2922 proto_item *tf;
2923 proto_tree *field_tree;
2925 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
2926 tvb_ip_to_str(tvb, offset + 2));
2927 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2928 dissect_ipcp_opt_type_len(tvb, offset, field_tree, optp->name);
2929 proto_tree_add_item(field_tree, hf_ipcp_opt_sec_nbns_address, tvb,
2930 offset + 2, 4, ENC_BIG_ENDIAN);
2934 static void
2935 dissect_osinlcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2936 const char *name)
2938 guint8 type;
2940 type = tvb_get_guint8(tvb, offset);
2941 proto_tree_add_uint_format_value(tree, hf_osinlcp_opt_type, tvb, offset, 1,
2942 type, "%s (%u)", name, type);
2943 proto_tree_add_item(tree, hf_osinlcp_opt_length, tvb, offset + 1, 1,
2944 ENC_NA);
2947 static void
2948 dissect_osinlcp_align_npdu_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2949 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2951 proto_item *tf;
2952 proto_tree *field_tree;
2954 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: Alignment: %u",
2955 optp->name, tvb_get_guint8(tvb, offset + 2));
2956 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2957 dissect_osinlcp_opt_type_len(tvb, offset, field_tree, optp->name);
2958 proto_tree_add_item(field_tree, hf_osinlcp_opt_alignment, tvb, offset + 2,
2959 1, ENC_NA);
2962 static void
2963 dissect_pppmuxcp_def_pid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
2964 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2966 pppmux_def_prot_id = tvb_get_ntohs(tvb, offset + 2);
2967 proto_tree_add_text(tree, tvb, offset + 2, length - 2, "%s: %s (0x%02x)",
2968 optp->name,
2969 val_to_str_ext_const(pppmux_def_prot_id, &ppp_vals_ext, "Unknown"),
2970 pppmux_def_prot_id);
2974 static void
2975 dissect_ccp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2976 const char *name)
2978 guint8 type;
2980 type = tvb_get_guint8(tvb, offset);
2981 proto_tree_add_uint_format_value(tree, hf_ccp_opt_type, tvb, offset, 1,
2982 type, "%s (%u)", name, type);
2983 proto_tree_add_item(tree, hf_ccp_opt_length, tvb, offset + 1, 1, ENC_NA);
2986 /* http://tools.ietf.org/html/rfc1962 */
2987 static void dissect_ccp_oui_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
2988 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
2990 proto_tree *field_tree;
2991 proto_item *tf, *ti;
2992 guint32 oui;
2993 const gchar *manuf;
2995 oui = tvb_get_ntoh24(tvb, offset + 2);
2996 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
2997 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
2998 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
2999 ti = proto_tree_add_uint_format_value(field_tree, hf_ccp_opt_oui, tvb,
3000 offset + 2, 3, oui, "%02x:%02x:%02x",
3001 (oui >> 16) & 0xff, (oui >> 8) & 0xff, oui & 0xff);
3002 manuf = uint_get_manuf_name_if_known(oui);
3003 if (manuf)
3004 proto_item_append_text(ti, "(%s)", manuf);
3006 proto_tree_add_item(field_tree, hf_ccp_opt_subtype, tvb, offset + 5, 1,
3007 ENC_NA);
3008 if (length > 6) {
3009 proto_tree_add_item(field_tree, hf_ccp_opt_data, tvb, offset + 6,
3010 length - 6, ENC_NA);
3014 /* The following configuration option types are mentioned at
3015 * http://www.iana.org/assignments/ppp-numbers as referencing RFC1962; however,
3016 * RFC1962 only mentions Proprietary Compression OUI in section 4.1. These
3017 * others are therefore being treated as section 4.2 "Other Compression Types",
3018 * in terms of how they are dissected:
3019 * 1) Predictor type 1
3020 * 2) Predictor type 2
3021 * 3) Puddle Jumper
3022 * 16) Hewlett-Packard PPC
3023 * 20) V.42bis compression
3025 static void dissect_ccp_other_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3026 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3028 proto_tree *field_tree;
3029 proto_item *tf;
3031 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3032 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3033 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3035 if (length > 2) {
3036 proto_tree_add_item(field_tree, hf_ccp_opt_data, tvb, offset + 2,
3037 length - 2, ENC_NA);
3041 /* http://tools.ietf.org/html/rfc1974 */
3042 static void
3043 dissect_ccp_stac_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3044 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3046 proto_item *tf;
3047 proto_tree *field_tree;
3048 const char *stac_ascend = "Stac Electronics LZS (Ascend Proprietary version)";
3049 static const int *check_mode_fields[] = {
3050 &hf_ccp_opt_cm_reserved,
3051 &hf_ccp_opt_cm_check_mode,
3052 NULL
3055 if (length == 6) {
3056 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", stac_ascend);
3057 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3058 dissect_ccp_opt_type_len(tvb, offset, field_tree, stac_ascend);
3060 /* We don't know how to decode the following 4 octets, since
3061 there are no public documents that describe their usage. */
3062 proto_tree_add_item(field_tree, hf_ccp_opt_data, tvb, offset + 2,
3063 length - 2, ENC_NA);
3064 } else {
3065 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3066 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3067 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3069 proto_tree_add_item(field_tree, hf_ccp_opt_history_count, tvb,
3070 offset + 2, 2, ENC_BIG_ENDIAN);
3071 proto_tree_add_bitmask(field_tree, tvb, offset + 4, hf_ccp_opt_cm,
3072 ett_ccp_stac_opt_check_mode, check_mode_fields, ENC_NA);
3077 * Microsoft Point-To-Point Compression (MPPC) and Encryption (MPPE)
3078 * supported bits.
3080 #define MPPC_SUPPORTED_BITS_C 0x00000001 /* MPPC negotiation */
3081 #define MPPE_SUPPORTED_BITS_D 0x00000010 /* Obsolete */
3082 #define MPPE_SUPPORTED_BITS_L 0x00000020 /* 40-bit encryption */
3083 #define MPPE_SUPPORTED_BITS_S 0x00000040 /* 128-bit encryption */
3084 #define MPPE_SUPPORTED_BITS_M 0x00000080 /* 56-bit encryption */
3085 #define MPPE_SUPPORTED_BITS_H 0x01000000 /* stateless mode */
3087 static const true_false_string ccp_mppe_h_tfs = {
3088 "Stateless mode ON",
3089 "Stateless mode OFF"
3091 static const true_false_string ccp_mppe_m_tfs = {
3092 "56-bit encryption ON",
3093 "56-bit encryption OFF"
3095 static const true_false_string ccp_mppe_s_tfs = {
3096 "128-bit encryption ON",
3097 "128-bit encryption OFF"
3099 static const true_false_string ccp_mppe_l_tfs = {
3100 "40-bit encryption ON",
3101 "40-bit encryption OFF"
3103 static const true_false_string ccp_mppe_d_tfs = {
3104 "Obsolete (should NOT be 1)",
3105 "Obsolete (should ALWAYS be 0)"
3107 static const true_false_string ccp_mppe_c_tfs = {
3108 "Desire to negotiate MPPC",
3109 "No desire to negotiate MPPC"
3112 /* http://tools.ietf.org/html/rfc2118,
3113 * http://tools.ietf.org/html/rfc3078 */
3114 static void
3115 dissect_ccp_mppe_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3116 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3118 proto_item *tf;
3119 proto_tree *field_tree;
3120 static const int *supported_bits_fields[] = {
3121 &hf_ccp_opt_supported_bits_h,
3122 &hf_ccp_opt_supported_bits_m,
3123 &hf_ccp_opt_supported_bits_s,
3124 &hf_ccp_opt_supported_bits_l,
3125 &hf_ccp_opt_supported_bits_d,
3126 &hf_ccp_opt_supported_bits_c,
3127 NULL
3130 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3131 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3132 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3134 proto_tree_add_bitmask(field_tree, tvb, offset + 2,
3135 hf_ccp_opt_supported_bits, ett_ccp_mppe_opt_supp_bits,
3136 supported_bits_fields, ENC_BIG_ENDIAN);
3139 /* http://tools.ietf.org/html/rfc1993 */
3140 static void dissect_ccp_gfza_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3141 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3143 proto_tree *field_tree;
3144 proto_item *tf;
3146 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3147 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3148 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3150 proto_tree_add_item(field_tree, hf_ccp_opt_history, tvb, offset + 2, 1,
3151 ENC_NA);
3153 if (length > 3) {
3154 proto_tree_add_item(field_tree, hf_ccp_opt_version, tvb, offset + 3,
3155 length - 3, ENC_NA);
3159 /* http://tools.ietf.org/html/rfc1977 */
3160 static void
3161 dissect_ccp_bsdcomp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3162 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3164 proto_item *tf;
3165 proto_tree *field_tree;
3166 static const int *vd_fields[] = {
3167 &hf_ccp_opt_vd_vers,
3168 &hf_ccp_opt_vd_dict,
3169 NULL
3172 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3173 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3174 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3176 proto_tree_add_bitmask(field_tree, tvb, offset + 2, hf_ccp_opt_vd,
3177 *optp->subtree_index, vd_fields, ENC_BIG_ENDIAN);
3180 /* http://tools.ietf.org/html/rfc1967 */
3181 static void
3182 dissect_ccp_lzsdcp_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3183 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3185 proto_item *tf;
3186 proto_tree *field_tree;
3188 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3189 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3190 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3192 proto_tree_add_item(field_tree, hf_ccp_opt_history_count, tvb,
3193 offset + 2, 2, ENC_BIG_ENDIAN);
3194 proto_tree_add_item(field_tree, hf_ccp_opt_check_mode, tvb, offset + 4, 1,
3195 ENC_NA);
3196 proto_tree_add_item(field_tree, hf_ccp_opt_process_mode, tvb, offset + 5,
3197 1, ENC_NA);
3200 /* http://tools.ietf.org/html/rfc1975 */
3201 static void
3202 dissect_ccp_mvrca_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3203 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3205 proto_item *tf;
3206 proto_tree *field_tree;
3208 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3209 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3210 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3212 proto_tree_add_item(field_tree, hf_ccp_opt_fe, tvb, offset + 2, 1, ENC_NA);
3213 proto_tree_add_item(field_tree, hf_ccp_opt_p, tvb, offset + 2, 1, ENC_NA);
3214 proto_tree_add_item(field_tree, hf_ccp_opt_History, tvb, offset + 2, 1,
3215 ENC_NA);
3216 proto_tree_add_item(field_tree, hf_ccp_opt_contexts, tvb, offset + 3, 1,
3217 ENC_NA);
3220 /* http://tools.ietf.org/html/rfc1976 */
3221 static void
3222 dissect_ccp_dce_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3223 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3225 proto_item *tf;
3226 proto_tree *field_tree;
3228 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3229 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3230 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3232 proto_tree_add_item(field_tree, hf_ccp_opt_mode, tvb, offset + 2, 1,
3233 ENC_NA);
3236 static const value_string deflate_method_vals[] = {
3237 {8, "zlib compression"},
3238 {0, NULL}
3241 static const value_string deflate_chk_vals[] = {
3242 {0, "sequence number check method"},
3243 {0, NULL}
3246 /* http://tools.ietf.org/html/rfc1979 */
3247 static void
3248 dissect_ccp_deflate_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3249 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3251 proto_item *tf;
3252 proto_tree *field_tree;
3253 guint8 window;
3255 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3256 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3257 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3259 window = tvb_get_guint8(tvb, offset + 2);
3260 proto_tree_add_uint_format_value(field_tree, hf_ccp_opt_window, tvb,
3261 offset + 2, 1, window, "%u", 1 << (hi_nibble(window) + 8));
3262 proto_tree_add_item(field_tree, hf_ccp_opt_method, tvb, offset + 2, 1,
3263 ENC_NA);
3264 proto_tree_add_item(field_tree, hf_ccp_opt_mbz, tvb, offset + 3, 1,
3265 ENC_NA);
3266 proto_tree_add_item(field_tree, hf_ccp_opt_chk, tvb, offset + 3, 1,
3267 ENC_NA);
3270 static const range_string v44lzjh_mode_dict_rvals[] = {
3271 {0, 0, "Datagram Mode (one dictionary and no history)"},
3272 {1, 1, "Multi-Datagram Mode (one dictionary with history)"},
3273 {2, G_MAXUINT16, "Individual Link Mode" /* "(and proposed number of
3274 dictionaries each with a
3275 corresponding history" */},
3276 {0, 0, NULL}
3279 /* http://www.watersprings.org/pub/id/draft-heath-ppp-v44-01.txt */
3280 static void dissect_ccp_v44lzjh_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3281 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3283 proto_item *tf;
3284 proto_tree *field_tree;
3286 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3287 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3288 dissect_ccp_opt_type_len(tvb, offset, field_tree, optp->name);
3290 proto_tree_add_item(field_tree, hf_ccp_opt_mode_dictcount, tvb, offset + 2,
3291 2, ENC_BIG_ENDIAN);
3293 if (length > 4) {
3294 proto_tree_add_item(field_tree, hf_ccp_opt_dict_size, tvb, offset + 4,
3295 2, ENC_BIG_ENDIAN);
3296 if (length > 6) {
3297 proto_tree_add_item(field_tree, hf_ccp_opt_history_length, tvb,
3298 offset + 6, 2, ENC_BIG_ENDIAN);
3304 static void
3305 dissect_cbcp_no_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3306 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3308 proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3311 static void
3312 dissect_cbcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3313 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3315 proto_item *tf;
3316 proto_tree *field_tree;
3317 proto_tree *addr_tree;
3318 guint8 addr_type;
3319 guint addr_len;
3321 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3322 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3324 proto_tree_add_text(field_tree, tvb, offset + 2, 1, "Callback delay: %u",
3325 tvb_get_guint8(tvb, offset + 2));
3326 offset += 3;
3327 length -= 3;
3329 while (length > 0) {
3330 proto_tree_add_text(field_tree, tvb, offset, length,
3331 "Callback Address");
3332 addr_type = tvb_get_guint8(tvb, offset);
3333 addr_tree = proto_item_add_subtree(tf, ett_cbcp_callback_opt_addr);
3334 proto_tree_add_text(addr_tree, tvb, offset, 1, "Address Type: %s (%u)",
3335 ((addr_type == 1) ? "PSTN/ISDN" : "Other"), addr_type);
3336 offset++;
3337 length--;
3338 addr_len = tvb_strsize(tvb, offset);
3339 if (addr_len > length) {
3340 proto_tree_add_text(addr_tree, tvb, offset, length,
3341 "Address: (runs past end of option)");
3342 break;
3344 proto_tree_add_text(addr_tree, tvb, offset, addr_len, "Address: %s",
3345 tvb_format_text(tvb, offset, addr_len - 1));
3346 offset += addr_len;
3347 length -= addr_len;
3351 static void
3352 dissect_bacp_favored_peer_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3353 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3355 proto_item *tf;
3356 proto_tree *field_tree;
3358 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3359 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3361 proto_tree_add_text(field_tree, tvb, offset + 2, 4, "Magic number: 0x%08x",
3362 tvb_get_ntohl(tvb, offset + 2));
3365 static void
3366 dissect_bap_link_type_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3367 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3369 proto_item *tf;
3370 proto_tree *field_tree;
3371 guint8 link_type;
3373 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3374 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3376 proto_tree_add_text(field_tree, tvb, offset + 2, 2, "Link Speed: %u kbps",
3377 tvb_get_ntohs(tvb, offset + 2));
3378 link_type = tvb_get_guint8(tvb, offset + 4);
3379 proto_tree_add_text(field_tree, tvb, offset + 4, 1, "Link Type: %s (%u)",
3380 val_to_str_const(link_type, bap_link_type_vals, "Unknown"), link_type);
3383 static void
3384 dissect_bap_phone_delta_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3385 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3387 proto_item *tf;
3388 proto_tree *field_tree;
3389 proto_item *ti;
3390 proto_tree *suboption_tree;
3391 guint8 subopt_type;
3392 guint8 subopt_len;
3394 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3395 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3397 offset += 2;
3398 length -= 2;
3400 while (length > 0) {
3401 subopt_type = tvb_get_guint8(tvb, offset);
3402 subopt_len = tvb_get_guint8(tvb, offset + 1);
3403 ti = proto_tree_add_text(field_tree, tvb, offset, subopt_len,
3404 "Sub-Option (%u byte%s)", subopt_len,
3405 plurality(subopt_len, "", "s"));
3406 suboption_tree = proto_item_add_subtree(ti,
3407 ett_bap_phone_delta_subopt);
3409 proto_tree_add_text(suboption_tree, tvb, offset, 1,
3410 "Sub-Option Type: %s (%u)", val_to_str_const(subopt_type,
3411 bap_phone_delta_subopt_vals, "Unknown"), subopt_type);
3413 if (subopt_len < 2) {
3414 proto_tree_add_text(suboption_tree, tvb, offset + 1, 1,
3415 "Sub-Option Length: %u (invalid, must be >= 2)", subopt_len);
3416 return;
3418 if (subopt_len > length) {
3419 proto_tree_add_text(suboption_tree, tvb, offset + 1, 1,
3420 "Sub-Option Length: %u (invalid, must be <= length remaining "
3421 "in option %u)", subopt_len, length);
3422 return;
3425 proto_tree_add_text(suboption_tree, tvb, offset + 1, 1,
3426 "Sub-Option Length: %u", subopt_len);
3428 switch (subopt_type) {
3429 case BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT:
3430 if (subopt_len == 3) {
3431 proto_tree_add_text(suboption_tree, tvb, offset + 2, 1,
3432 "Unique Digit: %u", tvb_get_guint8(tvb, offset + 2));
3433 } else {
3434 proto_tree_add_text(suboption_tree, tvb, offset + 1, 1,
3435 "Invalid suboption length: %u (must be == 3)", subopt_len);
3437 break;
3438 case BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM:
3439 if (subopt_len > 2) {
3440 proto_tree_add_text(suboption_tree, tvb, offset + 2,
3441 subopt_len - 2, "Subscriber Number: %s",
3442 tvb_format_text(tvb, offset + 2, subopt_len - 2));
3443 } else {
3444 proto_tree_add_text(suboption_tree, tvb, offset + 1, 1,
3445 "Invalid suboption length: %u (must be > 2)", subopt_len);
3447 break;
3448 case BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR:
3449 if (subopt_len > 2) {
3450 proto_tree_add_text(suboption_tree, tvb, offset + 2,
3451 subopt_len - 2, "Phone Number Sub Address: %s",
3452 tvb_format_text(tvb, offset + 2, subopt_len - 2));
3453 } else {
3454 proto_tree_add_text(suboption_tree, tvb, offset + 1, 1,
3455 "Invalid suboption length: %u (must be > 2)", subopt_len);
3457 break;
3458 default:
3459 if (subopt_len > 2) {
3460 proto_tree_add_text(suboption_tree, tvb, offset + 2,
3461 subopt_len - 2, "Unknown");
3462 } else {
3463 proto_tree_add_text(suboption_tree, tvb, offset + 1, 1,
3464 "Invalid suboption length: %u (must be > 2)", subopt_len);
3466 break;
3468 offset += subopt_len;
3469 length -= subopt_len;
3473 static void
3474 dissect_bap_reason_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3475 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3477 if (length > 2) {
3478 proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
3479 tvb_format_text(tvb, offset + 2, length - 2));
3483 static void
3484 dissect_bap_link_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3485 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3487 proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%04x", optp->name,
3488 tvb_get_ntohs(tvb, offset + 2));
3491 static void
3492 dissect_bap_call_status_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3493 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3495 proto_item *tf;
3496 proto_tree *field_tree;
3497 guint8 status, action;
3499 tf = proto_tree_add_text(tree, tvb, offset, length, "%s", optp->name);
3500 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
3502 status = tvb_get_guint8(tvb, offset + 2);
3503 proto_tree_add_text(field_tree, tvb, offset + 2, 1, "Status: %s (0x%02x)",
3504 val_to_str_ext_const(status, &q931_cause_code_vals_ext, "Unknown"),
3505 status);
3507 action = tvb_get_guint8(tvb, offset + 3);
3508 proto_tree_add_text(field_tree, tvb, offset + 3, 1, "Action: %s (0x%02x)",
3509 val_to_str_const(action, bap_call_status_opt_action_vals, "Unknown"),
3510 action);
3513 static void
3514 dissect_vsncp_pdnid_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3515 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3517 guint8 PDNID;
3519 PDNID = tvb_get_guint8(tvb, offset + 2);
3520 proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%02x", optp->name,
3521 PDNID);
3524 static void
3525 dissect_vsncp_attachtype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3526 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3528 static const value_string attach_vals[] = {
3529 {1, "Initial Attach"},
3530 {3, "Handover Attach"},
3531 {0, NULL}
3533 guint8 attach;
3535 if (tree) {
3536 attach = tvb_get_guint8(tvb, offset + 2);
3537 proto_tree_add_text(tree, tvb, offset, length, "%s: %s (0x%02x)",
3538 optp->name, val_to_str_const(attach , attach_vals, "Unknown"),
3539 attach);
3543 static void
3544 dissect_vsncp_pdntype_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3545 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3547 static const value_string pdntype_vals[] = {
3548 {1, "IPv4"},
3549 {2, "IPv6"},
3550 {3, "IPv6/IPv4"},
3551 {0, NULL}
3553 guint8 pdntype;
3555 if (tree) {
3556 pdntype = tvb_get_guint8(tvb, offset + 2);
3557 proto_tree_add_text(tree, tvb, offset, length, "%s: %s (0x%02x)",
3558 optp->name, val_to_str_const(pdntype, pdntype_vals, "Unknown"),
3559 pdntype);
3563 static void
3564 dissect_vsncp_errorcode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3565 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3567 static const value_string errorcode_vals[] = {
3568 {0, "General Eror"},
3569 {1, "Unauthorized APN"},
3570 {2, "PDN Limit Exceeded"},
3571 {3, "NO PG-W Available"},
3572 {4, "P-GW Unreachable"},
3573 {5, "P-GW Reject"},
3574 {6, "Insufficient Parameters"},
3575 {7, "Resource Unavailable"},
3576 {8, "Admin Prohibited"},
3577 {9, "PDN-ID Already in Use"},
3578 {10, "Subscription Limitation"},
3579 {11, "PDN connection already exists for APN"},
3580 {12, "Emergency services not supported"},
3581 {13, "Reconnect to this APN not allowed"},
3582 {14, "APN congested"},
3583 {0, NULL}
3585 guint8 pdntype;
3587 if (tree) {
3588 pdntype = tvb_get_guint8(tvb, offset + 2);
3589 proto_tree_add_text(tree, tvb, offset, length, "%s: %s (0x%02x)",
3590 optp->name, val_to_str_const(pdntype, errorcode_vals, "Unknown"),
3591 pdntype);
3595 static void
3596 dissect_vsncp_pdnaddress_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3597 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3599 guint8 pdnaddtype;
3600 static const value_string pdntype_vals[] = {
3601 {0, "Initial Request by UE"},
3602 {1, "IPv4 Address"},
3603 {2, "IPv6 Address"},
3604 {3, "IPv6/IPv4 Address"},
3605 {0, NULL}
3607 proto_item *tf;
3608 proto_tree *field_tree;
3610 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: (%d byte%s)",
3611 optp->name, length, plurality(length, "", "s"));
3612 field_tree = proto_item_add_subtree(tf, ett_lcp_options);
3614 pdnaddtype = tvb_get_guint8(tvb, offset + 2);
3615 proto_tree_add_text(field_tree, tvb, offset + 2, 1,
3616 "PDN Type (%s): 0x%02x",
3617 val_to_str_const(pdnaddtype, pdntype_vals, "Unknown"), pdnaddtype);
3619 switch (pdnaddtype) {
3620 case 1:
3621 proto_tree_add_text(field_tree, tvb, offset + 3, length - 3, "%s: %s",
3622 val_to_str_const(pdnaddtype, pdntype_vals, "Unknown"),
3623 tvb_ip_to_str(tvb, offset + 3));
3624 break;
3626 case 2:
3628 struct e_in6_addr *ad = wmem_new0(wmem_packet_scope(),struct e_in6_addr);
3630 tvb_memcpy(tvb, &ad->bytes[8], offset + 3, 8);
3631 proto_tree_add_text(field_tree, tvb, offset + 3, length - 3, "%s: %s",
3632 val_to_str_const(pdnaddtype, pdntype_vals, "Unknown"),
3633 ip6_to_str(ad));
3634 break;
3637 case 3:
3639 struct e_in6_addr *ad = wmem_new0(wmem_packet_scope(), struct e_in6_addr);
3641 tvb_memcpy(tvb, &ad->bytes[8], offset + 3, 8);
3642 proto_tree_add_text(field_tree, tvb, offset + 3, length - 3, "%s: %s",
3643 val_to_str_const(pdnaddtype, pdntype_vals, "Unknown"),
3644 ip6_to_str(ad));
3645 proto_tree_add_text(field_tree, tvb, offset + 11, length - 11,
3646 "%s: %s", val_to_str_const(pdnaddtype, pdntype_vals, "Unknown"),
3647 tvb_ip_to_str(tvb, offset + 11));
3648 break;
3651 default:
3652 break;
3656 static void
3657 dissect_vsncp_ipv4address_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3658 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3660 proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
3661 tvb_ip_to_str(tvb, offset + 2));
3664 static void
3665 dissect_vsncp_apname_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3666 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3668 proto_item *tf;
3669 proto_tree *field_tree;
3671 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: (%d byte%s)",
3672 optp->name, length, plurality(length, "", "s"));
3673 field_tree = proto_item_add_subtree(tf, ett_lcp_options);
3675 if (length > 2) {
3676 guint8 i = 0;
3677 guint8 j = 1;
3678 guint8 lengthofapn;
3679 int off = offset + 2;
3681 while (i < (length - 2)) {
3682 lengthofapn = tvb_get_guint8(tvb, off++);
3683 proto_tree_add_text(field_tree, tvb, off, lengthofapn,
3684 "Label%d (%d byte%s): %s", j++, lengthofapn,
3685 plurality(lengthofapn, "", "s"),
3686 tvb_format_text(tvb, off, lengthofapn));
3687 off += lengthofapn;
3688 i += lengthofapn + 1;
3693 static void
3694 dissect_vsncp_addressalloc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3695 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3697 static const value_string alloc_vals[] = {
3698 {0, "Null Value (Attach or Handover)"},
3699 {18, "New PDN type due to network preference"},
3700 {255, "Success"},
3701 {0, NULL}
3704 guint8 alloc;
3706 if (tree) {
3707 alloc = tvb_get_guint8(tvb, offset + 2);
3708 proto_tree_add_text(tree, tvb, offset, length, "%s: %s (0x%02x)",
3709 optp->name, val_to_str_const(alloc, alloc_vals, "Unknown"), alloc);
3713 static void
3714 dissect_vsncp_apn_ambr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
3715 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3717 proto_item *tf;
3718 proto_tree *field_tree;
3720 if (tree) {
3722 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: (%d byte%s)",
3723 optp->name, length, plurality(length, "", "s"));
3724 field_tree = proto_item_add_subtree(tf, ett_lcp_options);
3726 /*de_esm_apn_aggr_max_br(tvb, field_tree, pinfo, offset, length, NULL, 0);*/
3727 proto_tree_add_text(field_tree, tvb, offset, length, "AMBR Data");
3731 static void
3732 dissect_vsncp_ipv6_hsgw_lla_iid_opt(const ip_tcp_opt *optp _U_, tvbuff_t *tvb,
3733 int offset, guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3735 proto_item *tf;
3736 proto_tree *field_tree;
3738 if (tree) {
3739 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: (%d byte%s)",
3740 optp->name, length, plurality(length, "", "s"));
3741 field_tree = proto_item_add_subtree(tf, ett_lcp_options);
3743 proto_tree_add_text(field_tree, tvb, offset, length, "IPv6 interface identifier");
3747 static void
3748 dissect_vsncp_pco_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
3749 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
3751 /* Ch 10.5.6.3 3GPP TS 24.008 version 11.5.0 Release 11 */
3752 static const value_string pco_vals[] = {
3753 {0x8021, "IPCP (DNS Address Request)"},
3754 {0x0001, "P-CSCF Address Request (IPv6)"},
3755 {0x0005, "MS Support of Network Requested Bearer Control indicator"},
3756 {0x0003, "DNS Server Address (IPv6)"},
3757 {0x000A, "IP address allocation via NAS signalling"},
3758 {0x000B, "IPv4 address allocation via DHCPv4"},
3759 {0x000D, "DNS Server IPv4 Address Request"},
3760 {0, NULL}
3762 int off = offset + 3;
3763 guint8 i = 0;
3764 guint16 pcotype;
3765 guint8 len;
3766 proto_item *tf;
3767 proto_tree *field_tree;
3769 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: (%d byte%s)",
3770 optp->name, length, plurality(length, "", "s"));
3771 field_tree = proto_item_add_subtree(tf, ett_lcp_options);
3773 while (i < (length - 3)) {
3774 pcotype = tvb_get_ntohs(tvb, off);
3775 len = tvb_get_guint8(tvb, (off + 2));
3776 proto_tree_add_text(field_tree, tvb, off, 2, "Protocol: %s (0x%02x)",
3777 val_to_str_const(pcotype, pco_vals, "Unknown"), pcotype);
3778 proto_tree_add_text(field_tree, tvb, off + 2, 1, "Length:(0x%02x)",
3779 len);
3780 if (len > 0) {
3781 proto_tree_add_text(field_tree, tvb, off + 3, len,
3782 "Data (%d byte%s)", len, plurality(len, "", "s"));
3785 off += 3 + len;
3786 i += 3 + len;
3790 static void
3791 dissect_cp(tvbuff_t *tvb, int proto_id, int proto_subtree_index,
3792 const value_string *proto_vals, int options_subtree_index,
3793 const ip_tcp_opt *opts, int nopts, packet_info *pinfo, proto_tree *tree)
3795 proto_item *ti;
3796 proto_tree *fh_tree = NULL;
3797 guint8 code;
3798 int length, offset;
3800 code = tvb_get_guint8(tvb, 0);
3801 length = tvb_get_ntohs(tvb, 2);
3803 col_set_str(pinfo->cinfo, COL_PROTOCOL,
3804 proto_get_protocol_short_name(find_protocol_by_id(proto_id)));
3805 col_set_str(pinfo->cinfo, COL_INFO,
3806 val_to_str_const(code, proto_vals, "Unknown"));
3808 if (tree) {
3809 ti = proto_tree_add_item(tree, proto_id, tvb, 0, length, ENC_NA);
3810 fh_tree = proto_item_add_subtree(ti, proto_subtree_index);
3811 proto_tree_add_uint_format_value(fh_tree, hf_ppp_code, tvb, 0, 1, code,
3812 "%s (%u)", val_to_str_const(code, proto_vals, "Unknown"), code);
3813 proto_tree_add_item(fh_tree, hf_ppp_identifier, tvb, 1, 1, ENC_NA);
3814 proto_tree_add_item(fh_tree, hf_ppp_length, tvb, 2, 2, ENC_BIG_ENDIAN);
3816 offset = 4;
3817 length -= 4;
3819 switch (code) {
3820 case VNDRSPCFC:
3821 if (tree) {
3822 guint32 oui;
3823 const gchar *manuf;
3825 proto_tree_add_item(fh_tree, hf_ppp_magic_number, tvb, offset, 4,
3826 ENC_BIG_ENDIAN);
3827 oui = tvb_get_ntoh24(tvb, offset + 4);
3828 ti = proto_tree_add_uint_format_value(fh_tree, hf_ppp_oui, tvb,
3829 offset + 4, 3, oui, "%02x:%02x:%02x", (oui >> 16) & 0xff,
3830 (oui >> 8) & 0xff, oui & 0xff);
3831 manuf = uint_get_manuf_name_if_known(oui);
3832 if (manuf){
3833 proto_item_append_text(ti, "(%s)", manuf);
3834 }else{
3835 /* check if we have the name in oui_vals */
3836 manuf = try_val_to_str(oui,oui_vals);
3837 if (manuf){
3838 proto_item_append_text(ti, "(%s)", manuf);
3841 proto_tree_add_item(fh_tree, hf_ppp_kind, tvb, offset + 7, 1,
3842 ENC_NA);
3843 if (length > 8) {
3844 proto_tree_add_item(fh_tree, hf_ppp_data, tvb, offset + 8,
3845 length - 8, ENC_NA);
3848 break;
3850 case CONFREQ:
3851 case CONFACK:
3852 case CONFNAK:
3853 case CONFREJ:
3854 if (length > 0) {
3855 proto_item *tf;
3856 proto_tree *field_tree;
3858 tf = proto_tree_add_text(fh_tree, tvb, offset, length,
3859 "Options: (%d byte%s)", length, plurality(length, "", "s"));
3860 field_tree = proto_item_add_subtree(tf, options_subtree_index);
3861 dissect_ip_tcp_options(tvb, offset, length, opts, nopts, -1, &PPP_OPT_TYPES,
3862 &ei_ppp_opt_len_invalid, pinfo, field_tree, NULL, NULL);
3864 break;
3866 case CODEREJ:
3867 if (tree && (length > 0)) {
3868 /* TODO: Decode the rejected packet here ... but wait until we have
3869 * a valid capture file with a CODEREJ, since the only capture file
3870 * with CODEREJ packets in it that I know of is pppoe.dump.gz from
3871 * the menagerie, and that file appears to have malformed CODEREJ
3872 * packets as they don't include the Code, Identifier or Length
3873 * fields so it's impossible to do the decode. */
3874 proto_tree_add_bytes_format(fh_tree, hf_ppp_data, tvb, offset,
3875 length, NULL, "Rejected Packet (%d byte%s): %s", length,
3876 plurality(length, "", "s"),
3877 tvb_bytes_to_str(tvb, offset, length));
3879 break;
3881 case PROTREJ: /* LCP only: RFC 1661 */
3882 if (tree) {
3883 proto_tree_add_item(fh_tree, hf_lcp_rej_proto, tvb, offset, 2,
3884 ENC_BIG_ENDIAN);
3886 if (length > 2) {
3887 gboolean save_in_error_pkt;
3888 tvbuff_t *next_tvb;
3889 guint16 protocol;
3891 protocol = tvb_get_ntohs(tvb, offset);
3892 offset += 2;
3893 length -= 2;
3896 * Save the current value of the "we're inside an error packet"
3897 * flag, and set that flag; subdissectors may treat packets that
3898 * are the payload of error packets differently from "real"
3899 * packets.
3901 save_in_error_pkt = pinfo->flags.in_error_pkt;
3902 pinfo->flags.in_error_pkt = TRUE;
3904 /* Decode the rejected packet. */
3905 next_tvb = tvb_new_subset(tvb, offset, length, length);
3906 if (!dissector_try_uint(ppp_subdissector_table, protocol, next_tvb,
3907 pinfo, fh_tree)) {
3908 call_dissector(data_handle, next_tvb, pinfo, fh_tree);
3911 /* Restore the "we're inside an error packet" flag. */
3912 pinfo->flags.in_error_pkt = save_in_error_pkt;
3914 break;
3916 case ECHOREQ: /* All 3 are LCP only: RFC 1661 */
3917 case ECHOREP:
3918 case DISCREQ:
3919 if (tree) {
3920 proto_tree_add_item(fh_tree, hf_lcp_magic_number, tvb, offset, 4,
3921 ENC_BIG_ENDIAN);
3922 if (length > 4) {
3923 proto_tree_add_item(fh_tree, hf_lcp_data, tvb, offset + 4,
3924 length - 4, ENC_NA);
3927 break;
3929 case IDENT: /* LCP only: RFC 1570 */
3930 if (tree) {
3931 proto_tree_add_item(fh_tree, hf_lcp_magic_number, tvb, offset, 4,
3932 ENC_BIG_ENDIAN);
3933 if (length > 4) {
3934 proto_tree_add_item(fh_tree, hf_lcp_message, tvb, offset + 4,
3935 length - 4, ENC_NA);
3938 break;
3940 case TIMEREMAIN: /* LCP only: RFC 1570 */
3941 if (tree) {
3942 guint32 secs_remaining;
3944 proto_tree_add_item(fh_tree, hf_lcp_magic_number, tvb, offset, 4,
3945 ENC_BIG_ENDIAN);
3946 secs_remaining = tvb_get_ntohl(tvb, offset + 4);
3947 proto_tree_add_uint_format_value(fh_tree, hf_lcp_secs_remaining,
3948 tvb, offset + 4, 4, secs_remaining, "%u %s", secs_remaining,
3949 (secs_remaining == 0xffffffff) ? "(forever)" : "seconds");
3950 if (length > 8) {
3951 proto_tree_add_item(fh_tree, hf_lcp_message, tvb, offset + 8,
3952 length - 8, ENC_NA);
3955 break;
3957 case TERMREQ:
3958 case TERMACK:
3959 case RESETREQ: /* RESETREQ and RESETACK are CCP only: RFC 1962 */
3960 case RESETACK:
3961 default:
3962 if (tree && (length > 0)) {
3963 proto_tree_add_item(fh_tree, hf_ppp_data, tvb, offset, length,
3964 ENC_NA);
3966 break;
3970 /* Protocol field compression */
3971 #define PFC_BIT 0x01
3973 static void
3974 dissect_ppp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3975 proto_tree *fh_tree, proto_item *ti, int proto_offset)
3977 guint16 ppp_prot;
3978 int proto_len;
3979 tvbuff_t *next_tvb;
3981 /* Make direction information filterable */
3982 if (tree &&
3983 (pinfo->p2p_dir == P2P_DIR_RECV || pinfo->p2p_dir == P2P_DIR_SENT)) {
3984 proto_item *direction_ti = proto_tree_add_uint(tree, hf_ppp_direction,
3985 tvb, 0, 0, pinfo->p2p_dir);
3986 PROTO_ITEM_SET_GENERATED(direction_ti);
3989 ppp_prot = tvb_get_guint8(tvb, 0);
3990 if (ppp_prot & PFC_BIT) {
3991 /* Compressed protocol field - just the byte we fetched. */
3992 proto_len = 1;
3993 } else {
3994 /* Uncompressed protocol field - fetch all of it. */
3995 ppp_prot = tvb_get_ntohs(tvb, 0);
3996 proto_len = 2;
3999 /* If "ti" is not null, it refers to the top-level "proto_ppp" item
4000 for PPP, and proto_offset is the length of any stuff in the header
4001 preceding the protocol type, e.g. an HDLC header; add the length
4002 of the protocol type field to it, and set the length of that item
4003 to the result. */
4004 if (ti != NULL)
4005 proto_item_set_len(ti, proto_offset + proto_len);
4007 if (tree) {
4008 proto_tree_add_uint(fh_tree, hf_ppp_protocol, tvb, 0, proto_len,
4009 ppp_prot);
4012 next_tvb = tvb_new_subset_remaining(tvb, proto_len);
4014 /* do lookup with the subdissector table */
4015 if (!dissector_try_uint(ppp_subdissector_table, ppp_prot, next_tvb, pinfo,
4016 tree)) {
4017 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", ppp_prot);
4018 col_add_fstr(pinfo->cinfo, COL_INFO, "PPP %s (0x%04x)",
4019 val_to_str_ext_const(ppp_prot, &ppp_vals_ext, "Unknown"),
4020 ppp_prot);
4021 call_dissector(data_handle,next_tvb, pinfo, tree);
4025 static void
4026 dissect_lcp_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4028 dissect_ip_tcp_options(tvb, 0, tvb_reported_length(tvb), lcp_opts,
4029 N_LCP_OPTS, -1, &PPP_OPT_TYPES, &ei_ppp_opt_len_invalid, pinfo, tree, NULL, NULL);
4033 * RFC's 1661, 2153 and 1570.
4035 static void
4036 dissect_lcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4038 dissect_cp(tvb, proto_lcp, ett_lcp, lcp_vals, ett_lcp_options, lcp_opts,
4039 N_LCP_OPTS, pinfo, tree);
4042 static void
4043 dissect_vsncp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4045 proto_item *ti;
4046 proto_tree *fh_tree = NULL;
4047 proto_item *tf;
4048 proto_tree *field_tree;
4049 guint8 code;
4050 guint8 id;
4051 int length, offset;
4053 code = tvb_get_guint8(tvb, 0);
4054 id = tvb_get_guint8(tvb, 1);
4055 length = tvb_get_ntohs(tvb, 2);
4057 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSNCP");
4058 col_set_str(pinfo->cinfo, COL_INFO,
4059 val_to_str_const(code, cp_vals, "Unknown"));
4061 if (tree) {
4062 ti = proto_tree_add_item(tree, proto_vsncp, tvb, 0, length, ENC_NA);
4063 fh_tree = proto_item_add_subtree(ti, ett_vsncp);
4064 proto_tree_add_text(fh_tree, tvb, 0, 1, "Code: %s (0x%02x)",
4065 val_to_str_const(code, cp_vals, "Unknown"), code);
4066 proto_tree_add_text(fh_tree, tvb, 1, 1, "Identifier: 0x%02x", id);
4067 proto_tree_add_text(fh_tree, tvb, 2, 2, "Length: %u", length);
4068 proto_tree_add_item(fh_tree, hf_ppp_oui, tvb, 4, 3, ENC_BIG_ENDIAN);
4071 offset = 7;
4072 length -= 7;
4074 switch (code) {
4075 case CONFREQ:
4076 case CONFACK:
4077 case CONFNAK:
4078 case CONFREJ:
4079 case TERMREQ:
4080 case TERMACK:
4081 if (length > 0) {
4082 tf = proto_tree_add_text(fh_tree, tvb, offset, length,
4083 "Options: (%d byte%s)", length,
4084 plurality(length, "", "s"));
4085 field_tree = proto_item_add_subtree(tf, ett_vsncp_options);
4086 dissect_ip_tcp_options(tvb, offset, length, vsncp_opts, N_VSNCP_OPTS, -1, &PPP_OPT_TYPES,
4087 &ei_ppp_opt_len_invalid, pinfo, field_tree, NULL, NULL);
4089 break;
4091 default:
4092 /* TODO? */
4093 break;
4097 static void
4098 dissect_vsnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4100 proto_item *vsnp_item = NULL;
4101 proto_tree *vsnp_tree = NULL;
4102 guint32 offset = 0;
4103 tvbuff_t *next_tvb;
4105 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSNP");
4107 if (tree) {
4108 vsnp_item = proto_tree_add_item(tree, proto_vsnp, tvb, 0, -1, ENC_NA);
4109 vsnp_tree = proto_item_add_subtree(vsnp_item, ett_vsnp);
4110 proto_tree_add_item(vsnp_tree, hf_vsnp_pdnid, tvb, offset, 1,
4111 ENC_BIG_ENDIAN);
4114 next_tvb = tvb_new_subset_remaining(tvb, 1);
4115 if (!dissector_try_uint(ppp_subdissector_table, PPP_IP, next_tvb, pinfo,
4116 tree)) {
4117 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", PPP_IP);
4118 col_add_fstr(pinfo->cinfo, COL_INFO, "PPP %s (0x%04x)",
4119 val_to_str_ext_const(PPP_IP, &ppp_vals_ext, "Unknown"), PPP_IP);
4120 call_dissector(data_handle, next_tvb, pinfo, tree);
4125 * RFC 1332.
4127 static void
4128 dissect_ipcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4130 dissect_cp(tvb, proto_ipcp, ett_ipcp, cp_vals, ett_ipcp_options, ipcp_opts,
4131 N_IPCP_OPTS, pinfo, tree);
4135 * RFC 3518
4137 #define BCP_FCS_PRESENT 0x80
4138 #define BCP_ZEROPAD 0x20
4139 #define BCP_IS_BCONTROL 0x10
4140 #define BCP_PADS_MASK 0x0f
4142 #define BCP_MACT_ETHERNET 1
4143 #define BCP_MACT_802_4 2
4144 #define BCP_MACT_802_5_NONCANON 3
4145 #define BCP_MACT_FDDI_NONCANON 4
4146 #define BCP_MACT_802_5_CANON 11
4147 #define BCP_MACT_FDDI_CANON 12
4149 static const value_string bcp_mac_type_vals[] = {
4150 {BCP_MACT_ETHERNET, "IEEE 802.3/Ethernet"},
4151 {BCP_MACT_802_4, "IEEE 802.4"},
4152 {BCP_MACT_802_5_NONCANON, "IEEE 802.5, non-canonical addresses"},
4153 {BCP_MACT_FDDI_NONCANON, "FDDI, non-canonical addresses"},
4154 {BCP_MACT_802_5_CANON, "IEEE 802.5, canonical addresses"},
4155 {BCP_MACT_FDDI_CANON, "FDDI, canonical addresses"},
4156 {0, NULL}
4159 static void
4160 dissect_bcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4162 proto_item *ti = NULL, *flags_item;
4163 proto_tree *bcp_tree = NULL, *flags_tree;
4164 int offset = 0;
4165 guint8 flags;
4166 guint8 mac_type;
4167 gint captured_length, reported_length, pad_length;
4168 tvbuff_t *next_tvb;
4170 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP BCP");
4171 col_clear(pinfo->cinfo, COL_INFO);
4173 if (tree) {
4174 ti = proto_tree_add_item(tree, proto_bcp, tvb, 0, -1, ENC_NA);
4175 bcp_tree = proto_item_add_subtree(ti, ett_bcp);
4178 flags = tvb_get_guint8(tvb, offset);
4179 if (flags & BCP_IS_BCONTROL) {
4180 col_set_str(pinfo->cinfo, COL_INFO, "Bridge control");
4182 if (tree) {
4183 flags_item = proto_tree_add_uint(bcp_tree, hf_bcp_flags, tvb, offset,
4184 1, flags);
4185 flags_tree = proto_item_add_subtree(flags_item, ett_bcp_flags);
4186 proto_tree_add_boolean(flags_tree, hf_bcp_fcs_present, tvb, offset,
4187 1, flags);
4188 proto_tree_add_boolean(flags_tree, hf_bcp_zeropad, tvb, offset, 1,
4189 flags);
4190 proto_tree_add_boolean(flags_tree, hf_bcp_bcontrol, tvb, offset, 1,
4191 flags);
4192 proto_tree_add_uint(flags_tree, hf_bcp_pads, tvb, offset, 1, flags);
4194 offset++;
4196 mac_type = tvb_get_guint8(tvb, offset);
4197 if (!(flags & BCP_IS_BCONTROL)) {
4198 col_add_str(pinfo->cinfo, COL_INFO,
4199 val_to_str(mac_type, bcp_mac_type_vals,
4200 "Unknown MAC type %u"));
4202 if (tree) {
4203 proto_tree_add_uint(bcp_tree, hf_bcp_mac_type, tvb, offset, 1,
4204 mac_type);
4206 offset++;
4208 switch (mac_type) {
4210 case BCP_MACT_802_4:
4211 case BCP_MACT_802_5_NONCANON:
4212 case BCP_MACT_FDDI_NONCANON:
4213 case BCP_MACT_802_5_CANON:
4214 case BCP_MACT_FDDI_CANON:
4215 if (tree)
4216 proto_tree_add_text(bcp_tree, tvb, offset, 1, "Pad");
4217 offset++;
4218 break;
4220 default:
4221 /* TODO? */
4222 break;
4225 if (!(flags & BCP_IS_BCONTROL)) {
4226 captured_length = tvb_length_remaining(tvb, offset);
4227 reported_length = tvb_reported_length_remaining(tvb, offset);
4228 pad_length = flags & BCP_PADS_MASK;
4229 if (reported_length >= pad_length) {
4230 reported_length -= pad_length;
4231 if (captured_length > reported_length)
4232 captured_length = reported_length;
4233 next_tvb = tvb_new_subset(tvb, offset, captured_length,
4234 reported_length);
4235 switch (mac_type) {
4237 case BCP_MACT_ETHERNET:
4238 if (flags & BCP_FCS_PRESENT) {
4239 call_dissector(eth_withfcs_handle, next_tvb, pinfo, tree);
4240 } else {
4241 call_dissector(eth_withoutfcs_handle, next_tvb, pinfo,
4242 tree);
4244 break;
4246 case BCP_MACT_802_4:
4247 case BCP_MACT_802_5_NONCANON:
4248 case BCP_MACT_FDDI_NONCANON:
4249 case BCP_MACT_802_5_CANON:
4250 case BCP_MACT_FDDI_CANON:
4251 break;
4253 default:
4254 call_dissector(data_handle, next_tvb, pinfo, tree);
4255 break;
4262 * RFC 1377.
4264 static void
4265 dissect_osinlcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4267 dissect_cp(tvb, proto_osinlcp, ett_osinlcp, cp_vals, ett_osinlcp_options,
4268 osinlcp_opts, N_OSINLCP_OPTS, pinfo, tree);
4272 * RFC 1962.
4274 static void
4275 dissect_ccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4277 dissect_cp(tvb, proto_ccp, ett_ccp, ccp_vals, ett_ccp_options, ccp_opts,
4278 N_CCP_OPTS, pinfo, tree);
4282 * Callback Control Protocol - see
4284 * http://www.linet.gr.jp/~manabe/PPxP/doc/Standards/draft-gidwani-ppp-callback-cp-00.txt
4286 static void
4287 dissect_cbcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4289 dissect_cp(tvb, proto_cbcp, ett_cbcp, cbcp_vals, ett_cbcp_options,
4290 cbcp_opts, N_CBCP_OPTS, pinfo, tree);
4294 * RFC 2125 (BACP and BAP).
4296 static void
4297 dissect_bacp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4299 dissect_cp(tvb, proto_bacp, ett_bacp, cp_vals, ett_bacp_options, bacp_opts,
4300 N_BACP_OPTS, pinfo, tree);
4303 static void
4304 dissect_bap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4306 proto_item *ti;
4307 proto_tree *fh_tree = NULL;
4308 proto_item *tf;
4309 proto_tree *field_tree;
4310 guint8 type;
4311 guint8 id;
4312 int length, offset;
4313 guint8 resp_code;
4315 type = tvb_get_guint8(tvb, 0);
4316 id = tvb_get_guint8(tvb, 1);
4317 length = tvb_get_ntohs(tvb, 2);
4319 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP BAP");
4320 col_set_str(pinfo->cinfo, COL_INFO,
4321 val_to_str_const(type, bap_vals, "Unknown"));
4323 if (tree) {
4324 ti = proto_tree_add_item(tree, proto_bap, tvb, 0, length, ENC_NA);
4325 fh_tree = proto_item_add_subtree(ti, ett_bap_options);
4326 proto_tree_add_text(fh_tree, tvb, 0, 1, "Type: %s (0x%02x)",
4327 val_to_str_const(type, bap_vals, "Unknown"), type);
4328 proto_tree_add_text(fh_tree, tvb, 1, 1, "Identifier: 0x%02x", id);
4329 proto_tree_add_text(fh_tree, tvb, 2, 2, "Length: %u", length);
4331 offset = 4;
4332 length -= 4;
4334 if (type == BAP_CRES || type == BAP_CBRES ||
4335 type == BAP_LDQRES || type == BAP_CSRES) {
4336 resp_code = tvb_get_guint8(tvb, offset);
4337 proto_tree_add_text(fh_tree, tvb, offset, 1,
4338 "Response Code: %s (0x%02x)",
4339 val_to_str_const(resp_code, bap_resp_code_vals, "Unknown"),
4340 resp_code);
4341 offset++;
4342 length--;
4345 if (length > 0) {
4346 tf = proto_tree_add_text(fh_tree, tvb, offset, length,
4347 "Data (%d byte%s)", length, plurality(length, "", "s"));
4348 field_tree = proto_item_add_subtree(tf, ett_bap_options);
4349 dissect_ip_tcp_options(tvb, offset, length, bap_opts, N_BAP_OPTS, -1, &PPP_OPT_TYPES,
4350 &ei_ppp_opt_len_invalid, pinfo, field_tree, NULL, NULL);
4354 #if 0 /* TODO? */
4355 static void
4356 dissect_comp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4358 proto_item *ti;
4359 proto_tree *comp_data_tree;
4361 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP Comp");
4362 col_set_str(pinfo->cinfo, COL_INFO, "Compressed data");
4364 if (tree) {
4365 ti = proto_tree_add_item(tree, proto_comp_data, tvb, 0, -1, ENC_NA);
4366 comp_data_tree = proto_item_add_subtree(ti, ett_comp_data);
4369 #else
4370 static void
4371 dissect_comp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4373 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP Comp");
4374 col_set_str(pinfo->cinfo, COL_INFO, "Compressed data");
4376 if (tree)
4377 proto_tree_add_item(tree, proto_comp_data, tvb, 0, -1, ENC_NA);
4379 #endif
4382 * RFC 3153 (both PPPMuxCP and PPPMux).
4384 static void
4385 dissect_pppmuxcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4387 dissect_cp(tvb, proto_pppmuxcp, ett_pppmuxcp, pppmuxcp_vals,
4388 ett_pppmuxcp_options, pppmuxcp_opts, N_PPPMUXCP_OPTS,pinfo, tree);
4391 #define PPPMUX_FLAGS_MASK 0xc0
4392 #define PPPMUX_PFF_BIT_SET 0x80
4393 #define PPPMUX_LXT_BIT_SET 0x40
4395 static void
4396 dissect_pppmux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4398 proto_tree *mux_tree, *hdr_tree, *sub_tree, *flag_tree;
4399 proto_tree *info_tree;
4400 proto_item *ti = NULL, *sub_ti = NULL;
4401 guint8 flags, byte;
4402 guint16 length;
4403 static guint16 pid;
4404 tvbuff_t *next_tvb;
4405 int offset = 0, length_remaining;
4406 int length_field = 0, pid_field = 0, hdr_length = 0;
4408 col_set_str(pinfo->cinfo,COL_PROTOCOL, "PPP PPPMux");
4409 col_set_str(pinfo->cinfo, COL_INFO, "PPP Multiplexing");
4411 length_remaining = tvb_reported_length(tvb);
4413 ti = proto_tree_add_item(tree, proto_pppmux, tvb, 0, -1, ENC_NA);
4414 mux_tree = proto_item_add_subtree(ti, ett_pppmux);
4416 while (length_remaining > 0) {
4417 flags = tvb_get_guint8(tvb,offset) & PPPMUX_FLAGS_MASK;
4419 if (flags & PPPMUX_LXT_BIT_SET) {
4420 length = tvb_get_ntohs(tvb,offset) & 0x3fff;
4421 length_field = 2;
4422 } else {
4423 length = tvb_get_guint8(tvb,offset) & 0x3f;
4424 length_field = 1;
4427 if (flags & PPPMUX_PFF_BIT_SET) {
4428 byte = tvb_get_guint8(tvb,offset + length_field);
4429 if (byte & PFC_BIT) { /* Compressed PID field */
4430 pid = byte;
4431 pid_field = 1;
4432 } else { /* PID field is 2 bytes */
4433 pid = tvb_get_ntohs(tvb,offset + length_field);
4434 pid_field = 2;
4436 } else {
4437 pid_field = 0; /* PID field is 0 bytes */
4438 if (!pid) { /* No Last PID, hence use the default */
4439 if (pppmux_def_prot_id)
4440 pid = pppmux_def_prot_id;
4444 hdr_length = length_field + pid_field;
4446 ti = proto_tree_add_text(mux_tree, tvb, offset, length + length_field,
4447 "PPPMux Sub-frame");
4448 sub_tree = proto_item_add_subtree(ti, ett_pppmux_subframe);
4449 sub_ti = proto_tree_add_text(sub_tree, tvb, offset, hdr_length,
4450 "Header field");
4452 hdr_tree = proto_item_add_subtree(sub_ti, ett_pppmux_subframe_hdr);
4453 ti = proto_tree_add_text(hdr_tree, tvb, offset, length_field,
4454 "PFF/LXT: 0x%02X", flags);
4455 flag_tree = proto_item_add_subtree(ti, ett_pppmux_subframe_flags);
4456 proto_tree_add_item(flag_tree, hf_pppmux_flags_pid, tvb, offset, length_field,
4457 ENC_BIG_ENDIAN);
4458 proto_tree_add_item(flag_tree, hf_pppmux_flags_field_length, tvb, offset, length_field,
4459 ENC_BIG_ENDIAN);
4460 proto_tree_add_text(hdr_tree, tvb,offset, length_field,
4461 "Sub-frame Length = %u", length);
4463 ti = proto_tree_add_uint(hdr_tree, hf_pppmux_protocol, tvb,
4464 offset + length_field, pid_field, pid);
4466 /* if protocol is not present in the sub-frame */
4467 if (!(flags & PPPMUX_PFF_BIT_SET)) {
4468 /* mark this item as generated */
4469 PROTO_ITEM_SET_GENERATED(ti);
4472 offset += hdr_length;
4473 length_remaining -= hdr_length;
4474 length -= pid_field;
4476 tvb_ensure_bytes_exist (tvb, offset, length);
4477 sub_ti = proto_tree_add_text(sub_tree, tvb,offset, length,
4478 "Information Field");
4479 info_tree = proto_item_add_subtree(sub_ti, ett_pppmux_subframe_info);
4480 next_tvb = tvb_new_subset(tvb, offset, length, length);
4482 if (!dissector_try_uint(ppp_subdissector_table, pid, next_tvb, pinfo,
4483 info_tree)) {
4484 call_dissector(data_handle, next_tvb, pinfo, info_tree);
4486 offset += length;
4487 length_remaining -= length;
4492 * RFC 2508 Internet Protocol Header Compression
4494 #define IPHC_CRTP_FH_FLAG_MASK 0xc0
4495 #define IPHC_CRTP_FH_FLAG_POS 6
4496 #define IPHC_CRTP_FH_CID8 1
4497 #define IPHC_CRTP_FH_CID16 3
4499 #define IPHC_CRTP_CS_CID8 1
4500 #define IPHC_CRTP_CS_CID16 2
4502 static const value_string iphc_crtp_fh_flags[] = {
4503 {IPHC_CRTP_FH_CID8, "8-bit Context Id"},
4504 {IPHC_CRTP_FH_CID16, "16-bit Context Id"},
4505 {0, NULL}
4508 static const value_string iphc_crtp_cs_flags[] = {
4509 {IPHC_CRTP_CS_CID8, "8-bit Context Id"},
4510 {IPHC_CRTP_CS_CID16, "16-bit Context Id"},
4511 {0, NULL}
4515 * 0x61 Packets: Full IP/UDP Header
4517 static void
4518 dissect_iphc_crtp_fh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4520 proto_tree *fh_tree = NULL, *info_tree;
4521 proto_item *ti = NULL;
4522 guint ip_hdr_len, flags;
4523 guint length;
4524 guint hdr_len;
4525 tvbuff_t *next_tvb;
4526 int offset_seq;
4527 int offset_cid;
4528 guint8 ip_version;
4529 guint8 next_protocol;
4530 guchar *ip_packet;
4532 length = tvb_reported_length(tvb);
4534 col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
4535 col_set_str(pinfo->cinfo, COL_INFO, "Full Header");
4537 /* only dissect IPv4 and UDP */
4538 ip_version = tvb_get_guint8(tvb, 0) >> 4;
4539 flags = (tvb_get_guint8(tvb, 2) & IPHC_CRTP_FH_FLAG_MASK) >>
4540 IPHC_CRTP_FH_FLAG_POS;
4541 next_protocol = tvb_get_guint8(tvb, 9);
4543 if (tree) {
4544 ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
4545 "%s", val_to_str_ext_const(PPP_RTP_FH, &ppp_vals_ext, "Unknown"));
4546 fh_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
4548 proto_tree_add_item(fh_tree, hf_iphc_crtp_fh_flags, tvb, 2, 1,
4549 ENC_BIG_ENDIAN);
4550 proto_tree_add_item(fh_tree, hf_iphc_crtp_gen, tvb, 2, 1,
4551 ENC_BIG_ENDIAN);
4555 /* calculate length of IP header, assume IPv4 */
4556 ip_hdr_len = (tvb_get_guint8(tvb, 0) & 0x0f) * 4;
4558 /* calculate total hdr length, assume UDP */
4559 hdr_len = ip_hdr_len + 8;
4561 if (ip_version != 4) {
4562 proto_tree_add_text(fh_tree, tvb, 3, -1,
4563 "IP version is %u: the only supported version is 4",
4564 ip_version);
4565 return;
4568 if (next_protocol != IP_PROTO_UDP) {
4569 proto_tree_add_text(fh_tree, tvb, 3, -1,
4570 "Next protocol is %s (%u): the only supported protocol is UDP",
4571 ipprotostr(next_protocol), next_protocol);
4572 return;
4575 /* context id and sequence fields */
4576 switch (flags) {
4577 case IPHC_CRTP_FH_CID8:
4578 offset_cid = 3;
4579 offset_seq = ip_hdr_len + 5;
4580 proto_tree_add_item(fh_tree, hf_iphc_crtp_cid8, tvb, offset_cid, 1,
4581 ENC_BIG_ENDIAN);
4582 proto_tree_add_item(fh_tree, hf_iphc_crtp_seq, tvb, offset_seq, 1,
4583 ENC_BIG_ENDIAN);
4584 break;
4586 case IPHC_CRTP_FH_CID16:
4587 offset_seq = 3;
4588 offset_cid = ip_hdr_len + 4;
4589 proto_tree_add_item(fh_tree, hf_iphc_crtp_seq, tvb, offset_seq, 1,
4590 ENC_BIG_ENDIAN);
4591 proto_tree_add_item(fh_tree, hf_iphc_crtp_cid16, tvb, offset_cid,
4592 2, ENC_BIG_ENDIAN);
4593 break;
4595 default:
4596 /* TODO? */
4597 break;
4600 /* information field */
4601 ti = proto_tree_add_text(fh_tree, tvb, 0, length, "Information Field");
4602 info_tree = proto_item_add_subtree(ti,ett_iphc_crtp_info);
4604 /* XXX: 1: May trap above; 2: really only need to check for ip_hdr_len+6 ?? */
4605 tvb_ensure_bytes_exist (tvb, 0, hdr_len); /* ip_hdr_len + 8 */
4607 /* allocate a copy of the IP packet */
4608 ip_packet = (guchar *)tvb_memdup(NULL, tvb, 0, length);
4610 /* restore the proper values to the IP and UDP length fields */
4611 ip_packet[2] = length >> 8;
4612 ip_packet[3] = length;
4614 ip_packet[ip_hdr_len + 4] = (length - ip_hdr_len) >> 8;
4615 ip_packet[ip_hdr_len + 5] = (length - ip_hdr_len);
4617 next_tvb = tvb_new_child_real_data(tvb, ip_packet, length, length);
4618 add_new_data_source(pinfo, next_tvb, "Decompressed Data");
4619 tvb_set_free_cb(next_tvb, g_free);
4621 if (!dissector_try_uint(ppp_subdissector_table, PPP_IP, next_tvb, pinfo,
4622 info_tree)) {
4623 call_dissector_only(data_handle, next_tvb, pinfo, info_tree, NULL);
4628 * 0x2067 Packets: Compressed UDP with 16-bit Context Identifier
4630 static void
4631 dissect_iphc_crtp_cudp16(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4633 proto_tree *cudp_tree;
4634 proto_item *ti = NULL;
4635 guint length;
4636 guint hdr_length;
4637 int offset = 0;
4639 col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
4640 col_set_str(pinfo->cinfo, COL_INFO, "Compressed UDP 16");
4642 length = tvb_reported_length(tvb);
4644 if (tree) {
4645 ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
4646 "%s",
4647 val_to_str_ext_const(PPP_RTP_CUDP16, &ppp_vals_ext, "Unknown"));
4648 cudp_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
4650 hdr_length = 3;
4652 proto_tree_add_item(cudp_tree, hf_iphc_crtp_cid16, tvb, 0, 2,
4653 ENC_BIG_ENDIAN);
4654 proto_tree_add_item(cudp_tree, hf_iphc_crtp_seq, tvb, 2, 1,
4655 ENC_BIG_ENDIAN);
4657 offset += hdr_length;
4658 length -= hdr_length;
4660 proto_tree_add_text(cudp_tree, tvb, offset, length, "Data (%d bytes)",
4661 length);
4666 * 0x67 Packets: Compressed UDP with 8-bit Context Identifier
4668 static void
4669 dissect_iphc_crtp_cudp8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4671 proto_tree *cudp_tree;
4672 proto_item *ti = NULL;
4673 guint length;
4674 guint hdr_length;
4675 int offset = 0;
4677 col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
4678 col_set_str(pinfo->cinfo, COL_INFO, "Compressed UDP 8");
4680 length = tvb_reported_length(tvb);
4682 if (tree) {
4683 ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
4684 "%s",
4685 val_to_str_ext_const(PPP_RTP_CUDP8, &ppp_vals_ext, "Unknown"));
4686 cudp_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
4688 hdr_length = 2;
4690 proto_tree_add_item(cudp_tree, hf_iphc_crtp_cid8, tvb, 0, 1,
4691 ENC_BIG_ENDIAN);
4692 proto_tree_add_item(cudp_tree, hf_iphc_crtp_seq, tvb, 1, 1,
4693 ENC_BIG_ENDIAN);
4695 offset += hdr_length;
4696 length -= hdr_length;
4698 proto_tree_add_text(cudp_tree, tvb, offset, length, "Data (%d bytes)",
4699 length);
4705 * 0x2065 Packets: Context State
4707 static void
4708 dissect_iphc_crtp_cs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4710 proto_tree *cs_tree;
4711 proto_item *ti = NULL;
4712 guint8 flags, cnt;
4713 guint length, cid_size;
4714 guint offset = 2, hf;
4716 col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
4717 col_set_str(pinfo->cinfo, COL_INFO, "Context State");
4719 if (tree) {
4720 ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
4721 "%s", val_to_str_ext_const(PPP_RTP_CS, &ppp_vals_ext, "Unknown"));
4723 cs_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
4725 proto_tree_add_item(cs_tree, hf_iphc_crtp_cs_flags, tvb, 0, 1,
4726 ENC_BIG_ENDIAN);
4727 proto_tree_add_item(cs_tree, hf_iphc_crtp_cs_cnt, tvb, 1, 1,
4728 ENC_BIG_ENDIAN);
4730 /* calculate required length */
4731 flags = tvb_get_guint8(tvb, 0);
4732 cnt = tvb_get_guint8(tvb, 1);
4734 if (flags == IPHC_CRTP_CS_CID8) {
4735 hf = hf_iphc_crtp_cid8;
4736 cid_size = 1;
4737 length = 3 * cnt;
4738 } else {
4739 hf = hf_iphc_crtp_cid16;
4740 cid_size = 2;
4741 length = 4 * cnt;
4744 tvb_ensure_bytes_exist(tvb, offset, length);
4746 while (offset < length) {
4747 proto_tree_add_item(cs_tree, hf, tvb, offset, cid_size,
4748 ENC_BIG_ENDIAN);
4749 offset += cid_size;
4750 proto_tree_add_item(cs_tree, hf_iphc_crtp_cs_invalid, tvb, offset,
4751 1, ENC_BIG_ENDIAN);
4752 proto_tree_add_item(cs_tree, hf_iphc_crtp_seq, tvb, offset, 1,
4753 ENC_BIG_ENDIAN);
4754 ++offset;
4755 proto_tree_add_item(cs_tree, hf_iphc_crtp_gen, tvb, offset, 1,
4756 ENC_BIG_ENDIAN);
4757 ++offset;
4764 * RFC 3032.
4766 static void
4767 dissect_mplscp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4769 dissect_cp(tvb, proto_mplscp, ett_mplscp, cp_vals, ett_mplscp_options,
4770 NULL, 0, pinfo, tree);
4774 * Cisco Discovery Protocol Control Protocol.
4775 * XXX - where is this documented?
4777 static void
4778 dissect_cdpcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4780 dissect_cp(tvb, proto_cdpcp, ett_cdpcp, cp_vals, ett_cdpcp_options, NULL,
4781 0, pinfo, tree);
4784 static gboolean mp_short_seqno = FALSE; /* Default to long sequence numbers */
4786 #define MP_FRAG_MASK 0xC0
4787 #define MP_FRAG(bits) ((bits) & MP_FRAG_MASK)
4788 #define MP_FRAG_FIRST 0x80
4789 #define MP_FRAG_LAST 0x40
4790 #define MP_FRAG_RESERVED 0x3f
4791 #define MP_FRAG_RESERVED_SHORT 0x30
4793 /* According to RFC 1990, the length the MP header isn't indicated anywhere
4794 in the header itself. It starts out at four bytes and can be
4795 negotiated down to two using LCP. We currently have a preference
4796 to select short headers. - gcc & gh
4798 static void
4799 dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4801 proto_tree *mp_tree = NULL, *hdr_tree;
4802 proto_item *ti = NULL;
4803 guint8 flags;
4804 const gchar *flag_str;
4805 gint hdrlen;
4806 tvbuff_t *next_tvb;
4808 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP MP");
4809 col_set_str(pinfo->cinfo, COL_INFO, "PPP Multilink");
4811 if (tree) {
4812 ti = proto_tree_add_item(tree, proto_mp, tvb, 0,
4813 mp_short_seqno ? 2 : 4, ENC_NA);
4814 mp_tree = proto_item_add_subtree(ti, ett_mp);
4817 flags = tvb_get_guint8(tvb, 0);
4819 if (tree) {
4820 switch (MP_FRAG(flags)) {
4821 case MP_FRAG_FIRST:
4822 flag_str = "First";
4823 break;
4824 case MP_FRAG_LAST:
4825 flag_str = "Last";
4826 break;
4827 case MP_FRAG_FIRST|MP_FRAG_LAST:
4828 flag_str = "First, Last";
4829 break;
4830 default:
4831 flag_str = "Unknown";
4832 break;
4834 ti = proto_tree_add_text(mp_tree, tvb, 0, 1, "Fragment: 0x%2X (%s)",
4835 MP_FRAG(flags), flag_str);
4836 hdr_tree = proto_item_add_subtree(ti, ett_mp_flags);
4838 proto_tree_add_boolean(hdr_tree, hf_mp_frag_first, tvb, 0, 1, flags);
4839 proto_tree_add_boolean(hdr_tree, hf_mp_frag_last, tvb, 0, 1, flags);
4840 if (mp_short_seqno) {
4841 proto_tree_add_item(hdr_tree, hf_mp_short_sequence_num_reserved, tvb, 0, 1,
4842 ENC_BIG_ENDIAN);
4843 proto_tree_add_item(mp_tree, hf_mp_short_sequence_num, tvb, 0, 2,
4844 ENC_BIG_ENDIAN);
4845 } else {
4846 proto_tree_add_item(hdr_tree, hf_mp_sequence_num_reserved, tvb, 0, 1,
4847 ENC_BIG_ENDIAN);
4848 proto_tree_add_item(mp_tree, hf_mp_sequence_num, tvb, 1, 3,
4849 ENC_BIG_ENDIAN);
4853 hdrlen = mp_short_seqno ? 2 : 4;
4854 if (tvb_reported_length_remaining(tvb, hdrlen) > 0) {
4855 next_tvb = tvb_new_subset_remaining(tvb, hdrlen);
4856 dissect_ppp(next_tvb, pinfo, tree);
4861 * Handles PPP without HDLC framing, just a protocol field (RFC 1661).
4863 static void
4864 dissect_ppp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4866 proto_item *ti = NULL;
4867 proto_tree *fh_tree = NULL;
4869 if (tree) {
4870 ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, -1, ENC_NA);
4871 fh_tree = proto_item_add_subtree(ti, ett_ppp);
4874 dissect_ppp_common(tvb, pinfo, tree, fh_tree, ti, 0);
4877 static void
4878 dissect_ppp_hdlc_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4880 proto_item *ti = NULL;
4881 proto_tree *fh_tree = NULL;
4882 guint8 byte0;
4883 int proto_offset;
4884 tvbuff_t *next_tvb;
4886 byte0 = tvb_get_guint8(tvb, 0);
4888 /* PPP HDLC encapsulation */
4889 if (byte0 == 0xff)
4890 proto_offset = 2;
4891 else {
4892 /* address and control are compressed (NULL) */
4893 proto_offset = 0;
4896 /* load the top pane info. This should be overwritten by
4897 the next protocol in the stack */
4898 if (tree) {
4899 ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, -1, ENC_NA);
4900 fh_tree = proto_item_add_subtree(ti, ett_ppp);
4901 if (byte0 == 0xff) {
4902 proto_tree_add_item(fh_tree, hf_ppp_address, tvb, 0, 1,
4903 ENC_BIG_ENDIAN);
4904 proto_tree_add_item(fh_tree, hf_ppp_control, tvb, 1, 1,
4905 ENC_BIG_ENDIAN);
4909 next_tvb = decode_fcs(tvb, fh_tree, ppp_fcs_decode, proto_offset);
4910 dissect_ppp_common(next_tvb, pinfo, tree, fh_tree, ti, proto_offset);
4914 * Handles link-layer encapsulations where the frame might be
4915 * a PPP in HDLC-like Framing frame (RFC 1662) or a Cisco HDLC frame.
4917 static void
4918 dissect_ppp_hdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4920 guint8 byte0;
4922 byte0 = tvb_get_guint8(tvb, 0);
4923 if (byte0 == CHDLC_ADDR_UNICAST || byte0 == CHDLC_ADDR_MULTICAST) {
4924 /* Cisco HDLC encapsulation */
4925 call_dissector(chdlc_handle, tvb, pinfo, tree);
4926 return;
4930 * XXX - should we have an exported dissector that always dissects PPP,
4931 * for use when we know the packets are PPP, not CHDLC?
4933 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP");
4934 switch (pinfo->p2p_dir) {
4936 case P2P_DIR_SENT:
4937 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
4938 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
4939 break;
4941 case P2P_DIR_RECV:
4942 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
4943 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
4944 break;
4946 default:
4947 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "N/A");
4948 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A");
4949 break;
4952 dissect_ppp_hdlc_common(tvb, pinfo, tree);
4955 static tvbuff_t*
4956 remove_escape_chars(tvbuff_t *tvb, packet_info *pinfo, int offset, int length)
4958 guint8 *buff;
4959 int i;
4960 int scanned_len = 0;
4961 guint8 octet;
4962 tvbuff_t *next_tvb;
4964 buff = (guint8 *)wmem_alloc(pinfo->pool, length);
4965 i = 0;
4966 while (scanned_len < length) {
4967 octet = tvb_get_guint8(tvb, offset);
4968 if (octet == 0x7d) {
4969 offset++;
4970 scanned_len++;
4971 if (scanned_len >= length)
4972 break;
4973 octet = tvb_get_guint8(tvb, offset);
4974 buff[i] = octet ^ 0x20;
4975 } else {
4976 buff[i] = octet;
4978 offset++;
4979 scanned_len++;
4980 i++;
4982 if (i == 0) {
4983 return NULL;
4985 next_tvb = tvb_new_child_real_data(tvb, buff, i, i);
4987 return next_tvb;
4991 * Handles link-layer encapsulations where we have a raw RFC 1662
4992 * HDLC-like asynchronous framing byte stream, and have to
4993 * break the byte stream into frames and remove escapes.
4995 static void
4996 dissect_ppp_raw_hdlc( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
4998 proto_item *ti;
4999 proto_tree *bs_tree = NULL;
5000 gint offset, end_offset, data_offset;
5001 int length, data_length;
5002 tvbuff_t *ppp_tvb;
5003 gboolean first = TRUE;
5005 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP");
5007 if (tree) {
5008 ti = proto_tree_add_item(tree, proto_ppp_hdlc, tvb, 0, -1, ENC_NA);
5009 bs_tree = proto_item_add_subtree(ti, ett_ppp_hdlc_data);
5013 * XXX - this needs to handle a PPP frame split over multiple higher-level
5014 * packets.
5018 * Look for a frame delimiter.
5020 offset = tvb_find_guint8(tvb, 0, -1, 0x7e);
5021 if (offset == -1) {
5023 * None found - this is presumably continued from an earlier
5024 * packet and continued in a later packet.
5026 col_set_str(pinfo->cinfo, COL_INFO, "PPP Fragment");
5027 if (tree)
5028 proto_tree_add_text(bs_tree, tvb, offset, -1, "PPP Fragment");
5029 offset++;
5030 length = tvb_length_remaining(tvb,offset);
5031 ppp_tvb = remove_escape_chars(tvb, pinfo, offset,length);
5032 if (ppp_tvb != NULL) {
5033 add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
5034 call_dissector(data_handle, ppp_tvb, pinfo, tree);
5036 return;
5038 if (offset != 0) {
5040 * We have some data preceding the first PPP packet;
5041 * mark it as a PPP fragment.
5043 col_set_str(pinfo->cinfo, COL_INFO, "PPP Fragment");
5044 length = offset;
5045 if (tree)
5046 proto_tree_add_text(bs_tree, tvb, 0, length, "PPP Fragment");
5047 if (length != 0) {
5048 ppp_tvb = remove_escape_chars(tvb, pinfo, 0, length - 1);
5049 if (ppp_tvb != NULL) {
5050 add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
5051 call_dissector(data_handle, ppp_tvb, pinfo, tree);
5055 while (tvb_reported_length_remaining(tvb, offset) > 0) {
5057 * Look for the next frame delimiter.
5059 end_offset = tvb_find_guint8(tvb, offset + 1, -1, 0x7e);
5060 if (end_offset == -1) {
5062 * We didn't find one. This is probably continued in a later
5063 * packet.
5065 if (first)
5066 col_set_str(pinfo->cinfo, COL_INFO, "PPP Fragment");
5067 if (tree)
5068 proto_tree_add_text(bs_tree, tvb, offset, -1, "PPP Fragment");
5069 offset++;
5070 length = tvb_length_remaining(tvb, offset);
5071 ppp_tvb = remove_escape_chars(tvb, pinfo, offset, length);
5072 if (ppp_tvb != NULL) {
5073 add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
5074 call_dissector(data_handle, ppp_tvb, pinfo, tree);
5076 return;
5079 data_offset = offset + 1; /* skip starting frame delimiter */
5080 data_length = end_offset - data_offset;
5083 * Is that frame delimiter immediately followed by another one?
5084 * Some PPP implementations put a frame delimiter at the
5085 * beginning and the end of each frame, although RFC 1662
5086 * appears only to require that there be one frame delimiter
5087 * between adjacent frames:
5089 * Each frame begins and ends with a Flag Sequence, which is the
5090 * binary sequence 01111110 (hexadecimal 0x7e). All implementations
5091 * continuously check for this flag, which is used for frame
5092 * synchronization.
5094 * Only one Flag Sequence is required between two frames. Two
5095 * consecutive Flag Sequences constitute an empty frame, which is
5096 * silently discarded, and not counted as a FCS error.
5098 * If the delimiter at the end of this frame is followed by
5099 * another delimiter, we consider the first delimiter part
5100 * of this frame.
5102 if (tvb_offset_exists(tvb, end_offset + 1) &&
5103 tvb_get_guint8(tvb, end_offset+1) == 0x7e) {
5104 end_offset++;
5106 length = end_offset - offset;
5107 if (tree)
5108 proto_tree_add_text(bs_tree, tvb, offset, length, "PPP Data");
5109 if (length > 1) {
5110 ppp_tvb = remove_escape_chars(tvb, pinfo, data_offset, data_length);
5111 if (ppp_tvb != NULL) {
5112 add_new_data_source(pinfo, ppp_tvb, "PPP Message");
5113 dissect_ppp_hdlc_common(ppp_tvb, pinfo, tree);
5114 first = FALSE;
5117 offset = end_offset;
5122 * At least for the PPP/USB captures I've seen, the data either starts with
5123 * 0x7eff03 or 0x7eff7d23 or 0xff03, so this function performs that heuristic
5124 * matching first before calling dissect_ppp_raw_hdlc(). Otherwise, if we call
5125 * it directly for USB captures, some captures like the following will not be
5126 * dissected correctly:
5127 * http://wiki.wireshark.org/SampleCaptures#head-886e340c31ca977f321c921f81cbec4c21bb7738
5129 * NOTE: I don't know if these heuristics are sufficient. Time will tell ...
5131 static gboolean
5132 dissect_ppp_usb( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ )
5135 * In some cases, the 0x03 normally in byte 3 is escaped so we must look
5136 * for the 2 byte sequence of 0x7d23 instead of 0x03. The 0x23 is
5137 * generated by 0x20^0x03 per section 4.2 of:
5138 * http://tools.ietf.org/html/rfc1662.html.
5140 const guchar buf1[3] = {0x7e, 0xff, 0x03};
5141 const guchar buf2[4] = {0x7e, 0xff, 0x7d, 0x23};
5142 tvbuff_t *next_tvb;
5144 if ((tvb_memeql(tvb, 0, buf2, sizeof(buf2)) == 0) ||
5145 (tvb_memeql(tvb, 0, buf1, sizeof(buf1)) == 0)) {
5146 dissect_ppp_raw_hdlc(tvb, pinfo, tree);
5147 } else if ((tvb_memeql(tvb, 0, &buf1[1], sizeof(buf1) - 1) == 0) ||
5148 (tvb_memeql(tvb, 0, &buf2[1], sizeof(buf2) - 1) == 0)) {
5149 /* It's missing the 0x7e framing character. What TODO?
5150 * Should we try faking it by sticking 0x7e in front? Or try telling
5151 * dissect_ppp_raw_hdlc() NOT to look for the 0x7e frame deliminator?
5152 * Or is this a bug in libpcap (used 1.1.0)?
5153 * Or a bug in the Linux kernel (tested with 2.6.24.4) Or a bug in
5154 * usbmon? Or is the data we're looking at really just part of the
5155 * payload and not control data? Well, at least in my case it's
5156 * definitely not, but not sure if this is always the case. Is this
5157 * issue applicable only to PPP/USB or PPP/XYZ, in which case a more
5158 * general solution should be found?
5160 /* For now, just try skipping the framing I guess??? */
5161 if (tvb_get_guint8(tvb, 1) == 0x03)
5162 next_tvb = tvb_new_subset_remaining(tvb, 2);
5163 else
5164 next_tvb = tvb_new_subset_remaining(tvb, 3);
5165 dissect_ppp(next_tvb, pinfo, tree);
5166 } else if (tvb_get_guint8(tvb, 0) == 0x7e) {
5167 /* Well, let's guess that since the 1st byte is 0x7e that it really is
5168 * a PPP frame, and the address and control bytes are compressed (NULL)
5169 * per http://tools.ietf.org/html/rfc1662, section 3.2. */
5170 next_tvb = tvb_new_subset_remaining(tvb, 1);
5171 dissect_ppp_hdlc_common(next_tvb, pinfo, tree);
5172 } else
5173 return (FALSE);
5174 return (TRUE);
5177 void
5178 proto_register_ppp_raw_hdlc(void)
5180 static gint *ett[] = {
5181 &ett_ppp_hdlc_data
5184 proto_ppp_hdlc = proto_register_protocol("PPP In HDLC-Like Framing",
5185 "PPP-HDLC", "ppp_hdlc");
5186 proto_register_subtree_array(ett, array_length(ett));
5189 void
5190 proto_reg_handoff_ppp_raw_hdlc(void)
5192 dissector_handle_t ppp_raw_hdlc_handle;
5194 ppp_raw_hdlc_handle = create_dissector_handle(dissect_ppp_raw_hdlc,
5195 proto_ppp);
5196 dissector_add_uint("gre.proto", ETHERTYPE_CDMA2000_A10_UBS,
5197 ppp_raw_hdlc_handle);
5198 dissector_add_uint("gre.proto", ETHERTYPE_3GPP2, ppp_raw_hdlc_handle);
5200 heur_dissector_add("usb.bulk", dissect_ppp_usb, proto_ppp);
5204 * Handles PAP just as a protocol field
5206 static void
5207 dissect_pap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5209 proto_item *ti, *data_ti;
5210 proto_tree *fh_tree, *data_tree = NULL;
5211 guint8 code;
5212 gchar *peer_id, *password, *message;
5213 guint8 peer_id_length, password_length, message_length;
5214 int offset = 0;
5216 code = tvb_get_guint8(tvb, 0);
5218 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP PAP");
5219 col_set_str(pinfo->cinfo, COL_INFO,
5220 val_to_str_const(code, pap_vals, "Unknown"));
5222 ti = proto_tree_add_item(tree, proto_pap, tvb, 0, -1, ENC_NA);
5223 fh_tree = proto_item_add_subtree(ti, ett_pap);
5225 proto_tree_add_item(fh_tree, hf_pap_code, tvb, offset, 1,
5226 ENC_BIG_ENDIAN);
5227 offset++;
5229 proto_tree_add_item(fh_tree, hf_pap_identifier, tvb, offset, 1,
5230 ENC_BIG_ENDIAN);
5231 offset++;
5233 proto_tree_add_item(fh_tree, hf_pap_length, tvb, offset, 2,
5234 ENC_BIG_ENDIAN);
5235 offset += 2;
5237 data_ti = proto_tree_add_item(fh_tree, hf_pap_data, tvb, offset, -1,
5238 ENC_NA);
5239 data_tree = proto_item_add_subtree(data_ti, ett_pap_data);
5241 switch (code) {
5242 case CONFREQ:
5243 proto_tree_add_item(data_tree, hf_pap_peer_id_length, tvb, offset,
5244 1, ENC_BIG_ENDIAN);
5245 peer_id_length = tvb_get_guint8(tvb, offset);
5246 offset++;
5248 proto_tree_add_item(data_tree, hf_pap_peer_id, tvb, offset,
5249 peer_id_length, ENC_ASCII|ENC_NA);
5250 peer_id = tvb_format_text(tvb, offset, peer_id_length);
5251 offset += peer_id_length;
5253 proto_tree_add_item(data_tree, hf_pap_password_length, tvb, offset,
5254 1, ENC_BIG_ENDIAN);
5255 password_length = tvb_get_guint8(tvb, offset);
5256 offset++;
5258 proto_tree_add_item(data_tree, hf_pap_password, tvb, offset,
5259 password_length, ENC_ASCII|ENC_NA);
5260 password = tvb_format_text(tvb, offset, password_length);
5262 col_append_fstr(pinfo->cinfo, COL_INFO,
5263 " (Peer-ID='%s', Password='%s')", peer_id, password);
5264 break;
5266 case CONFACK:
5267 case CONFNAK:
5268 proto_tree_add_item(data_tree, hf_pap_message_length, tvb, offset,
5269 1, ENC_BIG_ENDIAN);
5270 message_length = tvb_get_guint8(tvb, offset);
5271 offset +=1;
5273 proto_tree_add_item(data_tree, hf_pap_message, tvb, offset,
5274 message_length, ENC_ASCII|ENC_NA);
5275 message = tvb_format_text(tvb, offset, message_length);
5277 col_append_fstr(pinfo->cinfo, COL_INFO, " (Message='%s')",
5278 message);
5279 break;
5281 default:
5282 proto_tree_add_item(data_tree, hf_pap_stuff, tvb, offset, -1,
5283 ENC_NA);
5284 break;
5289 * RFC 1994
5290 * Handles CHAP just as a protocol field
5292 static void
5293 dissect_chap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5295 proto_item *ti = NULL;
5296 proto_tree *fh_tree = NULL;
5297 proto_item *tf;
5298 proto_tree *field_tree;
5299 guint8 code, value_size;
5300 guint32 length;
5301 int offset;
5303 code = tvb_get_guint8(tvb, 0);
5304 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP CHAP");
5305 col_set_str(pinfo->cinfo, COL_INFO,
5306 val_to_str_const(code, chap_vals, "Unknown"));
5308 if (tree) {
5309 /* Create CHAP protocol tree */
5310 ti = proto_tree_add_item(tree, proto_chap, tvb, 0, -1, ENC_NA);
5311 fh_tree = proto_item_add_subtree(ti, ett_chap);
5313 proto_tree_add_item(fh_tree, hf_chap_code, tvb, 0, 1, ENC_BIG_ENDIAN);
5314 proto_tree_add_item(fh_tree, hf_chap_identifier, tvb, 1, 1,
5315 ENC_BIG_ENDIAN);
5318 /* Length - make sure it's valid */
5319 length = tvb_get_ntohs(tvb, 2);
5320 if (length < 4) {
5321 proto_tree_add_uint_format_value(fh_tree, hf_chap_length, tvb, 2, 2,
5322 length, "%u (invalid, must be >= 4)", length);
5323 return;
5325 proto_item_set_len(ti, length);
5326 if (tree) {
5327 proto_tree_add_item(fh_tree, hf_chap_length, tvb, 2, 2,
5328 ENC_BIG_ENDIAN);
5331 offset = 4; /* Offset moved to after length field */
5332 length -= 4; /* Length includes previous 4 bytes, subtract */
5334 switch (code) {
5335 /* Challenge or Response data */
5336 case CHAP_CHAL:
5337 case CHAP_RESP:
5338 if (length > 0) {
5339 guint value_offset = 0;
5340 guint name_offset = 0, name_size = 0;
5342 /* Create data subtree */
5343 tf = proto_tree_add_item(fh_tree, hf_chap_data, tvb, offset,
5344 length, ENC_NA);
5345 field_tree = proto_item_add_subtree(tf, ett_chap_data);
5346 length--;
5348 /* Value size */
5349 value_size = tvb_get_guint8(tvb, offset);
5350 if (value_size > length) {
5351 proto_tree_add_text(field_tree, tvb, offset, 1,
5352 "Value Size: %d byte%s (invalid, must be <= %u)",
5353 value_size, plurality(value_size, "", "s"), length);
5354 return;
5356 proto_tree_add_item(field_tree, hf_chap_value_size, tvb,
5357 offset, 1, ENC_BIG_ENDIAN);
5358 offset++;
5360 /* Value */
5361 if (length > 0) {
5362 value_offset = offset;
5363 proto_tree_add_item(field_tree, hf_chap_value, tvb, offset,
5364 value_size, ENC_NA);
5366 /* Move along value_size bytes */
5367 offset += value_size;
5368 length -= value_size;
5370 /* Find name in remaining bytes */
5371 if (length > 0) {
5372 tvb_ensure_bytes_exist(tvb, offset, length);
5373 proto_tree_add_item(field_tree, hf_chap_name, tvb,
5374 offset, length, ENC_ASCII|ENC_NA);
5375 name_offset = offset;
5376 name_size = length;
5379 /* Show name and value in info column */
5380 col_append_fstr(pinfo->cinfo, COL_INFO,
5381 " (NAME='%s%s', VALUE=0x%s)",
5382 tvb_format_text(tvb, name_offset,
5383 (name_size > 20) ? 20 : name_size),
5384 (name_size > 20) ? "..." : "",
5385 tvb_bytes_to_str(tvb, value_offset, value_size));
5388 break;
5390 /* Success or Failure data */
5391 case CHAP_SUCC:
5392 case CHAP_FAIL:
5393 if (tree) {
5394 if (length > 0) {
5395 proto_tree_add_item(fh_tree, hf_chap_message, tvb, offset,
5396 length, ENC_ASCII|ENC_NA);
5400 /* Show message in info column */
5401 col_append_fstr(pinfo->cinfo, COL_INFO, " (MESSAGE='%s')",
5402 tvb_format_text(tvb, offset, length));
5403 break;
5405 /* Code from unknown code type... */
5406 default:
5407 if (length > 0)
5408 proto_tree_add_text(fh_tree, tvb, offset, length,
5409 "Stuff (%u byte%s)", length, plurality(length, "", "s"));
5410 break;
5415 * RFC 2472.
5417 static void
5418 dissect_ipv6cp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5420 dissect_cp(tvb, proto_ipv6cp, ett_ipv6cp, cp_vals, ett_ipv6cp_options,
5421 ipv6cp_opts, N_IPV6CP_OPTS, pinfo, tree);
5424 static void
5425 dissect_ipv6cp_if_id_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
5426 guint length, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
5428 proto_tree_add_text(tree, tvb, offset, length,
5429 "%s: %02x%02x:%02x%02x:%02x%x:%02x%02x", optp->name,
5430 tvb_get_guint8(tvb, offset + 2), tvb_get_guint8(tvb, offset + 3),
5431 tvb_get_guint8(tvb, offset + 4), tvb_get_guint8(tvb, offset + 5),
5432 tvb_get_guint8(tvb, offset + 6), tvb_get_guint8(tvb, offset + 7),
5433 tvb_get_guint8(tvb, offset + 8), tvb_get_guint8(tvb, offset + 9));
5436 void
5437 proto_register_ppp(void)
5439 static hf_register_info hf[] = {
5440 { &hf_ppp_direction,
5441 { "Direction", "ppp.direction", FT_UINT8, BASE_DEC,
5442 VALS(ppp_direction_vals), 0x0, "PPP direction", HFILL }},
5443 { &hf_ppp_address,
5444 { "Address", "ppp.address", FT_UINT8, BASE_HEX,
5445 NULL, 0x0, NULL, HFILL }},
5446 { &hf_ppp_control,
5447 { "Control", "ppp.control", FT_UINT8, BASE_HEX,
5448 NULL, 0x0, NULL, HFILL }},
5449 { &hf_ppp_protocol,
5450 { "Protocol", "ppp.protocol", FT_UINT16, BASE_HEX|BASE_EXT_STRING,
5451 &ppp_vals_ext, 0x0, NULL, HFILL }},
5452 { &hf_ppp_code,
5453 { "Code", "ppp.code", FT_UINT8, BASE_DEC,
5454 NULL, 0x0, NULL, HFILL }},
5455 { &hf_ppp_identifier,
5456 { "Identifier", "ppp.identifier", FT_UINT8, BASE_DEC_HEX,
5457 NULL, 0x0, NULL, HFILL }},
5458 { &hf_ppp_length,
5459 { "Length", "ppp.length", FT_UINT16, BASE_DEC,
5460 NULL, 0x0, NULL, HFILL }},
5461 { &hf_ppp_magic_number,
5462 { "Magic Number", "ppp.magic_number", FT_UINT32, BASE_HEX,
5463 NULL, 0x0, NULL, HFILL }},
5464 { &hf_ppp_oui,
5465 { "OUI", "ppp.oui", FT_UINT24, BASE_HEX,
5466 VALS(oui_vals), 0x0, NULL, HFILL }},
5467 { &hf_ppp_kind,
5468 { "Kind", "ppp.kind", FT_UINT8, BASE_DEC_HEX,
5469 NULL, 0x0, NULL, HFILL }},
5470 { &hf_ppp_data,
5471 { "Data", "ppp.data", FT_BYTES, BASE_NONE,
5472 NULL, 0x0, NULL, HFILL }},
5473 { &hf_ppp_opt_type,
5474 { "Type", "ppp.opt.type", FT_UINT8, BASE_DEC,
5475 NULL, 0x0, NULL, HFILL}},
5476 { &hf_ppp_opt_type_copy,
5477 { "Copy on fragmentation", "ppp.opt.type.copy", FT_BOOLEAN, 8,
5478 TFS(&tfs_yes_no), IPOPT_COPY_MASK, NULL, HFILL}},
5479 { &hf_ppp_opt_type_class,
5480 { "Class", "ppp.opt.type.class", FT_UINT8, BASE_DEC,
5481 VALS(ipopt_type_class_vals), IPOPT_CLASS_MASK, NULL, HFILL}},
5482 { &hf_ppp_opt_type_number,
5483 { "Number", "ppp.opt.type.number", FT_UINT8, BASE_DEC,
5484 VALS(ipopt_type_number_vals), IPOPT_NUMBER_MASK, NULL, HFILL}},
5486 static gint *ett[] = {
5487 &ett_ppp,
5488 &ett_ppp_opt_type
5490 static ei_register_info ei[] = {
5491 { &ei_ppp_opt_len_invalid, { "ppp.opt.len.invalid", PI_PROTOCOL, PI_WARN, "Invalid length for option", EXPFILL }},
5494 module_t *ppp_module;
5495 expert_module_t* expert_ppp;
5497 proto_ppp = proto_register_protocol("Point-to-Point Protocol", "PPP",
5498 "ppp");
5499 proto_register_field_array(proto_ppp, hf, array_length(hf));
5500 proto_register_subtree_array(ett, array_length(ett));
5501 expert_ppp = expert_register_protocol(proto_ppp);
5502 expert_register_field_array(expert_ppp, ei, array_length(ei));
5504 /* subdissector code */
5505 ppp_subdissector_table = register_dissector_table("ppp.protocol",
5506 "PPP protocol", FT_UINT16, BASE_HEX);
5508 register_dissector("ppp_hdlc", dissect_ppp_hdlc, proto_ppp);
5509 register_dissector("ppp_lcp_options", dissect_lcp_options, proto_ppp);
5510 register_dissector("ppp", dissect_ppp, proto_ppp);
5512 /* Register the preferences for the ppp protocol */
5513 ppp_module = prefs_register_protocol(proto_ppp, NULL);
5515 prefs_register_enum_preference(ppp_module, "fcs_type",
5516 "PPP Frame Checksum Type",
5517 "The type of PPP frame checksum (none, 16-bit, 32-bit)",
5518 &ppp_fcs_decode, fcs_options, FALSE);
5519 prefs_register_bool_preference(ppp_module, "decompress_vj",
5520 "Decompress Van Jacobson-compressed frames",
5521 "Whether Van Jacobson-compressed PPP frames should be decompressed",
5522 &ppp_vj_decomp);
5523 prefs_register_uint_preference(ppp_module, "default_proto_id",
5524 "PPPMuxCP Default PID (in hex)",
5525 "Default Protocol ID to be used for PPPMuxCP",
5526 16, &pppmux_def_prot_id);
5529 void
5530 proto_reg_handoff_ppp(void)
5532 dissector_handle_t ppp_hdlc_handle, ppp_handle;
5535 * Get a handle for the CHDLC dissector.
5537 chdlc_handle = find_dissector("chdlc");
5538 data_handle = find_dissector("data");
5540 ppp_handle = find_dissector("ppp");
5541 dissector_add_uint("fr.nlpid", NLPID_PPP, ppp_handle);
5543 ppp_hdlc_handle = find_dissector("ppp_hdlc");
5544 dissector_add_uint("wtap_encap", WTAP_ENCAP_PPP, ppp_hdlc_handle);
5545 dissector_add_uint("wtap_encap", WTAP_ENCAP_PPP_WITH_PHDR,
5546 ppp_hdlc_handle);
5547 dissector_add_uint("sll.ltype", LINUX_SLL_P_PPPHDLC, ppp_hdlc_handle);
5548 dissector_add_uint("osinl.excl", NLPID_PPP, ppp_handle);
5549 dissector_add_uint("gre.proto", ETHERTYPE_PPP, ppp_hdlc_handle);
5552 void
5553 proto_register_mp(void)
5555 static hf_register_info hf[] = {
5556 { &hf_mp_frag_first,
5557 { "First fragment", "mp.first", FT_BOOLEAN, 8,
5558 TFS(&tfs_yes_no), MP_FRAG_FIRST, NULL, HFILL }},
5559 { &hf_mp_frag_last,
5560 { "Last fragment", "mp.last", FT_BOOLEAN, 8,
5561 TFS(&tfs_yes_no), MP_FRAG_LAST, NULL, HFILL }},
5562 { &hf_mp_sequence_num,
5563 { "Sequence number", "mp.seq", FT_UINT24, BASE_DEC,
5564 NULL, 0x0, NULL, HFILL }},
5565 { &hf_mp_sequence_num_reserved,
5566 { "Reserved", "mp.sequence_num_reserved", FT_BOOLEAN, 8,
5567 NULL, MP_FRAG_RESERVED, NULL, HFILL }},
5568 { &hf_mp_short_sequence_num,
5569 { "Short Sequence number", "mp.sseq", FT_UINT16, BASE_DEC,
5570 NULL, 0x0FFF, NULL, HFILL }},
5571 { &hf_mp_short_sequence_num_reserved,
5572 { "Reserved", "mp.short_sequence_num_reserved", FT_BOOLEAN, 8,
5573 NULL, MP_FRAG_RESERVED_SHORT, NULL, HFILL }},
5575 static gint *ett[] = {
5576 &ett_mp,
5577 &ett_mp_flags
5580 module_t *mp_module;
5582 proto_mp = proto_register_protocol("PPP Multilink Protocol", "PPP MP",
5583 "mp");
5584 proto_register_field_array(proto_mp, hf, array_length(hf));
5585 proto_register_subtree_array(ett, array_length(ett));
5587 /* Register the preferences for the PPP multilink protocol */
5588 mp_module = prefs_register_protocol(proto_mp, NULL);
5590 prefs_register_bool_preference(mp_module, "short_seqno",
5591 "Short sequence numbers",
5592 "Whether PPP Multilink frames use 12-bit sequence numbers",
5593 &mp_short_seqno);
5596 void
5597 proto_reg_handoff_mp(void)
5599 dissector_handle_t mp_handle;
5601 mp_handle = create_dissector_handle(dissect_mp, proto_mp);
5602 dissector_add_uint("ppp.protocol", PPP_MP, mp_handle);
5605 void
5606 proto_register_lcp(void)
5608 static hf_register_info hf[] = {
5609 { &hf_lcp_magic_number,
5610 { "Magic Number", "lcp.magic_number", FT_UINT32, BASE_HEX,
5611 NULL, 0x0, NULL, HFILL }},
5612 { &hf_lcp_data,
5613 { "Data", "lcp.data", FT_BYTES, BASE_NONE,
5614 NULL, 0x0, NULL, HFILL }},
5615 { &hf_lcp_message,
5616 { "Message", "lcp.message", FT_STRING, BASE_NONE,
5617 NULL, 0x0, NULL, HFILL }},
5618 { &hf_lcp_secs_remaining,
5619 { "Seconds Remaining", "lcp.secs_remaining", FT_UINT32, BASE_DEC,
5620 NULL, 0x0, NULL, HFILL }},
5621 { &hf_lcp_rej_proto,
5622 { "Rejected Protocol", "lcp.rej_proto", FT_UINT16,
5623 BASE_HEX | BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
5624 { &hf_lcp_opt_type,
5625 { "Type", "lcp.opt.type", FT_UINT8, BASE_DEC,
5626 NULL, 0x0, NULL, HFILL }},
5627 { &hf_lcp_opt_length,
5628 { "Length", "lcp.opt.length", FT_UINT8, BASE_DEC,
5629 NULL, 0x0, NULL, HFILL }},
5630 { &hf_lcp_opt_oui,
5631 { "OUI", "lcp.opt.oui", FT_UINT24, BASE_HEX,
5632 NULL, 0x0, NULL, HFILL }},
5633 { &hf_lcp_opt_kind,
5634 { "Kind", "lcp.opt.kind", FT_UINT8, BASE_DEC_HEX,
5635 NULL, 0x0, NULL, HFILL }},
5636 { &hf_lcp_opt_data,
5637 { "Data", "lcp.opt.data", FT_BYTES, BASE_NONE,
5638 NULL, 0x0, NULL, HFILL }},
5639 { &hf_lcp_opt_mru,
5640 { "Maximum Receive Unit", "lcp.opt.mru", FT_UINT16, BASE_DEC,
5641 NULL, 0x0, NULL, HFILL }},
5642 { &hf_lcp_opt_asyncmap,
5643 { "Async Control Character Map", "lcp.opt.asyncmap", FT_UINT32,
5644 BASE_HEX, NULL, 0x0, NULL, HFILL }},
5645 { &hf_lcp_opt_asyncmap_nul,
5646 { "NUL", "lcp.opt.asyncmap.nul", FT_BOOLEAN, 32,
5647 NULL, 0x00000001, NULL, HFILL }},
5648 { &hf_lcp_opt_asyncmap_soh,
5649 { "SOH", "lcp.opt.asyncmap.soh", FT_BOOLEAN, 32,
5650 NULL, 0x00000002, NULL, HFILL }},
5651 { &hf_lcp_opt_asyncmap_stx,
5652 { "STX", "lcp.opt.asyncmap.stx", FT_BOOLEAN, 32,
5653 NULL, 0x00000004, NULL, HFILL }},
5654 { &hf_lcp_opt_asyncmap_etx,
5655 { "ETX", "lcp.opt.asyncmap.etx", FT_BOOLEAN, 32,
5656 NULL, 0x00000008, NULL, HFILL }},
5657 { &hf_lcp_opt_asyncmap_eot,
5658 { "EOT", "lcp.opt.asyncmap.eot", FT_BOOLEAN, 32,
5659 NULL, 0x00000010, NULL, HFILL }},
5660 { &hf_lcp_opt_asyncmap_enq,
5661 { "ENQ", "lcp.opt.asyncmap.enq", FT_BOOLEAN, 32,
5662 NULL, 0x00000020, NULL, HFILL }},
5663 { &hf_lcp_opt_asyncmap_ack,
5664 { "ACK", "lcp.opt.asyncmap.ack", FT_BOOLEAN, 32,
5665 NULL, 0x00000040, NULL, HFILL }},
5666 { &hf_lcp_opt_asyncmap_bel,
5667 { "BEL", "lcp.opt.asyncmap.bel", FT_BOOLEAN, 32,
5668 NULL, 0x00000080, NULL, HFILL }},
5669 { &hf_lcp_opt_asyncmap_bs,
5670 { "BS", "lcp.opt.asyncmap.bs", FT_BOOLEAN, 32,
5671 NULL, 0x00000100, NULL, HFILL }},
5672 { &hf_lcp_opt_asyncmap_ht,
5673 { "HT", "lcp.opt.asyncmap.ht", FT_BOOLEAN, 32,
5674 NULL, 0x00000200, NULL, HFILL }},
5675 { &hf_lcp_opt_asyncmap_lf,
5676 { "LF", "lcp.opt.asyncmap.lf", FT_BOOLEAN, 32,
5677 NULL, 0x00000400, NULL, HFILL }},
5678 { &hf_lcp_opt_asyncmap_vt,
5679 { "VT", "lcp.opt.asyncmap.vt", FT_BOOLEAN, 32,
5680 NULL, 0x00000800, NULL, HFILL }},
5681 { &hf_lcp_opt_asyncmap_ff,
5682 { "FF", "lcp.opt.asyncmap.ff", FT_BOOLEAN, 32,
5683 NULL, 0x00001000, NULL, HFILL }},
5684 { &hf_lcp_opt_asyncmap_cr,
5685 { "CR", "lcp.opt.asyncmap.cr", FT_BOOLEAN, 32,
5686 NULL, 0x00002000, NULL, HFILL }},
5687 { &hf_lcp_opt_asyncmap_so,
5688 { "SO", "lcp.opt.asyncmap.so", FT_BOOLEAN, 32,
5689 NULL, 0x00004000, NULL, HFILL }},
5690 { &hf_lcp_opt_asyncmap_si,
5691 { "SI", "lcp.opt.asyncmap.si", FT_BOOLEAN, 32,
5692 NULL, 0x00008000, NULL, HFILL }},
5693 { &hf_lcp_opt_asyncmap_dle,
5694 { "DLE", "lcp.opt.asyncmap.dle", FT_BOOLEAN, 32,
5695 NULL, 0x00010000, NULL, HFILL }},
5696 { &hf_lcp_opt_asyncmap_dc1,
5697 { "DC1 (XON)", "lcp.opt.asyncmap.dc1", FT_BOOLEAN, 32,
5698 NULL, 0x00020000, NULL, HFILL }},
5699 { &hf_lcp_opt_asyncmap_dc2,
5700 { "DC2", "lcp.opt.asyncmap.dc2", FT_BOOLEAN, 32,
5701 NULL, 0x00040000, NULL, HFILL }},
5702 { &hf_lcp_opt_asyncmap_dc3,
5703 { "DC3 (XOFF)", "lcp.opt.asyncmap.dc3", FT_BOOLEAN, 32,
5704 NULL, 0x00080000, NULL, HFILL }},
5705 { &hf_lcp_opt_asyncmap_dc4,
5706 { "DC4", "lcp.opt.asyncmap.dc4", FT_BOOLEAN, 32,
5707 NULL, 0x00100000, NULL, HFILL }},
5708 { &hf_lcp_opt_asyncmap_nak,
5709 { "NAK", "lcp.opt.asyncmap.nak", FT_BOOLEAN, 32,
5710 NULL, 0x00200000, NULL, HFILL }},
5711 { &hf_lcp_opt_asyncmap_syn,
5712 { "SYN", "lcp.opt.asyncmap.syn", FT_BOOLEAN, 32,
5713 NULL, 0x00400000, NULL, HFILL }},
5714 { &hf_lcp_opt_asyncmap_etb,
5715 { "ETB", "lcp.opt.asyncmap.etb", FT_BOOLEAN, 32,
5716 NULL, 0x00800000, NULL, HFILL }},
5717 { &hf_lcp_opt_asyncmap_can,
5718 { "CAN", "lcp.opt.asyncmap.can", FT_BOOLEAN, 32,
5719 NULL, 0x01000000, NULL, HFILL }},
5720 { &hf_lcp_opt_asyncmap_em,
5721 { "EM", "lcp.opt.asyncmap.em", FT_BOOLEAN, 32,
5722 NULL, 0x02000000, NULL, HFILL }},
5723 { &hf_lcp_opt_asyncmap_sub,
5724 { "SUB", "lcp.opt.asyncmap.sub", FT_BOOLEAN, 32,
5725 NULL, 0x04000000, NULL, HFILL }},
5726 { &hf_lcp_opt_asyncmap_esc,
5727 { "ESC", "lcp.opt.asyncmap.esc", FT_BOOLEAN, 32,
5728 NULL, 0x08000000, NULL, HFILL }},
5729 { &hf_lcp_opt_asyncmap_fs,
5730 { "FS", "lcp.opt.asyncmap.fs", FT_BOOLEAN, 32,
5731 NULL, 0x10000000, NULL, HFILL }},
5732 { &hf_lcp_opt_asyncmap_gs,
5733 { "GS", "lcp.opt.asyncmap.gs", FT_BOOLEAN, 32,
5734 NULL, 0x20000000, NULL, HFILL }},
5735 { &hf_lcp_opt_asyncmap_rs,
5736 { "RS", "lcp.opt.asyncmap.rs", FT_BOOLEAN, 32,
5737 NULL, 0x40000000, NULL, HFILL }},
5738 { &hf_lcp_opt_asyncmap_us,
5739 { "US", "lcp.opt.asyncmap.us", FT_BOOLEAN, 32,
5740 NULL, 0x80000000, NULL, HFILL }},
5741 { &hf_lcp_opt_auth_protocol,
5742 { "Authentication Protocol", "lcp.opt.auth_protocol", FT_UINT16,
5743 BASE_HEX | BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
5744 { &hf_lcp_opt_algorithm,
5745 { "Algorithm", "lcp.opt.algorithm", FT_UINT8,
5746 BASE_DEC | BASE_RANGE_STRING, &chap_alg_rvals,
5747 0x0, NULL, HFILL }},
5748 { &hf_lcp_opt_quality_protocol,
5749 { "Quality Protocol", "lcp.opt.quality_protocol", FT_UINT16,
5750 BASE_HEX | BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
5751 { &hf_lcp_opt_magic_number,
5752 { "Magic Number", "lcp.opt.magic_number", FT_UINT32, BASE_HEX,
5753 NULL, 0x0, NULL, HFILL }},
5754 { &hf_lcp_opt_reportingperiod,
5755 { "Reporting Period", "lcp.opt.reporting_period", FT_UINT32,
5756 BASE_DEC, NULL, 0x0,
5757 "Maximum time in micro-seconds that the remote end should "
5758 "wait between transmission of LCP Link-Quality-Report packets",
5759 HFILL }},
5760 { &hf_lcp_opt_fcs_alternatives,
5761 { "FCS Alternatives", "lcp.opt.fcs_alternatives", FT_UINT8,
5762 BASE_HEX, NULL, 0x0, NULL, HFILL }},
5763 { &hf_lcp_opt_fcs_alternatives_null,
5764 { "NULL FCS", "lcp.opt.fcs_alternatives.null", FT_BOOLEAN, 8,
5765 NULL, 0x01, NULL, HFILL }},
5766 { &hf_lcp_opt_fcs_alternatives_ccitt16,
5767 { "CCITT 16-bit", "lcp.opt.fcs_alternatives.ccitt16", FT_BOOLEAN,
5768 8, NULL, 0x02, NULL, HFILL }},
5769 { &hf_lcp_opt_fcs_alternatives_ccitt32,
5770 { "CCITT 32-bit", "lcp.opt.fcs_alternatives.ccitt32", FT_BOOLEAN,
5771 8, NULL, 0x04, NULL, HFILL }},
5772 { &hf_lcp_opt_maximum,
5773 { "Maximum", "lcp.opt.maximum", FT_UINT8, BASE_DEC, NULL, 0x0,
5774 "The largest number of padding octets which may be added "
5775 "to the frame.", HFILL }},
5776 { &hf_lcp_opt_window,
5777 { "Window", "lcp.opt.window", FT_UINT8, BASE_DEC, NULL, 0x0,
5778 "The number of frames the receiver will buffer.", HFILL }},
5779 { &hf_lcp_opt_hdlc_address,
5780 { "Address", "lcp.opt.hdlc_address", FT_BYTES, BASE_NONE, NULL,
5781 0x0, "An HDLC Address as specified in ISO 3309.", HFILL }},
5782 { &hf_lcp_opt_operation,
5783 { "Operation", "lcp.opt.operation", FT_UINT8, BASE_DEC,
5784 VALS(callback_op_vals), 0x0, NULL, HFILL }},
5785 { &hf_lcp_opt_message,
5786 { "Message", "lcp.opt.message", FT_BYTES, BASE_NONE,
5787 NULL, 0x0, NULL, HFILL }},
5788 { &hf_lcp_opt_mrru,
5789 { "MRRU", "lcp.opt.mrru", FT_UINT16, BASE_DEC, NULL, 0x0,
5790 "Maximum Receive Reconstructed Unit", HFILL }},
5791 { &hf_lcp_opt_ep_disc_class,
5792 { "Class", "lcp.opt.ep_disc_class", FT_UINT8, BASE_DEC,
5793 VALS(multilink_ep_disc_class_vals), 0x0, NULL, HFILL }},
5794 { &hf_lcp_opt_ip_address,
5795 { "IP Address", "lcp.opt.ip_address", FT_IPv4, BASE_NONE,
5796 NULL, 0x0, NULL, HFILL }},
5797 { &hf_lcp_opt_802_1_address,
5798 { "IEEE 802.1 Address", "lcp.opt.802_1_address", FT_ETHER,
5799 BASE_NONE, NULL, 0x0, NULL, HFILL }},
5800 { &hf_lcp_opt_magic_block,
5801 { "PPP Magic-Number Block", "lcp.opt.magic_block", FT_BYTES,
5802 BASE_NONE, NULL, 0x0, NULL, HFILL }},
5803 { &hf_lcp_opt_psndn,
5804 { "Public Switched Network Directory Number", "lcp.opt.psndn",
5805 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
5806 { &hf_lcp_opt_mode,
5807 { "Mode", "lcp.opt.mode", FT_UINT8, BASE_DEC,
5808 VALS(dce_id_mode_vals), 0x0, NULL, HFILL }},
5809 { &hf_lcp_opt_unused,
5810 { "Unused", "lcp.opt.unused", FT_BYTES, BASE_NONE,
5811 NULL, 0x0, NULL, HFILL }},
5812 { &hf_lcp_opt_link_discrim,
5813 { "Link Discriminator", "lcp.opt.link_discrim", FT_UINT16,
5814 BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }},
5815 { &hf_lcp_opt_id,
5816 { "Identification", "lcp.opt.id", FT_UINT_BYTES, BASE_NONE,
5817 NULL, 0x0, NULL, HFILL }},
5818 { &hf_lcp_opt_cobs_flags,
5819 { "Flags", "lcp.opt.flags", FT_UINT8, BASE_HEX,
5820 NULL, 0x0, NULL, HFILL }},
5821 { &hf_lcp_opt_cobs_flags_res,
5822 { "Reserved", "lcp.opt.flags.reserved", FT_UINT8, BASE_HEX,
5823 NULL, 0xFC, NULL, HFILL }},
5824 { &hf_lcp_opt_cobs_flags_pre,
5825 { "PRE", "lcp.opt.flags.pre", FT_BOOLEAN, 8,
5826 NULL, 0x02, "Preemption", HFILL }},
5827 { &hf_lcp_opt_cobs_flags_zxe,
5828 { "ZXE", "lcp.opt.flags.zxe", FT_BOOLEAN, 8,
5829 NULL, 0x01, "Zero pair/run elimination", HFILL }},
5830 { &hf_lcp_opt_class,
5831 { "Class", "lcp.opt.class", FT_UINT8, BASE_DEC,
5832 NULL, 0x0, NULL, HFILL }},
5833 { &hf_lcp_opt_prefix,
5834 { "Prefix", "lcp.opt.prefix", FT_UINT_BYTES, BASE_NONE,
5835 NULL, 0x0, NULL, HFILL }},
5836 { &hf_lcp_opt_code,
5837 { "Code", "lcp.opt.code", FT_UINT8, BASE_DEC,
5838 VALS(ml_hdr_fmt_code_vals), 0x0, NULL, HFILL }},
5839 { &hf_lcp_opt_max_susp_classes,
5840 { "Max suspendable classes", "lcp.opt.max_susp_classes",
5841 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
5842 { &hf_lcp_opt_MIBenum,
5843 { "MIBenum", "lcp.opt.MIBenum", FT_UINT32,
5844 BASE_DEC | BASE_EXT_STRING, &charset_vals_ext, 0x0,
5845 "A unique integer value identifying a charset", HFILL }},
5846 { &hf_lcp_opt_language_tag,
5847 { "Language-Tag", "lcp.opt.language_tag", FT_STRING, BASE_NONE,
5848 NULL, 0x0, NULL, HFILL }}
5851 static gint *ett[] = {
5852 &ett_lcp,
5853 &ett_lcp_options,
5854 &ett_lcp_vendor_opt,
5855 &ett_lcp_mru_opt,
5856 &ett_lcp_asyncmap_opt,
5857 &ett_lcp_authprot_opt,
5858 &ett_lcp_qualprot_opt,
5859 &ett_lcp_magicnumber_opt,
5860 &ett_lcp_linkqualmon_opt,
5861 &ett_lcp_pcomp_opt,
5862 &ett_lcp_acccomp_opt,
5863 &ett_lcp_fcs_alternatives_opt,
5864 &ett_lcp_self_desc_pad_opt,
5865 &ett_lcp_numbered_mode_opt,
5866 &ett_lcp_callback_opt,
5867 &ett_lcp_compound_frames_opt,
5868 &ett_lcp_nomdataencap_opt,
5869 &ett_lcp_multilink_mrru_opt,
5870 &ett_lcp_multilink_ssnh_opt,
5871 &ett_lcp_multilink_ep_disc_opt,
5872 &ett_lcp_magic_block,
5873 &ett_lcp_dce_identifier_opt,
5874 &ett_lcp_multilink_pp_opt,
5875 &ett_lcp_bacp_link_discrim_opt,
5876 &ett_lcp_auth_opt,
5877 &ett_lcp_cobs_opt,
5878 &ett_lcp_prefix_elision_opt,
5879 &ett_multilink_hdr_fmt_opt,
5880 &ett_lcp_internationalization_opt,
5881 &ett_lcp_simple_opt
5884 proto_lcp = proto_register_protocol("PPP Link Control Protocol", "PPP LCP",
5885 "lcp");
5886 proto_register_field_array(proto_lcp, hf, array_length(hf));
5887 proto_register_subtree_array(ett, array_length(ett));
5890 void
5891 proto_reg_handoff_lcp(void)
5893 dissector_handle_t lcp_handle;
5895 lcp_handle = create_dissector_handle(dissect_lcp, proto_lcp);
5896 dissector_add_uint("ppp.protocol", PPP_LCP, lcp_handle);
5899 * NDISWAN on Windows translates Ethernet frames from higher-level
5900 * protocols into PPP frames to hand to the PPP driver, and translates
5901 * PPP frames from the PPP driver to hand to the higher-level protocols.
5903 * Apparently the PPP driver, on at least some versions of Windows,
5904 * passes frames for internal-to-PPP protocols up through NDISWAN;
5905 * the protocol type field appears to be passed through unchanged
5906 * (unlike what's done with, for example, the protocol type field
5907 * for IP, which is mapped from its PPP value to its Ethernet value).
5909 * This means that we may see, on Ethernet captures, frames for
5910 * protocols internal to PPP, so we register PPP_LCP with the
5911 * "ethertype" dissector table as well as the PPP protocol dissector
5912 * table.
5914 dissector_add_uint("ethertype", PPP_LCP, lcp_handle);
5917 * for GSM-A / MobileL3 / GPRS SM / PCO
5919 dissector_add_uint("sm_pco.protocol", PPP_LCP, lcp_handle);
5922 void
5923 proto_register_vsncp(void)
5925 static gint *ett[] = {
5926 &ett_vsncp,
5927 &ett_vsncp_options
5930 proto_vsncp = proto_register_protocol("Vendor Specific Control Protocol",
5931 "VSNCP", "vsncp");
5932 proto_register_subtree_array(ett, array_length(ett));
5935 void
5936 proto_reg_handoff_vsncp(void)
5938 dissector_handle_t vsncp_handle;
5940 vsncp_handle = create_dissector_handle(dissect_vsncp, proto_vsncp);
5941 dissector_add_uint("ppp.protocol", PPP_VSNCP, vsncp_handle);
5944 void
5945 proto_register_vsnp(void)
5947 static gint *ett[] = {
5948 &ett_vsnp
5951 static hf_register_info hf[] = {
5952 { &hf_vsnp_pdnid,
5953 { "PDN ID", "vsnp.pdnid", FT_UINT8, BASE_HEX,
5954 NULL, 0x0, NULL, HFILL }}
5957 proto_vsnp = proto_register_protocol("Vendor Specific Network Protocol",
5958 "PPP VSNP", "vsnp");
5959 proto_register_subtree_array(ett, array_length(ett));
5960 proto_register_field_array(proto_vsnp, hf, array_length(hf));
5963 void
5964 proto_reg_handoff_vsnp(void)
5966 dissector_handle_t vsnp_handle;
5968 vsnp_handle = create_dissector_handle(dissect_vsnp, proto_vsnp);
5969 dissector_add_uint("ppp.protocol", PPP_VSNP, vsnp_handle);
5972 void
5973 proto_register_ipcp(void)
5975 static hf_register_info hf[] = {
5976 { &hf_ipcp_opt_type,
5977 { "Type", "ipcp.opt.type", FT_UINT8, BASE_DEC,
5978 NULL, 0x0, NULL, HFILL }},
5979 { &hf_ipcp_opt_length,
5980 { "Length", "ipcp.opt.length", FT_UINT8, BASE_DEC,
5981 NULL, 0x0, NULL, HFILL }},
5982 { &hf_ipcp_opt_src_address,
5983 { "Source IP Address", "ipcp.opt.src_address", FT_IPv4, BASE_NONE,
5984 NULL, 0x0, NULL, HFILL }},
5985 { &hf_ipcp_opt_dst_address,
5986 { "Destination IP Address", "ipcp.opt.dst_address", FT_IPv4,
5987 BASE_NONE, NULL, 0x0, NULL, HFILL }},
5988 { &hf_ipcp_opt_compress_proto,
5989 { "IP Compression Protocol", "ipcp.opt.compress_proto", FT_UINT16,
5990 BASE_HEX, VALS(ipcp_compress_proto_vals), 0x0, NULL, HFILL }},
5991 { &hf_ipcp_opt_max_cid,
5992 { "Max CID", "ipcp.opt.max_cid", FT_UINT16, BASE_DEC,
5993 NULL, 0x0, "Maximum value of a context identifier", HFILL }},
5994 { &hf_ipcp_opt_mrru,
5995 { "MRRU", "ipcp.opt.mrru", FT_UINT16, BASE_DEC,
5996 NULL, 0x0, "Maximum Reconstructed Reception Unit", HFILL }},
5997 { &hf_ipcp_opt_max_slot_id,
5998 { "Max Slot ID", "ipcp.opt.max_slot_id", FT_UINT8, BASE_DEC,
5999 NULL, 0x0, NULL, HFILL }},
6000 { &hf_ipcp_opt_comp_slot_id,
6001 { "Comp Slot ID", "ipcp.opt.comp_slot_id", FT_BOOLEAN, 8,
6002 TFS(&tfs_comp_slot_id), 0x01, NULL, HFILL }},
6003 { &hf_ipcp_opt_tcp_space,
6004 { "TCP Space", "ipcp.opt.tcp_space", FT_UINT16, BASE_DEC,
6005 NULL, 0x0, NULL, HFILL }},
6006 { &hf_ipcp_opt_non_tcp_space,
6007 { "Non TCP Space", "ipcp.opt.non_tcp_space", FT_UINT16, BASE_DEC,
6008 NULL, 0x0, NULL, HFILL }},
6009 { &hf_ipcp_opt_f_max_period,
6010 { "F Max Period", "ipcp.opt.f_max_period", FT_UINT16, BASE_DEC,
6011 NULL, 0x0, "Maximum interval between full headers", HFILL }},
6012 { &hf_ipcp_opt_f_max_time,
6013 { "F Max Time", "ipcp.opt.f_max_time", FT_UINT16, BASE_DEC, NULL,
6014 0x0, "Maximum time interval between full headers", HFILL }},
6015 { &hf_ipcp_opt_max_header,
6016 { "Max Header", "ipcp.opt.max_header", FT_UINT16, BASE_DEC, NULL,
6017 0x0,
6018 "The largest header size in octets that may be compressed",
6019 HFILL }},
6020 { &hf_ipcp_data,
6021 { "Data", "ipcp.data", FT_BYTES, BASE_NONE,
6022 NULL, 0x0, NULL, HFILL }},
6023 { &hf_ipcp_opt_ip_address,
6024 { "IP Address", "ipcp.opt.ip_address", FT_IPv4, BASE_NONE,
6025 NULL, 0x0, NULL, HFILL }},
6026 { &hf_ipcp_opt_mobilenodehomeaddr,
6027 { "Mobile Node's Home Address", "ipcp.opt.mobilenodehomeaddress",
6028 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6029 { &hf_ipcp_opt_pri_dns_address,
6030 { "Primary DNS Address", "ipcp.opt.pri_dns_address",
6031 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6032 { &hf_ipcp_opt_pri_nbns_address,
6033 { "Primary NBNS Address", "ipcp.opt.pri_nbns_address",
6034 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6035 { &hf_ipcp_opt_sec_dns_address,
6036 { "Secondary DNS Address", "ipcp.opt.sec_dns_address",
6037 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6038 { &hf_ipcp_opt_sec_nbns_address,
6039 { "Secondary NBNS Address", "ipcp.opt.sec_nbns_address",
6040 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6041 { &hf_ipcp_opt_rohc_type,
6042 { "Type", "ipcp.opt.rohc.type", FT_UINT8, BASE_DEC,
6043 NULL, 0x0, NULL, HFILL }},
6044 { &hf_ipcp_opt_rohc_length,
6045 { "Length", "ipcp.opt.rohc.length", FT_UINT8, BASE_DEC,
6046 NULL, 0x0, NULL, HFILL }},
6047 { &hf_ipcp_opt_rohc_profile,
6048 { "Profile", "ipcp.opt.rohc.profile", FT_UINT16, BASE_HEX,
6049 VALS(ipcp_rohc_profile_vals), 0x0, NULL, HFILL }},
6050 { &hf_ipcp_opt_iphc_type,
6051 { "Type", "ipcp.opt.iphc.type", FT_UINT8, BASE_DEC,
6052 NULL, 0x0, NULL, HFILL }},
6053 { &hf_ipcp_opt_iphc_length,
6054 { "Length", "ipcp.opt.iphc.length", FT_UINT8, BASE_DEC,
6055 NULL, 0x0, NULL, HFILL }},
6056 { &hf_ipcp_opt_iphc_param,
6057 { "Parameter", "ipcp.opt.iphc.param", FT_UINT8, BASE_DEC,
6058 VALS(ipcp_iphc_parameter_vals), 0x0, NULL, HFILL }}
6061 static gint *ett[] = {
6062 &ett_ipcp,
6063 &ett_ipcp_options,
6064 &ett_ipcp_ipaddrs_opt,
6065 &ett_ipcp_compress_opt,
6066 &ett_ipcp_ipaddr_opt,
6067 &ett_ipcp_mobileipv4_opt,
6068 &ett_ipcp_pridns_opt,
6069 &ett_ipcp_secdns_opt,
6070 &ett_ipcp_prinbns_opt,
6071 &ett_ipcp_secnbns_opt,
6072 &ett_ipcp_iphc_rtp_compress_opt,
6073 &ett_ipcp_iphc_enhanced_rtp_compress_opt,
6074 &ett_ipcp_iphc_neghdrcomp_opt,
6075 &ett_ipcp_rohc_profiles_opt
6078 proto_ipcp = proto_register_protocol("PPP IP Control Protocol", "PPP IPCP",
6079 "ipcp");
6080 proto_register_field_array(proto_ipcp, hf, array_length(hf));
6081 proto_register_subtree_array(ett, array_length(ett));
6084 void
6085 proto_reg_handoff_ipcp(void)
6087 dissector_handle_t ipcp_handle;
6089 ipcp_handle = create_dissector_handle(dissect_ipcp, proto_ipcp);
6090 dissector_add_uint("ppp.protocol", PPP_IPCP, ipcp_handle);
6093 * See above comment about NDISWAN for an explanation of why we're
6094 * registering with the "ethertype" dissector table.
6096 dissector_add_uint("ethertype", PPP_IPCP, ipcp_handle);
6099 * for GSM-A / MobileL3 / GPRS SM / PCO
6101 dissector_add_uint("sm_pco.protocol", PPP_IPCP, ipcp_handle);
6104 void
6105 proto_register_bcp(void)
6107 static hf_register_info hf[] = {
6108 { &hf_bcp_flags,
6109 { "Flags", "bcp.flags", FT_UINT8, BASE_HEX,
6110 NULL, 0x0, NULL, HFILL }},
6111 { &hf_bcp_fcs_present,
6112 { "LAN FCS present", "bcp.flags.fcs_present", FT_BOOLEAN, 8,
6113 TFS(&tfs_yes_no), BCP_FCS_PRESENT, NULL, HFILL }},
6114 { &hf_bcp_zeropad,
6115 { "802.3 pad zero-filled", "bcp.flags.zeropad", FT_BOOLEAN, 8,
6116 TFS(&tfs_yes_no), BCP_ZEROPAD, NULL, HFILL }},
6117 { &hf_bcp_bcontrol,
6118 { "Bridge control", "bcp.flags.bcontrol", FT_BOOLEAN, 8,
6119 TFS(&tfs_yes_no), BCP_IS_BCONTROL, NULL, HFILL }},
6120 { &hf_bcp_pads,
6121 { "Pads", "bcp.pads", FT_UINT8, BASE_DEC,
6122 NULL, BCP_PADS_MASK, NULL, HFILL }},
6123 { &hf_bcp_mac_type,
6124 { "MAC Type", "bcp.mac_type", FT_UINT8, BASE_DEC,
6125 VALS(bcp_mac_type_vals), 0x0, NULL, HFILL }}
6128 static gint *ett[] = {
6129 &ett_bcp,
6130 &ett_bcp_flags
6133 proto_bcp = proto_register_protocol("PPP Bridging Control Protocol",
6134 "PPP BCP", "bcp");
6135 proto_register_field_array(proto_bcp, hf, array_length(hf));
6136 proto_register_subtree_array(ett, array_length(ett));
6139 void
6140 proto_register_osinlcp(void)
6142 static hf_register_info hf[] = {
6143 { &hf_osinlcp_opt_type,
6144 { "Type", "osinlcp.opt.type", FT_UINT8, BASE_DEC,
6145 NULL, 0x0, NULL, HFILL }},
6146 { &hf_osinlcp_opt_length,
6147 { "Length", "osinlcp.opt.length", FT_UINT8, BASE_DEC,
6148 NULL, 0x0, NULL, HFILL }},
6149 { &hf_osinlcp_opt_alignment,
6150 { "Alignment", "osinlcp.opt.alignment", FT_UINT8, BASE_DEC,
6151 NULL, 0x0, NULL, HFILL }}
6154 static gint *ett[] = {
6155 &ett_osinlcp,
6156 &ett_osinlcp_options,
6157 &ett_osinlcp_align_npdu_opt
6160 proto_osinlcp = proto_register_protocol(
6161 "PPP OSI Network Layer Control Protocol", "PPP OSINLCP", "osinlcp");
6162 proto_register_field_array(proto_osinlcp, hf, array_length(hf));
6163 proto_register_subtree_array(ett, array_length(ett));
6166 void
6167 proto_reg_handoff_bcp(void)
6169 dissector_handle_t bcp_handle;
6171 eth_withfcs_handle = find_dissector("eth_withfcs");
6172 eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
6174 bcp_handle = create_dissector_handle(dissect_bcp, proto_bcp);
6175 dissector_add_uint("ppp.protocol", PPP_BCP, bcp_handle);
6178 void
6179 proto_reg_handoff_osinlcp(void)
6181 dissector_handle_t osinlcp_handle;
6183 osinlcp_handle = create_dissector_handle(dissect_osinlcp, proto_osinlcp);
6184 dissector_add_uint("ppp.protocol", PPP_OSINLCP, osinlcp_handle);
6187 * See above comment about NDISWAN for an explanation of why we're
6188 * registering with the "ethertype" dissector table.
6190 dissector_add_uint("ethertype", PPP_OSINLCP, osinlcp_handle);
6193 void
6194 proto_register_ccp(void)
6196 static hf_register_info hf[] = {
6197 { &hf_ccp_opt_type,
6198 { "Type", "ccp.opt.type", FT_UINT8, BASE_DEC,
6199 NULL, 0x0, NULL, HFILL }},
6200 { &hf_ccp_opt_length,
6201 { "Length", "ccp.opt.length", FT_UINT8, BASE_DEC,
6202 NULL, 0x0, NULL, HFILL }},
6203 { &hf_ccp_opt_oui,
6204 { "OUI", "ccp.opt.oui", FT_UINT24, BASE_HEX,
6205 NULL, 0x0, NULL, HFILL }},
6206 { &hf_ccp_opt_subtype,
6207 { "Subtype", "ccp.opt.subtype", FT_UINT8, BASE_DEC_HEX,
6208 NULL, 0x0, NULL, HFILL }},
6209 { &hf_ccp_opt_history_count,
6210 { "History Count", "ccp.opt.history_count", FT_UINT16, BASE_DEC,
6211 NULL, 0x0, "The maximum number of compression histories",
6212 HFILL }},
6213 { &hf_ccp_opt_cm,
6214 { "Check Mode Field", "ccp.opt.cm", FT_UINT8, BASE_DEC,
6215 NULL, 0x0, NULL, HFILL }},
6216 { &hf_ccp_opt_cm_reserved,
6217 { "Reserved", "ccp.opt.cm.reserved", FT_UINT8, BASE_DEC,
6218 NULL, 0xF8, NULL, HFILL }},
6219 { &hf_ccp_opt_cm_check_mode,
6220 { "Check Mode", "ccp.opt.cm.check_mode", FT_UINT8, BASE_DEC,
6221 VALS(stac_checkmode_vals), 0x07, NULL, HFILL }},
6222 { &hf_ccp_opt_supported_bits,
6223 { "Supported Bits", "ccp.opt.supported_bits", FT_UINT32, BASE_HEX,
6224 NULL, 0x0, NULL, HFILL }},
6225 { &hf_ccp_opt_supported_bits_h,
6226 { "H", "ccp.opt.supported_bits.h", FT_BOOLEAN, 32,
6227 TFS(&ccp_mppe_h_tfs), MPPE_SUPPORTED_BITS_H, NULL, HFILL }},
6228 { &hf_ccp_opt_supported_bits_m,
6229 { "M", "ccp.opt.supported_bits.m", FT_BOOLEAN, 32,
6230 TFS(&ccp_mppe_m_tfs), MPPE_SUPPORTED_BITS_M, NULL, HFILL }},
6231 { &hf_ccp_opt_supported_bits_s,
6232 { "S", "ccp.opt.supported_bits.s", FT_BOOLEAN, 32,
6233 TFS(&ccp_mppe_s_tfs), MPPE_SUPPORTED_BITS_S, NULL, HFILL }},
6234 { &hf_ccp_opt_supported_bits_l,
6235 { "L", "ccp.opt.supported_bits.l", FT_BOOLEAN, 32,
6236 TFS(&ccp_mppe_l_tfs), MPPE_SUPPORTED_BITS_L, NULL, HFILL }},
6237 { &hf_ccp_opt_supported_bits_d,
6238 { "D", "ccp.opt.supported_bits.d", FT_BOOLEAN, 32,
6239 TFS(&ccp_mppe_d_tfs), MPPE_SUPPORTED_BITS_D, NULL, HFILL }},
6240 { &hf_ccp_opt_supported_bits_c,
6241 { "C", "ccp.opt.supported_bits.c", FT_BOOLEAN, 32,
6242 TFS(&ccp_mppe_c_tfs), MPPC_SUPPORTED_BITS_C, NULL, HFILL }},
6243 { &hf_ccp_opt_history,
6244 { "History", "ccp.opt.history", FT_UINT8, BASE_DEC, NULL, 0x0,
6245 "Maximum size of the compression history in powers of 2",
6246 HFILL }},
6247 { &hf_ccp_opt_version,
6248 { "Version", "ccp.opt.version", FT_BYTES, BASE_NONE,
6249 NULL, 0x0, NULL, HFILL }},
6250 { &hf_ccp_opt_vd,
6251 { "Vers/Dict", "ccp.opt.vd", FT_UINT8, BASE_HEX,
6252 NULL, 0x0, NULL, HFILL }},
6253 { &hf_ccp_opt_vd_vers,
6254 { "Vers", "ccp.opt.vd.vers", FT_UINT8, BASE_DEC,
6255 NULL, 0xE0, NULL, HFILL }},
6256 { &hf_ccp_opt_vd_dict,
6257 { "Dict", "ccp.opt.vd.dict", FT_UINT8, BASE_DEC, NULL,
6258 0x1F, "The size in bits of the largest code used", HFILL }},
6259 { &hf_ccp_opt_check_mode,
6260 { "Check Mode", "ccp.opt.check_mode", FT_UINT8, BASE_DEC,
6261 VALS(&lzsdcp_checkmode_vals), 0x0, NULL, HFILL }},
6262 { &hf_ccp_opt_process_mode,
6263 { "Process Mode", "ccp.opt.process_mode", FT_UINT8, BASE_DEC,
6264 VALS(&lzsdcp_processmode_vals), 0x0, NULL, HFILL }},
6265 { &hf_ccp_opt_fe,
6266 { "Features", "ccp.opt.fe", FT_UINT8, BASE_DEC,
6267 NULL, 0xC0, NULL, HFILL }},
6268 { &hf_ccp_opt_p,
6269 { "Packet by Packet flag", "ccp.opt.p", FT_BOOLEAN, 8,
6270 TFS(&tfs_enabled_disabled), 0x20, NULL, HFILL }},
6271 { &hf_ccp_opt_History,
6272 { "History", "ccp.opt.History", FT_UINT8, BASE_DEC,
6273 NULL, 0x1F, NULL, HFILL }},
6274 { &hf_ccp_opt_contexts,
6275 { "# Contexts", "ccp.opt.contexts", FT_UINT8, BASE_DEC,
6276 NULL, 0x0, NULL, HFILL }},
6277 { &hf_ccp_opt_mode,
6278 { "Mode", "ccp.opt.mode", FT_UINT8, BASE_DEC,
6279 VALS(&dce_mode_vals), 0x0, NULL, HFILL }},
6280 { &hf_ccp_opt_window,
6281 { "Window", "ccp.opt.window", FT_UINT8, BASE_DEC,
6282 NULL, 0xF0, NULL, HFILL }},
6283 { &hf_ccp_opt_method,
6284 { "Method", "ccp.opt.method", FT_UINT8, BASE_DEC,
6285 VALS(&deflate_method_vals), 0x0F, NULL, HFILL }},
6286 { &hf_ccp_opt_mbz,
6287 { "MBZ", "ccp.opt.mbz", FT_UINT8, BASE_DEC,
6288 NULL, 0xFC, NULL, HFILL }},
6289 { &hf_ccp_opt_chk,
6290 { "Chk", "ccp.opt.chk", FT_UINT8, BASE_DEC,
6291 VALS(&deflate_chk_vals), 0x03, NULL, HFILL }},
6292 { &hf_ccp_opt_mode_dictcount,
6293 { "Mode/Dictionary Count", "ccp.opt.mode_dictcount", FT_UINT16,
6294 BASE_DEC | BASE_RANGE_STRING, RVALS(v44lzjh_mode_dict_rvals),
6295 0x0, NULL, HFILL }},
6296 { &hf_ccp_opt_dict_size,
6297 { "Dictionary Size", "ccp.opt.dict_size", FT_UINT16, BASE_DEC,
6298 NULL, 0x0, NULL, HFILL }},
6299 { &hf_ccp_opt_history_length,
6300 { "History Length", "ccp.opt.history_length", FT_UINT16, BASE_DEC,
6301 NULL, 0x0, NULL, HFILL }},
6302 { &hf_ccp_opt_data,
6303 { "Data", "ccp.opt.data", FT_BYTES, BASE_NONE,
6304 NULL, 0x0, NULL, HFILL }},
6306 static gint *ett[] = {
6307 &ett_ccp,
6308 &ett_ccp_options,
6309 &ett_ccp_oui_opt,
6310 &ett_ccp_predict1_opt,
6311 &ett_ccp_predict2_opt,
6312 &ett_ccp_puddle_opt,
6313 &ett_ccp_hpppc_opt,
6314 &ett_ccp_stac_opt,
6315 &ett_ccp_stac_opt_check_mode,
6316 &ett_ccp_mppe_opt,
6317 &ett_ccp_mppe_opt_supp_bits,
6318 &ett_ccp_gfza_opt,
6319 &ett_ccp_v42bis_opt,
6320 &ett_ccp_bsdcomp_opt,
6321 &ett_ccp_lzsdcp_opt,
6322 &ett_ccp_mvrca_opt,
6323 &ett_ccp_dce_opt,
6324 &ett_ccp_deflate_opt,
6325 &ett_ccp_v44lzjh_opt
6328 proto_ccp = proto_register_protocol("PPP Compression Control Protocol",
6329 "PPP CCP", "ccp");
6330 proto_register_field_array(proto_ccp, hf, array_length(hf));
6331 proto_register_subtree_array(ett, array_length(ett));
6334 void
6335 proto_reg_handoff_ccp(void)
6337 dissector_handle_t ccp_handle;
6339 ccp_handle = create_dissector_handle(dissect_ccp, proto_ccp);
6340 dissector_add_uint("ppp.protocol", PPP_CCP, ccp_handle);
6343 * See above comment about NDISWAN for an explanation of why we're
6344 * registering with the "ethertype" dissector table.
6346 dissector_add_uint("ethertype", PPP_CCP, ccp_handle);
6349 void
6350 proto_register_cbcp(void)
6352 static gint *ett[] = {
6353 &ett_cbcp,
6354 &ett_cbcp_options,
6355 &ett_cbcp_callback_opt,
6356 &ett_cbcp_callback_opt_addr
6359 proto_cbcp = proto_register_protocol("PPP Callback Control Protocol",
6360 "PPP CBCP", "cbcp");
6361 proto_register_subtree_array(ett, array_length(ett));
6364 void
6365 proto_reg_handoff_cbcp(void)
6367 dissector_handle_t cbcp_handle;
6369 cbcp_handle = create_dissector_handle(dissect_cbcp, proto_cbcp);
6370 dissector_add_uint("ppp.protocol", PPP_CBCP, cbcp_handle);
6373 * See above comment about NDISWAN for an explanation of why we're
6374 * registering with the "ethertype" dissector table.
6376 dissector_add_uint("ethertype", PPP_CBCP, cbcp_handle);
6379 void
6380 proto_register_bacp(void)
6382 static gint *ett[] = {
6383 &ett_bacp,
6384 &ett_bacp_options,
6385 &ett_bacp_favored_peer_opt
6388 proto_bacp = proto_register_protocol(
6389 "PPP Bandwidth Allocation Control Protocol", "PPP BACP", "bacp");
6390 proto_register_subtree_array(ett, array_length(ett));
6393 void
6394 proto_reg_handoff_bacp(void)
6396 dissector_handle_t bacp_handle;
6398 bacp_handle = create_dissector_handle(dissect_bacp, proto_bacp);
6399 dissector_add_uint("ppp.protocol", PPP_BACP, bacp_handle);
6402 * See above comment about NDISWAN for an explanation of why we're
6403 * registering with the "ethertype" dissector table.
6405 dissector_add_uint("ethertype", PPP_BACP, bacp_handle);
6408 void
6409 proto_register_bap(void)
6411 static gint *ett[] = {
6412 &ett_bap,
6413 &ett_bap_options,
6414 &ett_bap_link_type_opt,
6415 &ett_bap_phone_delta_opt,
6416 &ett_bap_phone_delta_subopt,
6417 &ett_bap_call_status_opt
6420 proto_bap = proto_register_protocol("PPP Bandwidth Allocation Protocol",
6421 "PPP BAP", "bap");
6422 proto_register_subtree_array(ett, array_length(ett));
6425 void
6426 proto_reg_handoff_bap(void)
6428 dissector_handle_t bap_handle;
6430 bap_handle = create_dissector_handle(dissect_bap, proto_bap);
6431 dissector_add_uint("ppp.protocol", PPP_BAP, bap_handle);
6434 * See above comment about NDISWAN for an explanation of why we're
6435 * registering with the "ethertype" dissector table.
6437 dissector_add_uint("ethertype", PPP_BAP, bap_handle);
6440 void
6441 proto_register_comp_data(void)
6443 #if 0 /* See dissect_comp_data() */
6444 static gint *ett[] = {
6445 &ett_comp_data
6447 #endif
6449 proto_comp_data = proto_register_protocol("PPP Compressed Datagram",
6450 "PPP Comp", "comp_data");
6451 #if 0
6452 proto_register_subtree_array(ett, array_length(ett));
6453 #endif
6456 void
6457 proto_reg_handoff_comp_data(void)
6459 dissector_handle_t comp_data_handle;
6461 comp_data_handle = create_dissector_handle(dissect_comp_data,
6462 proto_comp_data);
6463 dissector_add_uint("ppp.protocol", PPP_COMP, comp_data_handle);
6466 * See above comment about NDISWAN for an explanation of why we're
6467 * registering with the "ethertype" dissector table.
6469 dissector_add_uint("ethertype", PPP_COMP, comp_data_handle);
6472 void
6473 proto_register_pap(void)
6475 static gint *ett[] = {
6476 &ett_pap,
6477 &ett_pap_data
6480 static hf_register_info hf[] = {
6481 { &hf_pap_code,
6482 { "Code", "pap.code", FT_UINT8, BASE_DEC, VALS(pap_vals), 0x0,
6483 "The Code field is one octet and identifies the type of PAP "
6484 "packet", HFILL }},
6485 { &hf_pap_identifier,
6486 { "Identifier", "pap.identifier", FT_UINT8, BASE_DEC, NULL, 0x0,
6487 "The Identifier field is one octet and aids in matching "
6488 "requests and replies.", HFILL }},
6489 { &hf_pap_length,
6490 { "Length", "pap.length", FT_UINT16, BASE_DEC, NULL, 0x0,
6491 "The Length field is two octets and indicates the length of "
6492 "the PAP packet", HFILL }},
6493 { &hf_pap_data,
6494 { "Data", "pap.data", FT_NONE, BASE_NONE, NULL, 0x0,
6495 "The format of the Data field is determined by the Code field",
6496 HFILL }},
6497 { &hf_pap_peer_id_length,
6498 { "Peer-ID-Length", "pap.peer_id.length",
6499 FT_UINT8, BASE_DEC, NULL, 0x0,
6500 "The Peer-ID-Length field is one octet and indicates the "
6501 "length of the Peer-ID field", HFILL }},
6502 { &hf_pap_peer_id,
6503 { "Peer-ID", "pap.peer_id", FT_STRING, BASE_NONE, NULL, 0x0,
6504 "The Peer-ID field is zero or more octets and indicates the "
6505 "name of the peer to be authenticated", HFILL }},
6506 { &hf_pap_password_length,
6507 { "Password-Length", "pap.password.length",
6508 FT_UINT8, BASE_DEC, NULL, 0x0,
6509 "The Password-Length field is one octet and indicates the "
6510 "length of the Password field", HFILL }},
6511 { &hf_pap_password,
6512 { "Password", "pap.password", FT_STRING, BASE_NONE, NULL, 0x0,
6513 "The Password field is zero or more octets and indicates the "
6514 "password to be used for authentication", HFILL }},
6515 { &hf_pap_message_length,
6516 { "Message-Length", "pap.message.length",
6517 FT_UINT8, BASE_DEC, NULL, 0x0,
6518 "The Message-Length field is one octet and indicates the "
6519 "length of the Message field", HFILL }},
6520 { &hf_pap_message,
6521 { "Message", "pap.message", FT_STRING, BASE_NONE, NULL, 0x0,
6522 "The Message field is zero or more octets, and its contents "
6523 "are implementation dependent.", HFILL }},
6524 { &hf_pap_stuff,
6525 { "stuff", "pap.stuff", FT_BYTES, BASE_NONE,
6526 NULL, 0x0, NULL, HFILL }}
6529 proto_pap = proto_register_protocol("PPP Password Authentication Protocol",
6530 "PPP PAP", "pap");
6531 proto_register_field_array(proto_pap, hf, array_length(hf));
6532 proto_register_subtree_array(ett, array_length(ett));
6535 void
6536 proto_reg_handoff_pap(void)
6538 dissector_handle_t pap_handle;
6540 pap_handle = create_dissector_handle(dissect_pap, proto_pap);
6541 dissector_add_uint("ppp.protocol", PPP_PAP, pap_handle);
6544 * See above comment about NDISWAN for an explanation of why we're
6545 * registering with the "ethertype" dissector table.
6547 dissector_add_uint("ethertype", PPP_PAP, pap_handle);
6550 * for GSM-A / MobileL3 / GPRS SM / PCO
6552 dissector_add_uint("sm_pco.protocol", PPP_PAP, pap_handle);
6555 void
6556 proto_register_chap(void)
6558 static gint *ett[] = {
6559 &ett_chap,
6560 &ett_chap_data
6563 static hf_register_info hf[] = {
6564 { &hf_chap_code,
6565 { "Code", "chap.code", FT_UINT8, BASE_DEC, VALS(chap_vals), 0x0,
6566 "CHAP code", HFILL }},
6567 { &hf_chap_identifier,
6568 { "Identifier", "chap.identifier", FT_UINT8, BASE_DEC, NULL, 0x0,
6569 "CHAP identifier", HFILL }},
6570 { &hf_chap_length,
6571 { "Length", "chap.length", FT_UINT16, BASE_DEC, NULL, 0x0,
6572 "CHAP length", HFILL }},
6573 { &hf_chap_data,
6574 { "Data", "chap.data", FT_NONE, BASE_NONE, NULL, 0x0,
6575 "CHAP Data", HFILL }},
6576 { &hf_chap_value_size,
6577 { "Value Size", "chap.value_size", FT_UINT8, BASE_DEC, NULL, 0x0,
6578 "CHAP value size", HFILL }},
6579 { &hf_chap_value,
6580 { "Value", "chap.value", FT_BYTES, BASE_NONE, NULL, 0x0,
6581 "CHAP value data", HFILL }},
6582 { &hf_chap_name,
6583 { "Name", "chap.name", FT_STRING, BASE_NONE, NULL, 0x0,
6584 "CHAP name", HFILL }},
6585 { &hf_chap_message,
6586 { "Message", "chap.message", FT_STRING, BASE_NONE, NULL, 0x0,
6587 "CHAP message", HFILL }}
6590 proto_chap = proto_register_protocol(
6591 "PPP Challenge Handshake Authentication Protocol", "PPP CHAP", "chap");
6592 proto_register_field_array(proto_chap, hf, array_length(hf));
6593 proto_register_subtree_array(ett, array_length(ett));
6596 void
6597 proto_reg_handoff_chap(void)
6599 dissector_handle_t chap_handle = create_dissector_handle(dissect_chap,
6600 proto_chap);
6601 dissector_add_uint("ppp.protocol", PPP_CHAP, chap_handle);
6604 * See above comment about NDISWAN for an explanation of why we're
6605 * registering with the "ethertype" dissector table.
6607 dissector_add_uint("ethertype", PPP_CHAP, chap_handle);
6610 * for GSM-A / MobileL3 / GPRS SM / PCO
6612 dissector_add_uint("sm_pco.protocol", PPP_CHAP, chap_handle);
6615 void
6616 proto_register_pppmuxcp(void)
6618 static hf_register_info hf[] = {
6619 { &hf_pppmux_flags_pid,
6620 { "PID", "pppmuxcp.flags.pid", FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x80,
6621 NULL, HFILL }},
6622 { &hf_pppmux_flags_field_length,
6623 { "Length field", "pppmuxcp.flags.field_length", FT_BOOLEAN, 8, TFS(&tfs_pppmux_length_field), 0x40,
6624 NULL, HFILL }},
6627 static gint *ett[] = {
6628 &ett_pppmuxcp,
6629 &ett_pppmuxcp_options
6632 proto_pppmuxcp = proto_register_protocol("PPPMux Control Protocol",
6633 "PPP PPPMuxCP", "pppmuxcp");
6634 proto_register_field_array(proto_pppmuxcp, hf, array_length(hf));
6635 proto_register_subtree_array(ett, array_length(ett));
6639 void
6640 proto_reg_handoff_pppmuxcp(void)
6642 dissector_handle_t muxcp_handle;
6644 muxcp_handle = create_dissector_handle(dissect_pppmuxcp, proto_pppmuxcp);
6645 dissector_add_uint("ppp.protocol", PPP_MUXCP, muxcp_handle);
6648 * See above comment about NDISWAN for an explanation of why we're
6649 * registering with the "ethertype" dissector table.
6651 dissector_add_uint("ethertype", PPP_MUXCP, muxcp_handle);
6655 void
6656 proto_register_pppmux(void)
6658 static hf_register_info hf[] = {
6659 { &hf_pppmux_protocol,
6660 { "Protocol", "pppmux.protocol", FT_UINT16,
6661 BASE_HEX|BASE_EXT_STRING, &ppp_vals_ext, 0x0,
6662 "The protocol of the sub-frame.", HFILL }}
6665 static gint *ett[] = {
6666 &ett_pppmux,
6667 &ett_pppmux_subframe,
6668 &ett_pppmux_subframe_hdr,
6669 &ett_pppmux_subframe_flags,
6670 &ett_pppmux_subframe_info
6673 proto_pppmux = proto_register_protocol("PPP Multiplexing", "PPP PPPMux",
6674 "pppmux");
6675 proto_register_field_array(proto_pppmux, hf, array_length(hf));
6676 proto_register_subtree_array(ett, array_length(ett));
6679 void
6680 proto_reg_handoff_pppmux(void)
6682 dissector_handle_t pppmux_handle;
6684 pppmux_handle = create_dissector_handle(dissect_pppmux, proto_pppmux);
6685 dissector_add_uint("ppp.protocol", PPP_MUX, pppmux_handle);
6688 * See above comment about NDISWAN for an explanation of why we're
6689 * registering with the "ethertype" dissector table.
6691 dissector_add_uint("ethertype", PPP_MUX, pppmux_handle);
6694 void
6695 proto_register_mplscp(void)
6697 static gint *ett[] = {
6698 &ett_mplscp,
6699 &ett_mplscp_options
6702 proto_mplscp = proto_register_protocol("PPP MPLS Control Protocol",
6703 "PPP MPLSCP", "mplscp");
6704 proto_register_subtree_array(ett, array_length(ett));
6707 void
6708 proto_reg_handoff_mplscp(void)
6710 dissector_handle_t mplscp_handle;
6712 mplscp_handle = create_dissector_handle(dissect_mplscp, proto_mplscp);
6713 dissector_add_uint("ppp.protocol", PPP_MPLSCP, mplscp_handle);
6716 * See above comment about NDISWAN for an explanation of why we're
6717 * registering with the "ethertype" dissector table.
6719 dissector_add_uint("ethertype", PPP_MPLSCP, mplscp_handle);
6722 void
6723 proto_register_cdpcp(void)
6725 static gint *ett[] = {
6726 &ett_cdpcp,
6727 &ett_cdpcp_options
6730 proto_cdpcp = proto_register_protocol("PPP CDP Control Protocol",
6731 "PPP CDPCP", "cdpcp");
6732 proto_register_subtree_array(ett, array_length(ett));
6735 void
6736 proto_reg_handoff_cdpcp(void)
6738 dissector_handle_t cdpcp_handle;
6740 cdpcp_handle = create_dissector_handle(dissect_cdpcp, proto_cdpcp);
6741 dissector_add_uint("ppp.protocol", PPP_CDPCP, cdpcp_handle);
6744 * See above comment about NDISWAN for an explanation of why we're
6745 * registering with the "ethertype" dissector table.
6747 dissector_add_uint("ethertype", PPP_CDPCP, cdpcp_handle);
6750 void
6751 proto_register_ipv6cp(void)
6753 static gint *ett[] = {
6754 &ett_ipv6cp,
6755 &ett_ipv6cp_options,
6756 &ett_ipv6cp_if_id_opt,
6757 &ett_ipv6cp_compress_opt
6760 proto_ipv6cp = proto_register_protocol("PPP IPv6 Control Protocol",
6761 "PPP IPV6CP", "ipv6cp");
6762 proto_register_subtree_array(ett, array_length(ett));
6765 void
6766 proto_reg_handoff_ipv6cp(void)
6768 dissector_handle_t ipv6cp_handle;
6770 ipv6cp_handle = create_dissector_handle(dissect_ipv6cp, proto_ipv6cp);
6771 dissector_add_uint("ppp.protocol", PPP_IPV6CP, ipv6cp_handle);
6774 * See above comment about NDISWAN for an explanation of why we're
6775 * registering with the "ethertype" dissector table.
6777 dissector_add_uint("ethertype", PPP_IPV6CP, ipv6cp_handle);
6780 * for GSM-A / MobileL3 / GPRS SM / PCO
6782 dissector_add_uint("sm_pco.protocol", PPP_IPV6CP, ipv6cp_handle);
6785 void
6786 proto_register_iphc_crtp(void)
6788 static hf_register_info hf[] = {
6789 { &hf_iphc_crtp_cid16,
6790 { "Context Id", "crtp.cid", FT_UINT16, BASE_DEC, NULL, 0x0,
6791 "The context identifier of the compressed packet.", HFILL }},
6792 { &hf_iphc_crtp_cid8,
6793 { "Context Id", "crtp.cid", FT_UINT8, BASE_DEC, NULL, 0x0,
6794 "The context identifier of the compressed packet.", HFILL }},
6795 { &hf_iphc_crtp_gen,
6796 { "Generation", "crtp.gen", FT_UINT8, BASE_DEC, NULL, 0x3f,
6797 "The generation of the compressed packet.", HFILL }},
6798 { &hf_iphc_crtp_seq,
6799 { "Sequence", "crtp.seq", FT_UINT8, BASE_DEC, NULL, 0x0f,
6800 "The sequence of the compressed packet.", HFILL }},
6801 { &hf_iphc_crtp_fh_flags,
6802 { "Flags", "crtp.fh_flags", FT_UINT8, BASE_HEX, iphc_crtp_fh_flags,
6803 0xc0, "The flags of the full header packet.", HFILL }},
6804 { &hf_iphc_crtp_cs_flags,
6805 { "Flags", "crtp.cs_flags", FT_UINT8, BASE_DEC, iphc_crtp_cs_flags,
6806 0x0, "The flags of the context state packet.", HFILL }},
6807 { &hf_iphc_crtp_cs_cnt,
6808 { "Count", "crtp.cnt", FT_UINT8, BASE_DEC, NULL, 0x0,
6809 "The count of the context state packet.", HFILL }},
6810 { &hf_iphc_crtp_cs_invalid,
6811 { "Invalid", "crtp.invalid", FT_BOOLEAN, 8, NULL, 0x80,
6812 "The invalid bit of the context state packet.", HFILL }}
6815 static gint *ett[] = {
6816 &ett_iphc_crtp,
6817 &ett_iphc_crtp_hdr,
6818 &ett_iphc_crtp_info
6821 proto_iphc_crtp = proto_register_protocol("CRTP", "CRTP", "crtp");
6822 proto_register_field_array(proto_iphc_crtp, hf, array_length(hf));
6823 proto_register_subtree_array(ett, array_length(ett));
6826 void
6827 proto_reg_handoff_iphc_crtp(void)
6829 dissector_handle_t fh_handle;
6830 dissector_handle_t cudp16_handle;
6831 dissector_handle_t cudp8_handle;
6832 dissector_handle_t cs_handle;
6834 fh_handle = create_dissector_handle(dissect_iphc_crtp_fh, proto_iphc_crtp);
6835 dissector_add_uint("ppp.protocol", PPP_RTP_FH, fh_handle);
6837 cudp16_handle = create_dissector_handle(dissect_iphc_crtp_cudp16,
6838 proto_iphc_crtp);
6839 dissector_add_uint("ppp.protocol", PPP_RTP_CUDP16, cudp16_handle);
6841 cudp8_handle = create_dissector_handle(dissect_iphc_crtp_cudp8,
6842 proto_iphc_crtp);
6843 dissector_add_uint("ppp.protocol", PPP_RTP_CUDP8, cudp8_handle);
6845 cs_handle = create_dissector_handle(dissect_iphc_crtp_cs, proto_iphc_crtp);
6846 dissector_add_uint("ppp.protocol", PPP_RTP_CS, cs_handle);
6849 * See above comment about NDISWAN for an explanation of why we're
6850 * registering with the "ethertype" dissector table.
6852 dissector_add_uint("ethertype", PPP_RTP_FH, fh_handle);
6853 dissector_add_uint("ethertype", PPP_RTP_CUDP16, cudp16_handle);
6854 dissector_add_uint("ethertype", PPP_RTP_CUDP8, cudp16_handle);
6855 dissector_add_uint("ethertype", PPP_RTP_CS, cs_handle);
6859 * Editor modelines - http://www.wireshark.org/tools/modelines.html
6861 * Local variables:
6862 * c-basic-offset: 4
6863 * tab-width: 8
6864 * indent-tabs-mode: nil
6865 * End:
6867 * vi: set shiftwidth=4 tabstop=8 expandtab:
6868 * :indentSize=4:tabSize=8:noTabs=true: