2 * Routines for ppp packet disassembly
4 * $Id: packet-ppp.c,v 1.14 1999/08/24 06:14:16 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 static int proto_ppp = -1;
40 /* PPP structs and definitions */
42 typedef struct _e_ppphdr {
49 /* Protocol types, from Linux "ppp_defs.h" and
51 http://www.isi.edu/in-notes/iana/assignments/ppp-numbers
54 #define PPP_IP 0x21 /* Internet Protocol */
55 #define PPP_AT 0x29 /* AppleTalk Protocol */
56 #define PPP_IPX 0x2b /* IPX protocol */
57 #define PPP_VJC_COMP 0x2d /* VJ compressed TCP */
58 #define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */
59 #define PPP_VINES 0x35 /* Banyan Vines */
60 #define PPP_IPV6 0x57 /* Internet Protocol Version 6 */
61 #define PPP_COMP 0xfd /* compressed packet */
62 #define PPP_IPCP 0x8021 /* IP Control Protocol */
63 #define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */
64 #define PPP_IPXCP 0x802b /* IPX Control Protocol */
65 #define PPP_CCP 0x80fd /* Compression Control Protocol */
66 #define PPP_LCP 0xc021 /* Link Control Protocol */
67 #define PPP_PAP 0xc023 /* Password Authentication Protocol */
68 #define PPP_LQR 0xc025 /* Link Quality Report protocol */
69 #define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */
70 #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" },
93 /* CP (LCP, IPCP, etc.) codes.
96 #define CONFREQ 1 /* Configuration Request */
97 #define CONFACK 2 /* Configuration Ack */
98 #define CONFNAK 3 /* Configuration Nak */
99 #define CONFREJ 4 /* Configuration Reject */
100 #define TERMREQ 5 /* Termination Request */
101 #define TERMACK 6 /* Termination Ack */
102 #define CODEREJ 7 /* Code Reject */
104 static const value_string cp_vals[] = {
105 {CONFREQ, "Configuration Request " },
106 {CONFACK, "Configuration Ack " },
107 {CONFNAK, "Configuration Nak " },
108 {CONFREJ, "Configuration Reject " },
109 {TERMREQ, "Termination Request " },
110 {TERMACK, "Termination Ack " },
111 {CODEREJ, "Code Reject " },
115 * LCP-specific packet types.
117 #define PROTREJ 8 /* Protocol Reject */
118 #define ECHOREQ 9 /* Echo Request */
119 #define ECHOREP 10 /* Echo Reply */
120 #define DISCREQ 11 /* Discard Request */
121 #define CBCP_OPT 6 /* Use callback control protocol */
123 static const value_string lcp_vals[] = {
124 {CONFREQ, "Configuration Request " },
125 {CONFACK, "Configuration Ack " },
126 {CONFNAK, "Configuration Nak " },
127 {CONFREJ, "Configuration Reject " },
128 {TERMREQ, "Termination Request " },
129 {TERMACK, "Termination Ack " },
130 {CODEREJ, "Code Reject " },
131 {PROTREJ, "Protocol Reject " },
132 {ECHOREQ, "Echo Request " },
133 {ECHOREP, "Echo Reply " },
134 {DISCREQ, "Discard Request " },
135 {CBCP_OPT, "Use callback control protocol" },
141 #define CI_MRU 1 /* Maximum Receive Unit */
142 #define CI_ASYNCMAP 2 /* Async Control Character Map */
143 #define CI_AUTHTYPE 3 /* Authentication Type */
144 #define CI_QUALITY 4 /* Quality Protocol */
145 #define CI_MAGICNUMBER 5 /* Magic Number */
146 #define CI_PCOMPRESSION 7 /* Protocol Field Compression */
147 #define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */
148 #define CI_CALLBACK 13 /* callback */
150 static const value_string lcp_opt_vals[] = {
151 {CI_MRU, "Maximum Receive Unit" },
152 {CI_ASYNCMAP, "Async Control Character Map" },
153 {CI_AUTHTYPE, "Authentication Type" },
154 {CI_QUALITY, "Quality Protocol" },
155 {CI_MAGICNUMBER, "Magic Number" },
156 {CI_PCOMPRESSION, "Protocol Field Compression" },
157 {CI_ACCOMPRESSION,"Address/Control Field Compression" },
158 {CI_CALLBACK, "callback" },
164 #define CI_ADDRS 1 /* IP Addresses */
165 #define CI_COMPRESSTYPE 2 /* Compression Type */
167 #define CI_MS_DNS1 129 /* Primary DNS value */
168 #define CI_MS_WINS1 130 /* Primary WINS value */
169 #define CI_MS_DNS2 131 /* Secondary DNS value */
170 #define CI_MS_WINS2 132 /* Secondary WINS value */
172 static const value_string ipcp_opt_vals[] = {
173 {CI_ADDRS, "IP Addresses" },
174 {CI_COMPRESSTYPE,"Compression Type" },
175 {CI_ADDR, "Address" },
176 {CI_MS_DNS1, "Primary DNS value" },
177 {CI_MS_WINS1, "Primary WINS value" },
178 {CI_MS_DNS2, "Secondary DNS value" },
179 {CI_MS_WINS2, "Secondary WINS value" },
183 capture_ppp( const u_char *pd, guint32 cap_len, packet_counts *ld ) {
184 switch (pntohs(&pd[2])) {
186 capture_ip(pd, 4, cap_len, ld);
195 dissect_ipcp( const u_char *pd, int offset, frame_data *fd, proto_tree *tree ) {
203 ipcpcode = pd[0+offset];
204 ipcpid = pd[1+offset];
205 optionslength= pntohs(&pd[2+offset]);
207 if(check_col(fd, COL_INFO))
208 col_add_fstr(fd, COL_INFO, "IPCP %s",
209 val_to_str(ipcpcode, cp_vals, "Unknown"));
212 ti = proto_tree_add_text(tree, 0+offset, 4, "IP Control Protocol" );
213 fh_tree = proto_item_add_subtree(ti, ETT_IPCP);
214 proto_tree_add_text(fh_tree, 0+offset, 1, "Code: %s (0x%02x)",
215 val_to_str(ipcpcode, cp_vals, "Unknown"), ipcpcode);
216 proto_tree_add_text(fh_tree, 1+offset, 1, "Identifier: 0x%02x",
218 proto_tree_add_text(fh_tree, 2+offset, 2, "Length: %d",
223 /* decode lcp options here. */
225 dissect_data(pd, 4+offset, fd, tree);
231 dissect_lcp( const u_char *pd, int offset, frame_data *fd, proto_tree *tree ) {
239 lcpcode = pd[0+offset];
240 lcpid = pd[1+offset];
241 optionslength= pntohs(&pd[2+offset]);
243 if(check_col(fd, COL_INFO))
244 col_add_fstr(fd, COL_INFO, "LCP %s",
245 val_to_str(lcpcode, lcp_vals, "Unknown"));
248 ti = proto_tree_add_text(tree, 0+offset, 4, "Link Control Protocol" );
249 fh_tree = proto_item_add_subtree(ti, ETT_LCP);
250 proto_tree_add_text(fh_tree, 0+offset, 1, "Code: %s (0x%02x)",
251 val_to_str(lcpcode, lcp_vals, "Unknown"), lcpcode);
252 proto_tree_add_text(fh_tree, 1+offset, 1, "Identifier: 0x%02x",
254 proto_tree_add_text(fh_tree, 2+offset, 2, "Length: %d",
259 /* decode lcp options here. */
261 dissect_data(pd, 4+offset, fd, tree);
267 dissect_payload_ppp( const u_char *pd, int offset, frame_data *fd, proto_tree *tree ) {
272 /* ph.ppp_addr = pd[0+offset]; */
273 /* ph.ppp_ctl = pd[1+offset]; */
274 ph.ppp_prot = pntohs(&pd[0+offset]);
276 /* populate a tree in the second pane with the status of the link
279 ti = proto_tree_add_item(tree, proto_ppp, 0+offset, 2, NULL);
280 fh_tree = proto_item_add_subtree(ti, ETT_PPP);
281 proto_tree_add_text(fh_tree, 0+offset, 2, "Protocol: %s (0x%04x)",
282 val_to_str(ph.ppp_prot, ppp_vals, "Unknown"), ph.ppp_prot);
285 switch (ph.ppp_prot) {
287 dissect_ip(pd, 2+offset, fd, tree);
290 dissect_ddp(pd, 2+offset, fd, tree);
293 dissect_ipx(pd, 2+offset, fd, tree);
296 dissect_vines(pd, 2+offset, fd, tree);
299 dissect_ipv6(pd, 2+offset, fd, tree);
302 dissect_lcp(pd, 2+offset, fd, tree);
305 dissect_ipcp(pd, 2+offset, fd, tree);
308 dissect_data(pd, 2+offset, fd, tree);
309 if (check_col(fd, COL_INFO))
310 col_add_fstr(fd, COL_INFO, "PPP %s (0x%04x)",
311 val_to_str(ph.ppp_prot, ppp_vals, "Unknown"), ph.ppp_prot);
317 dissect_ppp( const u_char *pd, frame_data *fd, proto_tree *tree ) {
322 static const value_string ppp_vals[] = {
324 {PPP_AT, "Appletalk" },
325 {PPP_IPX, "Netware IPX/SPX"},
326 {PPP_VINES, "Vines" },
332 ph.ppp_prot = pntohs(&pd[2]);
334 /* load the top pane info. This should be overwritten by
335 the next protocol in the stack */
337 if(check_col(fd, COL_RES_DL_SRC))
338 col_add_str(fd, COL_RES_DL_SRC, "N/A" );
339 if(check_col(fd, COL_RES_DL_DST))
340 col_add_str(fd, COL_RES_DL_DST, "N/A" );
341 if(check_col(fd, COL_PROTOCOL))
342 col_add_str(fd, COL_PROTOCOL, "PPP" );
343 if(check_col(fd, COL_INFO))
344 col_add_str(fd, COL_INFO, "PPP" );
346 /* populate a tree in the second pane with the status of the link
349 ti = proto_tree_add_item(tree, proto_ppp, 0, 4, NULL);
350 fh_tree = proto_item_add_subtree(ti, ETT_PPP);
351 proto_tree_add_text(fh_tree, 0, 1, "Address: %02x", ph.ppp_addr);
352 proto_tree_add_text(fh_tree, 1, 1, "Control: %02x", ph.ppp_ctl);
353 proto_tree_add_text(fh_tree, 2, 2, "Protocol: %s (0x%04x)",
354 val_to_str(ph.ppp_prot, ppp_vals, "Unknown"), ph.ppp_prot);
357 switch (ph.ppp_prot) {
359 dissect_ip(pd, 4, fd, tree);
362 dissect_ddp(pd, 4, fd, tree);
365 dissect_ipx(pd, 4, fd, tree);
368 dissect_vines(pd, 4, fd, tree);
371 dissect_ipv6(pd, 4, fd, tree);
374 dissect_data(pd, 4, fd, tree);
375 if (check_col(fd, COL_PROTOCOL))
376 col_add_fstr(fd, COL_PROTOCOL, "0x%04x", ph.ppp_prot);
382 proto_register_ppp(void)
384 /* static hf_register_info hf[] = {
386 { "Name", "ppp.abbreviation", TYPE, VALS_POINTER }},
389 proto_ppp = proto_register_protocol("Point-to-Point Protocol", "ppp");
390 /* proto_register_field_array(proto_ppp, hf, array_length(hf));*/