xref: /freebsd/contrib/tcpdump/print-ppp.c (revision 6990ffd8a95caaba6858ad44ff1b3157d1efba8f)
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  * Extensively modified by Motonori Shindo (mshindo@mshindo.net) for more
22  * complete PPP support.
23  *
24  * $FreeBSD$
25  */
26 
27 /*
28  * TODO:
29  * o resolve XXX as much as possible
30  * o MP support
31  * o BAP support
32  */
33 
34 #ifndef lint
35 static const char rcsid[] =
36     "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.58 2000/12/27 11:09:08 itojun Exp $ (LBL)";
37 #endif
38 
39 #ifdef HAVE_CONFIG_H
40 #include "config.h"
41 #endif
42 
43 #include <sys/param.h>
44 #include <sys/time.h>
45 
46 #ifdef __bsdi__
47 #include <net/slcompress.h>
48 #include <net/if_ppp.h>
49 #endif
50 
51 #include <netinet/in.h>
52 
53 #include <ctype.h>
54 #include <netdb.h>
55 #include <pcap.h>
56 #include <stdio.h>
57 
58 #include "interface.h"
59 #include "extract.h"
60 #include "addrtoname.h"
61 #include "ppp.h"
62 #include "chdlc.h"
63 #include "ethertype.h"
64 
65 /*
66  * The following constatns are defined by IANA. Please refer to
67  *    http://www.isi.edu/in-notes/iana/assignments/ppp-numbers
68  * for the up-to-date information.
69  */
70 
71 /* Control Protocols (LCP/IPCP/CCP etc.) Codes */
72 
73 #define CPCODES_VEXT		0	/* Vendor-Specific (RFC2153) */
74 #define CPCODES_CONF_REQ	1	/* Configure-Request */
75 #define CPCODES_CONF_ACK	2	/* Configure-Ack */
76 #define CPCODES_CONF_NAK	3	/* Configure-Nak */
77 #define CPCODES_CONF_REJ	4	/* Configure-Reject */
78 #define CPCODES_TERM_REQ	5	/* Terminate-Request */
79 #define CPCODES_TERM_ACK	6	/* Terminate-Ack */
80 #define CPCODES_CODE_REJ	7	/* Code-Reject */
81 #define CPCODES_PROT_REJ	8	/* Protocol-Reject (LCP only) */
82 #define CPCODES_ECHO_REQ	9	/* Echo-Request (LCP only) */
83 #define CPCODES_ECHO_RPL	10	/* Echo-Reply (LCP only) */
84 #define CPCODES_DISC_REQ	11	/* Discard-Request (LCP only) */
85 #define CPCODES_ID		12	/* Identification (LCP only) */
86 #define CPCODES_TIME_REM	13	/* Time-Remaining (LCP only) */
87 #define CPCODES_RESET_REQ	14	/* Reset-Request (CCP only) */
88 #define CPCODES_RESET_REP	15	/* Reset-Reply (CCP only) */
89 
90 #define CPCODES_MIN	CPCODES_VEXT
91 #define CPCODES_MAX	CPCODES_RESET_REP
92 
93 static const char *cpcodes[] = {
94 	/*
95 	 * Control Protocol code values (RFC1661)
96 	 */
97 	"Vend-Ext",	/* (0) RFC2153 */
98 	"Conf-Req",	/* (1) */
99 	"Conf-Ack",	/* (2) */
100 	"Conf-Nak",	/* (3) */
101 	"Conf-Rej",	/* (4) */
102 	"Term-Req",	/* (5) */
103 	"Term-Ack",	/* (6) */
104  	"Code-Rej",	/* (7) */
105 	"Prot-Rej",	/* (8) */
106 	"Echo-Req",	/* (9) */
107 	"Echo-Rep",	/* (10) */
108 	"Disc-Req",	/* (11) */
109 	"Ident",	/* (12) RFC1570 */
110 	"Time-Rem",	/* (13) RFC1570 */
111 	"Reset-Req",	/* (14) RFC1962 */
112 	"Reset-Ack",	/* (15) RFC1962 */
113 };
114 
115 /* LCP Config Options */
116 
117 #define LCPOPT_VEXT	0
118 #define LCPOPT_MRU	1
119 #define LCPOPT_ACCM	2
120 #define LCPOPT_AP	3
121 #define LCPOPT_QP	4
122 #define LCPOPT_MN	5
123 #define LCPOPT_DEP6	6
124 #define LCPOPT_PFC	7
125 #define LCPOPT_ACFC	8
126 #define LCPOPT_FCSALT	9
127 #define LCPOPT_SDP	10
128 #define LCPOPT_NUMMODE	11
129 #define LCPOPT_DEP12	12
130 #define LCPOPT_CBACK	13
131 #define LCPOPT_DEP14	14
132 #define LCPOPT_DEP15	15
133 #define LCPOPT_DEP16	16
134 #define LCPOPT_MLMRRU	17
135 #define LCPOPT_MLSSNHF	18
136 #define LCPOPT_MLED	19
137 #define LCPOPT_PROP	20
138 #define LCPOPT_DCEID	21
139 #define LCPOPT_MPP	22
140 #define LCPOPT_LD	23
141 #define LCPOPT_LCPAOPT	24
142 #define LCPOPT_COBS	25
143 #define LCPOPT_PE	26
144 #define LCPOPT_MLHF	27
145 #define LCPOPT_I18N	28
146 #define LCPOPT_SDLOS	29
147 #define LCPOPT_PPPMUX	30
148 
149 #define LCPOPT_MIN LCPOPT_VEXT
150 #define LCPOPT_MAX LCPOPT_PPPMUX
151 
152 static const char *lcpconfopts[] = {
153 	"Vend-Ext",		/* (0) */
154 	"MRU",			/* (1) */
155 	"ACCM",			/* (2) */
156 	"Auth-Prot",		/* (3) */
157 	"Qual-Prot",		/* (4) */
158 	"Magic-Num",		/* (5) */
159 	"deprecated(6)",	/* used to be a Quality Protocol */
160 	"PFC",			/* (7) */
161 	"ACFC",			/* (8) */
162 	"FCS-Alt",		/* (9) */
163 	"SDP",			/* (10) */
164 	"Num-Mode",		/* (11) */
165 	"deprecated(12)",	/* used to be a Multi-Link-Procedure*/
166 	"Call-Back",		/* (13) */
167 	"deprecated(14)",	/* used to be a Connect-Time */
168 	"deprecated(15)",	/* used to be a Compund-Frames */
169 	"deprecated(16)",	/* used to be a Nominal-Data-Encap */
170 	"MRRU",			/* (17) */
171 	"SSNHF",		/* (18) */
172 	"End-Disc",		/* (19) */
173 	"Proprietary",		/* (20) */
174 	"DCE-Id",		/* (21) */
175 	"MP+",			/* (22) */
176 	"Link-Disc",		/* (23) */
177 	"LCP-Auth-Opt",		/* (24) */
178 	"COBS",			/* (25) */
179 	"Prefix-elision",	/* (26) */
180 	"Multilink-header-Form",/* (27) */
181 	"I18N",			/* (28) */
182 	"SDL-over-SONET/SDH",	/* (29) */
183 	"PPP-Muxing",		/* (30) */
184 };
185 
186 /* IPV6CP - to be supported */
187 /* ECP - to be supported */
188 
189 /* CCP Config Options */
190 
191 #define CCPOPT_OUI	0	/* RFC1962 */
192 #define CCPOPT_PRED1	1	/* RFC1962 */
193 #define CCPOPT_PRED2	2	/* RFC1962 */
194 #define CCPOPT_PJUMP	3	/* RFC1962 */
195 /* 4-15 unassigned */
196 #define CCPOPT_HPPPC	16	/* RFC1962 */
197 #define CCPOPT_STACLZS	17	/* RFC1974 */
198 #define CCPOPT_MPPC	18	/* RFC2118 */
199 #define CCPOPT_GFZA	19	/* RFC1962 */
200 #define CCPOPT_V42BIS	20	/* RFC1962 */
201 #define CCPOPT_BSDCOMP	21	/* RFC1977 */
202 /* 22 unassigned */
203 #define CCPOPT_LZSDCP	23	/* RFC1967 */
204 #define CCPOPT_MVRCA	24	/* RFC1975 */
205 #define CCPOPT_DEC	25	/* RFC1976 */
206 #define CCPOPT_DEFLATE	26	/* RFC1979 */
207 /* 27-254 unassigned */
208 #define CCPOPT_RESV	255	/* RFC1962 */
209 
210 #define CCPOPT_MIN CCPOPT_OUI
211 #define CCPOPT_MAX CCPOPT_DEFLATE    /* XXX: should be CCPOPT_RESV but... */
212 
213 static const char *ccpconfopts[] = {
214 	"OUI",			/* (0) */
215 	"Pred-1",		/* (1) */
216 	"Pred-2",		/* (2) */
217 	"Puddle",		/* (3) */
218 	"unassigned(4)",	/* (4) */
219 	"unassigned(5)",	/* (5) */
220 	"unassigned(6)",	/* (6) */
221 	"unassigned(7)",	/* (7) */
222 	"unassigned(8)",	/* (8) */
223 	"unassigned(9)",	/* (9) */
224 	"unassigned(10)",	/* (10) */
225 	"unassigned(11)",	/* (11) */
226 	"unassigned(12)",	/* (12) */
227 	"unassigned(13)",	/* (13) */
228 	"unassigned(14)",	/* (14) */
229 	"unassigned(15)",	/* (15) */
230 	"HP-PPC",		/* (16) */
231 	"Stac-LZS",		/* (17) */
232 	"MPPC",			/* (18) */
233 	"Gand-FZA",		/* (19) */
234 	"V.42bis",		/* (20) */
235 	"BSD-Comp",		/* (21) */
236 	"unassigned(22)",	/* (22) */
237 	"LZS-DCP",		/* (23) */
238 	"MVRCA",		/* (24) */
239 	"DEC",			/* (25) */
240 	"Deflate",		/* (26) */
241 };
242 
243 /* BACP Config Options */
244 
245 #define BACPOPT_FPEER	1	/* RFC2125 */
246 
247 /* SDCP - to be supported */
248 
249 /* IPCP Config Options */
250 
251 #define IPCPOPT_2ADDR	1	/* RFC1172, RFC1332 (deprecated) */
252 #define IPCPOPT_IPCOMP	2	/* RFC1332 */
253 #define IPCPOPT_ADDR	3	/* RFC1332 */
254 #define IPCPOPT_MOBILE4	4	/* RFC2290 */
255 
256 #define IPCPOPT_PRIDNS	129	/* RFC1877 */
257 #define IPCPOPT_PRINBNS	130	/* RFC1877 */
258 #define IPCPOPT_SECDNS	131	/* RFC1877 */
259 #define IPCPOPT_SECNBNS	132	/* RFC1877 */
260 
261 /* ATCP - to be supported */
262 /* OSINLCP - to be supported */
263 /* BVCP - to be supported */
264 /* BCP - to be supported */
265 /* IPXCP - to be supported */
266 
267 /* Auth Algorithms */
268 
269 /* 0-4 Reserved (RFC1994) */
270 #define AUTHALG_CHAPMD5	5	/* RFC1994 */
271 #define AUTHALG_MSCHAP1	128	/* RFC2433 */
272 #define AUTHALG_MSCHAP2	129	/* RFC2795 */
273 
274 /* FCS Alternatives - to be supported */
275 
276 /* Multilink Endpoint Discriminator (RFC1717) */
277 #define MEDCLASS_NULL	0	/* Null Class */
278 #define MEDCLASS_LOCAL	1	/* Locally Assigned */
279 #define MEDCLASS_IPV4	2	/* Internet Protocol (IPv4) */
280 #define MEDCLASS_MAC	3	/* IEEE 802.1 global MAC address */
281 #define MEDCLASS_MNB	4	/* PPP Magic Number Block */
282 #define MEDCLASS_PSNDN	5	/* Public Switched Network Director Number */
283 
284 /* PPP LCP Callback */
285 #define CALLBACK_AUTH	0	/* Location determined by user auth */
286 #define CALLBACK_DSTR	1	/* Dialing string */
287 #define CALLBACK_LID	2	/* Location identifier */
288 #define CALLBACK_E164	3	/* E.164 number */
289 #define CALLBACK_X500	4	/* X.500 distinguished name */
290 #define CALLBACK_CBCP	6	/* Location is determined during CBCP nego */
291 
292 /* CHAP */
293 
294 #define CHAP_CHAL	1
295 #define CHAP_RESP	2
296 #define CHAP_SUCC	3
297 #define CHAP_FAIL	4
298 
299 #define CHAP_CODEMIN CHAP_CHAL
300 #define CHAP_CODEMAX CHAP_FAIL
301 
302 static const char *chapcode[] = {
303 	"Chal",		/* (1) */
304 	"Resp",		/* (2) */
305 	"Succ",		/* (3) */
306 	"Fail",		/* (4) */
307 };
308 
309 /* PAP */
310 
311 #define PAP_AREQ	1
312 #define PAP_AACK	2
313 #define PAP_ANAK	3
314 
315 #define PAP_CODEMIN	PAP_AREQ
316 #define PAP_CODEMAX	PAP_ANAK
317 
318 static const char *papcode[] = {
319 	"Auth-Req",	/* (1) */
320 	"Auth-Ack",	/* (2) */
321 	"Auth-Nak",	/* (3) */
322 };
323 
324 /* BAP */
325 #define BAP_CALLREQ	1
326 #define BAP_CALLRES	2
327 #define BAP_CBREQ	3
328 #define BAP_CBRES	4
329 #define BAP_LDQREQ	5
330 #define BAP_LDQRES	6
331 #define BAP_CSIND	7
332 #define BAP_CSRES	8
333 
334 static const char *ppp_protoname (u_int proto);
335 static void handle_ctrl_proto (u_int proto,const u_char *p, int length);
336 static void handle_chap (const u_char *p, int length);
337 static void handle_pap (const u_char *p, int length);
338 static void handle_bap (const u_char *p, int length);
339 static int print_lcp_config_options (const u_char *p, int);
340 static int print_ipcp_config_options (const u_char *p, int);
341 static int print_ccp_config_options (const u_char *p, int);
342 static int print_bacp_config_options (const u_char *p, int);
343 static void handle_ppp (u_int proto, const u_char *p, int length);
344 
345 static const char *
346 ppp_protoname(u_int proto)
347 {
348 	static char buf[20];
349 
350 	switch (proto) {
351 	case PPP_IP:	return "IP";
352 	case PPP_IPV6:	return "IPv6";
353 #ifdef PPP_XNS
354 	case PPP_XNS:	return "XNS";
355 #endif
356 	case PPP_IPX:	return "IPX";
357 	case PPP_VJC:	return "VJC";
358 	case PPP_VJNC:	return "VJNC";
359 #ifdef PPP_COMP
360 	case PPP_COMP:	return "COMP";
361 #endif
362 	case PPP_IPCP:	return "IPCP";
363 	case PPP_IPV6CP: return "IPv6CP";
364 	case PPP_IPXCP:	return "IPXCP";
365 	case PPP_CCP:	return "CCP";
366 	case PPP_LCP:	return "LCP";
367 	case PPP_PAP:	return "PAP";
368 #ifdef PPP_LQR
369 	case PPP_LQR:	return "LQR";
370 #endif
371 	case PPP_CHAP:	return "CHAP";
372 	case PPP_BACP:	return "BACP";
373 	case PPP_BAP:	return "BAP";
374 	default:
375 		snprintf(buf, sizeof(buf), "unknown-0x%04x", proto);
376 		return buf;
377 	}
378 }
379 
380 /* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */
381 static void
382 handle_ctrl_proto(u_int proto, const u_char *p, int length)
383 {
384 	u_int code, len;
385 	int (*pfunc)(const u_char *, int);
386 	int x, j;
387 
388 	if (length < 1) {
389 		printf("[|%s]", ppp_protoname(proto));
390 		return;
391 	} else if (length < 4) {
392 		printf("[|%s 0x%02x]", ppp_protoname(proto), *p);
393 		return;
394 	}
395 
396 	code = *p;
397 	if ((code >= CPCODES_MIN) && (code <= CPCODES_MAX))
398 		printf("%s", cpcodes[code]);
399 	else {
400 		printf("0x%02x", code);
401 		return;
402 	}
403 	p++;
404 
405 	printf("(%u)", *p);		/* ID */
406 	p++;
407 
408 	len = EXTRACT_16BITS(p);
409 	p += 2;
410 
411 	if (length <= 4)
412 		return;		/* there may be a NULL confreq etc. */
413 
414 	switch (code) {
415 	case CPCODES_VEXT:
416 		if (length < 11)
417 			break;
418 		printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
419 		p += 4;
420 		printf(" OUI=%02x%02x%02x", p[0], p[1], p[2]);
421 		/* XXX: need to decode Kind and Value(s)? */
422 		break;
423 	case CPCODES_CONF_REQ:
424 	case CPCODES_CONF_ACK:
425 	case CPCODES_CONF_NAK:
426 	case CPCODES_CONF_REJ:
427 		x = len - 4;	/* Code(1), Identifier(1) and Length(2) */
428 		do {
429 			switch (proto) {
430 			case PPP_LCP:
431 				pfunc = print_lcp_config_options;
432 				break;
433 			case PPP_IPCP:
434 				pfunc = print_ipcp_config_options;
435 				break;
436 			case PPP_CCP:
437 				pfunc = print_ccp_config_options;
438 				break;
439 			case PPP_BACP:
440 				pfunc = print_bacp_config_options;
441 				break;
442 			default:
443 				/*
444 				 * This should never happen, but we set
445 				 * "pfunc" to squelch uninitialized
446 				 * variable warnings from compilers.
447 				 */
448 				pfunc = NULL;
449 				break;
450 			}
451 			if ((j = (*pfunc)(p, len)) == 0)
452 				break;
453 			x -= j;
454 			p += j;
455 		} while (x > 0);
456 		break;
457 
458 	case CPCODES_TERM_REQ:
459 	case CPCODES_TERM_ACK:
460 		/* XXX: need to decode Data? */
461 		break;
462 	case CPCODES_CODE_REJ:
463 		/* XXX: need to decode Rejected-Packet? */
464 		break;
465 	case CPCODES_PROT_REJ:
466 		if (length < 6)
467 			break;
468 		printf(", Rejected-Protocol=%04x", EXTRACT_16BITS(p));
469 		/* XXX: need to decode Rejected-Information? */
470 		break;
471 	case CPCODES_ECHO_REQ:
472 	case CPCODES_ECHO_RPL:
473 	case CPCODES_DISC_REQ:
474 	case CPCODES_ID:
475 		if (length < 8)
476 			break;
477 		printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
478 		/* XXX: need to decode Data? */
479 		break;
480 	case CPCODES_TIME_REM:
481 		if (length < 12)
482 			break;
483 		printf(", Magic-Num=%08x", EXTRACT_32BITS(p));
484 		printf(" Seconds-Remaining=%u", EXTRACT_32BITS(p + 4));
485 		/* XXX: need to decode Message? */
486 		break;
487 	default:
488 		printf(", unknown-Codes-0x%02x", code);
489 		break;
490 	}
491 }
492 
493 /* LCP config options */
494 static int
495 print_lcp_config_options(const u_char *p, int length)
496 {
497 	int len, opt;
498 
499 	if (length < 2)
500 		return 0;
501 	len = p[1];
502 	opt = p[0];
503 	if (length < len)
504 		return 0;
505 	if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
506 		printf(", %s", lcpconfopts[opt]);
507 	else {
508 		printf(", unknwhown-%d", opt);
509 		return len;
510 	}
511 
512 	switch (opt) {
513 	case LCPOPT_VEXT:
514 		if (len >= 6) {
515 			printf(" OUI=%02x%02x%02x", p[2], p[3], p[4]);
516 #if 0
517 			printf(" kind=%02x", p[5]);
518 			printf(" val=")
519 			for (i = 0; i < len - 6; i++) {
520 				printf("%02x", p[6 + i]);
521 			}
522 #endif
523 		}
524 		break;
525 	case LCPOPT_MRU:
526 		if (len == 4)
527 			printf("=%u", EXTRACT_16BITS(p + 2));
528 		break;
529 	case LCPOPT_ACCM:
530 		if (len == 6)
531 			printf("=%08x", EXTRACT_32BITS(p + 2));
532 		break;
533 	case LCPOPT_AP:
534 		if (len >= 4) {
535 			if (p[2] == 0xc0 && p[3] == 0x23)
536 				printf(" PAP");
537 			else if (p[2] == 0xc2 && p[3] == 0x23) {
538 				printf(" CHAP/");
539 				switch (p[4]) {
540 				default:
541 					printf("unknown-algorithm-%u", p[4]);
542 					break;
543 				case AUTHALG_CHAPMD5:
544 					printf("MD5");
545 					break;
546 				case AUTHALG_MSCHAP1:
547 					printf("MSCHAPv1");
548 					break;
549 				case AUTHALG_MSCHAP2:
550 					printf("MSCHAPv2");
551 					break;
552 				}
553 			}
554 			else if (p[2] == 0xc2 && p[3] == 0x27)
555 				printf(" EAP");
556 			else if (p[2] == 0xc0 && p[3] == 0x27)
557 				printf(" SPAP");
558 			else if (p[2] == 0xc1 && p[3] == 0x23)
559 				printf(" Old-SPAP");
560 			else
561 				printf("unknown");
562 		}
563 		break;
564 	case LCPOPT_QP:
565 		if (len >= 4) {
566 			if (p[2] == 0xc0 && p[3] == 0x25)
567 				printf(" LQR");
568 			else
569 				printf(" unknown");
570 		}
571 		break;
572 	case LCPOPT_MN:
573 		if (len == 6)
574 			printf("=%08x", EXTRACT_32BITS(p + 2));
575 		break;
576 	case LCPOPT_PFC:
577 		break;
578 	case LCPOPT_ACFC:
579 		break;
580 	case LCPOPT_LD:
581 		if (len == 4)
582 			printf("=%04x", EXTRACT_16BITS(p + 2));
583 		break;
584 	case LCPOPT_CBACK:
585 		if (len < 3)
586 			break;
587 		switch (p[2]) {		/* Operation */
588 		case CALLBACK_AUTH:
589 			printf(" UserAuth");
590 			break;
591 		case CALLBACK_DSTR:
592 			printf(" DialString");
593 			break;
594 		case CALLBACK_LID:
595 			printf(" LocalID");
596 			break;
597 		case CALLBACK_E164:
598 			printf(" E.164");
599 			break;
600 		case CALLBACK_X500:
601 			printf(" X.500");
602 			break;
603 		case CALLBACK_CBCP:
604 			printf(" CBCP");
605 			break;
606 		default:
607 			printf(" unknown-operation=%u", p[2]);
608 			break;
609 		}
610 		break;
611 	case LCPOPT_MLMRRU:
612 		if (len == 4)
613 			printf("=%u", EXTRACT_16BITS(p + 2));
614 		break;
615 	case LCPOPT_MLED:
616 		if (len < 3)
617 			break;
618 		switch (p[2]) {		/* class */
619 		case MEDCLASS_NULL:
620 			printf(" Null");
621 			break;
622 		case MEDCLASS_LOCAL:
623 			printf(" Local"); /* XXX */
624 			break;
625 		case MEDCLASS_IPV4:
626 			if (len != 7)
627 				break;
628 			printf(" IPv4=%s", ipaddr_string(p + 3));
629 			break;
630 		case MEDCLASS_MAC:
631 			if (len != 9)
632 				break;
633 			printf(" MAC=%02x:%02x:%02x:%02x:%02x:%02x",
634 			       p[3], p[4], p[5], p[6], p[7], p[8]);
635 			break;
636 		case MEDCLASS_MNB:
637 			printf(" Magic-Num-Block"); /* XXX */
638 			break;
639 		case MEDCLASS_PSNDN:
640 			printf(" PSNDN"); /* XXX */
641 			break;
642 		}
643 		break;
644 
645 /* XXX: to be supported */
646 #if 0
647 	case LCPOPT_DEP6:
648 	case LCPOPT_FCSALT:
649 	case LCPOPT_SDP:
650 	case LCPOPT_NUMMODE:
651 	case LCPOPT_DEP12:
652 	case LCPOPT_DEP14:
653 	case LCPOPT_DEP15:
654 	case LCPOPT_DEP16:
655 	case LCPOPT_MLSSNHF:
656 	case LCPOPT_PROP:
657 	case LCPOPT_DCEID:
658 	case LCPOPT_MPP:
659 	case LCPOPT_LCPAOPT:
660 	case LCPOPT_COBS:
661 	case LCPOPT_PE:
662 	case LCPOPT_MLHF:
663 	case LCPOPT_I18N:
664 	case LCPOPT_SDLOS:
665 	case LCPOPT_PPPMUX:
666 		break;
667 #endif
668 	}
669 	return len;
670 }
671 
672 /* CHAP */
673 static void
674 handle_chap(const u_char *p, int length)
675 {
676 	u_int code, len;
677 	int val_size, name_size, msg_size;
678 	const u_char *p0;
679 	int i;
680 
681 	p0 = p;
682 	if (length < 1) {
683 		printf("[|chap]");
684 		return;
685 	} else if (length < 4) {
686 		printf("[|chap 0x%02x]", *p);
687 		return;
688 	}
689 
690 	code = *p;
691 	if ((code >= CHAP_CODEMIN) && (code <= CHAP_CODEMAX))
692 		printf("%s", chapcode[code - 1]);
693 	else {
694 		printf("0x%02x", code);
695 		return;
696 	}
697 	p++;
698 
699 	printf("(%u)", *p);		/* ID */
700 	p++;
701 
702 	len = EXTRACT_16BITS(p);
703 	p += 2;
704 
705 	/*
706 	 * Note that this is a generic CHAP decoding routine. Since we
707 	 * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1,
708 	 * MS-CHAPv2) is used at this point, we can't decode packet
709 	 * specifically to each algorithms. Instead, we simply decode
710 	 * the GCD (Gratest Common Denominator) for all algorithms.
711 	 */
712 	switch (code) {
713 	case CHAP_CHAL:
714 	case CHAP_RESP:
715 		if (length - (p - p0) < 1)
716 			return;
717 		val_size = *p;		/* value size */
718 		p++;
719 		if (length - (p - p0) < val_size)
720 			return;
721 		printf(", Value=");
722 		for (i = 0; i < val_size; i++)
723 			printf("%02x", *p++);
724 		name_size = len - (p - p0);
725 		printf(", Name=");
726 		for (i = 0; i < name_size; i++)
727 			safeputchar(*p++);
728 		break;
729 	case CHAP_SUCC:
730 	case CHAP_FAIL:
731 		msg_size = len - (p - p0);
732 		printf(", Msg=");
733 		for (i = 0; i< msg_size; i++)
734 			safeputchar(*p++);
735 		break;
736 	}
737 }
738 
739 /* PAP (see RFC 1334) */
740 static void
741 handle_pap(const u_char *p, int length)
742 {
743 	u_int code, len;
744 	int peerid_len, passwd_len, msg_len;
745 	const u_char *p0;
746 	int i;
747 
748 	p0 = p;
749 	if (length < 1) {
750 		printf("[|pap]");
751 		return;
752 	} else if (length < 4) {
753 		printf("[|pap 0x%02x]", *p);
754 		return;
755 	}
756 
757 	code = *p;
758 	if ((code >= PAP_CODEMIN) && (code <= PAP_CODEMAX))
759 		printf("%s", papcode[code - 1]);
760 	else {
761 		printf("0x%02x", code);
762 		return;
763 	}
764 	p++;
765 
766 	printf("(%u)", *p);		/* ID */
767 	p++;
768 
769 	len = EXTRACT_16BITS(p);
770 	p += 2;
771 
772 	switch (code) {
773 	case PAP_AREQ:
774 		if (length - (p - p0) < 1)
775 			return;
776 		peerid_len = *p;	/* Peer-ID Length */
777 		p++;
778 		if (length - (p - p0) < peerid_len)
779 			return;
780 		printf(", Peer=");
781 		for (i = 0; i < peerid_len; i++)
782 			safeputchar(*p++);
783 
784 		if (length - (p - p0) < 1)
785 			return;
786 		passwd_len = *p;	/* Password Length */
787 		p++;
788 		if (length - (p - p0) < passwd_len)
789 			return;
790 		printf(", Name=");
791 		for (i = 0; i < passwd_len; i++)
792 			safeputchar(*p++);
793 		break;
794 	case PAP_AACK:
795 	case PAP_ANAK:
796 		if (length - (p - p0) < 1)
797 			return;
798 		msg_len = *p;		/* Msg-Length */
799 		p++;
800 		if (length - (p - p0) < msg_len)
801 			return;
802 		printf(", Msg=");
803 		for (i = 0; i< msg_len; i++)
804 			safeputchar(*p++);
805 		break;
806 	}
807 	return;
808 }
809 
810 /* BAP */
811 static void
812 handle_bap(const u_char *p, int length)
813 {
814 	/* XXX: to be supported!! */
815 }
816 
817 
818 /* IPCP config options */
819 static int
820 print_ipcp_config_options(const u_char *p, int length)
821 {
822 	int len, opt;
823 
824 	if (length < 2)
825 		return 0;
826 	len = p[1];
827 	opt = p[0];
828 	if (length < len)
829 		return 0;
830 	switch (opt) {
831 	case IPCPOPT_2ADDR:		/* deprecated */
832 		if (len != 10)
833 			goto invlen;
834 		printf(", IP-Addrs src=%s dst=%s",
835 		       ipaddr_string(p + 2),
836 		       ipaddr_string(p + 6));
837 		break;
838 	case IPCPOPT_IPCOMP:
839 		if (len < 4)
840 			goto invlen;
841 		printf(", IP-Comp");
842 		if (EXTRACT_16BITS(p + 2) == PPP_VJC) {
843 			printf(" VJ-Comp");
844 			/* XXX: VJ-Comp parameters should be decoded */
845 		} else
846 			printf(" unknown-comp-proto=%04x", EXTRACT_16BITS(p + 2));
847 		break;
848 	case IPCPOPT_ADDR:
849 		if (len != 6)
850 			goto invlen;
851 		printf(", IP-Addr=%s", ipaddr_string(p + 2));
852 		break;
853 	case IPCPOPT_MOBILE4:
854 		if (len != 6)
855 			goto invlen;
856 		printf(", Home-Addr=%s", ipaddr_string(p + 2));
857 		break;
858 	case IPCPOPT_PRIDNS:
859 		if (len != 6)
860 			goto invlen;
861 		printf(", Pri-DNS=%s", ipaddr_string(p + 2));
862 		break;
863 	case IPCPOPT_PRINBNS:
864 		if (len != 6)
865 			goto invlen;
866 		printf(", Pri-NBNS=%s", ipaddr_string(p + 2));
867 		break;
868 	case IPCPOPT_SECDNS:
869 		if (len != 6)
870 			goto invlen;
871 		printf(", Sec-DNS=%s", ipaddr_string(p + 2));
872 		break;
873 	case IPCPOPT_SECNBNS:
874 		if (len != 6)
875 			goto invlen;
876 		printf(", Sec-NBNS=%s", ipaddr_string(p + 2));
877 		break;
878 	default:
879 		printf(", unknown-%d", opt);
880 		break;
881 	}
882 	return len;
883 
884 invlen:
885 	printf(", invalid-length-%d", opt);
886 	return 0;
887 }
888 
889 /* CCP config options */
890 static int
891 print_ccp_config_options(const u_char *p, int length)
892 {
893 	int len, opt;
894 
895 	if (length < 2)
896 		return 0;
897 	len = p[1];
898 	opt = p[0];
899 	if (length < len)
900 		return 0;
901 	if ((opt >= CCPOPT_MIN) && (opt <= CCPOPT_MAX))
902 		printf(", %s", ccpconfopts[opt]);
903 #if 0	/* XXX */
904 	switch (opt) {
905 	case CCPOPT_OUI:
906 	case CCPOPT_PRED1:
907 	case CCPOPT_PRED2:
908 	case CCPOPT_PJUMP:
909 	case CCPOPT_HPPPC:
910 	case CCPOPT_STACLZS:
911 	case CCPOPT_MPPC:
912 	case CCPOPT_GFZA:
913 	case CCPOPT_V42BIS:
914 	case CCPOPT_BSDCOMP:
915 	case CCPOPT_LZSDCP:
916 	case CCPOPT_MVRCA:
917 	case CCPOPT_DEC:
918 	case CCPOPT_DEFLATE:
919 	case CCPOPT_RESV:
920 		break;
921 
922 	default:
923 		printf(", unknown-%d", opt);
924 		break;
925 	}
926 #endif
927 	return len;
928 }
929 
930 /* BACP config options */
931 static int
932 print_bacp_config_options(const u_char *p, int length)
933 {
934 	int len, opt;
935 
936 	if (length < 2)
937 		return 0;
938 	len = p[1];
939 	opt = p[0];
940 	if (length < len)
941 		return 0;
942 	if (opt == BACPOPT_FPEER) {
943 		printf(", Favored-Peer");
944 		printf(" Magic-Num=%08x", EXTRACT_32BITS(p + 2));
945 	} else {
946 		printf(", unknown-option-%d", opt);
947 	}
948 	return len;
949 }
950 
951 
952 /* PPP */
953 static void
954 handle_ppp(u_int proto, const u_char *p, int length)
955 {
956 	switch (proto) {
957 	case PPP_LCP:
958 	case PPP_IPCP:
959 	case PPP_CCP:
960 	case PPP_BACP:
961 		handle_ctrl_proto(proto, p, length);
962 		break;
963 	case PPP_CHAP:
964 		handle_chap(p, length);
965 		break;
966 	case PPP_PAP:
967 		handle_pap(p, length);
968 		break;
969 	case PPP_BAP:		/* XXX: not yet completed */
970 		handle_bap(p, length);
971 		break;
972 	case ETHERTYPE_IP:	/*XXX*/
973 	case PPP_IP:
974 		ip_print(p, length);
975 		break;
976 #ifdef INET6
977 	case ETHERTYPE_IPV6:	/*XXX*/
978 	case PPP_IPV6:
979 		ip6_print(p, length);
980 		break;
981 #endif
982 	case ETHERTYPE_IPX:	/*XXX*/
983 	case PPP_IPX:
984 		ipx_print(p, length);
985 		break;
986 	}
987 }
988 
989 /* Standard PPP printer */
990 void
991 ppp_print(register const u_char *p, u_int length)
992 {
993 	u_int proto;
994 	u_int full_length = length;
995 
996 	/*
997 	 * Here, we assume that p points to the Address and Control
998 	 * field (if they present).
999 	 */
1000 	if (length < 2)
1001 		goto trunc;
1002 	if (*p == PPP_ADDRESS && *(p + 1) == PPP_CONTROL) {
1003 		p += 2;			/* ACFC not used */
1004 		length -= 2;
1005 	}
1006 
1007 	if (length < 2)
1008 		goto trunc;
1009 	if (*p % 2) {
1010 		proto = *p;		/* PFC is used */
1011 		p++;
1012 		length--;
1013 	} else {
1014 		proto = EXTRACT_16BITS(p);
1015 		p += 2;
1016 		length -= 2;
1017 	}
1018 
1019 	printf("%s %d: ", ppp_protoname(proto), full_length);
1020 
1021 	handle_ppp(proto, p, length);
1022 	return;
1023 trunc:
1024 	printf("[|ppp]");
1025 }
1026 
1027 
1028 /* PPP I/F printer */
1029 void
1030 ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
1031 	     register const u_char *p)
1032 {
1033 	register u_int length = h->len;
1034 	register u_int caplen = h->caplen;
1035 
1036 	ts_print(&h->ts);
1037 
1038 	if (caplen < PPP_HDRLEN) {
1039 		printf("[|ppp]");
1040 		goto out;
1041 	}
1042 
1043 	/*
1044 	 * Some printers want to get back at the link level addresses,
1045 	 * and/or check that they're not walking off the end of the packet.
1046 	 * Rather than pass them all the way down, we set these globals.  */
1047 
1048 	packetp = p;
1049 	snapend = p + caplen;
1050 
1051 #if 0
1052 	/*
1053 	 * XXX: seems to assume that there are 2 octets prepended to an
1054 	 * actual PPP frame. The 1st octet looks like Input/Output flag
1055 	 * while 2nd octet is unknown, at least to me
1056 	 * (mshindo@mshindo.net).
1057 	 *
1058 	 * That was what the original tcpdump code did.
1059 	 *
1060 	 * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound
1061 	 * packets and 0 for inbound packets - but only if the
1062 	 * protocol field has the 0x8000 bit set (i.e., it's a network
1063 	 * control protocol); it does so before running the packet through
1064 	 * "bpf_filter" to see if it should be discarded, and to see
1065 	 * if we should update the time we sent the most recent packet...
1066 	 *
1067 	 * ...but it puts the original address field back after doing
1068 	 * so.
1069 	 *
1070 	 * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion.
1071 	 *
1072 	 * I don't know if any PPP implementation handed up to a BPF
1073 	 * device packets with the first octet being 1 for outbound and
1074 	 * 0 for inbound packets, so I (guy@alum.mit.edu) don't know
1075 	 * whether that ever needs to be checked or not.
1076 	 *
1077 	 * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP,
1078 	 * and its tcpdump appears to assume that the frame always
1079 	 * begins with an address field and a control field, and that
1080 	 * the address field might be 0x0f or 0x8f, for Cisco
1081 	 * point-to-point with HDLC framing as per section 4.3.1 of RFC
1082 	 * 1547, as well as 0xff, for PPP in HDLC-like framing as per
1083 	 * RFC 1662.
1084 	 *
1085 	 * (Is the Cisco framing in question what DLT_C_HDLC, in
1086 	 * BSD/OS, is?)
1087 	 */
1088 	if (eflag)
1089 		printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]);
1090 #endif
1091 
1092 	ppp_print(p, length);
1093 
1094 	if (xflag)
1095 		default_print(p, caplen);
1096 out:
1097 	putchar('\n');
1098 }
1099 
1100 /*
1101  * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like
1102  * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547,
1103  * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL,
1104  * discard them *if* those are the first two octets, and parse the remaining
1105  * packet as a PPP packet, as "ppp_print()" does).
1106  *
1107  * This handles, for example, DLT_PPP_SERIAL in NetBSD.
1108  */
1109 void
1110 ppp_hdlc_if_print(u_char *user, const struct pcap_pkthdr *h,
1111 	     register const u_char *p)
1112 {
1113 	register u_int length = h->len;
1114 	register u_int caplen = h->caplen;
1115 	u_int proto;
1116 
1117 	if (caplen < 2) {
1118 		printf("[|ppp]");
1119 		goto out;
1120 	}
1121 
1122 	/*
1123 	 * Some printers want to get back at the link level addresses,
1124 	 * and/or check that they're not walking off the end of the packet.
1125 	 * Rather than pass them all the way down, we set these globals.
1126 	 */
1127 	packetp = p;
1128 	snapend = p + caplen;
1129 
1130 	switch (p[0]) {
1131 
1132 	case PPP_ADDRESS:
1133 		if (caplen < 4) {
1134 			printf("[|ppp]");
1135 			goto out;
1136 		}
1137 
1138 		ts_print(&h->ts);
1139 		if (eflag)
1140 			printf("%02x %02x %d ", p[0], p[1], length);
1141 		p += 2;
1142 		length -= 2;
1143 
1144 		proto = EXTRACT_16BITS(p);
1145 		p += 2;
1146 		length -= 2;
1147 		printf("%s: ", ppp_protoname(proto));
1148 
1149 		handle_ppp(proto, p, length);
1150 		break;
1151 
1152 	case CHDLC_UNICAST:
1153 	case CHDLC_BCAST:
1154 		/*
1155 		 * Have the Cisco HDLC print routine do all the work.
1156 		 */
1157 		chdlc_if_print(user, h, p);
1158 		return;
1159 
1160 	default:
1161 		ts_print(&h->ts);
1162 		if (eflag)
1163 			printf("%02x %02x %d ", p[0], p[1], length);
1164 		p += 2;
1165 		length -= 2;
1166 
1167 		/*
1168 		 * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats
1169 		 * the next two octets as an Ethernet type; does that
1170 		 * ever happen?
1171 		 */
1172 		printf("unknown addr %02x; ctrl %02x", p[0], p[1]);
1173 		break;
1174 	}
1175 
1176 	if (xflag)
1177 		default_print(p, caplen);
1178 out:
1179 	putchar('\n');
1180 }
1181 
1182 
1183 
1184 struct tok ppptype2str[] = {
1185 	{ PPP_IP,	"IP" },
1186 	{ PPP_OSI,	"OSI" },
1187 	{ PPP_NS,	"NS" },
1188 	{ PPP_DECNET,	"DECNET" },
1189 	{ PPP_APPLE,	"APPLE" },
1190 	{ PPP_IPX,	"IPX" },
1191 	{ PPP_VJC,	"VJC" },
1192 	{ PPP_VJNC,	"VJNC" },
1193 	{ PPP_BRPDU,	"BRPDU" },
1194 	{ PPP_STII,	"STII" },
1195 	{ PPP_VINES,	"VINES" },
1196 
1197 	{ PPP_HELLO,	"HELLO" },
1198 	{ PPP_LUXCOM,	"LUXCOM" },
1199 	{ PPP_SNS,	"SNS" },
1200 	{ PPP_IPCP,	"IPCP" },
1201 	{ PPP_OSICP,	"OSICP" },
1202 	{ PPP_NSCP,	"NSCP" },
1203 	{ PPP_DECNETCP, "DECNETCP" },
1204 	{ PPP_APPLECP,	"APPLECP" },
1205 	{ PPP_IPXCP,	"IPXCP" },
1206 	{ PPP_STIICP,	"STIICP" },
1207 	{ PPP_VINESCP,	"VINESCP" },
1208 
1209 	{ PPP_LCP,	"LCP" },
1210 	{ PPP_PAP,	"PAP" },
1211 	{ PPP_LQM,	"LQM" },
1212 	{ PPP_CHAP,	"CHAP" },
1213 	{ PPP_BACP,	"BACP" },
1214 	{ PPP_BAP,	"BAP" },
1215 	{ PPP_MP,	"MP" },
1216 	{ 0,		NULL }
1217 };
1218 
1219 #define PPP_BSDI_HDRLEN 24
1220 
1221 /* BSD/OS specific PPP printer */
1222 void
1223 ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
1224 	     register const u_char *p)
1225 {
1226 #ifdef __bsdi__
1227 	register u_int length = h->len;
1228 	register u_int caplen = h->caplen;
1229 	register int hdrlength;
1230 	u_int16_t ptype;
1231 	const u_char *q;
1232 	int i;
1233 
1234 	ts_print(&h->ts);
1235 
1236 	if (caplen < PPP_BSDI_HDRLEN) {
1237 		printf("[|ppp]");
1238 		goto out;
1239 	}
1240 
1241 	/*
1242 	 * Some printers want to get back at the link level addresses,
1243 	 * and/or check that they're not walking off the end of the packet.
1244 	 * Rather than pass them all the way down, we set these globals.
1245 	 */
1246 	packetp = p;
1247 	snapend = p + caplen;
1248 	hdrlength = 0;
1249 
1250 #if 0
1251 	if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
1252 		if (eflag)
1253 			printf("%02x %02x ", p[0], p[1]);
1254 		p += 2;
1255 		hdrlength = 2;
1256 	}
1257 
1258 	if (eflag)
1259 		printf("%d ", length);
1260 	/* Retrieve the protocol type */
1261 	if (*p & 01) {
1262 		/* Compressed protocol field */
1263 		ptype = *p;
1264 		if (eflag)
1265 			printf("%02x ", ptype);
1266 		p++;
1267 		hdrlength += 1;
1268 	} else {
1269 		/* Un-compressed protocol field */
1270 		ptype = ntohs(*(u_int16_t *)p);
1271 		if (eflag)
1272 			printf("%04x ", ptype);
1273 		p += 2;
1274 		hdrlength += 2;
1275 	}
1276 #else
1277 	ptype = 0;	/*XXX*/
1278 	if (eflag)
1279 		printf("%c ", p[SLC_DIR] ? 'O' : 'I');
1280 	if (p[SLC_LLHL]) {
1281 		/* link level header */
1282 		struct ppp_header *ph;
1283 
1284 		q = p + SLC_BPFHDRLEN;
1285 		ph = (struct ppp_header *)q;
1286 		if (ph->phdr_addr == PPP_ADDRESS
1287 		 && ph->phdr_ctl == PPP_CONTROL) {
1288 			if (eflag)
1289 				printf("%02x %02x ", q[0], q[1]);
1290 			ptype = ntohs(ph->phdr_type);
1291 			if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
1292 				printf("%s ", tok2str(ppptype2str,
1293 						"proto-#%d", ptype));
1294 			}
1295 		} else {
1296 			if (eflag) {
1297 				printf("LLH=[");
1298 				for (i = 0; i < p[SLC_LLHL]; i++)
1299 					printf("%02x", q[i]);
1300 				printf("] ");
1301 			}
1302 		}
1303 	}
1304 	if (eflag)
1305 		printf("%d ", length);
1306 	if (p[SLC_CHL]) {
1307 		q = p + SLC_BPFHDRLEN + p[SLC_LLHL];
1308 
1309 		switch (ptype) {
1310 		case PPP_VJC:
1311 			ptype = vjc_print(q, length - (q - p), ptype);
1312 			hdrlength = PPP_BSDI_HDRLEN;
1313 			p += hdrlength;
1314 			switch (ptype) {
1315 			case PPP_IP:
1316 				ip_print(p, length);
1317 				break;
1318 #ifdef INET6
1319 			case PPP_IPV6:
1320 				ip6_print(p, length);
1321 				break;
1322 #endif
1323 			}
1324 			goto printx;
1325 		case PPP_VJNC:
1326 			ptype = vjc_print(q, length - (q - p), ptype);
1327 			hdrlength = PPP_BSDI_HDRLEN;
1328 			p += hdrlength;
1329 			switch (ptype) {
1330 			case PPP_IP:
1331 				ip_print(p, length);
1332 				break;
1333 #ifdef INET6
1334 			case PPP_IPV6:
1335 				ip6_print(p, length);
1336 				break;
1337 #endif
1338 			}
1339 			goto printx;
1340 		default:
1341 			if (eflag) {
1342 				printf("CH=[");
1343 				for (i = 0; i < p[SLC_LLHL]; i++)
1344 					printf("%02x", q[i]);
1345 				printf("] ");
1346 			}
1347 			break;
1348 		}
1349 	}
1350 
1351 	hdrlength = PPP_BSDI_HDRLEN;
1352 #endif
1353 
1354 	length -= hdrlength;
1355 	p += hdrlength;
1356 
1357 	switch (ptype) {
1358 	case PPP_IP:
1359 		ip_print(p, length);
1360 		break;
1361 #ifdef INET6
1362 	case PPP_IPV6:
1363 		ip6_print(p, length);
1364 		break;
1365 #endif
1366 	default:
1367 		printf("%s ", tok2str(ppptype2str, "proto-#%d", ptype));
1368 	}
1369 
1370 printx:
1371 	if (xflag)
1372 		default_print((const u_char *)p, caplen - hdrlength);
1373 out:
1374 	putchar('\n');
1375 #endif /* __bsdi__ */
1376 }
1377