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