1 /* $OpenBSD: print-ppp.c,v 1.37 2024/10/30 10:36:28 sthen Exp $ */
2
3 /*
4 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
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 #ifdef PPP
25 #include <sys/time.h>
26 #include <sys/socket.h>
27 #include <sys/file.h>
28 #include <sys/ioctl.h>
29
30 #include <net/if.h>
31
32 #include <netinet/in.h>
33 #include <netinet/ip.h>
34
35 #include <ctype.h>
36 #include <netdb.h>
37 #include <pcap.h>
38 #include <signal.h>
39 #include <stdio.h>
40
41 #include <netinet/if_ether.h>
42 #include "ethertype.h"
43
44 #include <net/ppp_defs.h>
45 #include "interface.h"
46 #include "addrtoname.h"
47 #include "extract.h"
48
49 #ifndef nitems
50 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
51 #endif
52
53 #ifndef PPP_EAP
54 #define PPP_EAP 0xc227
55 #endif
56
57 #ifndef PPP_CDP
58 #define PPP_CDP 0x0207
59 #endif
60
61 #ifndef PPP_CDPCP
62 #define PPP_CDPCP 0x8207
63 #endif
64
65 struct protonames {
66 u_short protocol;
67 char *name;
68 };
69
70 static const struct protonames protonames[] = {
71 /*
72 * Protocol field values.
73 */
74 { PPP_IP, "IP" }, /* Internet Protocol */
75 { PPP_XNS, "XNS" }, /* Xerox NS */
76 { PPP_IPX, "IPX" }, /* IPX Datagram (RFC1552) */
77 { PPP_AT, "AppleTalk" }, /* AppleTalk Protocol */
78 { PPP_VJC_COMP, "VJC_UNCOMP" }, /* VJ compressed TCP */
79 { PPP_VJC_UNCOMP,"VJC_UNCOMP" },/* VJ uncompressed TCP */
80 { PPP_IPV6, "IPv6" }, /* Internet Protocol version 6 */
81 { PPP_COMP, "COMP" }, /* compressed packet */
82 { PPP_IPCP, "IPCP" }, /* IP Control Protocol */
83 { PPP_ATCP, "AppleTalkCP" },/* AppleTalk Control Protocol */
84 { PPP_IPXCP, "IPXCP" }, /* IPX Control Protocol (RFC1552) */
85 { PPP_IPV6CP, "IPV6CP" }, /* IPv6 Control Protocol */
86 { PPP_CCP, "CCP" }, /* Compression Control Protocol */
87 { PPP_LCP, "LCP" }, /* Link Control Protocol */
88 { PPP_PAP, "PAP" }, /* Password Authentication Protocol */
89 { PPP_LQR, "LQR" }, /* Link Quality Report protocol */
90 { PPP_CBCP, "CBCP" }, /* Callback Control Protocol */
91 { PPP_CHAP, "CHAP" }, /* Cryptographic Handshake Auth. Proto */
92 { PPP_EAP, "EAP" }, /* Extensible Auth. Protocol */
93 { PPP_CDP, "CDP" },
94 { PPP_CDPCP, "CDPCP" },
95 };
96
97 struct ppp_control {
98 uint8_t code;
99 uint8_t id;
100 uint16_t len;
101 };
102
103 struct ppp_cp_type {
104 const char *unkname;
105 int mincode;
106 int maxcode;
107 const char **codes;
108 };
109
110 /* LCP */
111
112 #define LCP_CONF_REQ 1
113 #define LCP_CONF_ACK 2
114 #define LCP_CONF_NAK 3
115 #define LCP_CONF_REJ 4
116 #define LCP_TERM_REQ 5
117 #define LCP_TERM_ACK 6
118 #define LCP_CODE_REJ 7
119 #define LCP_PROT_REJ 8
120 #define LCP_ECHO_REQ 9
121 #define LCP_ECHO_RPL 10
122 #define LCP_DISC_REQ 11
123
124 #define LCP_MIN LCP_CONF_REQ
125 #define LCP_MAX LCP_DISC_REQ
126
127 static const char *lcpcodes[] = {
128 /*
129 * LCP code values (RFC1661, pp26)
130 */
131 "Configure-Request",
132 "Configure-Ack",
133 "Configure-Nak",
134 "Configure-Reject",
135 "Terminate-Request",
136 "Terminate-Ack",
137 "Code-Reject",
138 "Protocol-Reject",
139 "Echo-Request",
140 "Echo-Reply",
141 "Discard-Request",
142 };
143
144 #define LCPOPT_VEXT 0
145 #define LCPOPT_MRU 1
146 #define LCPOPT_ACCM 2
147 #define LCPOPT_AP 3
148 #define LCPOPT_QP 4
149 #define LCPOPT_MN 5
150 #define LCPOPT_PFC 7
151 #define LCPOPT_ACFC 8
152
153 static char *lcpconfopts[] = {
154 "Vendor-Ext",
155 "Max-Rx-Unit",
156 "Async-Ctrl-Char-Map",
157 "Auth-Prot",
158 "Quality-Prot",
159 "Magic-Number",
160 "unassigned (6)",
161 "Prot-Field-Compr",
162 "Add-Ctrl-Field-Compr",
163 "FCS-Alternatives",
164 "Self-Describing-Pad",
165 "Numbered-Mode",
166 "Multi-Link-Procedure",
167 "Call-Back",
168 "Connect-Time"
169 "Compund-Frames",
170 "Nominal-Data-Encap",
171 "Multilink-MRRU",
172 "Multilink-SSNHF",
173 "Multilink-ED",
174 "Proprietary",
175 "DCE-Identifier",
176 "Multilink-Plus-Proc",
177 "Link-Discriminator",
178 "LCP-Auth-Option",
179 };
180
181 /* CHAP */
182
183 #define CHAP_CHAL 1
184 #define CHAP_RESP 2
185 #define CHAP_SUCC 3
186 #define CHAP_FAIL 4
187
188 #define CHAP_CODEMIN 1
189 #define CHAP_CODEMAX 4
190
191 static const char *chapcode[] = {
192 "Challenge",
193 "Response",
194 "Success",
195 "Failure",
196 };
197
198 /* PAP */
199
200 #define PAP_AREQ 1
201 #define PAP_AACK 2
202 #define PAP_ANAK 3
203
204 #define PAP_CODEMIN 1
205 #define PAP_CODEMAX 3
206
207 static const char *papcode[] = {
208 "Authenticate-Request",
209 "Authenticate-Ack",
210 "Authenticate-Nak",
211 };
212
213 /* EAP */
214
215 #define EAP_CHAL 1
216 #define EAP_RESP 2
217 #define EAP_SUCC 3
218 #define EAP_FAIL 4
219
220 #define EAP_CODEMIN EAP_CHAL
221 #define EAP_CODEMAX EAP_FAIL
222
223 #define EAP_TYPE_IDENTITY 1
224 #define EAP_TYPE_NOTIFICATION 2
225 #define EAP_TYPE_NAK 3
226 #define EAP_TYPE_MD5_CHALLENGE 4
227 #define EAP_TYPE_OTP 5
228 #define EAP_TYPE_TOKEN 6
229
230 #define EAP_TYPEMIN EAP_TYPE_IDENTITY
231 #define EAP_TYPEMAX EAP_TYPE_TOKEN
232
233 static const char *eapcode[] = {
234 "Challenge",
235 "Response",
236 "Success",
237 "Failure",
238 };
239
240 static const char *eaptype[] = {
241 "Identity",
242 "Notification",
243 "Nak",
244 "MD5-Challenge",
245 "One-Time-Password",
246 "Token",
247 };
248
249
250 /* IPCP */
251
252 #define IPCP_CODE_CFG_REQ 1
253 #define IPCP_CODE_CFG_ACK 2
254 #define IPCP_CODE_CFG_NAK 3
255 #define IPCP_CODE_CFG_REJ 4
256 #define IPCP_CODE_TRM_REQ 5
257 #define IPCP_CODE_TRM_ACK 6
258 #define IPCP_CODE_COD_REJ 7
259
260 #define IPCP_CODE_MIN IPCP_CODE_CFG_REQ
261 #define IPCP_CODE_MAX IPCP_CODE_COD_REJ
262
263 #define IPCP_2ADDR 1
264 #define IPCP_CP 2
265 #define IPCP_ADDR 3
266
267 /* IPV6CP */
268
269 #define IPV6CP_CODE_CFG_REQ 1
270 #define IPV6CP_CODE_CFG_ACK 2
271 #define IPV6CP_CODE_CFG_NAK 3
272 #define IPV6CP_CODE_CFG_REJ 4
273 #define IPV6CP_CODE_TRM_REQ 5
274 #define IPV6CP_CODE_TRM_ACK 6
275 #define IPV6CP_CODE_COD_REJ 7
276
277 #define IPV6CP_CODE_MIN IPV6CP_CODE_CFG_REQ
278 #define IPV6CP_CODE_MAX IPV6CP_CODE_COD_REJ
279
280 #define IPV6CP_IFID 1
281
282 static int print_lcp_config_options(const u_char *p, int);
283 static void handle_lcp(const u_char *, int);
284 static void handle_chap(const u_char *p, int);
285 static void handle_eap(const u_char *p, int);
286 static void handle_ipcp(const u_char *p, int);
287 static int print_ipcp_config_options(const u_char *, int);
288 static void handle_ipv6cp(const u_char *p, int);
289 static int print_ipv6cp_config_options(const u_char *, int);
290 static void handle_pap(const u_char *p, int);
291
292 struct pppoe_header {
293 u_int8_t vertype; /* PPPoE version/type */
294 u_int8_t code; /* PPPoE code (packet type) */
295 u_int16_t sessionid; /* PPPoE session id */
296 u_int16_t len; /* PPPoE payload length */
297 };
298 #define PPPOE_CODE_SESSION 0x00 /* Session */
299 #define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */
300 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */
301 #define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */
302 #define PPPOE_CODE_PADS 0x65 /* Active Discovery Session-Confirm */
303 #define PPPOE_CODE_PADT 0xa7 /* Active Discovery Terminate */
304 #define PPPOE_TAG_END_OF_LIST 0x0000 /* End Of List */
305 #define PPPOE_TAG_SERVICE_NAME 0x0101 /* Service Name */
306 #define PPPOE_TAG_AC_NAME 0x0102 /* Access Concentrator Name */
307 #define PPPOE_TAG_HOST_UNIQ 0x0103 /* Host Uniq */
308 #define PPPOE_TAG_AC_COOKIE 0x0104 /* Access Concentratr Cookie */
309 #define PPPOE_TAG_VENDOR_SPEC 0x0105 /* Vendor Specific */
310 #define PPPOE_TAG_RELAY_SESSION 0x0110 /* Relay Session Id */
311 #define PPPOE_TAG_MAX_PAYLOAD 0x0120 /* RFC 4638 Max Payload */
312 #define PPPOE_TAG_SERVICE_NAME_ERROR 0x0201 /* Service Name Error */
313 #define PPPOE_TAG_AC_SYSTEM_ERROR 0x0202 /* Acc. Concentrator Error */
314 #define PPPOE_TAG_GENERIC_ERROR 0x0203 /* Generic Error */
315
316 static void
ppp_protoname(uint16_t proto)317 ppp_protoname(uint16_t proto)
318 {
319 const struct protonames *protoname;
320 int i;
321
322 /* bsearch? */
323 for (i = 0; i < nitems(protonames); i++) {
324 protoname = &protonames[i];
325
326 if (proto == protoname->protocol) {
327 printf("%s ", protoname->name);
328 return;
329 }
330 }
331
332 printf("unknown-ppp-%04x", proto);
333 }
334
335 void
ppp_print(const u_char * p,u_int length)336 ppp_print(const u_char *p, u_int length)
337 {
338 uint16_t proto;
339 int l;
340
341 l = snapend - p;
342
343 if (l < sizeof(proto)) {
344 printf("[|ppp]");
345 return;
346 }
347
348 proto = EXTRACT_16BITS(p);
349
350 p += sizeof(proto);
351 l -= sizeof(proto);
352 length -= sizeof(proto);
353
354 if (eflag)
355 ppp_protoname(proto);
356
357 switch (proto) {
358 case PPP_IP:
359 ip_print(p, length);
360 return;
361 case PPP_IPV6:
362 ip6_print(p, length);
363 return;
364 }
365
366 if (!eflag)
367 ppp_protoname(proto);
368
369 switch(proto) {
370 case PPP_LCP:
371 handle_lcp(p, l);
372 break;
373 case PPP_CHAP:
374 handle_chap(p, l);
375 break;
376 case PPP_EAP:
377 handle_eap(p, l);
378 break;
379 case PPP_PAP:
380 handle_pap(p, l);
381 break;
382 case PPP_IPCP:
383 handle_ipcp(p, l);
384 break;
385 case PPP_IPV6CP:
386 handle_ipv6cp(p, l);
387 break;
388 case PPP_CDP:
389 cdp_print(p, length, l, 0);
390 break;
391 }
392 }
393
394 static int
ppp_cp_header(struct ppp_control * pc,const u_char * p,int l,const struct ppp_cp_type * t)395 ppp_cp_header(struct ppp_control *pc, const u_char *p, int l,
396 const struct ppp_cp_type *t)
397 {
398 uint8_t code;
399 int off = 0;
400 int len;
401
402 len = sizeof(pc->code);
403 if (l < len)
404 return (-1);
405
406 pc->code = code = *(p + off);
407 if (code >= t->mincode && code <= t->maxcode)
408 printf("%s ", t->codes[code - 1]);
409 else
410 printf("unknown-%s-%u ", t->unkname, pc->code);
411
412 off = len;
413 len += sizeof(pc->id);
414 if (l < len)
415 return (-1);
416
417 pc->id = *(p + off);
418 printf("Id=0x%02x:", pc->id);
419
420 off = len;
421 len += sizeof(pc->len);
422 if (l < len)
423 return (-1);
424
425 pc->len = EXTRACT_16BITS(p + off);
426
427 return (len);
428 }
429
430 /* print LCP frame */
431
432 static const struct ppp_cp_type ppp_cp_lcp = {
433 "lcp",
434 LCP_MIN, LCP_MAX,
435 lcpcodes,
436 };
437
438 static void
handle_lcp(const u_char * p,int l)439 handle_lcp(const u_char *p, int l)
440 {
441 struct ppp_control pc;
442 int i;
443
444 if (ppp_cp_header(&pc, p, l, &ppp_cp_lcp) == -1)
445 goto trunc;
446
447 if (l > pc.len)
448 l = pc.len;
449
450 p += sizeof(pc);
451 l -= sizeof(pc);
452
453 switch (pc.code) {
454 case LCP_CONF_REQ:
455 case LCP_CONF_ACK:
456 case LCP_CONF_NAK:
457 case LCP_CONF_REJ:
458 while (l > 0) {
459 int optlen;
460
461 optlen = print_lcp_config_options(p, l);
462 if (optlen == -1)
463 goto trunc;
464 if (optlen == 0)
465 break;
466
467 p += optlen;
468 l -= optlen;
469 }
470 break;
471 case LCP_ECHO_REQ:
472 case LCP_ECHO_RPL:
473 if (l < 4)
474 goto trunc;
475 printf(" Magic-Number=%u", EXTRACT_32BITS(p));
476 p += 4;
477 l -= 4;
478
479 i = sizeof(pc) + 4;
480 if (i == pc.len)
481 break;
482
483 printf(" Data=");
484 do {
485 if (l == 0)
486 goto trunc;
487
488 printf("%02x", *p);
489
490 p++;
491 l--;
492 } while (++i < pc.len);
493 break;
494 case LCP_TERM_REQ:
495 case LCP_TERM_ACK:
496 case LCP_CODE_REJ:
497 case LCP_PROT_REJ:
498 case LCP_DISC_REQ:
499 default:
500 break;
501 }
502 return;
503
504 trunc:
505 printf("[|lcp]");
506 }
507
508 /* LCP config options */
509
510 static int
print_lcp_config_options(const u_char * p,int l)511 print_lcp_config_options(const u_char *p, int l)
512 {
513 uint8_t type, length;
514 uint16_t proto;
515
516 if (l < sizeof(type))
517 return (-1);
518
519 type = p[0];
520 if (type < nitems(lcpconfopts))
521 printf(" %s", lcpconfopts[type]);
522 else
523 printf(" unknown-lcp-%u", type);
524
525 if (l < sizeof(type) + sizeof(length))
526 return (-1);
527
528 length = p[1];
529
530 if (length < sizeof(type) + sizeof(length))
531 return (0);
532
533 if (l > length)
534 l = length;
535
536 p += sizeof(type) + sizeof(length);
537 l -= sizeof(type) + sizeof(length);
538
539 switch (type) {
540 case LCPOPT_MRU:
541 if (length != 4)
542 goto invalid;
543 if (l < 2)
544 return (-1);
545
546 printf("=%u", EXTRACT_16BITS(p));
547 break;
548 case LCPOPT_AP:
549 if (length < 4)
550 goto invalid;
551 if (l < sizeof(proto))
552 return (-1);
553
554 proto = EXTRACT_16BITS(p);
555 switch (proto) {
556 case PPP_PAP:
557 printf("=PAP");
558 break;
559 case PPP_CHAP:
560 printf("=CHAP");
561 if (length < 5)
562 goto invalid;
563
564 p += sizeof(proto);
565 l -= sizeof(proto);
566
567 type = *p;
568 switch (type) {
569 case 0x05:
570 printf("/MD5");
571 break;
572 case 0x80:
573 printf("/Microsoft");
574 break;
575 default:
576 printf("/unknown-algorithm-%02x", type);
577 break;
578 }
579 break;
580 case PPP_EAP:
581 printf("=EAP");
582 break;
583 case 0xc027:
584 printf("=SPAP");
585 break;
586 case 0xc127:
587 printf("=Old-SPAP");
588 break;
589 default:
590 printf("=unknown-ap-%04x", proto);
591 break;
592 }
593 break;
594 case LCPOPT_QP:
595 if (length < 4)
596 goto invalid;
597 if (l < sizeof(proto))
598 return (-1);
599
600 proto = EXTRACT_16BITS(p);
601 switch (proto) {
602 case PPP_LQR:
603 printf(" LQR");
604 break;
605 default:
606 printf(" unknown-qp-%u", proto);
607 }
608 break;
609 case LCPOPT_MN:
610 if (length < 6)
611 goto invalid;
612 if (l < 4)
613 return (-1);
614
615 printf("=%u", EXTRACT_32BITS(p));
616 break;
617 case LCPOPT_PFC:
618 printf(" PFC");
619 break;
620 case LCPOPT_ACFC:
621 printf(" ACFC");
622 break;
623 }
624
625 return (length);
626
627 invalid:
628 printf(" invalid opt len %u", length);
629 return (length);
630 }
631
632 /* CHAP */
633
634 static const struct ppp_cp_type ppp_cp_chap = {
635 "chap",
636 CHAP_CODEMIN, CHAP_CODEMAX,
637 chapcode,
638 };
639
640 static void
handle_chap(const u_char * p,int l)641 handle_chap(const u_char *p, int l)
642 {
643 struct ppp_control pc;
644 uint8_t vsize;
645 int i;
646
647 if (ppp_cp_header(&pc, p, l, &ppp_cp_chap) == -1)
648 goto trunc;
649
650 if (l > pc.len)
651 l = pc.len;
652
653 p += sizeof(pc);
654 l -= sizeof(pc);
655
656 switch (pc.code) {
657 case CHAP_CHAL:
658 case CHAP_RESP:
659 if (l < sizeof(vsize))
660 goto trunc;
661
662 vsize = *p;
663 if (vsize < 1) {
664 printf(" invalid Value-Size");
665 return;
666 }
667
668 p += sizeof(vsize);
669 l -= sizeof(vsize);
670
671 printf(" Value=");
672 for (i = 0; i < vsize; i++) {
673 if (l == 0)
674 goto trunc;
675
676 printf("%02x", *p);
677
678 p++;
679 l--;
680 }
681
682 printf(" Name=");
683 for (i += sizeof(pc) + sizeof(vsize); i < pc.len; i++) {
684 if (l == 0)
685 goto trunc;
686
687 safeputchar(*p);
688
689 p++;
690 l--;
691 }
692 break;
693 case CHAP_SUCC:
694 case CHAP_FAIL:
695 printf(" Message=");
696 for (i = sizeof(pc); i < pc.len; i++) {
697 if (l == 0)
698 goto trunc;
699
700 safeputchar(*p);
701
702 p++;
703 l--;
704 }
705 break;
706 }
707 return;
708
709 trunc:
710 printf("[|chap]");
711 }
712
713 /* EAP */
714
715 static const struct ppp_cp_type ppp_cp_eap = {
716 "eap",
717 EAP_CODEMIN, EAP_CODEMAX,
718 eapcode,
719 };
720
721 static void
handle_eap(const u_char * p,int l)722 handle_eap(const u_char *p, int l)
723 {
724 struct ppp_control pc;
725 uint8_t type, vsize;
726 int i;
727
728 if (ppp_cp_header(&pc, p, l, &ppp_cp_eap) == -1)
729 goto trunc;
730
731 if (l > pc.len)
732 l = pc.len;
733
734 p += sizeof(pc);
735 l -= sizeof(pc);
736
737 switch (pc.code) {
738 case EAP_CHAL:
739 case EAP_RESP:
740 if (l < sizeof(type))
741 goto trunc;
742
743 type = *p;
744 p += sizeof(type);
745 l -= sizeof(type);
746
747 if (type >= EAP_TYPEMIN && type <= EAP_TYPEMAX)
748 printf(" %s", eaptype[type - 1]);
749 else {
750 printf(" unknown-eap-type-%u", type);
751 return;
752 }
753
754 switch (type) {
755 case EAP_TYPE_IDENTITY:
756 case EAP_TYPE_NOTIFICATION:
757 case EAP_TYPE_OTP:
758 i = sizeof(pc) + sizeof(type);
759 if (i == pc.len)
760 break;
761
762 printf("=");
763 do {
764 if (l == 0)
765 goto trunc;
766
767 safeputchar(*p);
768
769 p++;
770 l--;
771 } while (++i < pc.len);
772 break;
773
774 case EAP_TYPE_NAK:
775 if (l < sizeof(type))
776 goto trunc;
777 type = *p;
778 if (type >= EAP_TYPEMIN && type <= EAP_TYPEMAX)
779 printf(" %s", eaptype[type - 1]);
780 else
781 printf(" unknown-eap-type-%u", type);
782 break;
783 case EAP_TYPE_MD5_CHALLENGE:
784 if (l < sizeof(vsize))
785 goto trunc;
786
787 vsize = *p;
788 p += sizeof(vsize);
789 l -= sizeof(vsize);
790
791 printf("=");
792 for (i = 0; i < vsize; i++) {
793 if (l == 0)
794 goto trunc;
795
796 printf("%02x", *p);
797
798 p++;
799 l--;
800 }
801 break;
802 }
803 break;
804 case CHAP_SUCC:
805 case CHAP_FAIL:
806 break;
807 }
808 return;
809
810 trunc:
811 printf("[|eap]");
812 }
813
814 /* PAP */
815
816 static const struct ppp_cp_type ppp_cp_pap = {
817 "pap",
818 PAP_CODEMIN, PAP_CODEMAX,
819 papcode,
820 };
821
822 static void
handle_pap(const u_char * p,int l)823 handle_pap(const u_char *p, int l)
824 {
825 struct ppp_control pc;
826 uint8_t x;
827 int i;
828
829 if (ppp_cp_header(&pc, p, l, &ppp_cp_pap) == -1)
830 goto trunc;
831
832 if (l > pc.len)
833 l = pc.len;
834
835 p += sizeof(pc);
836 l -= sizeof(pc);
837
838 switch (pc.code) {
839 case PAP_AREQ:
840 if (l < sizeof(x)) /* Peer-ID Length */
841 goto trunc;
842
843 x = *p;
844
845 p += sizeof(x);
846 l -= sizeof(x);
847
848 printf(" Peer-Id=");
849 for (i = 0; i < x; i++) {
850 if (l == 0)
851 goto trunc;
852
853 safeputchar(*p);
854
855 p++;
856 l--;
857 }
858
859 if (l < sizeof(x)) /* Passwd-Length */
860 goto trunc;
861
862 x = *p;
863
864 p += sizeof(x);
865 l -= sizeof(x);
866
867 printf(" Passwd=");
868 for (i = 0; i < x; i++) {
869 if (l == 0)
870 goto trunc;
871
872 safeputchar(*p);
873
874 p++;
875 l--;
876 }
877 break;
878
879 case PAP_AACK:
880 case PAP_ANAK:
881 if (l < sizeof(x)) /* Msg-Length */
882 goto trunc;
883
884 x = *p;
885
886 p += sizeof(x);
887 l -= sizeof(x);
888
889 printf(" Message=");
890 for (i = 0; i < x; i++) {
891 if (l == 0)
892 goto trunc;
893
894 safeputchar(*p);
895
896 p++;
897 l--;
898 }
899 break;
900 }
901
902 return;
903
904 trunc:
905 printf("[|pap]");
906 }
907
908 /* IPCP */
909
910 #define IP_LEN 4
911 #define IP_FMT "%u.%u.%u.%u"
912 #define IP_ARG(_p) (_p)[0], (_p)[1], (_p)[2], (_p)[3]
913
914 static const struct ppp_cp_type ppp_cp_ipcp = {
915 "ipcp",
916 IPCP_CODE_MIN, IPCP_CODE_MAX,
917 lcpcodes,
918 };
919
920 static void
handle_ipcp(const u_char * p,int l)921 handle_ipcp(const u_char *p, int l)
922 {
923 struct ppp_control pc;
924
925 if (ppp_cp_header(&pc, p, l, &ppp_cp_ipcp) == -1)
926 goto trunc;
927
928 if (l > pc.len)
929 l = pc.len;
930
931 p += sizeof(pc);
932 l -= sizeof(pc);
933
934 switch (pc.code) {
935 case IPCP_CODE_CFG_REQ:
936 case IPCP_CODE_CFG_ACK:
937 case IPCP_CODE_CFG_NAK:
938 case IPCP_CODE_CFG_REJ:
939 while (l > 0) {
940 int optlen;
941
942 optlen = print_ipcp_config_options(p, l);
943 if (optlen == -1)
944 goto trunc;
945 if (optlen == 0)
946 break;
947
948 p += optlen;
949 l -= optlen;
950 }
951 break;
952
953 case IPCP_CODE_TRM_REQ:
954 case IPCP_CODE_TRM_ACK:
955 case IPCP_CODE_COD_REJ:
956 default:
957 break;
958 }
959
960 return;
961
962 trunc:
963 printf("[|ipcp]");
964 }
965
966 static int
print_ipcp_config_options(const u_char * p,int l)967 print_ipcp_config_options(const u_char *p, int l)
968 {
969 uint8_t type, length;
970
971 if (l < sizeof(type))
972 return (-1);
973
974 type = p[0];
975 switch (type) {
976 case IPCP_2ADDR:
977 printf(" IP-Addresses");
978 break;
979 case IPCP_CP:
980 printf(" IP-Compression-Protocol");
981 break;
982 case IPCP_ADDR:
983 printf(" IP-Address");
984 break;
985 default:
986 printf(" ipcp-type-%u", type);
987 break;
988 }
989
990 if (l < sizeof(type) + sizeof(length))
991 return (-1);
992
993 length = p[1];
994
995 p += (sizeof(type) + sizeof(length));
996 l -= (sizeof(type) + sizeof(length));
997
998 switch (type) {
999 case IPCP_2ADDR:
1000 if (length != 10)
1001 goto invalid;
1002 if (l < IP_LEN)
1003 return (-1);
1004
1005 printf(" Src=" IP_FMT, IP_ARG(p));
1006
1007 p += IP_LEN;
1008 l -= IP_LEN;
1009
1010 if (l < IP_LEN)
1011 return (-1);
1012
1013 printf(" Dst=" IP_FMT, IP_ARG(p));
1014 break;
1015 case IPCP_CP:
1016 if (length < 4)
1017 goto invalid;
1018 if (l < sizeof(type))
1019 return (-1);
1020
1021 type = EXTRACT_16BITS(p);
1022 switch (type) {
1023 case 0x0037:
1024 printf(" Van Jacobsen Compressed TCP/IP");
1025 break;
1026 default:
1027 printf("ipcp-compression-type-%u", type);
1028 break;
1029 }
1030 break;
1031 case IPCP_ADDR:
1032 if (length != 6)
1033 goto invalid;
1034 if (l < IP_LEN)
1035 return (-1);
1036
1037 printf("=" IP_FMT, IP_ARG(p));
1038 break;
1039 }
1040
1041 return (length);
1042
1043 invalid:
1044 printf(" invalid opt len %u", length);
1045 return (length);
1046 }
1047
1048 /* IPV6CP */
1049
1050 static const struct ppp_cp_type ppp_cp_ipv6cp = {
1051 "ipv6cp",
1052 IPV6CP_CODE_MIN, IPV6CP_CODE_MAX,
1053 lcpcodes,
1054 };
1055
1056 static void
handle_ipv6cp(const u_char * p,int l)1057 handle_ipv6cp(const u_char *p, int l)
1058 {
1059 struct ppp_control pc;
1060
1061 if (ppp_cp_header(&pc, p, l, &ppp_cp_ipv6cp) == -1)
1062 goto trunc;
1063
1064 if (l > pc.len)
1065 l = pc.len;
1066
1067 p += sizeof(pc);
1068 l -= sizeof(pc);
1069
1070 switch (pc.code) {
1071 case IPV6CP_CODE_CFG_REQ:
1072 case IPV6CP_CODE_CFG_ACK:
1073 case IPV6CP_CODE_CFG_NAK:
1074 case IPV6CP_CODE_CFG_REJ:
1075 while (l > 0) {
1076 int optlen;
1077
1078 optlen = print_ipv6cp_config_options(p, l);
1079 if (optlen == -1)
1080 goto trunc;
1081 if (optlen == 0)
1082 break;
1083
1084 p += optlen;
1085 l -= optlen;
1086 }
1087 break;
1088
1089 case IPV6CP_CODE_TRM_REQ:
1090 case IPV6CP_CODE_TRM_ACK:
1091 case IPV6CP_CODE_COD_REJ:
1092 default:
1093 break;
1094 }
1095
1096 return;
1097
1098 trunc:
1099 printf("[|ipv6cp]");
1100 }
1101
1102 static int
print_ipv6cp_config_options(const u_char * p,int l)1103 print_ipv6cp_config_options(const u_char *p, int l)
1104 {
1105 uint8_t type, length;
1106
1107 if (l < sizeof(type))
1108 return (-1);
1109
1110 type = p[0];
1111 switch (type) {
1112 case IPV6CP_IFID:
1113 printf(" IPv6-Interface-Id");
1114 break;
1115 default:
1116 printf(" ipv6cp-type-%u", type);
1117 break;
1118 }
1119
1120 if (l < sizeof(type) + sizeof(length))
1121 return (-1);
1122
1123 length = p[1];
1124
1125 p += (sizeof(type) + sizeof(length));
1126 l -= (sizeof(type) + sizeof(length));
1127
1128 switch (type) {
1129 case IPV6CP_IFID:
1130 if (length != 10)
1131 goto invalid;
1132 if (l < 8)
1133 return (-1);
1134
1135 printf("=%04x:%04x:%04x:%04x", EXTRACT_16BITS(p + 0),
1136 EXTRACT_16BITS(p + 2), EXTRACT_16BITS(p + 4),
1137 EXTRACT_16BITS(p + 6));
1138 break;
1139 default:
1140 break;
1141 }
1142
1143 return (length);
1144 invalid:
1145 printf(" invalid opt len %u", length);
1146 return (length);
1147 }
1148
1149 void
ppp_if_print(u_char * user,const struct pcap_pkthdr * h,const u_char * p)1150 ppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
1151 {
1152 u_int length = h->len;
1153 u_int caplen = h->caplen;
1154
1155 packetp = p;
1156 snapend = p + caplen;
1157
1158 ts_print(&h->ts);
1159
1160 ppp_hdlc_print(p, length);
1161
1162 if (xflag)
1163 default_print((const u_char *)(p + PPP_HDRLEN),
1164 caplen - PPP_HDRLEN);
1165
1166 putchar('\n');
1167 }
1168
1169 void
ppp_ether_if_print(u_char * user,const struct pcap_pkthdr * h,const u_char * p)1170 ppp_ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
1171 {
1172 u_int16_t pppoe_sid, pppoe_len;
1173 u_int l = h->caplen;
1174 u_int length = h->len;
1175
1176 packetp = p;
1177 snapend = p + l;
1178
1179 ts_print(&h->ts);
1180
1181 if (eflag)
1182 printf("PPPoE ");
1183
1184 if (l < sizeof(struct pppoe_header)) {
1185 printf("[|pppoe]");
1186 return;
1187 }
1188
1189 pppoe_sid = EXTRACT_16BITS(p + 2);
1190 pppoe_len = EXTRACT_16BITS(p + 4);
1191
1192 if (eflag) {
1193 printf("\n\tcode ");
1194 switch (p[1]) {
1195 case PPPOE_CODE_PADI:
1196 printf("Initiation");
1197 break;
1198 case PPPOE_CODE_PADO:
1199 printf("Offer");
1200 break;
1201 case PPPOE_CODE_PADR:
1202 printf("Request");
1203 break;
1204 case PPPOE_CODE_PADS:
1205 printf("Confirm");
1206 break;
1207 case PPPOE_CODE_PADT:
1208 printf("Terminate");
1209 break;
1210 case PPPOE_CODE_SESSION:
1211 printf("Session");
1212 break;
1213 default:
1214 printf("Unknown(0x%02x)", p[1]);
1215 break;
1216 }
1217 printf(", version %d, type %d, id 0x%04x, length %d\n\t",
1218 (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len);
1219 }
1220
1221 if (length < pppoe_len) {
1222 printf(" truncated-pppoe - %d bytes missing!",
1223 pppoe_len - length);
1224 pppoe_len = length;
1225 }
1226
1227 ppp_print(p + sizeof(struct pppoe_header), pppoe_len);
1228
1229 if (xflag)
1230 default_print(p, h->caplen);
1231
1232 putchar('\n');
1233 }
1234
1235 int
pppoe_if_print(u_short ethertype,const u_char * p,u_int length,u_int l)1236 pppoe_if_print(u_short ethertype, const u_char *p, u_int length, u_int l)
1237 {
1238 uint16_t pppoe_sid, pppoe_len;
1239
1240 if (ethertype == ETHERTYPE_PPPOEDISC)
1241 printf("PPPoE-Discovery");
1242 else
1243 printf("PPPoE-Session");
1244
1245 if (l < sizeof(struct pppoe_header))
1246 goto trunc;
1247
1248 printf("\n\tcode ");
1249 switch (p[1]) {
1250 case PPPOE_CODE_PADI:
1251 printf("Initiation");
1252 break;
1253 case PPPOE_CODE_PADO:
1254 printf("Offer");
1255 break;
1256 case PPPOE_CODE_PADR:
1257 printf("Request");
1258 break;
1259 case PPPOE_CODE_PADS:
1260 printf("Confirm");
1261 break;
1262 case PPPOE_CODE_PADT:
1263 printf("Terminate");
1264 break;
1265 case PPPOE_CODE_SESSION:
1266 printf("Session");
1267 break;
1268 default:
1269 printf("Unknown(0x%02x)", p[1]);
1270 break;
1271 }
1272
1273 pppoe_sid = EXTRACT_16BITS(p + 2);
1274 pppoe_len = EXTRACT_16BITS(p + 4);
1275 printf(", version %d, type %d, id 0x%04x, length %d",
1276 (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len);
1277
1278 p += sizeof(struct pppoe_header);
1279 l -= sizeof(struct pppoe_header);
1280 length -= sizeof(struct pppoe_header);
1281
1282 if (length < pppoe_len) {
1283 printf(" truncated-pppoe - %d bytes missing!",
1284 pppoe_len - length);
1285 pppoe_len = length;
1286 }
1287
1288 if (l > pppoe_len)
1289 l = pppoe_len;
1290
1291 if (ethertype == ETHERTYPE_PPPOEDISC) {
1292 while (l > 0) {
1293 u_int16_t t_type, t_len;
1294 int text = 0;
1295
1296 if (l < 4)
1297 goto trunc;
1298 t_type = EXTRACT_16BITS(p);
1299 t_len = EXTRACT_16BITS(p + 2);
1300
1301 p += 4;
1302 l -= 4;
1303
1304 if (l < t_len)
1305 goto trunc;
1306
1307 printf("\n\ttag ");
1308 switch (t_type) {
1309 case PPPOE_TAG_END_OF_LIST:
1310 printf("End-Of-List");
1311 break;
1312 case PPPOE_TAG_SERVICE_NAME:
1313 printf("Service-Name");
1314 text = 1;
1315 break;
1316 case PPPOE_TAG_AC_NAME:
1317 printf("AC-Name");
1318 text = 1;
1319 break;
1320 case PPPOE_TAG_HOST_UNIQ:
1321 printf("Host-Uniq");
1322 break;
1323 case PPPOE_TAG_AC_COOKIE:
1324 printf("AC-Cookie");
1325 break;
1326 case PPPOE_TAG_VENDOR_SPEC:
1327 printf("Vendor-Specific");
1328 break;
1329 case PPPOE_TAG_RELAY_SESSION:
1330 printf("Relay-Session");
1331 break;
1332 case PPPOE_TAG_MAX_PAYLOAD:
1333 printf("PPP-Max-Payload");
1334 break;
1335 case PPPOE_TAG_SERVICE_NAME_ERROR:
1336 printf("Service-Name-Error");
1337 text = 1;
1338 break;
1339 case PPPOE_TAG_AC_SYSTEM_ERROR:
1340 printf("AC-System-Error");
1341 text = 1;
1342 break;
1343 case PPPOE_TAG_GENERIC_ERROR:
1344 printf("Generic-Error");
1345 text = 1;
1346 break;
1347 default:
1348 printf("Unknown(0x%04x)", t_type);
1349 }
1350 printf(", length %u%s", t_len, t_len ? " " : "");
1351
1352 if (t_len && text == 1) {
1353 for (t_type = 0; t_type < t_len; t_type++) {
1354 if (isprint(p[t_type]))
1355 printf("%c", p[t_type]);
1356 else
1357 printf("\\%03o", p[t_type]);
1358 }
1359 } else if (t_len) {
1360 printf("0x");
1361 for (t_type = 0; t_type < t_len; t_type++)
1362 printf("%02x", p[t_type]);
1363 }
1364 p += t_len;
1365 l -= t_len;
1366 }
1367 } else if (ethertype == ETHERTYPE_PPPOE) {
1368 printf("\n\t");
1369 ppp_print(p, pppoe_len);
1370 }
1371
1372 return (1);
1373
1374 trunc:
1375 printf("[|pppoe]");
1376 return (1);
1377 }
1378
1379 void
ppp_hdlc_print(const u_char * p,u_int length)1380 ppp_hdlc_print(const u_char *p, u_int length)
1381 {
1382 uint8_t address, control;
1383 int l;
1384
1385 l = snapend - p;
1386
1387 if (l < sizeof(address) + sizeof(control))
1388 goto trunc;
1389
1390 address = p[0];
1391 control = p[1];
1392
1393 p += sizeof(address) + sizeof(control);
1394 l -= sizeof(address) + sizeof(control);
1395 length -= sizeof(address) + sizeof(control);
1396
1397 switch (address) {
1398 case 0xff: /* All-Stations */
1399 if (eflag)
1400 printf("%02x %02x %u ", address, control, length);
1401
1402 if (control != 0x3) {
1403 printf(" discard");
1404 break;
1405 }
1406
1407 ppp_print(p, length);
1408 break;
1409
1410 default:
1411 printf("ppp address 0x%02x unknown", address);
1412 break;
1413 }
1414 return;
1415
1416 trunc:
1417 printf("[|ppp]");
1418 }
1419
1420 void
ppp_hdlc_if_print(u_char * user,const struct pcap_pkthdr * h,const u_char * p)1421 ppp_hdlc_if_print(u_char *user, const struct pcap_pkthdr *h,
1422 const u_char *p)
1423 {
1424 int l = h->caplen;
1425
1426 packetp = p;
1427 snapend = p + l;
1428
1429 ts_print(&h->ts);
1430
1431 if (eflag)
1432 printf("PPP ");
1433
1434 ppp_hdlc_print(p, h->len);
1435
1436 if (xflag)
1437 default_print(p, l);
1438
1439 printf("\n");
1440 }
1441
1442 #else
1443
1444 #include <sys/types.h>
1445 #include <sys/time.h>
1446
1447 #include <stdio.h>
1448
1449 #include "interface.h"
1450 void
ppp_if_print(user,h,p)1451 ppp_if_print(user, h, p)
1452 u_char *user;
1453 const struct pcap_pkthdr *h;
1454 const u_char *p;
1455 {
1456 error("not configured for ppp");
1457 /* NOTREACHED */
1458 }
1459 #endif
1460