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 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
15 #include <sys/types.h>
26 int start_time_tenths;
27 int tot_sent, tot_rcvd;
40 while ((i = getopt(ac, av, "hprdm:a")) != -1) {
61 fprintf(stderr, "Usage: %s [-h | -p[d]] [-r] [-m mru] [-a] [file ...]\n", av[0]);
68 for (i = optind; i < ac; ++i) {
70 if ((f = fopen(p, "r")) == NULL) {
89 unsigned char buf[16];
91 while ((c = getc(f)) != EOF) {
97 printf("%s %c", c==1? "sent": "rcvd", hexmode? ' ': '"');
100 n = (n << 8) + getc(f);
101 *(c==1? &tot_sent: &tot_rcvd) += n;
112 for (k = 0; k < nb; ++k) {
114 putchar((' ' <= c2 && c2 <= '~')? c2: '.');
122 k = (' ' <= c && c <= '~')? (c != '\\' && c != '"')? 1: 2: 3;
123 if ((col += k) >= 78) {
141 for (k = nb; k < 16; ++k)
144 for (k = 0; k < nb; ++k) {
146 putchar((' ' <= c2 && c2 <= '~')? c2: '.');
154 printf("end %s\n", c==3? "send": "recv");
168 * FCS lookup table as calculated by genfcstab.
170 static u_short fcstab[256] = {
171 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
172 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
173 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
174 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
175 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
176 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
177 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
178 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
179 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
180 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
181 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
182 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
183 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
184 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
185 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
186 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
187 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
188 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
189 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
190 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
191 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
192 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
193 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
194 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
195 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
196 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
197 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
198 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
199 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
200 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
201 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
202 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
209 struct compressor *comp;
211 unsigned char buf[8192];
214 /* Values for flags */
217 #define CCP_FATALERROR 4
218 #define CCP_ERR (CCP_ERROR | CCP_FATALERROR)
219 #define CCP_DECOMP_RUN 8
221 unsigned char dbuf[8192];
227 int nb, nl, dn, proto, rv;
229 unsigned char *p, *r, *endp;
234 spkt.cnt = rpkt.cnt = 0;
235 spkt.esc = rpkt.esc = 0;
236 while ((c = getc(f)) != EOF) {
242 dir = c==1? "sent": "rcvd";
243 pkt = c==1? &spkt: &rpkt;
245 n = (n << 8) + getc(f);
246 *(c==1? &tot_sent: &tot_rcvd) += n;
253 printf("[%d bytes in incomplete send packet]\n",
256 printf("[%d bytes in incomplete recv packet]\n",
263 printf("%s aborted packet:\n ", dir);
271 printf("%s short packet [%d bytes]:", q, nb);
272 for (k = 0; k < nb; ++k)
273 printf(" %.2x", p[k]);
278 for (k = 0; k < nb; ++k)
279 fcs = PPP_FCS(fcs, p[k]);
284 if (r[0] == 0xff && r[1] == 3)
290 printf(" ERROR: length (%d) > MRU (%d)\n",
292 if (decompress && fcs == PPP_GOODFCS) {
293 /* See if this is a CCP or compressed packet */
296 if (r[0] == 0xff && r[1] == 3) {
301 if ((proto & 1) == 0)
302 proto = (proto << 8) + r[1];
303 if (proto == PPP_CCP) {
304 handle_ccp(pkt, r + 2, endp - r - 2);
305 } else if (proto == PPP_COMP) {
306 if ((pkt->flags & CCP_ISUP)
307 && (pkt->flags & CCP_DECOMP_RUN)
309 && (pkt->flags & CCP_ERR) == 0) {
310 rv = pkt->comp->decompress(pkt->state, r,
320 printf(" ERROR: decompressed length (%d) > MRU (%d)\n", dn, mru);
323 printf(" DECOMPRESSION ERROR\n");
324 pkt->flags |= CCP_ERROR;
326 case DECOMP_FATALERROR:
327 printf(" FATAL DECOMPRESSION ERROR\n");
328 pkt->flags |= CCP_FATALERROR;
332 } else if (pkt->state
333 && (pkt->flags & CCP_DECOMP_RUN)) {
334 pkt->comp->incomp(pkt->state, r, endp - r);
338 nl = nb < 16? nb: 16;
340 for (k = 0; k < nl; ++k)
341 printf(" %.2x", p[k]);
345 for (k = 0; k < nl; ++k) {
347 putchar((' ' <= c && c <= '~')? c: '.');
354 if (fcs != PPP_GOODFCS)
355 printf(" BAD FCS: (residue = %x)\n", fcs);
363 /* else fall through */
369 pkt->buf[pkt->cnt++] = c;
378 dir = c==3? "send": "recv";
379 pkt = c==3? &spkt: &rpkt;
380 printf("end %s", dir);
382 printf(" [%d bytes in incomplete packet]", pkt->cnt);
396 extern struct compressor ppp_bsd_compress, ppp_deflate;
398 struct compressor *compressors[] = {
408 handle_ccp(cp, dp, len)
414 struct compressor **comp;
416 if (len < CCP_HDRLEN)
418 clen = CCP_LENGTH(dp);
422 switch (CCP_CODE(dp)) {
424 cp->flags &= ~(CCP_DECOMP_RUN | CCP_ISUP);
425 if (clen < CCP_HDRLEN + CCP_OPT_MINLEN
426 || clen < CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN))
430 for (comp = compressors; *comp != NULL; ++comp) {
431 if ((*comp)->compress_proto == dp[0]) {
432 if (cp->state != NULL) {
433 (*cp->comp->decomp_free)(cp->state);
437 cp->state = (*comp)->decomp_alloc(dp, CCP_OPT_LENGTH(dp));
438 cp->flags |= CCP_ISUP;
439 if (cp->state != NULL
440 && (*cp->comp->decomp_init)
441 (cp->state, dp, clen, 0, 0, 8192, 1))
442 cp->flags = (cp->flags & ~CCP_ERR) | CCP_DECOMP_RUN;
450 cp->flags &= ~(CCP_DECOMP_RUN | CCP_ISUP);
454 if (cp->flags & CCP_ISUP) {
455 if (cp->state && (cp->flags & CCP_DECOMP_RUN)) {
456 (*cp->comp->decomp_reset)(cp->state);
457 cp->flags &= ~CCP_ERROR;
474 t = (t << 8) + getc(f);
475 t = (t << 8) + getc(f);
476 t = (t << 8) + getc(f);
477 printf("start %s", ctime(&t));
479 start_time_tenths = 0;
480 tot_sent = tot_rcvd = 0;
484 for (c = 3; c > 0; --c)
485 n = (n << 8) + getc(f);
488 n += start_time_tenths;
489 start_time += n / 10;
490 start_time_tenths = n % 10;
491 tm = localtime(&start_time);
492 printf("time %.2d:%.2d:%.2d.%d", tm->tm_hour, tm->tm_min,
493 tm->tm_sec, start_time_tenths);
494 printf(" (sent %d, rcvd %d)\n", tot_sent, tot_rcvd);
496 printf("time %.1fs\n", (double) n / 10);