xref: /openbsd-src/usr.sbin/tcpdump/print-ppp.c (revision 62a742911104f98b9185b2c6b6007d9b1c36396c)
1 /*	$OpenBSD: print-ppp.c,v 1.8 1999/02/16 03:45:11 deraadt Exp $	*/
2 
3 /*
4  * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution, and (3) all advertising materials mentioning
13  * features or use of this software display the following acknowledgement:
14  * ``This product includes software developed by the University of California,
15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16  * the University nor the names of its contributors may be used to endorse
17  * or promote products derived from this software without specific prior
18  * written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  */
23 
24 #ifndef lint
25 static const char rcsid[] =
26     "@(#) $Header: /home/cvs/src/usr.sbin/tcpdump/print-ppp.c,v 1.8 1999/02/16 03:45:11 deraadt Exp $ (LBL)";
27 #endif
28 
29 #ifdef PPP
30 #include <sys/param.h>
31 #include <sys/time.h>
32 #include <sys/socket.h>
33 #include <sys/file.h>
34 #include <sys/ioctl.h>
35 
36 #ifdef __STDC__
37 struct mbuf;
38 struct rtentry;
39 #endif
40 #include <net/if.h>
41 
42 #include <netinet/in.h>
43 #include <netinet/in_systm.h>
44 #include <netinet/ip.h>
45 
46 #include <netipx/ipx.h>
47 #include <netipx/ipx_if.h>
48 
49 #include <ctype.h>
50 #include <netdb.h>
51 #include <pcap.h>
52 #include <signal.h>
53 #include <stdio.h>
54 
55 #include <netinet/if_ether.h>
56 #include "ethertype.h"
57 
58 #include <net/ppp_defs.h>
59 #include "interface.h"
60 #include "addrtoname.h"
61 
62 struct protonames {
63 	u_short protocol;
64 	char *name;
65 };
66 
67 static struct protonames protonames[] = {
68 	/*
69 	 * Protocol field values.
70 	 */
71 	PPP_IP,		"IP",		/* Internet Protocol */
72 	PPP_XNS,	"XNS",		/* Xerox NS */
73 	PPP_IPX,	"IPX",		/* IPX Datagram (RFC1552) */
74 	PPP_VJC_COMP,	"VJC_UNCOMP",	/* VJ compressed TCP */
75 	PPP_VJC_UNCOMP,	"VJC_UNCOMP",	/* VJ uncompressed TCP */
76 	PPP_COMP,	"COMP",		/* compressed packet */
77 	PPP_IPCP,	"IPCP",		/* IP Control Protocol */
78 	PPP_IPXCP,	"IPXCP",	/* IPX Control Protocol (RFC1552) */
79 	PPP_CCP,	"CCP",		/* Compression Control Protocol */
80 	PPP_LCP,	"LCP",		/* Link Control Protocol */
81 	PPP_PAP,	"PAP",		/* Password Authentication Protocol */
82 	PPP_LQR,	"LQR",		/* Link Quality Report protocol */
83 	PPP_CHAP,	"CHAP",		/* Cryptographic Handshake Auth. Proto*/
84 };
85 
86 /* LCP */
87 
88 #define LCP_CONF_REQ	1
89 #define LCP_CONF_ACK	2
90 #define LCP_CONF_NAK	3
91 #define LCP_CONF_REJ	4
92 #define LCP_TERM_REQ	5
93 #define LCP_TERM_ACK	6
94 #define LCP_CODE_REJ	7
95 #define LCP_PROT_REJ	8
96 #define LCP_ECHO_REQ	9
97 #define LCP_ECHO_RPL	10
98 #define LCP_DISC_REQ	11
99 
100 #define LCP_MIN	LCP_CONF_REQ
101 #define LCP_MAX LCP_DISC_REQ
102 
103 static char *lcpcodes[] = {
104 	/*
105 	 * LCP code values (RFC1661, pp26)
106 	 */
107 	"Configure-Request",
108 	"Configure-Ack",
109 	"Configure-Nak",
110 	"Configure-Reject",
111 	"Terminate-Request",
112 	"Terminate-Ack",
113  	"Code-Reject",
114 	"Protocol-Reject",
115 	"Echo-Request",
116 	"Echo-Reply",
117 	"Discard-Request",
118 };
119 
120 #define LCPOPT_VEXT	0
121 #define LCPOPT_MRU	1
122 #define LCPOPT_ACCM	2
123 #define LCPOPT_AP	3
124 #define LCPOPT_QP	4
125 #define LCPOPT_MN	5
126 #define LCPOPT_PFC	7
127 #define LCPOPT_ACFC	8
128 
129 #define LCPOPT_MIN 0
130 #define LCPOPT_MAX 24
131 
132 static char *lcpconfopts[] = {
133 	"Vendor-Ext",
134 	"Max-Rx-Unit",
135 	"Async-Ctrl-Char-Map",
136 	"Auth-Prot",
137 	"Quality-Prot",
138 	"Magic-Number",
139 	"unassigned (6)",
140 	"Prot-Field-Compr",
141 	"Add-Ctrl-Field-Compr",
142 	"FCS-Alternatives",
143 	"Self-Describing-Pad",
144 	"Numbered-Mode",
145 	"Multi-Link-Procedure",
146 	"Call-Back",
147 	"Connect-Time"
148 	"Compund-Frames",
149 	"Nominal-Data-Encap",
150 	"Multilink-MRRU",
151 	"Multilink-SSNHF",
152 	"Multilink-ED",
153 	"Proprietary",
154 	"DCE-Identifier",
155 	"Multilink-Plus-Proc",
156 	"Link-Discriminator",
157 	"LCP-Auth-Option",
158 };
159 
160 /* CHAP */
161 
162 #define CHAP_CHAL	1
163 #define CHAP_RESP	2
164 #define CHAP_SUCC	3
165 #define CHAP_FAIL	4
166 
167 #define CHAP_CODEMIN 1
168 #define CHAP_CODEMAX 4
169 
170 static char *chapcode[] = {
171 	"Challenge",
172 	"Response",
173 	"Success",
174 	"Failure",
175 };
176 
177 /* PAP */
178 
179 #define PAP_AREQ	1
180 #define PAP_AACK	2
181 #define PAP_ANAK	3
182 
183 #define PAP_CODEMIN	1
184 #define PAP_CODEMAX	3
185 
186 static char *papcode[] = {
187 	"Authenticate-Request",
188 	"Authenticate-Ack",
189 	"Authenticate-Nak",
190 };
191 
192 /* IPCP */
193 
194 #define IPCP_CODE_CFG_REQ	1
195 #define IPCP_CODE_CFG_ACK	2
196 #define IPCP_CODE_CFG_NAK	3
197 #define IPCP_CODE_CFG_REJ	4
198 #define IPCP_CODE_TRM_REQ	5
199 #define IPCP_CODE_TRM_ACK	6
200 #define IPCP_CODE_COD_REJ	7
201 
202 #define IPCP_CODE_MIN IPCP_CODE_CFG_REQ
203 #define IPCP_CODE_MAX IPCP_CODE_COD_REJ
204 
205 #define IPCP_2ADDR	1
206 #define IPCP_CP		2
207 #define IPCP_ADDR	3
208 
209 static int handle_lcp(const u_char *p, int length);
210 static int print_lcp_config_options(u_char *p);
211 static int handle_chap(const u_char *p, int length);
212 static int handle_ipcp(const u_char *p, int length);
213 static int handle_pap(const u_char *p, int length);
214 
215 void
216 ppp_hdlc_print(p, length)
217 	const u_char *p;
218 	int length;
219 {
220 	int proto = PPP_PROTOCOL(p);
221 	int i, j, x;
222 	u_char *ptr;
223 
224 	printf("ID-%03d ", *(p+5));
225 
226 	for (i = sizeof(protonames) / sizeof(protonames[0]) - 1; i >= 0; i--) {
227 		if (proto == protonames[i].protocol) {
228 			printf("%s: ", protonames[i].name);
229 
230 			switch(proto) {
231 
232 			case PPP_LCP:
233 				handle_lcp(p, length);
234 				break;
235 			case PPP_CHAP:
236 				handle_chap(p, length);
237 				break;
238 			case PPP_PAP:
239 				handle_pap(p, length);
240 				break;
241 			case PPP_IPCP:
242 				handle_ipcp(p, length);
243 				break;
244 			}
245 			break;
246 		}
247 	}
248 	if (i < 0)
249 		printf("%04x: ", proto);
250 }
251 
252 /* print LCP frame */
253 
254 static int
255 handle_lcp(p, length)
256 	const u_char *p;
257 	int length;
258 {
259 	int x, j;
260 	u_char *ptr;
261 
262 	x = *(p + 4);
263 
264 	if ((x >= LCP_MIN) && (x <= LCP_MAX))
265 		printf("%s", lcpcodes[x-1]);
266 	else {
267 		printf("0x%02x", x);
268 		return;
269 	}
270 
271 	length -= 4;
272 
273 	switch(x) {
274 
275 	case LCP_CONF_REQ:
276 	case LCP_CONF_ACK:
277 	case LCP_CONF_NAK:
278 	case LCP_CONF_REJ:
279 		x = length;
280 		ptr = (u_char *)p+8;
281 		do {
282 			if((j = print_lcp_config_options(ptr)) == 0)
283 				break;
284 			x -= j;
285 			ptr += j;
286 		}
287 		while(x > 0);
288 		break;
289 
290 	case LCP_ECHO_REQ:
291 	case LCP_ECHO_RPL:
292 		printf(", Magic-Number=%d", ((*(p+ 8) << 24) + (*(p+9) << 16) +
293 					     (*(p+10) <<  8) + (*(p+11))));
294 		break;
295 	case LCP_TERM_REQ:
296 	case LCP_TERM_ACK:
297 	case LCP_CODE_REJ:
298 	case LCP_PROT_REJ:
299 	case LCP_DISC_REQ:
300 	default:
301 		break;
302 	}
303 }
304 
305 /* LCP config options */
306 
307 static int
308 print_lcp_config_options(p)
309 	u_char *p;
310 {
311 	int len	= *(p+1);
312 	int opt = *p;
313 
314 	if((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
315 		printf(", %s", lcpconfopts[opt]);
316 
317 	switch(opt) {
318 	case LCPOPT_MRU:
319 		if(len == 4)
320 			printf("=%d", (*(p+2) << 8) + *(p+3));
321 		break;
322 	case LCPOPT_AP:
323 		if(len >= 4) {
324 			if(*(p+2) == 0xc0 && *(p+3) == 0x23)
325 				printf(" PAP");
326 			else if(*(p+2) == 0xc2 && *(p+3) == 0x23) {
327 				printf(" CHAP/");
328 				switch(*(p+4)) {
329 				default:
330 					printf("unknown-algorithm-%d", *(p+4));
331 					break;
332 				case 5:
333 					printf("MD5");
334 					break;
335 				case 0x80:
336 					printf("Microsoft");
337 					break;
338 				}
339 			} else if(*(p+2) == 0xc2 && *(p+3) == 0x27)
340 					printf(" EAP");
341 			else if(*(p+2) == 0xc0 && *(p+3) == 0x27)
342 				printf(" SPAP");
343 			else if(*(p+2) == 0xc1 && *(p+3) == 0x23)
344 				printf(" Old-SPAP");
345 			else
346 				printf("unknown");
347 		}
348 		break;
349 	case LCPOPT_QP:
350 		if(len >= 4) {
351 			if(*(p+2) == 0xc0 && *(p+3) == 0x25)
352 				printf(" LQR");
353 			else
354 				printf(" unknown");
355 		}
356 		break;
357 	case LCPOPT_MN:
358 		if(len == 6)
359 			printf("=%d", ((*(p+2) << 24) + (*(p+3) << 16) +
360 				       (*(p+4) <<  8) + (*(p+5))));
361 		break;
362 	case LCPOPT_PFC:
363 		printf(" PFC");
364 		break;
365 	case LCPOPT_ACFC:
366 		printf(" ACFC");
367 		break;
368 	}
369 	return(len);
370 }
371 
372 /* CHAP */
373 
374 static int
375 handle_chap(p, length)
376 	const u_char *p;
377 	int length;
378 {
379 	int x, j;
380 	u_char *ptr;
381 
382 	x = *(p+4);
383 
384 	if((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX))
385 		printf("%s", chapcode[x-1]);
386 	else {
387 		printf("0x%02x", x);
388 		return;
389 	}
390 
391 	length -= 4;
392 
393 	switch(x) {
394 	case CHAP_CHAL:
395 	case CHAP_RESP:
396 		printf(", Value=");
397 		x = *(p+8);	/* value size */
398 		ptr = (u_char *)p+9;
399 		while(--x >= 0)
400 			printf("%02x", *ptr++);
401 		x = length - *(p+8) - 1;
402 		printf(", Name=");
403 		while(--x >= 0)
404 			printf("%c", *ptr++);
405 		break;
406 	}
407 }
408 
409 /* PAP */
410 
411 static int
412 handle_pap(p, length)
413 	const u_char *p;
414 	int length;
415 {
416 	int x, j;
417 	u_char *ptr;
418 
419 	x = *(p+4);
420 
421 	if((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX))
422 		printf("%s", papcode[x-1]);
423 	else {
424 		printf("0x%02x", x);
425 		return;
426 	}
427 
428 	length -= 4;
429 
430 	switch(x) {
431 	case PAP_AREQ:
432 		printf(", Peer-Id=");
433 		x = *(p+8);	/* peerid size */
434 		ptr = (u_char *)p+9;
435 		while(--x >= 0)
436 			printf("%c", *ptr++);
437 		x = *ptr++;
438 		printf(", Passwd=");
439 		while(--x >= 0)
440 			printf("%c", *ptr++);
441 		break;
442 	case PAP_AACK:
443 	case PAP_ANAK:
444 		break;
445 	}
446 }
447 
448 /* IPCP */
449 
450 static int
451 handle_ipcp(p, length)
452 	const u_char *p;
453 	int length;
454 {
455 	int x, j;
456 	u_char *ptr;
457 
458 	x = *(p+4);
459 
460 	if((x >= IPCP_CODE_MIN) && (x <= IPCP_CODE_MAX))
461 		printf("%s", lcpcodes[x-1]);	/* share table with LCP */
462 	else {
463 		printf("0x%02x", x);
464 		return;
465 	}
466 
467 	length -= 4;
468 
469 	switch(*(p+8)) {
470 	case IPCP_2ADDR:
471 		printf(", IP-Addresses");
472 		printf(", Src=%d.%d.%d.%d",
473 		       *(p+10), *(p+11), *(p+12), *(p+13));
474 		printf(", Dst=%d.%d.%d.%d",
475 		       *(p+14), *(p+15), *(p+16), *(p+17));
476 		break;
477 
478 	case IPCP_CP:
479 		printf(", IP-Compression-Protocol");
480 		break;
481 
482 	case IPCP_ADDR:
483 		printf(", IP-Address=%d.%d.%d.%d",
484 		       *(p+10), *(p+11), *(p+12), *(p+13));
485 		break;
486 	default:
487 		printf(", Unknown IPCP code 0x%x", *(p+8));
488 		break;
489 	}
490 }
491 
492 void
493 ppp_if_print(user, h, p)
494 	u_char *user;
495 	const struct pcap_pkthdr *h;
496 	register const u_char *p;
497 {
498 	register u_int length = h->len;
499 	register u_int caplen = h->caplen;
500 
501 	ts_print(&h->ts);
502 
503 	if (caplen < PPP_HDRLEN) {
504 		printf("[|ppp]");
505 		goto out;
506 	}
507 
508 	/*
509 	 * Some printers want to get back at the link level addresses,
510 	 * and/or check that they're not walking off the end of the packet.
511 	 * Rather than pass them all the way down, we set these globals.
512 	 */
513 	packetp = p;
514 	snapend = p + caplen;
515 
516 	if (eflag)
517 		ppp_hdlc_print(p, length);
518 
519 	length -= PPP_HDRLEN;
520 
521 	switch(PPP_PROTOCOL(p)) {
522 	case PPP_IP:
523 	case ETHERTYPE_IP:
524 		ip_print((const u_char *)(p + PPP_HDRLEN), length);
525 		break;
526 	case PPP_IPX:
527 	case ETHERTYPE_IPX:
528 		ipx_print((const u_char *)(p + PPP_HDRLEN), length);
529 		break;
530 
531 	default:
532 		if(!eflag)
533 			ppp_hdlc_print(p, length);
534 		if(!xflag)
535 			default_print((const u_char *)(p + PPP_HDRLEN),
536 				      caplen - PPP_HDRLEN);
537 	}
538 
539 	if (xflag)
540 		default_print((const u_char *)(p + PPP_HDRLEN),
541 			      caplen - PPP_HDRLEN);
542 out:
543 	putchar('\n');
544 }
545 
546 #else
547 
548 #include <sys/types.h>
549 #include <sys/time.h>
550 
551 #include <stdio.h>
552 
553 #include "interface.h"
554 void
555 ppp_if_print(user, h, p)
556 	u_char *user;
557 	const struct pcap_pkthdr *h;
558 	const u_char *p;
559 {
560 	error("not configured for ppp");
561 	/* NOTREACHED */
562 }
563 #endif
564