]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-ppp.c
This commit was generated by cvs2svn to compensate for changes in r51415,
[FreeBSD/FreeBSD.git] / contrib / 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: print-ppp.c,v 1.26 97/06/12 14:21:29 leres 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
43 #include <ctype.h>
44 #include <netdb.h>
45 #include <pcap.h>
46 #include <stdio.h>
47
48 #include <net/ethernet.h>
49 #include "ethertype.h"
50
51 #include <net/ppp_defs.h>
52 #include "interface.h"
53 #include "addrtoname.h"
54 #include "ppp.h"
55
56 struct protonames {
57         u_short protocol;
58         char *name;
59 };
60
61 static struct protonames protonames[] = {
62         /*
63          * Protocol field values.
64          */
65         PPP_IP,         "IP",           /* Internet Protocol */
66         PPP_XNS,        "XNS",          /* Xerox NS */
67         PPP_IPX,        "IPX",          /* IPX Datagram (RFC1552) */
68         PPP_VJC_COMP,   "VJC_UNCOMP",   /* VJ compressed TCP */
69         PPP_VJC_UNCOMP, "VJC_UNCOMP",   /* VJ uncompressed TCP */
70         PPP_COMP,       "COMP",         /* compressed packet */
71         PPP_IPCP,       "IPCP",         /* IP Control Protocol */
72         PPP_IPXCP,      "IPXCP",        /* IPX Control Protocol (RFC1552) */
73         PPP_CCP,        "CCP",          /* Compression Control Protocol */
74         PPP_LCP,        "LCP",          /* Link Control Protocol */
75         PPP_PAP,        "PAP",          /* Password Authentication Protocol */
76         PPP_LQR,        "LQR",          /* Link Quality Report protocol */
77         PPP_CHAP,       "CHAP",         /* Cryptographic Handshake Auth. Proto*/
78 };
79
80 /* LCP */
81
82 #define LCP_CONF_REQ    1
83 #define LCP_CONF_ACK    2
84 #define LCP_CONF_NAK    3
85 #define LCP_CONF_REJ    4
86 #define LCP_TERM_REQ    5
87 #define LCP_TERM_ACK    6
88 #define LCP_CODE_REJ    7
89 #define LCP_PROT_REJ    8
90 #define LCP_ECHO_REQ    9
91 #define LCP_ECHO_RPL    10
92 #define LCP_DISC_REQ    11
93
94 #define LCP_MIN LCP_CONF_REQ
95 #define LCP_MAX LCP_DISC_REQ
96
97 static char *lcpcodes[] = {
98         /*
99          * LCP code values (RFC1661, pp26)
100          */
101         "Configure-Request",
102         "Configure-Ack",
103         "Configure-Nak",
104         "Configure-Reject",
105         "Terminate-Request",
106         "Terminate-Ack",
107         "Code-Reject",
108         "Protocol-Reject",
109         "Echo-Request",
110         "Echo-Reply",
111         "Discard-Request",
112 };
113
114 #define LCPOPT_VEXT     0
115 #define LCPOPT_MRU      1
116 #define LCPOPT_ACCM     2
117 #define LCPOPT_AP       3
118 #define LCPOPT_QP       4
119 #define LCPOPT_MN       5
120 #define LCPOPT_PFC      7
121 #define LCPOPT_ACFC     8
122
123 #define LCPOPT_MIN 0
124 #define LCPOPT_MAX 24
125
126 static char *lcpconfopts[] = {
127         "Vendor-Ext",
128         "Max-Rx-Unit",
129         "Async-Ctrl-Char-Map",
130         "Auth-Prot",
131         "Quality-Prot",
132         "Magic-Number",
133         "unassigned (6)",       
134         "Prot-Field-Compr",
135         "Add-Ctrl-Field-Compr",
136         "FCS-Alternatives",
137         "Self-Describing-Pad",
138         "Numbered-Mode",
139         "Multi-Link-Procedure",
140         "Call-Back",
141         "Connect-Time"
142         "Compund-Frames",
143         "Nominal-Data-Encap",
144         "Multilink-MRRU",
145         "Multilink-SSNHF",
146         "Multilink-ED",
147         "Proprietary",
148         "DCE-Identifier",
149         "Multilink-Plus-Proc",
150         "Link-Discriminator",
151         "LCP-Auth-Option",
152 };
153
154 /* CHAP */
155
156 #define CHAP_CHAL       1
157 #define CHAP_RESP       2
158 #define CHAP_SUCC       3
159 #define CHAP_FAIL       4
160
161 #define CHAP_CODEMIN 1
162 #define CHAP_CODEMAX 4
163
164 static char *chapcode[] = {
165         "Challenge",
166         "Response",
167         "Success",
168         "Failure",      
169 };
170
171 /* PAP */
172
173 #define PAP_AREQ        1
174 #define PAP_AACK        2
175 #define PAP_ANAK        3
176
177 #define PAP_CODEMIN     1
178 #define PAP_CODEMAX     3
179
180 static char *papcode[] = {
181         "Authenticate-Request",
182         "Authenticate-Ack",
183         "Authenticate-Nak",
184 };
185
186 /* IPCP */
187
188 #define IPCP_2ADDR      1
189 #define IPCP_CP         2
190 #define IPCP_ADDR       3
191
192 static int handle_lcp(const u_char *p, int length);
193 static int print_lcp_config_options(u_char *p);
194 static int handle_chap(const u_char *p, int length);
195 static int handle_ipcp(const u_char *p, int length);
196 static int handle_pap(const u_char *p, int length);
197
198 /* Standard PPP printer */
199 void
200 ppp_hdlc_print(const u_char *p, int length)
201 {
202         int proto = PPP_PROTOCOL(p);
203         int i, j, x;
204         u_char *ptr;
205
206         printf("ID-%03d ", *(p+5));
207                         
208         for (i = (sizeof(protonames) / sizeof(protonames[0])) - 1; i >= 0; --i)
209         {
210                 if (proto == protonames[i].protocol)
211                 {
212                         printf("%s: ", protonames[i].name);
213
214                         switch(proto)
215                         {
216                                 case PPP_LCP:
217                                         handle_lcp(p, length);
218                                         break;
219                                 case PPP_CHAP:
220                                         handle_chap(p, length);
221                                         break;
222                                 case PPP_PAP:
223                                         handle_pap(p, length);
224                                         break;
225                                 case PPP_IPCP:
226                                         handle_ipcp(p, length);
227                                         break;
228                         }
229                         break;
230                 }
231         }
232         if (i < 0)
233         {
234                 printf("%04x: ", proto);
235         }
236 }
237
238 /* print LCP frame */
239
240 static int
241 handle_lcp(const u_char *p, int length)
242 {
243         int x, j;
244         u_char *ptr;
245
246         x = *(p+4);
247
248         if((x >= LCP_MIN) && (x <= LCP_MAX))
249         {
250                 printf("%s", lcpcodes[x-1]);
251         }
252         else
253         {
254                 printf("0x%02x", x);
255                 return;
256         }
257
258         length -= 4;
259         
260         switch(x)
261         {
262                 case LCP_CONF_REQ:
263                 case LCP_CONF_ACK:
264                 case LCP_CONF_NAK:
265                 case LCP_CONF_REJ:
266                         x = length;
267                         ptr = (u_char *)p+8;
268                         do
269                         {
270                                 if((j = print_lcp_config_options(ptr)) == 0)
271                                         break;
272                                 x -= j;
273                                 ptr += j;
274                         }
275                         while(x > 0);
276                         break;
277
278                 case LCP_ECHO_REQ:
279                 case LCP_ECHO_RPL:
280                         printf(", Magic-Number=%d", ((*(p+8) << 24) + (*(p+9) << 16) + (*(p+10) << 8) + (*(p+11))));
281                         break;
282                 case LCP_TERM_REQ:
283                 case LCP_TERM_ACK:
284                 case LCP_CODE_REJ:
285                 case LCP_PROT_REJ:
286                 case LCP_DISC_REQ:
287                 default:
288                         break;
289         }
290 }
291
292 /* LCP config options */
293
294 static int
295 print_lcp_config_options(u_char *p)
296 {
297         int len = *(p+1);
298         int opt = *p;
299         
300         if((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
301                 printf(", %s", lcpconfopts[opt]);
302
303         switch(opt)
304         {
305                 case LCPOPT_MRU:
306                         if(len == 4)
307                                 printf("=%d", (*(p+2) << 8) + *(p+3));
308                         break;
309                 case LCPOPT_AP:
310                         if(len >= 4)
311                         {
312                                 if(*(p+2) == 0xc0 && *(p+3) == 0x23)
313                                 {
314                                         printf(" PAP");
315                                 }
316                                 else if(*(p+2) == 0xc2 && *(p+3) == 0x23)
317                                 {
318                                         printf(" CHAP/");
319                                         switch(*(p+4))
320                                         {
321                                                 default:
322                                                         printf("unknown-algorithm-%d", *(p+4));
323                                                         break;
324                                                 case 5:
325                                                         printf("MD5");
326                                                         break;
327                                                 case 0x80:
328                                                         printf("Microsoft");
329                                                         break;
330                                         }
331                                 }
332                                 else if(*(p+2) == 0xc2 && *(p+3) == 0x27)
333                                 {
334                                         printf(" EAP");
335                                 }
336                                 else if(*(p+2) == 0xc0 && *(p+3) == 0x27)
337                                 {
338                                         printf(" SPAP");
339                                 }
340                                 else if(*(p+2) == 0xc1 && *(p+3) == 0x23)
341                                 {
342                                         printf(" Old-SPAP");
343                                 }
344                                 else
345                                 {
346                                         printf("unknown");
347                                 }
348                         }
349                         break;
350                 case LCPOPT_QP:
351                         if(len >= 4)
352                         {
353                                 if(*(p+2) == 0xc0 && *(p+3) == 0x25)
354                                         printf(" LQR");
355                                 else
356                                         printf(" unknown");
357                         }
358                         break;
359                 case LCPOPT_MN:
360                         if(len == 6)
361                         {
362                                 printf("=%d", ((*(p+2) << 24) + (*(p+3) << 16) + (*(p+4) << 8) + (*(p+5))));
363                         }
364                         break;
365                 case LCPOPT_PFC:
366                         printf(" PFC");
367                         break;
368                 case LCPOPT_ACFC:
369                         printf(" ACFC");
370                         break;
371         }
372         return(len);
373 }
374
375 /* CHAP */
376
377 static int
378 handle_chap(const u_char *p, int length)
379 {
380         int x, j;
381         u_char *ptr;
382
383         x = *(p+4);
384
385         if((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX))
386         {
387                 printf("%s", chapcode[x-1]);
388         }
389         else
390         {
391                 printf("0x%02x", x);
392                 return;
393         }
394
395         length -= 4;
396         
397         switch(x)
398         {
399                 case CHAP_CHAL:
400                 case CHAP_RESP:
401                         printf(", Value=");
402                         x = *(p+8);     /* value size */
403                         ptr = (u_char *)p+9;
404                         while(--x >= 0)
405                                 printf("%02x", *ptr++);
406                         x = length - *(p+8) - 1;
407                         printf(", Name=");
408                         while(--x >= 0)
409                                 printf("%c", *ptr++);
410                         break;
411         }
412 }
413
414 /* PAP */
415
416 static int
417 handle_pap(const u_char *p, int length)
418 {
419         int x, j;
420         u_char *ptr;
421
422         x = *(p+4);
423
424         if((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX))
425         {
426                 printf("%s", papcode[x-1]);
427         }
428         else
429         {
430                 printf("0x%02x", x);
431                 return;
432         }
433
434         length -= 4;
435         
436         switch(x)
437         {
438                 case PAP_AREQ:
439                         printf(", Peer-Id=");
440                         x = *(p+8);     /* peerid size */
441                         ptr = (u_char *)p+9;
442                         while(--x >= 0)
443                                 printf("%c", *ptr++);
444                         x = *ptr++;
445                         printf(", Passwd=");
446                         while(--x >= 0)
447                                 printf("%c", *ptr++);
448                         break;
449                 case PAP_AACK:
450                 case PAP_ANAK:          
451                         break;                  
452         }
453 }
454
455 /* IPCP */
456         
457 static int
458 handle_ipcp(const u_char *p, int length)
459 {
460         int x, j;
461
462         x = *(p+8);
463
464         length -= 4;
465         
466         switch(x)
467         {
468                 case IPCP_2ADDR:
469                         printf("IP-Addresses");
470                         printf(", Src=%d.%d.%d.%d", *(p+10), *(p+11), *(p+12), *(p+13));
471                         printf(", Dst=%d.%d.%d.%d", *(p+14), *(p+15), *(p+16), *(p+17));
472                         break;
473                         
474                 case IPCP_CP:
475                         printf("IP-Compression-Protocol");
476                         break;
477
478                 case IPCP_ADDR:
479                         printf("IP-Address=%d.%d.%d.%d", *(p+10), *(p+11), *(p+12), *(p+13));
480                         break;
481         }
482 }
483         
484 void
485 ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
486              register const u_char *p)
487 {
488         register u_int length = h->len;
489         register u_int caplen = h->caplen;
490
491         ts_print(&h->ts);
492
493         if (caplen < PPP_HDRLEN) {
494                 printf("[|ppp]");
495                 goto out;
496         }
497
498         /*
499          * Some printers want to get back at the link level addresses,
500          * and/or check that they're not walking off the end of the packet.
501          * Rather than pass them all the way down, we set these globals.
502          */
503         packetp = p;
504         snapend = p + caplen;
505
506         if (eflag)
507                 ppp_hdlc_print(p, length);
508
509         length -= PPP_HDRLEN;
510
511         switch(PPP_PROTOCOL(p)) {
512         case PPP_IP:
513         case ETHERTYPE_IP:
514                 ip_print((const u_char *)(p + PPP_HDRLEN), length);
515                 break;
516         case PPP_IPX:
517         case ETHERTYPE_IPX:
518                 ipx_print((const u_char *)(p + PPP_HDRLEN), length);
519                 break;
520
521         default:
522                 if(!eflag)
523                         ppp_hdlc_print(p, length);
524                 if(!xflag)
525                         default_print((const u_char *)(p + PPP_HDRLEN),
526                                         caplen - PPP_HDRLEN);
527         }
528
529         if (xflag)
530                 default_print((const u_char *)(p + PPP_HDRLEN),
531                                 caplen - PPP_HDRLEN);
532 out:
533         putchar('\n');
534 }
535
536 /* proto type to string mapping */
537 static struct tok ptype2str[] = {
538         { PPP_VJC,      "VJC" },
539         { PPP_VJNC,     "VJNC" },
540         { PPP_OSI,      "OSI" },
541         { PPP_LCP,      "LCP" },
542         { PPP_IPCP,     "IPCP" },
543         { 0,            NULL }
544 };
545
546 #define PPP_BSDI_HDRLEN 24
547
548 /* BSD/OS specific PPP printer */
549 void
550 ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
551              register const u_char *p)
552 {
553         register u_int length = h->len;
554         register u_int caplen = h->caplen;
555         register int hdrlength;
556         u_short ptype;
557
558         ts_print(&h->ts);
559
560         if (caplen < PPP_BSDI_HDRLEN) {
561                 printf("[|ppp]");
562                 goto out;
563         }
564
565         /*
566          * Some printers want to get back at the link level addresses,
567          * and/or check that they're not walking off the end of the packet.
568          * Rather than pass them all the way down, we set these globals.
569          */
570         packetp = p;
571         snapend = p + caplen;
572         hdrlength = 0;
573
574         if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
575                 if (eflag) 
576                         printf("%02x %02x ", p[0], p[1]);
577                 p += 2;
578                 hdrlength = 2;
579         }
580
581         if (eflag) 
582                 printf("%d ", length);
583         /* Retrieve the protocol type */
584         if (*p & 01) {
585                 /* Compressed protocol field */
586                 ptype = *p;
587                 if (eflag) 
588                         printf("%02x ", ptype);
589                 p++;
590                 hdrlength += 1;
591         } else {
592                 /* Un-compressed protocol field */
593                 ptype = ntohs(*(u_short *)p);
594                 if (eflag) 
595                         printf("%04x ", ptype);
596                 p += 2;
597                 hdrlength += 2;
598         }
599   
600         length -= hdrlength;
601
602         if (ptype == PPP_IP)
603                 ip_print(p, length);
604         else
605                 printf("%s ", tok2str(ptype2str, "proto-#%d", ptype));
606
607         if (xflag)
608                 default_print((const u_char *)p, caplen - hdrlength);
609 out:
610         putchar('\n');
611 }