2 * Routines for ppp packet disassembly
4 * $Id: packet-ppp.c,v 1.18 1999/08/28 08:31:26 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>
37 #include "packet-ip.h"
39 static int proto_ppp = -1;
41 /* PPP structs and definitions */
43 typedef struct _e_ppphdr {
50 /* Protocol types, from Linux "ppp_defs.h" and
52 http://www.isi.edu/in-notes/iana/assignments/ppp-numbers
55 #define PPP_IP 0x21 /* Internet Protocol */
56 #define PPP_AT 0x29 /* AppleTalk Protocol */
57 #define PPP_IPX 0x2b /* IPX protocol */
58 #define PPP_VJC_COMP 0x2d /* VJ compressed TCP */
59 #define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */
60 #define PPP_VINES 0x35 /* Banyan Vines */
61 #define PPP_IPV6 0x57 /* Internet Protocol Version 6 */
62 #define PPP_COMP 0xfd /* compressed packet */
63 #define PPP_IPCP 0x8021 /* IP Control Protocol */
64 #define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */
65 #define PPP_IPXCP 0x802b /* IPX Control Protocol */
66 #define PPP_CCP 0x80fd /* Compression Control Protocol */
67 #define PPP_LCP 0xc021 /* Link Control Protocol */
68 #define PPP_PAP 0xc023 /* Password Authentication Protocol */
69 #define PPP_LQR 0xc025 /* Link Quality Report protocol */
70 #define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */
71 #define PPP_CBCP 0xc029 /* Callback Control Protocol */
73 static const value_string ppp_vals[] = {
75 {PPP_AT, "Appletalk" },
76 {PPP_IPX, "Netware IPX/SPX"},
77 {PPP_VJC_COMP, "VJ compressed TCP"},
78 {PPP_VJC_UNCOMP,"VJ uncompressed TCP"},
79 {PPP_VINES, "Vines" },
81 {PPP_COMP, "compressed packet" },
82 {PPP_IPCP, "IP Control Protocol" },
83 {PPP_ATCP, "AppleTalk Control Protocol" },
84 {PPP_IPXCP, "IPX Control Protocol" },
85 {PPP_CCP, "Compression Control Protocol" },
86 {PPP_LCP, "Link Control Protocol" },
87 {PPP_PAP, "Password Authentication Protocol" },
88 {PPP_LQR, "Link Quality Report protocol" },
89 {PPP_CHAP, "Cryptographic Handshake Auth. Protocol" },
90 {PPP_CBCP, "Callback Control Protocol" },
94 /* CP (LCP, IPCP, etc.) codes.
97 #define CONFREQ 1 /* Configuration Request */
98 #define CONFACK 2 /* Configuration Ack */
99 #define CONFNAK 3 /* Configuration Nak */
100 #define CONFREJ 4 /* Configuration Reject */
101 #define TERMREQ 5 /* Termination Request */
102 #define TERMACK 6 /* Termination Ack */
103 #define CODEREJ 7 /* Code Reject */
105 static const value_string cp_vals[] = {
106 {CONFREQ, "Configuration Request" },
107 {CONFACK, "Configuration Ack" },
108 {CONFNAK, "Configuration Nak" },
109 {CONFREJ, "Configuration Reject" },
110 {TERMREQ, "Termination Request" },
111 {TERMACK, "Termination Ack" },
112 {CODEREJ, "Code Reject" },
116 * LCP-specific packet types.
118 #define PROTREJ 8 /* Protocol Reject */
119 #define ECHOREQ 9 /* Echo Request */
120 #define ECHOREP 10 /* Echo Reply */
121 #define DISCREQ 11 /* Discard Request */
122 #define IDENT 12 /* Identification */
123 #define TIMEREMAIN 13 /* Time remaining */
125 #define CBCP_OPT 6 /* Use callback control protocol */
127 static const value_string lcp_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" },
135 {PROTREJ, "Protocol Reject" },
136 {ECHOREQ, "Echo Request" },
137 {ECHOREP, "Echo Reply" },
138 {DISCREQ, "Discard Request" },
139 {IDENT, "Identification" },
140 {TIMEREMAIN, "Time Remaining" },
147 #define CI_MRU 1 /* Maximum Receive Unit */
148 #define CI_ASYNCMAP 2 /* Async Control Character Map */
149 #define CI_AUTHTYPE 3 /* Authentication Type */
150 #define CI_QUALITY 4 /* Quality Protocol */
151 #define CI_MAGICNUMBER 5 /* Magic Number */
152 #define CI_PCOMPRESSION 7 /* Protocol Field Compression */
153 #define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */
154 #define CI_FCS_ALTERNATIVES 9 /* FCS Alternatives (RFC 1570) */
155 #define CI_SELF_DESCRIBING_PAD 10 /* Self-Describing Pad (RFC 1570) */
156 #define CI_NUMBERED_MODE 11 /* Numbered Mode (RFC 1663) */
157 #define CI_CALLBACK 13 /* Callback (RFC 1570) */
158 #define CI_COMPOUND_FRAMES 15 /* Compound frames (RFC 1570) */
159 #define CI_MULTILINK_MRRU 17 /* Multilink MRRU (RFC 1717) */
160 #define CI_MULTILINK_SSNH 18 /* Multilink Short Sequence Number
162 #define CI_MULTILINK_EP_DISC 19 /* Multilink Endpoint Discriminator
164 #define CI_DCE_IDENTIFIER 21 /* DCE Identifier */
165 #define CI_MULTILINK_PLUS_PROC 22 /* Multilink Plus Procedure */
166 #define CI_LINK_DISC_FOR_BACP 23 /* Link Discriminator for BACP
168 #define CI_LCP_AUTHENTICATION 24 /* LCP Authentication Option */
169 #define CI_COBS 25 /* Consistent Overhead Byte
171 #define CI_PREFIX_ELISION 26 /* Prefix elision */
172 #define CI_MULTILINK_HDR_FMT 27 /* Multilink header format */
173 #define CI_INTERNATIONALIZATION 28 /* Internationalization (RFC 2484) */
174 #define CI_SDL_ON_SONET_SDH 29 /* Simple Data Link on SONET/SDH */
176 static void dissect_lcp_mru_opt(const ip_tcp_opt *optp, const u_char *opd,
177 int offset, guint length, proto_tree *tree);
178 static void dissect_lcp_async_map_opt(const ip_tcp_opt *optp, const u_char *opd,
179 int offset, guint length, proto_tree *tree);
180 static void dissect_lcp_protocol_opt(const ip_tcp_opt *optp, const u_char *opd,
181 int offset, guint length, proto_tree *tree);
182 static void dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp,
183 const u_char *opd, int offset, guint length,
185 static void dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp,
186 const u_char *opd, int offset, guint length,
188 static void dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp,
189 const u_char *opd, int offset, guint length,
191 static void dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp,
192 const u_char *opd, int offset, guint length,
194 static void dissect_lcp_callback_opt(const ip_tcp_opt *optp, const u_char *opd,
195 int offset, guint length, proto_tree *tree);
196 static void dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp,
197 const u_char *opd, int offset, guint length,
199 static void dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp,
200 const u_char *opd, int offset, guint length,
202 static void dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp,
203 const u_char *opd, int offset, guint length,
205 static void dissect_lcp_internationalization_opt(const ip_tcp_opt *optp,
206 const u_char *opd, int offset, guint length,
209 static const ip_tcp_opt lcp_opts[] = {
212 "Maximum Receive Unit",
220 "Async Control Character Map",
221 ETT_LCP_ASYNC_MAP_OPT,
224 dissect_lcp_async_map_opt
228 "Authentication protocol",
229 ETT_LCP_AUTHPROT_OPT,
232 dissect_lcp_protocol_opt
237 ETT_LCP_QUALPROT_OPT,
240 dissect_lcp_protocol_opt
245 ETT_LCP_MAGICNUM_OPT,
248 dissect_lcp_magicnumber_opt
252 "Protocol field compression",
260 "Address/control field compression",
269 ETT_LCP_FCS_ALTERNATIVES_OPT,
272 dissect_lcp_fcs_alternatives_opt
275 CI_SELF_DESCRIBING_PAD,
280 dissect_lcp_self_describing_pad_opt
285 ETT_LCP_NUMBERED_MODE_OPT,
288 dissect_lcp_numbered_mode_opt
293 ETT_LCP_CALLBACK_OPT,
296 dissect_lcp_callback_opt,
312 dissect_lcp_multilink_mrru_opt
316 "Use short sequence number headers",
323 CI_MULTILINK_EP_DISC,
324 "Multilink endpoint discriminator",
325 ETT_LCP_MULTILINK_EP_DISC_OPT,
328 dissect_lcp_multilink_ep_disc_opt,
339 CI_MULTILINK_PLUS_PROC,
340 "Multilink Plus Procedure",
347 CI_LINK_DISC_FOR_BACP,
352 dissect_lcp_bap_link_discriminator_opt
355 CI_LCP_AUTHENTICATION,
356 "LCP authentication",
364 "Consistent Overhead Byte Stuffing",
379 CI_MULTILINK_HDR_FMT,
380 "Multilink header format",
387 CI_INTERNATIONALIZATION,
388 "Internationalization",
389 ETT_LCP_INTERNATIONALIZATION_OPT,
392 dissect_lcp_internationalization_opt
396 "Simple data link on SONET/SDH",
404 #define N_LCP_OPTS (sizeof lcp_opts / sizeof lcp_opts[0])
409 #define CI_ADDRS 1 /* IP Addresses (deprecated) (RFC 1172) */
410 #define CI_COMPRESSTYPE 2 /* Compression Type (RFC 1332) */
411 #define CI_ADDR 3 /* IP Address (RFC 1332) */
412 #define CI_MOBILE_IPv4 4 /* Mobile IPv4 (RFC 2290) */
413 #define CI_MS_DNS1 129 /* Primary DNS value (RFC 1877) */
414 #define CI_MS_WINS1 130 /* Primary WINS value (RFC 1877) */
415 #define CI_MS_DNS2 131 /* Secondary DNS value (RFC 1877) */
416 #define CI_MS_WINS2 132 /* Secondary WINS value (RFC 1877) */
418 static void dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, const u_char *opd,
419 int offset, guint length, proto_tree *tree);
420 static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, const u_char *opd,
421 int offset, guint length, proto_tree *tree);
423 static const ip_tcp_opt ipcp_opts[] = {
426 "IP addresses (deprecated)",
427 ETT_IPCP_IPADDRS_OPT,
430 dissect_ipcp_addrs_opt
434 "IP compression protocol",
435 ETT_IPCP_COMPRESSPROT_OPT,
438 dissect_lcp_protocol_opt
446 dissect_ipcp_addr_opt
450 "Mobile node's home IP address",
454 dissect_ipcp_addr_opt
458 "Primary DNS server IP address",
462 dissect_ipcp_addr_opt
466 "Primary WINS server IP address",
470 dissect_ipcp_addr_opt
474 "Secondary DNS server IP address",
478 dissect_ipcp_addr_opt
482 "Secondary WINS server IP address",
486 dissect_ipcp_addr_opt
490 #define N_IPCP_OPTS (sizeof ipcp_opts / sizeof ipcp_opts[0])
493 capture_ppp( const u_char *pd, guint32 cap_len, packet_counts *ld ) {
494 switch (pntohs(&pd[2])) {
496 capture_ip(pd, 4, cap_len, ld);
505 dissect_lcp_mru_opt(const ip_tcp_opt *optp, const u_char *opd, int offset,
506 guint length, proto_tree *tree)
508 proto_tree_add_text(tree, offset, length, "MRU: %u", pntohs(opd));
512 dissect_lcp_async_map_opt(const ip_tcp_opt *optp, const u_char *opd, int offset,
513 guint length, proto_tree *tree)
515 proto_tree_add_text(tree, offset, length, "Async characters to map: 0x%08x",
520 dissect_lcp_protocol_opt(const ip_tcp_opt *optp, const u_char *opd, int offset,
521 guint length, proto_tree *tree)
525 proto_tree *field_tree = NULL;
527 tf = proto_tree_add_text(tree, offset, length, "%s: %u byte%s",
528 optp->name, length, plurality(length, "", "s"));
529 field_tree = proto_item_add_subtree(tf, optp->subtree_index);
532 protocol = pntohs(opd);
533 proto_tree_add_text(field_tree, offset, 2, "%s: %s (0x%02x)", optp->name,
534 val_to_str(protocol, ppp_vals, "Unknown"), protocol);
539 proto_tree_add_text(field_tree, offset, length, "Data (%d byte%s)", length,
540 plurality(length, "", "s"));
544 dissect_lcp_magicnumber_opt(const ip_tcp_opt *optp, const u_char *opd,
545 int offset, guint length, proto_tree *tree)
547 proto_tree_add_text(tree, offset, length, "Magic number: 0x%08x",
552 dissect_lcp_fcs_alternatives_opt(const ip_tcp_opt *optp, const u_char *opd,
553 int offset, guint length, proto_tree *tree)
556 proto_tree *field_tree = NULL;
560 tf = proto_tree_add_text(tree, offset, length, "%s: 0x%02x",
561 optp->name, alternatives);
562 field_tree = proto_item_add_subtree(tf, optp->subtree_index);
564 if (alternatives & 0x1)
565 proto_tree_add_text(field_tree, offset + 2, 1, "%s",
566 decode_boolean_bitfield(alternatives, 0x1, 8, "Null FCS", NULL));
567 if (alternatives & 0x2)
568 proto_tree_add_text(field_tree, offset + 2, 1, "%s",
569 decode_boolean_bitfield(alternatives, 0x2, 8, "CCITT 16-bit FCS", NULL));
570 if (alternatives & 0x4)
571 proto_tree_add_text(field_tree, offset + 2, 1, "%s",
572 decode_boolean_bitfield(alternatives, 0x4, 8, "CCITT 32-bit FCS", NULL));
576 dissect_lcp_self_describing_pad_opt(const ip_tcp_opt *optp, const u_char *opd,
577 int offset, guint length, proto_tree *tree)
579 proto_tree_add_text(tree, offset, length,
580 "Maximum octets of self-describing padding: %u",
585 dissect_lcp_numbered_mode_opt(const ip_tcp_opt *optp, const u_char *opd,
586 int offset, guint length, proto_tree *tree)
589 proto_tree *field_tree = NULL;
591 tf = proto_tree_add_text(tree, offset, length, "%s: %u byte%s",
592 optp->name, length, plurality(length, "", "s"));
593 field_tree = proto_item_add_subtree(tf, optp->subtree_index);
596 proto_tree_add_text(field_tree, offset, 1, "Window: %u", *opd);
601 proto_tree_add_text(field_tree, offset, length, "Address (%d byte%s)",
602 length, plurality(length, "", "s"));
605 static const value_string callback_op_vals[] = {
606 {0, "Location is determined by user authentication" },
607 {1, "Message is dialing string" },
608 {2, "Message is location identifier" },
609 {3, "Message is E.164" },
610 {4, "Message is distinguished name" },
615 dissect_lcp_callback_opt(const ip_tcp_opt *optp, const u_char *opd, int offset,
616 guint length, proto_tree *tree)
619 proto_tree *field_tree = NULL;
621 tf = proto_tree_add_text(tree, offset, length, "%s: %u byte%s",
622 optp->name, length, plurality(length, "", "s"));
623 field_tree = proto_item_add_subtree(tf, optp->subtree_index);
626 proto_tree_add_text(field_tree, offset, 1, "Operation: %s (0x%02x)",
627 val_to_str(*opd, callback_op_vals, "Unknown"),
633 proto_tree_add_text(field_tree, offset, length, "Message (%d byte%s)",
634 length, plurality(length, "", "s"));
638 dissect_lcp_multilink_mrru_opt(const ip_tcp_opt *optp, const u_char *opd,
639 int offset, guint length, proto_tree *tree)
641 proto_tree_add_text(tree, offset, length, "Multilink MRRU: %u",
646 #define CLASS_LOCAL 1
648 #define CLASS_IEEE_802_1 3
649 #define CLASS_PPP_MAGIC_NUMBER 4
650 #define CLASS_PSDN_DIRECTORY_NUMBER 5
652 static const value_string multilink_ep_disc_class_vals[] = {
653 {CLASS_NULL, "Null" },
654 {CLASS_LOCAL, "Locally assigned address" },
655 {CLASS_IP, "IP address" },
656 {CLASS_IEEE_802_1, "IEEE 802.1 globally assigned MAC address" },
657 {CLASS_PPP_MAGIC_NUMBER, "PPP magic-number block" },
658 {CLASS_PSDN_DIRECTORY_NUMBER, "Public switched network directory number" },
663 dissect_lcp_multilink_ep_disc_opt(const ip_tcp_opt *optp, const u_char *opd,
664 int offset, guint length, proto_tree *tree)
667 proto_tree *field_tree = NULL;
668 guint8 ep_disc_class;
670 tf = proto_tree_add_text(tree, offset, length, "%s: %u byte%s",
671 optp->name, length, plurality(length, "", "s"));
672 field_tree = proto_item_add_subtree(tf, optp->subtree_index);
675 ep_disc_class = *opd;
676 proto_tree_add_text(field_tree, offset, 1, "Class: %s (%u)",
677 val_to_str(ep_disc_class, multilink_ep_disc_class_vals, "Unknown"),
683 switch (ep_disc_class) {
686 proto_tree_add_text(field_tree, offset, length,
687 "Address (%d byte%s), should have been empty",
688 length, plurality(length, "", "s"));
693 proto_tree_add_text(field_tree, offset, length,
694 "Address (%d byte%s), should have been <20",
695 length, plurality(length, "", "s"));
697 proto_tree_add_text(field_tree, offset, length,
698 "Address (%d byte%s)",
699 length, plurality(length, "", "s"));
705 proto_tree_add_text(field_tree, offset, length,
706 "Address (%d byte%s), should have been 4",
707 length, plurality(length, "", "s"));
709 proto_tree_add_text(field_tree, offset, length,
710 "Address: %s", ip_to_str(opd));
714 case CLASS_IEEE_802_1:
716 proto_tree_add_text(field_tree, offset, length,
717 "Address (%d byte%s), should have been 6",
718 length, plurality(length, "", "s"));
720 proto_tree_add_text(field_tree, offset, length,
721 "Address: %s", ether_to_str(opd));
725 case CLASS_PPP_MAGIC_NUMBER:
726 /* XXX - dissect as 32-bit magic numbers */
728 proto_tree_add_text(field_tree, offset, length,
729 "Address (%d byte%s), should have been <20",
730 length, plurality(length, "", "s"));
732 proto_tree_add_text(field_tree, offset, length,
733 "Address (%d byte%s)",
734 length, plurality(length, "", "s"));
738 case CLASS_PSDN_DIRECTORY_NUMBER:
740 proto_tree_add_text(field_tree, offset, length,
741 "Address (%d byte%s), should have been <20",
742 length, plurality(length, "", "s"));
744 proto_tree_add_text(field_tree, offset, length,
745 "Address (%d byte%s)",
746 length, plurality(length, "", "s"));
751 proto_tree_add_text(field_tree, offset, length,
752 "Address (%d byte%s)",
753 length, plurality(length, "", "s"));
760 dissect_lcp_bap_link_discriminator_opt(const ip_tcp_opt *optp, const u_char *opd,
761 int offset, guint length, proto_tree *tree)
763 proto_tree_add_text(tree, offset, length,
764 "Link discriminator for BAP: 0x%04x",
768 /* Character set numbers from the IANA charset registry. */
769 static const value_string charset_num_vals[] = {
775 dissect_lcp_internationalization_opt(const ip_tcp_opt *optp, const u_char *opd,
776 int offset, guint length, proto_tree *tree)
779 proto_tree *field_tree = NULL;
781 tf = proto_tree_add_text(tree, 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, offset, 4, "Character set: %s (0x%04x)",
787 val_to_str(pntohl(opd), charset_num_vals, "Unknown"),
793 /* XXX - should be displayed as an ASCII string */
794 proto_tree_add_text(field_tree, offset, length, "Language tag (%d byte%s)",
795 length, plurality(length, "", "s"));
800 dissect_ipcp_addrs_opt(const ip_tcp_opt *optp, const u_char *opd,
801 int offset, guint length, proto_tree *tree)
804 proto_tree *field_tree = NULL;
806 tf = proto_tree_add_text(tree, offset, length, "%s: %u byte%s",
807 optp->name, length, plurality(length, "", "s"));
808 field_tree = proto_item_add_subtree(tf, optp->subtree_index);
811 proto_tree_add_text(field_tree, offset, 4,
812 "Source IP address: %s", ip_to_str(opd));
816 proto_tree_add_text(field_tree, offset, 4,
817 "Destination IP address: %s", ip_to_str(opd));
820 static void dissect_ipcp_addr_opt(const ip_tcp_opt *optp, const u_char *opd,
821 int offset, guint length, proto_tree *tree)
823 proto_tree_add_text(tree, offset, length, "%s: %s", optp->name,
824 ip_to_str((guint8 *)opd));
828 dissect_cp( const u_char *pd, int offset, const char *proto_short_name,
829 const char *proto_long_name, int proto_subtree_index,
830 const value_string *proto_vals, int options_subtree_index,
831 const ip_tcp_opt *opts, int nopts, frame_data *fd, proto_tree *tree ) {
833 proto_tree *fh_tree = NULL;
835 proto_tree *field_tree;
844 length = pntohs(&pd[2+offset]);
846 if(check_col(fd, COL_INFO))
847 col_add_fstr(fd, COL_INFO, "%sCP %s", proto_short_name,
848 val_to_str(code, proto_vals, "Unknown"));
851 ti = proto_tree_add_text(tree, 0+offset, 4, "%s Control Protocol",
853 fh_tree = proto_item_add_subtree(ti, proto_subtree_index);
854 proto_tree_add_text(fh_tree, 0+offset, 1, "Code: %s (0x%02x)",
855 val_to_str(code, proto_vals, "Unknown"), code);
856 proto_tree_add_text(fh_tree, 1+offset, 1, "Identifier: 0x%02x",
858 proto_tree_add_text(fh_tree, 2+offset, 2, "Length: %u",
871 tf = proto_tree_add_text(fh_tree, offset, length,
872 "Options: (%d byte%s)", length, plurality(length, "", "s"));
873 field_tree = proto_item_add_subtree(tf, options_subtree_index);
874 dissect_ip_tcp_options(&pd[offset], offset, length, opts, nopts,
885 proto_tree_add_text(fh_tree, offset, 4, "Magic number: 0x%08x",
886 pntohl(&pd[offset]));
890 proto_tree_add_text(fh_tree, offset, length, "Message (%d byte%s)",
891 length, plurality(length, "", "s"));
897 proto_tree_add_text(fh_tree, offset, 4, "Magic number: 0x%08x",
898 pntohl(&pd[offset]));
901 proto_tree_add_text(fh_tree, offset, 4, "Seconds remaining: %u",
902 pntohl(&pd[offset]));
906 proto_tree_add_text(fh_tree, offset, length, "Message (%d byte%s)",
907 length, plurality(length, "", "s"));
913 protocol = pntohs(&pd[offset]);
914 proto_tree_add_text(fh_tree, offset, 2, "Rejected protocol: %s (0x%04x)",
915 val_to_str(protocol, ppp_vals, "Unknown"), protocol);
919 proto_tree_add_text(fh_tree, offset, length, "Rejected packet (%d byte%s)",
920 length, plurality(length, "", "s"));
921 /* XXX - should be dissected as a PPP packet */
926 /* decode the rejected LCP packet here. */
928 proto_tree_add_text(fh_tree, offset, length, "Rejected packet (%d byte%s)",
929 length, plurality(length, "", "s"));
935 proto_tree_add_text(fh_tree, offset, length, "Data (%d byte%s)",
936 length, plurality(length, "", "s"));
941 proto_tree_add_text(fh_tree, offset, length, "Stuff (%d byte%s)",
942 length, plurality(length, "", "s"));
948 dissect_ppp_stuff( const u_char *pd, int offset, frame_data *fd,
949 proto_tree *tree, proto_tree *fh_tree ) {
952 ppp_prot = pntohs(&pd[offset]);
955 proto_tree_add_text(fh_tree, offset, 2, "Protocol: %s (0x%04x)",
956 val_to_str(ppp_prot, ppp_vals, "Unknown"), ppp_prot);
962 dissect_ip(pd, offset, fd, tree);
965 dissect_ddp(pd, offset, fd, tree);
968 dissect_ipx(pd, offset, fd, tree);
971 dissect_vines(pd, offset, fd, tree);
974 dissect_ipv6(pd, offset, fd, tree);
977 dissect_cp(pd, offset, "L", "Link", ETT_LCP, lcp_vals, ETT_LCP_OPTIONS,
978 lcp_opts, N_LCP_OPTS, fd, tree);
981 dissect_cp(pd, offset, "IP", "IP", ETT_IPCP, cp_vals, ETT_IPCP_OPTIONS,
982 ipcp_opts, N_IPCP_OPTS, fd, tree);
985 if (check_col(fd, COL_INFO))
986 col_add_fstr(fd, COL_INFO, "PPP %s (0x%04x)",
987 val_to_str(ppp_prot, ppp_vals, "Unknown"), ppp_prot);
988 dissect_data(pd, offset, fd, tree);
994 dissect_payload_ppp( const u_char *pd, int offset, frame_data *fd, proto_tree *tree ) {
996 proto_tree *fh_tree = NULL;
998 /* populate a tree in the second pane with the status of the link
1001 ti = proto_tree_add_item(tree, proto_ppp, 0+offset, 2, NULL);
1002 fh_tree = proto_item_add_subtree(ti, ETT_PPP);
1005 dissect_ppp_stuff(pd, offset, fd, tree, fh_tree);
1009 dissect_ppp( const u_char *pd, frame_data *fd, proto_tree *tree ) {
1012 proto_tree *fh_tree = NULL;
1014 ph.ppp_addr = pd[0];
1016 ph.ppp_prot = pntohs(&pd[2]);
1018 /* load the top pane info. This should be overwritten by
1019 the next protocol in the stack */
1021 if(check_col(fd, COL_RES_DL_SRC))
1022 col_add_str(fd, COL_RES_DL_SRC, "N/A" );
1023 if(check_col(fd, COL_RES_DL_DST))
1024 col_add_str(fd, COL_RES_DL_DST, "N/A" );
1025 if(check_col(fd, COL_PROTOCOL))
1026 col_add_str(fd, COL_PROTOCOL, "PPP" );
1028 /* populate a tree in the second pane with the status of the link
1031 ti = proto_tree_add_item(tree, proto_ppp, 0, 4, NULL);
1032 fh_tree = proto_item_add_subtree(ti, ETT_PPP);
1033 proto_tree_add_text(fh_tree, 0, 1, "Address: %02x", ph.ppp_addr);
1034 proto_tree_add_text(fh_tree, 1, 1, "Control: %02x", ph.ppp_ctl);
1037 if (!dissect_ppp_stuff(pd, 2, fd, tree, fh_tree)) {
1038 if (check_col(fd, COL_PROTOCOL))
1039 col_add_fstr(fd, COL_PROTOCOL, "0x%04x", ph.ppp_prot);
1044 proto_register_ppp(void)
1046 /* static hf_register_info hf[] = {
1048 { "Name", "ppp.abbreviation", TYPE, VALS_POINTER }},
1051 proto_ppp = proto_register_protocol("Point-to-Point Protocol", "ppp");
1052 /* proto_register_field_array(proto_ppp, hf, array_length(hf));*/