2 * pppdump - print out the contents of a record file generated by
3 * pppd in readable form.
5 * Copyright (C) 1999 Paul Mackerras. All rights reserved.
7 * Redistribution and use in source and binary forms are permitted
8 * provided that the above copyright notice and this paragraph are
9 * duplicated in all such forms. The name of the author
10 * may not be used to endorse or promote products derived
11 * from this software without specific prior written permission.
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
13 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
14 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 #include <sys/types.h>
30 int start_time_tenths
;
31 int tot_sent
, tot_rcvd
;
44 while ((i
= getopt(ac
, av
, "hprdm:a")) != -1) {
65 fprintf(stderr
, "Usage: %s [-h | -p[d]] [-r] [-m mru] [-a] [file ...]\n", av
[0]);
72 for (i
= optind
; i
< ac
; ++i
) {
74 if ((f
= fopen(p
, "r")) == NULL
) {
93 unsigned char buf
[16];
95 while ((c
= getc(f
)) != EOF
) {
101 printf("%s %c", c
==1? "sent": "rcvd", hexmode
? ' ': '"');
104 n
= (n
<< 8) + getc(f
);
105 *(c
==1? &tot_sent
: &tot_rcvd
) += n
;
116 for (k
= 0; k
< nb
; ++k
) {
118 putchar((' ' <= c2
&& c2
<= '~')? c2
: '.');
126 k
= (' ' <= c
&& c
<= '~')? (c
!= '\\' && c
!= '"')? 1: 2: 3;
127 if ((col
+= k
) >= 78) {
145 for (k
= nb
; k
< 16; ++k
)
148 for (k
= 0; k
< nb
; ++k
) {
150 putchar((' ' <= c2
&& c2
<= '~')? c2
: '.');
158 printf("end %s\n", c
==3? "send": "recv");
172 * FCS lookup table as calculated by genfcstab.
174 static u_short fcstab
[256] = {
175 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
176 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
177 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
178 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
179 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
180 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
181 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
182 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
183 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
184 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
185 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
186 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
187 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
188 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
189 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
190 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
191 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
192 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
193 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
194 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
195 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
196 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
197 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
198 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
199 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
200 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
201 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
202 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
203 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
204 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
205 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
206 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
213 struct compressor
*comp
;
215 unsigned char buf
[8192];
218 /* Values for flags */
221 #define CCP_FATALERROR 4
222 #define CCP_ERR (CCP_ERROR | CCP_FATALERROR)
223 #define CCP_DECOMP_RUN 8
225 unsigned char dbuf
[8192];
231 int nb
, nl
, dn
, proto
, rv
;
233 unsigned char *p
, *r
, *endp
;
238 spkt
.cnt
= rpkt
.cnt
= 0;
239 spkt
.esc
= rpkt
.esc
= 0;
240 while ((c
= getc(f
)) != EOF
) {
246 dir
= c
==1? "sent": "rcvd";
247 pkt
= c
==1? &spkt
: &rpkt
;
249 n
= (n
<< 8) + getc(f
);
250 *(c
==1? &tot_sent
: &tot_rcvd
) += n
;
257 printf("[%d bytes in incomplete send packet]\n",
260 printf("[%d bytes in incomplete recv packet]\n",
267 printf("%s aborted packet:\n ", dir
);
275 printf("%s short packet [%d bytes]:", q
, nb
);
276 for (k
= 0; k
< nb
; ++k
)
277 printf(" %.2x", p
[k
]);
282 for (k
= 0; k
< nb
; ++k
)
283 fcs
= PPP_FCS(fcs
, p
[k
]);
288 if (r
[0] == 0xff && r
[1] == 3)
294 printf(" ERROR: length (%d) > MRU (%d)\n",
296 if (decompress
&& fcs
== PPP_GOODFCS
) {
297 /* See if this is a CCP or compressed packet */
300 if (r
[0] == 0xff && r
[1] == 3) {
305 if ((proto
& 1) == 0)
306 proto
= (proto
<< 8) + r
[1];
307 if (proto
== PPP_CCP
) {
308 handle_ccp(pkt
, r
+ 2, endp
- r
- 2);
309 } else if (proto
== PPP_COMP
) {
310 if ((pkt
->flags
& CCP_ISUP
)
311 && (pkt
->flags
& CCP_DECOMP_RUN
)
313 && (pkt
->flags
& CCP_ERR
) == 0) {
314 rv
= pkt
->comp
->decompress(pkt
->state
, r
,
324 printf(" ERROR: decompressed length (%d) > MRU (%d)\n", dn
, mru
);
327 printf(" DECOMPRESSION ERROR\n");
328 pkt
->flags
|= CCP_ERROR
;
330 case DECOMP_FATALERROR
:
331 printf(" FATAL DECOMPRESSION ERROR\n");
332 pkt
->flags
|= CCP_FATALERROR
;
336 } else if (pkt
->state
337 && (pkt
->flags
& CCP_DECOMP_RUN
)) {
338 pkt
->comp
->incomp(pkt
->state
, r
, endp
- r
);
342 nl
= nb
< 16? nb
: 16;
344 for (k
= 0; k
< nl
; ++k
)
345 printf(" %.2x", p
[k
]);
349 for (k
= 0; k
< nl
; ++k
) {
351 putchar((' ' <= c
&& c
<= '~')? c
: '.');
358 if (fcs
!= PPP_GOODFCS
)
359 printf(" BAD FCS: (residue = %x)\n", fcs
);
367 /* else fall through */
373 pkt
->buf
[pkt
->cnt
++] = c
;
382 dir
= c
==3? "send": "recv";
383 pkt
= c
==3? &spkt
: &rpkt
;
384 printf("end %s", dir
);
386 printf(" [%d bytes in incomplete packet]", pkt
->cnt
);
400 extern struct compressor ppp_bsd_compress
, ppp_deflate
;
402 struct compressor
*compressors
[] = {
412 handle_ccp(cp
, dp
, len
)
418 struct compressor
**comp
;
420 if (len
< CCP_HDRLEN
)
422 clen
= CCP_LENGTH(dp
);
426 switch (CCP_CODE(dp
)) {
428 cp
->flags
&= ~(CCP_DECOMP_RUN
| CCP_ISUP
);
429 if (clen
< CCP_HDRLEN
+ CCP_OPT_MINLEN
430 || clen
< CCP_HDRLEN
+ CCP_OPT_LENGTH(dp
+ CCP_HDRLEN
))
434 for (comp
= compressors
; *comp
!= NULL
; ++comp
) {
435 if ((*comp
)->compress_proto
== dp
[0]) {
436 if (cp
->state
!= NULL
) {
437 (*cp
->comp
->decomp_free
)(cp
->state
);
441 cp
->state
= (*comp
)->decomp_alloc(dp
, CCP_OPT_LENGTH(dp
));
442 cp
->flags
|= CCP_ISUP
;
443 if (cp
->state
!= NULL
444 && (*cp
->comp
->decomp_init
)
445 (cp
->state
, dp
, clen
, 0, 0, 8192, 1))
446 cp
->flags
= (cp
->flags
& ~CCP_ERR
) | CCP_DECOMP_RUN
;
454 cp
->flags
&= ~(CCP_DECOMP_RUN
| CCP_ISUP
);
458 if (cp
->flags
& CCP_ISUP
) {
459 if (cp
->state
&& (cp
->flags
& CCP_DECOMP_RUN
)) {
460 (*cp
->comp
->decomp_reset
)(cp
->state
);
461 cp
->flags
&= ~CCP_ERROR
;
478 t
= (t
<< 8) + getc(f
);
479 t
= (t
<< 8) + getc(f
);
480 t
= (t
<< 8) + getc(f
);
481 printf("start %s", ctime(&t
));
483 start_time_tenths
= 0;
484 tot_sent
= tot_rcvd
= 0;
488 for (c
= 3; c
> 0; --c
)
489 n
= (n
<< 8) + getc(f
);
492 n
+= start_time_tenths
;
493 start_time
+= n
/ 10;
494 start_time_tenths
= n
% 10;
495 tm
= localtime(&start_time
);
496 printf("time %.2d:%.2d:%.2d.%d", tm
->tm_hour
, tm
->tm_min
,
497 tm
->tm_sec
, start_time_tenths
);
498 printf(" (sent %d, rcvd %d)\n", tot_sent
, tot_rcvd
);
500 printf("time %.1fs\n", (double) n
/ 10);