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);