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, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * 3. The name(s) of the authors of this software must not be used to
20 * endorse or promote products derived from this software without
21 * prior written permission.
23 * 4. Redistributions of any form whatsoever must retain the following
25 * "This product includes software developed by Paul Mackerras
26 * <paulus@samba.org>".
28 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
29 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
30 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
31 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
32 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
33 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
34 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
40 #include <sys/types.h>
51 int start_time_tenths
;
52 int tot_sent
, tot_rcvd
;
71 while ((i
= getopt(ac
, av
, "hprdm:a")) != -1) {
92 fprintf(stderr
, "Usage: %s [-h | -p[d]] [-r] [-m mru] [-a] [file ...]\n", av
[0]);
99 for (i
= optind
; i
< ac
; ++i
) {
101 if ((f
= fopen(p
, "r")) == NULL
) {
121 unsigned char buf
[16];
123 while ((c
= getc(f
)) != EOF
) {
129 printf("%s %c", c
==1? "sent": "rcvd", hexmode
? ' ': '"');
132 n
= (n
<< 8) + getc(f
);
133 *(c
==1? &tot_sent
: &tot_rcvd
) += n
;
144 for (k
= 0; k
< nb
; ++k
) {
146 putchar((' ' <= c2
&& c2
<= '~')? c2
: '.');
154 k
= (' ' <= c
&& c
<= '~')? (c
!= '\\' && c
!= '"')? 1: 2: 3;
155 if ((col
+= k
) >= 78) {
173 for (k
= nb
; k
< 16; ++k
)
176 for (k
= 0; k
< nb
; ++k
) {
178 putchar((' ' <= c2
&& c2
<= '~')? c2
: '.');
186 printf("end %s\n", c
==3? "send": "recv");
200 * FCS lookup table as calculated by genfcstab.
202 static u_short fcstab
[256] = {
203 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
204 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
205 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
206 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
207 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
208 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
209 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
210 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
211 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
212 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
213 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
214 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
215 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
216 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
217 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
218 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
219 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
220 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
221 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
222 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
223 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
224 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
225 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
226 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
227 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
228 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
229 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
230 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
231 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
232 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
233 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
234 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
241 struct compressor
*comp
;
243 unsigned char buf
[8192];
246 /* Values for flags */
249 #define CCP_FATALERROR 4
250 #define CCP_ERR (CCP_ERROR | CCP_FATALERROR)
251 #define CCP_DECOMP_RUN 8
253 unsigned char dbuf
[8192];
260 int nb
, nl
, dn
, proto
, rv
;
262 unsigned char *p
, *r
, *endp
;
267 spkt
.cnt
= rpkt
.cnt
= 0;
268 spkt
.esc
= rpkt
.esc
= 0;
269 while ((c
= getc(f
)) != EOF
) {
275 dir
= c
==1? "sent": "rcvd";
276 pkt
= c
==1? &spkt
: &rpkt
;
278 n
= (n
<< 8) + getc(f
);
279 *(c
==1? &tot_sent
: &tot_rcvd
) += n
;
286 printf("[%d bytes in incomplete send packet]\n",
289 printf("[%d bytes in incomplete recv packet]\n",
296 printf("%s aborted packet:\n ", dir
);
304 printf("%s short packet [%d bytes]:", q
, nb
);
305 for (k
= 0; k
< nb
; ++k
)
306 printf(" %.2x", p
[k
]);
311 for (k
= 0; k
< nb
; ++k
)
312 fcs
= PPP_FCS(fcs
, p
[k
]);
317 if (r
[0] == 0xff && r
[1] == 3)
323 printf(" ERROR: length (%d) > MRU (%d)\n",
325 if (decompress
&& fcs
== PPP_GOODFCS
) {
326 /* See if this is a CCP or compressed packet */
329 if (r
[0] == 0xff && r
[1] == 3) {
334 if ((proto
& 1) == 0)
335 proto
= (proto
<< 8) + r
[1];
336 if (proto
== PPP_CCP
) {
337 handle_ccp(pkt
, r
+ 2, endp
- r
- 2);
338 } else if (proto
== PPP_COMP
) {
339 if ((pkt
->flags
& CCP_ISUP
)
340 && (pkt
->flags
& CCP_DECOMP_RUN
)
342 && (pkt
->flags
& CCP_ERR
) == 0) {
343 rv
= pkt
->comp
->decompress(pkt
->state
, r
,
353 printf(" ERROR: decompressed length (%d) > MRU (%d)\n", dn
, mru
);
356 printf(" DECOMPRESSION ERROR\n");
357 pkt
->flags
|= CCP_ERROR
;
359 case DECOMP_FATALERROR
:
360 printf(" FATAL DECOMPRESSION ERROR\n");
361 pkt
->flags
|= CCP_FATALERROR
;
365 } else if (pkt
->state
366 && (pkt
->flags
& CCP_DECOMP_RUN
)) {
367 pkt
->comp
->incomp(pkt
->state
, r
, endp
- r
);
371 nl
= nb
< 16? nb
: 16;
373 for (k
= 0; k
< nl
; ++k
)
374 printf(" %.2x", p
[k
]);
378 for (k
= 0; k
< nl
; ++k
) {
380 putchar((' ' <= c
&& c
<= '~')? c
: '.');
387 if (fcs
!= PPP_GOODFCS
)
388 printf(" BAD FCS: (residue = %x)\n", fcs
);
396 /* else fall through */
402 pkt
->buf
[pkt
->cnt
++] = c
;
411 dir
= c
==3? "send": "recv";
412 pkt
= c
==3? &spkt
: &rpkt
;
413 printf("end %s", dir
);
415 printf(" [%d bytes in incomplete packet]", pkt
->cnt
);
429 extern struct compressor ppp_bsd_compress
, ppp_deflate
;
431 struct compressor
*compressors
[] = {
442 handle_ccp(cp
, dp
, len
)
448 struct compressor
**comp
;
450 if (len
< CCP_HDRLEN
)
452 clen
= CCP_LENGTH(dp
);
456 switch (CCP_CODE(dp
)) {
458 cp
->flags
&= ~(CCP_DECOMP_RUN
| CCP_ISUP
);
459 if (clen
< CCP_HDRLEN
+ CCP_OPT_MINLEN
460 || clen
< CCP_HDRLEN
+ CCP_OPT_LENGTH(dp
+ CCP_HDRLEN
))
464 for (comp
= compressors
; *comp
!= NULL
; ++comp
) {
465 if ((*comp
)->compress_proto
== dp
[0]) {
466 if (cp
->state
!= NULL
) {
467 (*cp
->comp
->decomp_free
)(cp
->state
);
471 cp
->state
= (*comp
)->decomp_alloc(dp
, CCP_OPT_LENGTH(dp
));
472 cp
->flags
|= CCP_ISUP
;
473 if (cp
->state
!= NULL
474 && (*cp
->comp
->decomp_init
)
475 (cp
->state
, dp
, clen
, 0, 0, 8192, 1))
476 cp
->flags
= (cp
->flags
& ~CCP_ERR
) | CCP_DECOMP_RUN
;
484 cp
->flags
&= ~(CCP_DECOMP_RUN
| CCP_ISUP
);
488 if (cp
->flags
& CCP_ISUP
) {
489 if (cp
->state
&& (cp
->flags
& CCP_DECOMP_RUN
)) {
490 (*cp
->comp
->decomp_reset
)(cp
->state
);
491 cp
->flags
&= ~CCP_ERROR
;
509 t
= (t
<< 8) + getc(f
);
510 t
= (t
<< 8) + getc(f
);
511 t
= (t
<< 8) + getc(f
);
512 printf("start %s", ctime(&t
));
514 start_time_tenths
= 0;
515 tot_sent
= tot_rcvd
= 0;
519 for (c
= 3; c
> 0; --c
)
520 n
= (n
<< 8) + getc(f
);
523 n
+= start_time_tenths
;
524 start_time
+= n
/ 10;
525 start_time_tenths
= n
% 10;
526 tm
= localtime(&start_time
);
527 printf("time %.2d:%.2d:%.2d.%d", tm
->tm_hour
, tm
->tm_min
,
528 tm
->tm_sec
, start_time_tenths
);
529 printf(" (sent %d, rcvd %d)\n", tot_sent
, tot_rcvd
);
531 printf("time %.1fs\n", (double) n
/ 10);