2 * Routines for ppp packet disassembly
4 * $Id: packet-ppp.c,v 1.50 2001/01/03 07:53:43 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
9 * This file created and by Mike Hall <mlh@io.com>
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
38 #include "packet-ppp.h"
40 #include "packet-atalk.h"
41 #include "packet-ip.h"
42 #include "packet-ipv6.h"
43 #include "packet-ipx.h"
44 #include "packet-vines.h"
46 static int proto_ppp = -1;
48 static gint ett_ppp = -1;
49 static gint ett_ipcp = -1;
50 static gint ett_ipcp_options = -1;
51 static gint ett_ipcp_ipaddrs_opt = -1;
52 static gint ett_ipcp_compressprot_opt = -1;
53 static gint ett_lcp = -1;
54 static gint ett_lcp_options = -1;
55 static gint ett_lcp_mru_opt = -1;
56 static gint ett_lcp_async_map_opt = -1;
57 static gint ett_lcp_authprot_opt = -1;
58 static gint ett_lcp_qualprot_opt = -1;
59 static gint ett_lcp_magicnum_opt = -1;
60 static gint ett_lcp_fcs_alternatives_opt = -1;
61 static gint ett_lcp_numbered_mode_opt = -1;
62 static gint ett_lcp_callback_opt = -1;
63 static gint ett_lcp_multilink_ep_disc_opt = -1;
64 static gint ett_lcp_internationalization_opt = -1;
66 static dissector_table_t subdissector_table;
68 static int proto_mp = -1;
69 static int hf_mp_frag_first = -1;
70 static int hf_mp_frag_last = -1;
71 static int hf_mp_sequence_num = -1;
73 static int ett_mp = -1;
74 static int ett_mp_flags = -1;
77 static gint ppp_fcs_decode = 0; /* 0 = No FCS, 1 = 16 bit FCS, 2 = 32 bit FCS */
82 /* PPP structs and definitions */
84 typedef struct _e_ppphdr {
90 static const value_string ppp_vals[] = {
92 {PPP_AT, "Appletalk" },
93 {PPP_IPX, "Netware IPX/SPX"},
94 {PPP_VJC_COMP, "VJ compressed TCP"},
95 {PPP_VJC_UNCOMP,"VJ uncompressed TCP"},
96 {PPP_VINES, "Vines" },
97 {PPP_MP, "Multilink"},
99 {PPP_COMP, "compressed packet" },
100 {PPP_IPCP, "IP Control Protocol" },
101 {PPP_ATCP, "AppleTalk Control Protocol" },
102 {PPP_IPXCP, "IPX Control Protocol" },
103 {PPP_CCP, "Compression Control Protocol" },
104 {PPP_LCP, "Link Control Protocol" },
105 {PPP_PAP, "Password Authentication Protocol" },
106 {PPP_LQR, "Link Quality Report protocol" },
107 {PPP_CHAP, "Cryptographic Handshake Auth. Protocol" },
108 {PPP_CBCP, "Callback Control Protocol" },
109 {PPP_MPLS_UNI, "MPLS Uni-cast"},
110 {PPP_MPLS_MULTI, "MPLS Multi-cast"},
111 {CISCO_IP, "CISCO HDLC IP"},
112 {CISCO_SLARP, "CISCO HDLC SLARP"},
116 /* CP (LCP, IPCP, etc.) codes.
119 #define CONFREQ 1 /* Configuration Request */
120 #define CONFACK 2 /* Configuration Ack */
121 #define CONFNAK 3 /* Configuration Nak */
122 #define CONFREJ 4 /* Configuration Reject */
123 #define TERMREQ 5 /* Termination Request */
124 #define TERMACK 6 /* Termination Ack */
125 #define CODEREJ 7 /* Code Reject */
127 static const value_string cp_vals[] = {
128 {CONFREQ, "Configuration Request" },
129 {CONFACK, "Configuration Ack" },
130 {CONFNAK, "Configuration Nak" },
131 {CONFREJ, "Configuration Reject" },
132 {TERMREQ, "Termination Request" },
133 {TERMACK, "Termination Ack" },
134 {CODEREJ, "Code Reject" },
138 * LCP-specific packet types.
140 #define PROTREJ 8 /* Protocol Reject */
141 #define ECHOREQ 9 /* Echo Request */
142 #define ECHOREP 10 /* Echo Reply */
143 #define DISCREQ 11 /* Discard Request */
144 #define IDENT 12 /* Identification */
145 #define TIMEREMAIN 13 /* Time remaining */
147 #define CBCP_OPT 6 /* Use callback control protocol */
149 static const value_string lcp_vals[] = {
150 {CONFREQ, "Configuration Request" },
151 {CONFACK, "Configuration Ack" },
152 {CONFNAK, "Configuration Nak" },
153 {CONFREJ, "Configuration Reject" },
154 {TERMREQ, "Termination Request" },
155 {TERMACK, "Termination Ack" },
156 {CODEREJ, "Code Reject" },
157 {PROTREJ, "Protocol Reject" },
158 {ECHOREQ, "Echo Request" },
159 {ECHOREP, "Echo Reply" },
160 {DISCREQ, "Discard Request" },
161 {IDENT, "Identification" },
162 {TIMEREMAIN, "Time Remaining" },
169 #define CI_MRU 1 /* Maximum Receive Unit */
170 #define CI_ASYNCMAP 2 /* Async Control Character Map */
171 #define CI_AUTHTYPE 3 /* Authentication Type */
172 #define CI_QUALITY 4 /* Quality Protocol */
173 #define CI_MAGICNUMBER 5 /* Magic Number */
174 #define CI_PCOMPRESSION 7 /* Protocol Field Compression */
175 #define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */
176 #define CI_FCS_ALTERNATIVES 9 /* FCS Alternatives (RFC 1570) */
177 #define CI_SELF_DESCRIBING_PAD 10 /* Self-Describing Pad (RFC 1570) */
178 #define CI_NUMBERED_MODE 11 /* Numbered Mode (RFC 1663) */
179 #define CI_CALLBACK 13 /* Callback (RFC 1570) */
180 #define CI_COMPOUND_FRAMES 15 /* Compound frames (RFC 1570) */
181 #define CI_MULTILINK_MRRU 17 /* Multilink MRRU (RFC 1717) */
182 #define CI_MULTILINK_SSNH 18 /* Multilink Short Sequence Number
184 #define CI_MULTILINK_EP_DISC 19 /* Multilink Endpoint Discriminator
186 #define CI_DCE_IDENTIFIER 21 /* DCE Identifier */
187 #define CI_MULTILINK_PLUS_PROC 22 /* Multilink Plus Procedure */
188 #define CI_LINK_DISC_FOR_BACP 23 /* Link Discriminator for BACP
190 #define CI_LCP_AUTHENTICATION 24 /* LCP Authentication Option */
191 #define CI_COBS 25 /* Consistent Overhead Byte
193 #define CI_PREFIX_ELISION 26 /* Prefix elision */
194 #define CI_MULTILINK_HDR_FMT 27 /* Multilink header format */
195 #define CI_INTERNATIONALIZATION 28 /* Internationalization (RFC 2484) */
196 #define CI_SDL_ON_SONET_SDH 29 /* Simple Data Link on SONET/SDH */
198 static void dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
199 int offset, guint length, frame_data *fd,
201 static void dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
202 int offset, guint length, frame_data *fd,
204 static void dissect_lcp_protocol_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
205 int offset, guint length, frame_data *fd,
207 static void dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp,
208 tvbuff_t *tvb, int offset, guint length,
209 frame_data *fd, proto_tree *tree);
210 static void dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp,
211 tvbuff_t *tvb, int offset, guint length,
212 frame_data *fd, proto_tree *tree);
213 static void dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp,
214 tvbuff_t *tvb, int offset, guint length,
215 frame_data *fd, proto_tree *tree);
216 static void dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp,
217 tvbuff_t *tvb, int offset, guint length,
218 frame_data *fd, proto_tree *tree);
219 static void dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
220 int offset, guint length, frame_data *fd,
222 static void dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp,
223 tvbuff_t *tvb, int offset, guint length,
224 frame_data *fd, proto_tree *tree);
225 static void dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp,
226 tvbuff_t *tvb, int offset, guint length,
227 frame_data *fd, proto_tree *tree);
228 static void dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp,
229 tvbuff_t *tvb, int offset, guint length,
230 frame_data *fd, proto_tree *tree);
231 static void dissect_lcp_internationalization_opt(const ip_tcp_opt *optp,
232 tvbuff_t *tvb, int offset, guint length,
233 frame_data *fd, proto_tree *tree);
234 static void dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
236 static const ip_tcp_opt lcp_opts[] = {
239 "Maximum Receive Unit",
247 "Async Control Character Map",
248 &ett_lcp_async_map_opt,
251 dissect_lcp_async_map_opt
255 "Authentication protocol",
256 &ett_lcp_authprot_opt,
259 dissect_lcp_protocol_opt
264 &ett_lcp_qualprot_opt,
267 dissect_lcp_protocol_opt
272 &ett_lcp_magicnum_opt,
275 dissect_lcp_magicnumber_opt
279 "Protocol field compression",
287 "Address/control field compression",
296 &ett_lcp_fcs_alternatives_opt,
299 dissect_lcp_fcs_alternatives_opt
302 CI_SELF_DESCRIBING_PAD,
307 dissect_lcp_self_describing_pad_opt
312 &ett_lcp_numbered_mode_opt,
315 dissect_lcp_numbered_mode_opt
320 &ett_lcp_callback_opt,
323 dissect_lcp_callback_opt,
339 dissect_lcp_multilink_mrru_opt
343 "Use short sequence number headers",
350 CI_MULTILINK_EP_DISC,
351 "Multilink endpoint discriminator",
352 &ett_lcp_multilink_ep_disc_opt,
355 dissect_lcp_multilink_ep_disc_opt,
366 CI_MULTILINK_PLUS_PROC,
367 "Multilink Plus Procedure",
374 CI_LINK_DISC_FOR_BACP,
379 dissect_lcp_bap_link_discriminator_opt
382 CI_LCP_AUTHENTICATION,
383 "LCP authentication",
391 "Consistent Overhead Byte Stuffing",
406 CI_MULTILINK_HDR_FMT,
407 "Multilink header format",
414 CI_INTERNATIONALIZATION,
415 "Internationalization",
416 &ett_lcp_internationalization_opt,
419 dissect_lcp_internationalization_opt
423 "Simple data link on SONET/SDH",
431 #define N_LCP_OPTS (sizeof lcp_opts / sizeof lcp_opts[0])
436 #define CI_ADDRS 1 /* IP Addresses (deprecated) (RFC 1172) */
437 #define CI_COMPRESSTYPE 2 /* Compression Type (RFC 1332) */
438 #define CI_ADDR 3 /* IP Address (RFC 1332) */
439 #define CI_MOBILE_IPv4 4 /* Mobile IPv4 (RFC 2290) */
440 #define CI_MS_DNS1 129 /* Primary DNS value (RFC 1877) */
441 #define CI_MS_WINS1 130 /* Primary WINS value (RFC 1877) */
442 #define CI_MS_DNS2 131 /* Secondary DNS value (RFC 1877) */
443 #define CI_MS_WINS2 132 /* Secondary WINS value (RFC 1877) */
445 static void dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
446 int offset, guint length, frame_data *fd,
448 static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
449 int offset, guint length, frame_data *fd,
452 static const ip_tcp_opt ipcp_opts[] = {
455 "IP addresses (deprecated)",
456 &ett_ipcp_ipaddrs_opt,
459 dissect_ipcp_addrs_opt
463 "IP compression protocol",
464 &ett_ipcp_compressprot_opt,
467 dissect_lcp_protocol_opt
475 dissect_ipcp_addr_opt
479 "Mobile node's home IP address",
483 dissect_ipcp_addr_opt
487 "Primary DNS server IP address",
491 dissect_ipcp_addr_opt
495 "Primary WINS server IP address",
499 dissect_ipcp_addr_opt
503 "Secondary DNS server IP address",
507 dissect_ipcp_addr_opt
511 "Secondary WINS server IP address",
515 dissect_ipcp_addr_opt
519 #define N_IPCP_OPTS (sizeof ipcp_opts / sizeof ipcp_opts[0])
521 const unsigned int fcstab_32[256] =
523 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
524 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
525 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
526 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
527 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
528 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
529 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
530 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
531 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
532 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
533 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
534 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
535 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
536 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
537 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
538 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
539 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
540 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
541 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
542 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
543 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
544 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
545 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
546 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
547 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
548 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
549 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
550 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
551 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
552 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
553 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
554 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
555 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
556 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
557 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
558 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
559 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
560 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
561 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
562 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
563 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
564 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
565 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
566 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
567 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
568 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
569 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
570 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
571 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
572 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
573 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
574 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
575 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
576 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
577 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
578 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
579 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
580 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
581 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
582 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
583 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
584 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
585 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
586 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
589 const unsigned short fcstab_16[256] = {
590 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
591 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
592 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
593 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
594 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
595 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
596 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
597 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
598 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
599 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
600 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
601 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
602 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
603 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
604 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
605 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
606 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
607 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
608 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
609 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
610 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
611 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
612 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
613 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
614 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
615 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
616 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
617 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
618 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
619 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
620 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
621 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
625 *******************************************************************************
626 * DETAILS : Calculate a new FCS-16 given the current FCS-16 and the new data.
627 *******************************************************************************
630 fcs16(register guint16 fcs,
636 /* Check for Invalid Length */
640 val = tvb_get_guint8(tvbuff, offset++);
641 fcs = (guint16)((fcs >> 8) & 0x00ff) ^
642 fcstab_16[((guint16)(fcs ^ (guint16)((val) & 0x00ff)) & 0x00ff)];
645 return (fcs ^ 0xffff);
649 *******************************************************************************
650 * DETAILS : Calculate a new FCS-32 given the current FCS-32 and the new data.
651 *******************************************************************************
660 /* Check for invalid Length */
665 val = tvb_get_guint8(tvbuff, offset++);
666 fcs = (((fcs) >> 8) ^ fcstab_32[((fcs) ^ (val)) & 0xff]);
668 return (fcs ^ 0xffffffff);
672 capture_ppp( const u_char *pd, int offset, packet_counts *ld ) {
673 switch (pntohs(&pd[offset + 2])) {
676 capture_ip(pd, offset + 4, ld);
679 capture_ipx(pd, offset + 4, ld);
682 capture_vines(pd, offset + 4, ld);
691 dissect_lcp_mru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
692 guint length, frame_data *fd, proto_tree *tree)
694 proto_tree_add_text(tree, tvb, offset, length, "MRU: %u",
695 tvb_get_ntohs(tvb, offset + 2));
699 dissect_lcp_async_map_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
700 guint length, frame_data *fd, proto_tree *tree)
702 proto_tree_add_text(tree, tvb, offset, length, "Async characters to map: 0x%08x",
703 tvb_get_ntohl(tvb, offset + 2));
707 dissect_lcp_protocol_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
708 guint length, frame_data *fd, proto_tree *tree)
712 proto_tree *field_tree = NULL;
714 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
715 optp->name, length, plurality(length, "", "s"));
716 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
719 protocol = tvb_get_ntohs(tvb, offset);
720 proto_tree_add_text(field_tree, tvb, offset, 2, "%s: %s (0x%02x)", optp->name,
721 val_to_str(protocol, ppp_vals, "Unknown"), protocol);
725 proto_tree_add_text(field_tree, tvb, offset, length, "Data (%d byte%s)", length,
726 plurality(length, "", "s"));
730 dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
731 int offset, guint length, frame_data *fd,
734 proto_tree_add_text(tree, tvb, offset, length, "Magic number: 0x%08x",
735 tvb_get_ntohl(tvb, offset + 2));
739 dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
740 int offset, guint length, frame_data *fd,
744 proto_tree *field_tree = NULL;
747 alternatives = tvb_get_guint8(tvb, offset + 2);
748 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: 0x%02x",
749 optp->name, alternatives);
750 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
752 if (alternatives & 0x1)
753 proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s",
754 decode_boolean_bitfield(alternatives, 0x1, 8, "Null FCS", NULL));
755 if (alternatives & 0x2)
756 proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s",
757 decode_boolean_bitfield(alternatives, 0x2, 8, "CCITT 16-bit FCS", NULL));
758 if (alternatives & 0x4)
759 proto_tree_add_text(field_tree, tvb, offset + 2, 1, "%s",
760 decode_boolean_bitfield(alternatives, 0x4, 8, "CCITT 32-bit FCS", NULL));
764 dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
765 int offset, guint length, frame_data *fd,
768 proto_tree_add_text(tree, tvb, offset, length,
769 "Maximum octets of self-describing padding: %u",
770 tvb_get_guint8(tvb, offset + 2));
774 dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
775 int offset, guint length, frame_data *fd,
779 proto_tree *field_tree = NULL;
781 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
782 optp->name, length, plurality(length, "", "s"));
783 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
786 proto_tree_add_text(field_tree, tvb, offset, 1, "Window: %u",
787 tvb_get_guint8(tvb, offset));
791 proto_tree_add_text(field_tree, tvb, offset, length, "Address (%d byte%s)",
792 length, plurality(length, "", "s"));
795 static const value_string callback_op_vals[] = {
796 {0, "Location is determined by user authentication" },
797 {1, "Message is dialing string" },
798 {2, "Message is location identifier" },
799 {3, "Message is E.164" },
800 {4, "Message is distinguished name" },
805 dissect_lcp_callback_opt(const ip_tcp_opt *optp, tvbuff_t *tvb, int offset,
806 guint length, frame_data *fd, proto_tree *tree)
809 proto_tree *field_tree = NULL;
812 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
813 optp->name, length, plurality(length, "", "s"));
814 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
817 operation = tvb_get_guint8(tvb, offset);
818 proto_tree_add_text(field_tree, tvb, offset, 1, "Operation: %s (0x%02x)",
819 val_to_str(operation, callback_op_vals, "Unknown"),
824 proto_tree_add_text(field_tree, tvb, offset, length, "Message (%d byte%s)",
825 length, plurality(length, "", "s"));
829 dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
830 int offset, guint length, frame_data *fd,
833 proto_tree_add_text(tree, tvb, offset, length, "Multilink MRRU: %u",
834 tvb_get_ntohs(tvb, offset + 2));
838 #define CLASS_LOCAL 1
840 #define CLASS_IEEE_802_1 3
841 #define CLASS_PPP_MAGIC_NUMBER 4
842 #define CLASS_PSDN_DIRECTORY_NUMBER 5
844 static const value_string multilink_ep_disc_class_vals[] = {
845 {CLASS_NULL, "Null" },
846 {CLASS_LOCAL, "Locally assigned address" },
847 {CLASS_IP, "IP address" },
848 {CLASS_IEEE_802_1, "IEEE 802.1 globally assigned MAC address" },
849 {CLASS_PPP_MAGIC_NUMBER, "PPP magic-number block" },
850 {CLASS_PSDN_DIRECTORY_NUMBER, "Public switched network directory number" },
855 dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
856 int offset, guint length, frame_data *fd,
860 proto_tree *field_tree = NULL;
861 guint8 ep_disc_class;
863 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
864 optp->name, length, plurality(length, "", "s"));
865 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
868 ep_disc_class = tvb_get_guint8(tvb, offset);
869 proto_tree_add_text(field_tree, tvb, offset, 1, "Class: %s (%u)",
870 val_to_str(ep_disc_class, multilink_ep_disc_class_vals, "Unknown"),
875 switch (ep_disc_class) {
878 proto_tree_add_text(field_tree, tvb, offset, length,
879 "Address (%d byte%s), should have been empty",
880 length, plurality(length, "", "s"));
885 proto_tree_add_text(field_tree, tvb, offset, length,
886 "Address (%d byte%s), should have been <20",
887 length, plurality(length, "", "s"));
889 proto_tree_add_text(field_tree, tvb, offset, length,
890 "Address (%d byte%s)",
891 length, plurality(length, "", "s"));
897 proto_tree_add_text(field_tree, tvb, offset, length,
898 "Address (%d byte%s), should have been 4",
899 length, plurality(length, "", "s"));
901 proto_tree_add_text(field_tree, tvb, offset, length,
902 "Address: %s", ip_to_str(tvb_get_ptr(tvb, offset, 4)));
906 case CLASS_IEEE_802_1:
908 proto_tree_add_text(field_tree, tvb, offset, length,
909 "Address (%d byte%s), should have been 6",
910 length, plurality(length, "", "s"));
912 proto_tree_add_text(field_tree, tvb, offset, length,
913 "Address: %s", ether_to_str(tvb_get_ptr(tvb, offset, 6)));
917 case CLASS_PPP_MAGIC_NUMBER:
918 /* XXX - dissect as 32-bit magic numbers */
920 proto_tree_add_text(field_tree, tvb, offset, length,
921 "Address (%d byte%s), should have been <20",
922 length, plurality(length, "", "s"));
924 proto_tree_add_text(field_tree, tvb, offset, length,
925 "Address (%d byte%s)",
926 length, plurality(length, "", "s"));
930 case CLASS_PSDN_DIRECTORY_NUMBER:
932 proto_tree_add_text(field_tree, tvb, offset, length,
933 "Address (%d byte%s), should have been <20",
934 length, plurality(length, "", "s"));
936 proto_tree_add_text(field_tree, tvb, offset, length,
937 "Address (%d byte%s)",
938 length, plurality(length, "", "s"));
943 proto_tree_add_text(field_tree, tvb, offset, length,
944 "Address (%d byte%s)",
945 length, plurality(length, "", "s"));
952 dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
953 int offset, guint length, frame_data *fd,
956 proto_tree_add_text(tree, tvb, offset, length,
957 "Link discriminator for BAP: 0x%04x",
958 tvb_get_ntohs(tvb, offset + 2));
961 /* Character set numbers from the IANA charset registry. */
962 static const value_string charset_num_vals[] = {
968 dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
969 int offset, guint length, frame_data *fd,
973 proto_tree *field_tree = NULL;
976 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
977 optp->name, length, plurality(length, "", "s"));
978 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
981 charset = tvb_get_ntohl(tvb, offset);
982 proto_tree_add_text(field_tree, tvb, offset, 4, "Character set: %s (0x%04x)",
983 val_to_str(charset, charset_num_vals, "Unknown"),
988 /* XXX - should be displayed as an ASCII string */
989 proto_tree_add_text(field_tree, tvb, offset, length, "Language tag (%d byte%s)",
990 length, plurality(length, "", "s"));
995 dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
996 int offset, guint length, frame_data *fd,
1000 proto_tree *field_tree = NULL;
1002 tf = proto_tree_add_text(tree, tvb, offset, length, "%s: %u byte%s",
1003 optp->name, length, plurality(length, "", "s"));
1004 field_tree = proto_item_add_subtree(tf, *optp->subtree_index);
1007 proto_tree_add_text(field_tree, tvb, offset, 4,
1008 "Source IP address: %s",
1009 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1012 proto_tree_add_text(field_tree, tvb, offset, 4,
1013 "Destination IP address: %s",
1014 ip_to_str(tvb_get_ptr(tvb, offset, 4)));
1017 static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, tvbuff_t *tvb,
1018 int offset, guint length, frame_data *fd,
1021 proto_tree_add_text(tree, tvb, offset, length, "%s: %s", optp->name,
1022 ip_to_str(tvb_get_ptr(tvb, offset + 2, 4)));
1026 dissect_cp( tvbuff_t *tvb, const char *proto_short_name,
1027 const char *proto_long_name, int proto_subtree_index,
1028 const value_string *proto_vals, int options_subtree_index,
1029 const ip_tcp_opt *opts, int nopts, packet_info *pinfo, proto_tree *tree ) {
1031 proto_tree *fh_tree = NULL;
1033 proto_tree *field_tree;
1040 code = tvb_get_guint8(tvb, 0);
1041 id = tvb_get_guint8(tvb, 1);
1042 length = tvb_get_ntohs(tvb, 2);
1044 if(check_col(pinfo->fd, COL_INFO))
1045 col_add_fstr(pinfo->fd, COL_INFO, "%sCP %s", proto_short_name,
1046 val_to_str(code, proto_vals, "Unknown"));
1049 ti = proto_tree_add_text(tree, tvb, 0, 4, "%s Control Protocol",
1051 fh_tree = proto_item_add_subtree(ti, proto_subtree_index);
1052 proto_tree_add_text(fh_tree, tvb, 0, 1, "Code: %s (0x%02x)",
1053 val_to_str(code, proto_vals, "Unknown"), code);
1054 proto_tree_add_text(fh_tree, tvb, 1, 1, "Identifier: 0x%02x",
1056 proto_tree_add_text(fh_tree, tvb, 2, 2, "Length: %u",
1069 tf = proto_tree_add_text(fh_tree, tvb, offset, length,
1070 "Options: (%d byte%s)", length, plurality(length, "", "s"));
1071 field_tree = proto_item_add_subtree(tf, options_subtree_index);
1072 dissect_ip_tcp_options(tvb, offset, length, opts, nopts, -1,
1073 pinfo->fd, field_tree);
1083 proto_tree_add_text(fh_tree, tvb, offset, 4, "Magic number: 0x%08x",
1084 tvb_get_ntohl(tvb, offset));
1088 proto_tree_add_text(fh_tree, tvb, offset, length, "Message (%d byte%s)",
1089 length, plurality(length, "", "s"));
1095 proto_tree_add_text(fh_tree, tvb, offset, 4, "Magic number: 0x%08x",
1096 tvb_get_ntohl(tvb, offset));
1099 proto_tree_add_text(fh_tree, tvb, offset, 4, "Seconds remaining: %u",
1100 tvb_get_ntohl(tvb, offset));
1104 proto_tree_add_text(fh_tree, tvb, offset, length, "Message (%d byte%s)",
1105 length, plurality(length, "", "s"));
1111 protocol = tvb_get_ntohs(tvb, offset);
1112 proto_tree_add_text(fh_tree, tvb, offset, 2, "Rejected protocol: %s (0x%04x)",
1113 val_to_str(protocol, ppp_vals, "Unknown"), protocol);
1117 proto_tree_add_text(fh_tree, tvb, offset, length, "Rejected packet (%d byte%s)",
1118 length, plurality(length, "", "s"));
1119 /* XXX - should be dissected as a PPP packet */
1124 /* decode the rejected LCP packet here. */
1126 proto_tree_add_text(fh_tree, tvb, offset, length, "Rejected packet (%d byte%s)",
1127 length, plurality(length, "", "s"));
1133 proto_tree_add_text(fh_tree, tvb, offset, length, "Data (%d byte%s)",
1134 length, plurality(length, "", "s"));
1139 proto_tree_add_text(fh_tree, tvb, offset, length, "Stuff (%d byte%s)",
1140 length, plurality(length, "", "s"));
1145 /* Protocol field compression */
1146 #define PFC_BIT 0x01
1149 dissect_ppp_stuff( tvbuff_t *tvb, packet_info *pinfo,
1150 proto_tree *tree, proto_tree *fh_tree ) {
1155 if (tvb_get_guint8(tvb, 0) & PFC_BIT) {
1156 ppp_prot = tvb_get_guint8(tvb, 0);
1159 ppp_prot = tvb_get_ntohs(tvb, 0);
1164 proto_tree_add_text(fh_tree, tvb, 0, proto_len, "Protocol: %s (0x%04x)",
1165 val_to_str(ppp_prot, ppp_vals, "Unknown"), ppp_prot);
1168 next_tvb = tvb_new_subset(tvb, proto_len, -1, -1);
1170 /* do lookup with the subdissector table */
1171 if (dissector_try_port(subdissector_table, ppp_prot, next_tvb, pinfo, tree))
1174 /* XXX - make "dissect_lcp()" and "dissect_ipcp()", have them just
1175 call "dissect_cp()", and register them as well?
1177 We can do that for "dissect_mp()", too. */
1180 dissect_mp(next_tvb, pinfo, tree);
1183 dissect_cp(next_tvb, "L", "Link", ett_lcp, lcp_vals, ett_lcp_options,
1184 lcp_opts, N_LCP_OPTS, pinfo, tree);
1187 dissect_cp(next_tvb, "IP", "IP", ett_ipcp, cp_vals, ett_ipcp_options,
1188 ipcp_opts, N_IPCP_OPTS, pinfo, tree);
1191 if (check_col(pinfo->fd, COL_INFO))
1192 col_add_fstr(pinfo->fd, COL_INFO, "PPP %s (0x%04x)",
1193 val_to_str(ppp_prot, ppp_vals, "Unknown"), ppp_prot);
1194 dissect_data(next_tvb, 0, pinfo, tree);
1199 #define MP_FRAG_MASK 0xC0
1200 #define MP_FRAG(bits) ((bits) & MP_FRAG_MASK)
1201 #define MP_FRAG_FIRST 0x80
1202 #define MP_FRAG_LAST 0x40
1203 #define MP_FRAG_RESERVED 0x3f
1205 /* According to RFC 1717, the length the MP header isn't indicated anywhere
1206 in the header itself. It starts out at four bytes and can be
1207 negotiated down to two using LCP. We currently assume that all
1208 headers are four bytes. - gcc
1211 dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1213 proto_tree *mp_tree, *hdr_tree, *fh_tree = NULL;
1221 CHECK_DISPLAY_AS_DATA(proto_mp, tvb, pinfo, tree);
1223 flags = tvb_get_guint8(tvb, 0);
1224 first = flags && MP_FRAG_FIRST;
1225 last = flags && MP_FRAG_LAST;
1226 seq = tvb_get_ntoh24(tvb, 1);
1228 if (check_col(pinfo->fd, COL_INFO))
1229 col_add_fstr(pinfo->fd, COL_INFO, "PPP Multilink");
1239 case MP_FRAG_FIRST|MP_FRAG_LAST:
1240 flag_str = "First, Last";
1243 flag_str = "Unknown";
1246 ti = proto_tree_add_item(tree, proto_mp, tvb, 0, 4, FALSE);
1247 mp_tree = proto_item_add_subtree(ti, ett_mp);
1248 ti = proto_tree_add_text(mp_tree, tvb, 0, 1, "Fragment: 0x%2X (%s)",
1250 hdr_tree = proto_item_add_subtree(ti, ett_mp_flags);
1251 proto_tree_add_boolean_format(hdr_tree, hf_mp_frag_first, tvb, 0, 1, first,
1252 "%s", decode_boolean_bitfield(flags, MP_FRAG_FIRST, sizeof(flags) * 8,
1253 "first", "not first"));
1254 proto_tree_add_boolean_format(hdr_tree, hf_mp_frag_last, tvb, 0, 1, last,
1255 "%s", decode_boolean_bitfield(flags, MP_FRAG_LAST, sizeof(flags) * 8,
1256 "last", "not last"));
1257 proto_tree_add_text(hdr_tree, tvb, 0, 1, "%s",
1258 decode_boolean_bitfield(flags, MP_FRAG_RESERVED, sizeof(flags) * 8,
1259 "reserved", "reserved"));
1260 proto_tree_add_uint(mp_tree, hf_mp_sequence_num, tvb, 1, 3, seq);
1263 next_tvb = tvb_new_subset(tvb, 4, -1, -1);
1265 if (tvb_length(next_tvb) > 0) {
1267 ti = proto_tree_add_item(tree, proto_ppp, next_tvb, 0, 1, FALSE);
1268 fh_tree = proto_item_add_subtree(ti, ett_ppp);
1270 dissect_ppp_stuff(next_tvb, pinfo, tree, fh_tree);
1275 dissect_payload_ppp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
1277 proto_tree *fh_tree = NULL;
1279 /* XXX - the length shouldn't be 2, it should be based on the length
1280 of the protocol field. */
1282 ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, 2, FALSE);
1283 fh_tree = proto_item_add_subtree(ti, ett_ppp);
1286 dissect_ppp_stuff(tvb, pinfo, tree, fh_tree);
1290 dissect_ppp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) {
1293 proto_tree *fh_tree = NULL;
1300 CHECK_DISPLAY_AS_DATA(proto_ppp, tvb, pinfo, tree);
1302 pinfo->current_proto = "PPP";
1303 byte0 = tvb_get_guint8(tvb, 0);
1305 if (byte0 == 0xff) {
1306 ph.ppp_addr = tvb_get_guint8(tvb, 0);
1307 ph.ppp_ctl = tvb_get_guint8(tvb, 1);
1308 ph.ppp_prot = tvb_get_ntohs(tvb, 2);
1311 /* Cisco HDLC format */
1312 else if (byte0 == 0x0f) {
1313 ph.ppp_addr = tvb_get_guint8(tvb, 0);
1314 ph.ppp_ctl = tvb_get_guint8(tvb, 1);
1315 ph.ppp_prot = tvb_get_ntohs(tvb, 2);
1319 /* address and control are compressed (NULL) */
1320 ph.ppp_prot = tvb_get_ntohs(tvb, 0);
1324 /* load the top pane info. This should be overwritten by
1325 the next protocol in the stack */
1327 if(check_col(pinfo->fd, COL_RES_DL_SRC))
1328 col_set_str(pinfo->fd, COL_RES_DL_SRC, "N/A" );
1329 if(check_col(pinfo->fd, COL_RES_DL_DST))
1330 col_set_str(pinfo->fd, COL_RES_DL_DST, "N/A" );
1331 if(check_col(pinfo->fd, COL_PROTOCOL))
1332 col_set_str(pinfo->fd, COL_PROTOCOL, "PPP" );
1335 ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, 4, FALSE);
1336 fh_tree = proto_item_add_subtree(ti, ett_ppp);
1337 if (byte0 == 0xff) {
1338 proto_tree_add_text(fh_tree, tvb, 0, 1, "Address: %02x", ph.ppp_addr);
1339 proto_tree_add_text(fh_tree, tvb, 1, 1, "Control: %02x", ph.ppp_ctl);
1341 else if (byte0 == 0x0f) {
1342 proto_tree_add_text(fh_tree, tvb, 0, 1, "Address: %02x", ph.ppp_addr);
1343 proto_tree_add_text(fh_tree, tvb, 1, 1, "Control: %02x", ph.ppp_ctl);
1347 next_tvb = tvb_new_subset(tvb, proto_offset, -1, -1);
1349 if (!dissect_ppp_stuff(next_tvb, pinfo, tree, fh_tree)) {
1350 if (check_col(pinfo->fd, COL_PROTOCOL))
1351 col_add_fstr(pinfo->fd, COL_PROTOCOL, "0x%04x", ph.ppp_prot);
1354 /* Calculate the FCS check */
1355 if (ppp_fcs_decode == FCS_16) {
1357 rx_fcs_exp = fcs16(0xFFFF, tvb, 0, tvb_length(tvb) - 2);
1358 rx_fcs_got = tvb_get_guint8(tvb, tvb_length(tvb) - 2) |
1359 (tvb_get_guint8(tvb, tvb_length(tvb) - 1) << 8);
1360 if (rx_fcs_got != rx_fcs_exp) {
1361 proto_tree_add_text(fh_tree, tvb, tvb_length(tvb) - 2, 2, "FCS 16: %04x (incorrect, should be %04x)", rx_fcs_got, rx_fcs_exp);
1364 proto_tree_add_text(fh_tree, tvb, tvb_length(tvb) - 2, 2, "FCS 16: %04x (correct)", rx_fcs_got);
1367 else if(ppp_fcs_decode == FCS_32) {
1369 rx_fcs_exp = fcs32(0xFFFFFFFF, tvb, 0, tvb_length(tvb) - 4);
1370 rx_fcs_got = tvb_get_guint8(tvb, tvb_length(tvb) - 4) |
1371 (tvb_get_guint8(tvb, tvb_length(tvb) - 3) << 8) |
1372 (tvb_get_guint8(tvb, tvb_length(tvb) - 2) << 16) |
1373 (tvb_get_guint8(tvb, tvb_length(tvb) - 1) << 24);
1374 if (rx_fcs_got != rx_fcs_exp) {
1375 proto_tree_add_text(fh_tree, tvb, tvb_length(tvb) - 4, 4, "FCS 32: %08x (incorrect, should be %08x) ", rx_fcs_got, rx_fcs_exp);
1378 proto_tree_add_text(fh_tree, tvb, tvb_length(tvb) - 4, 4, "FCS 32: %08x (correct)", rx_fcs_got);
1385 proto_register_ppp(void)
1387 /* static hf_register_info hf[] = {
1389 { "Name", "ppp.abbreviation", TYPE, VALS_POINTER }},
1391 static gint *ett[] = {
1395 &ett_ipcp_ipaddrs_opt,
1396 &ett_ipcp_compressprot_opt,
1400 &ett_lcp_async_map_opt,
1401 &ett_lcp_authprot_opt,
1402 &ett_lcp_qualprot_opt,
1403 &ett_lcp_magicnum_opt,
1404 &ett_lcp_fcs_alternatives_opt,
1405 &ett_lcp_numbered_mode_opt,
1406 &ett_lcp_callback_opt,
1407 &ett_lcp_multilink_ep_disc_opt,
1408 &ett_lcp_internationalization_opt,
1411 static enum_val_t ppp_options[] = {
1418 module_t *ppp_module;
1420 proto_ppp = proto_register_protocol("Point-to-Point Protocol",
1422 /* proto_register_field_array(proto_ppp, hf, array_length(hf));*/
1423 proto_register_subtree_array(ett, array_length(ett));
1425 /* subdissector code */
1426 subdissector_table = register_dissector_table("ppp.protocol");
1428 register_dissector("ppp", dissect_ppp);
1429 register_dissector("payload_ppp", dissect_payload_ppp);
1431 /* Register the preferences for the ppp protocol */
1432 ppp_module = prefs_register_protocol(proto_ppp, NULL);
1434 prefs_register_enum_preference(ppp_module,
1436 "PPP Frame Checksum",
1437 "PPP Frame Checksum",
1439 ppp_options, FALSE);
1443 proto_register_mp(void)
1445 static hf_register_info hf[] = {
1446 { &hf_mp_frag_first,
1447 { "First fragment", "mp.first", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1451 { "Last fragment", "mp.last", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1454 { &hf_mp_sequence_num,
1455 { "Sequence number", "mp.seq", FT_UINT24, BASE_DEC, NULL, 0x0,
1458 static gint *ett[] = {
1463 proto_mp = proto_register_protocol("PPP Multilink Protocol", "PPP MP", "mp");
1464 proto_register_field_array(proto_mp, hf, array_length(hf));
1465 proto_register_subtree_array(ett, array_length(ett));
1469 proto_reg_handoff_ppp(void)
1471 dissector_add("wtap_encap", WTAP_ENCAP_PPP, dissect_ppp);
1472 dissector_add("wtap_encap", WTAP_ENCAP_PPP_WITH_PHDR, dissect_ppp);