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.
14 #include <sys/types.h>
34 while ((i = getopt(ac, av, "hprdm:")) != -1) {
52 fprintf(stderr, "Usage: %s [-h | -p[d]] [-r] [-m mru] [file ...]\n", av[0]);
59 for (i = optind; i < ac; ++i) {
61 if ((f = fopen(p, "r")) == NULL) {
78 unsigned char buf[16];
84 while ((c = getc(f)) != EOF) {
85 if (c == 1 || c == 2) {
88 printf("%s %c", c==1? "sent": "rcvd", hexmode? ' ': '"');
91 n = (n << 8) + getc(f);
102 for (k = 0; k < nb; ++k) {
104 putchar((' ' <= c2 && c2 <= '~')? c2: '.');
112 k = (' ' <= c && c <= '~')? (c != '\\' && c != '"')? 1: 2: 3;
113 if ((col += k) >= 78) {
131 for (k = nb; k < 16; ++k)
134 for (k = 0; k < nb; ++k) {
136 putchar((' ' <= c2 && c2 <= '~')? c2: '.');
141 } else if (c == 3 || c == 4) {
142 printf("end %s\n", c==3? "send": "recv");
143 } else if (c == 5 || c == 6) {
146 for (c = 3; c > 0; --c)
147 n = (n << 8) + getc(f);
149 printf("time %.1fs\n", (double) n / 10);
158 * FCS lookup table as calculated by genfcstab.
160 static u_short fcstab[256] = {
161 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
162 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
163 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
164 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
165 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
166 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
167 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
168 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
169 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
170 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
171 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
172 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
173 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
174 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
175 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
176 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
177 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
178 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
179 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
180 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
181 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
182 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
183 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
184 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
185 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
186 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
187 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
188 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
189 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
190 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
191 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
192 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
199 struct compressor *comp;
201 unsigned char buf[8192];
204 /* Values for flags */
207 #define CCP_FATALERROR 4
208 #define CCP_ERR (CCP_ERROR | CCP_FATALERROR)
209 #define CCP_DECOMP_RUN 8
211 unsigned char dbuf[8192];
217 int nb, nl, dn, proto, rv;
219 unsigned char *p, *r, *endp;
224 spkt.cnt = rpkt.cnt = 0;
225 spkt.esc = rpkt.esc = 0;
226 while ((c = getc(f)) != EOF) {
227 if (c == 1 || c == 2) {
230 dir = c==1? "sent": "rcvd";
231 pkt = c==1? &spkt: &rpkt;
233 n = (n << 8) + getc(f);
240 printf("[%d bytes in incomplete send packet]\n",
243 printf("[%d bytes in incomplete recv packet]\n",
250 printf("%s aborted packet:\n ", dir);
258 printf("%s short packet [%d bytes]:", q, nb);
259 for (k = 0; k < nb; ++k)
260 printf(" %.2x", p[k]);
265 for (k = 0; k < nb; ++k)
266 fcs = PPP_FCS(fcs, p[k]);
271 if (r[0] == 0xff && r[1] == 3)
277 printf(" ERROR: length (%d) > MRU (%d)\n",
279 if (decompress && fcs == PPP_GOODFCS) {
280 /* See if this is a CCP or compressed packet */
283 if (r[0] == 0xff && r[1] == 3) {
288 if ((proto & 1) == 0)
289 proto = (proto << 8) + r[1];
290 if (proto == PPP_CCP) {
291 handle_ccp(pkt, r + 2, endp - r - 2);
292 } else if (proto == PPP_COMP) {
293 if ((pkt->flags & CCP_ISUP)
294 && (pkt->flags & CCP_DECOMP_RUN)
296 && (pkt->flags & CCP_ERR) == 0) {
297 rv = pkt->comp->decompress(pkt->state, r,
307 printf(" ERROR: decompressed length (%d) > MRU (%d)\n", dn, mru);
310 printf(" DECOMPRESSION ERROR\n");
311 pkt->flags |= CCP_ERROR;
313 case DECOMP_FATALERROR:
314 printf(" FATAL DECOMPRESSION ERROR\n");
315 pkt->flags |= CCP_FATALERROR;
319 } else if (pkt->state
320 && (pkt->flags & CCP_DECOMP_RUN)) {
321 pkt->comp->incomp(pkt->state, r, endp - r);
325 nl = nb < 16? nb: 16;
327 for (k = 0; k < nl; ++k)
328 printf(" %.2x", p[k]);
332 for (k = 0; k < nl; ++k) {
334 putchar((' ' <= c && c <= '~')? c: '.');
341 if (fcs != PPP_GOODFCS)
342 printf(" BAD FCS: (residue = %x)\n", fcs);
350 /* else fall through */
356 pkt->buf[pkt->cnt++] = c;
360 } else if (c == 3 || c == 4) {
363 dir = c==3? "send": "recv";
364 pkt = c==3? &spkt: &rpkt;
365 printf("end %s", dir);
367 printf(" [%d bytes in incomplete packet]", pkt->cnt);
369 } else if (c == 5 || c == 6) {
372 for (c = 3; c > 0; --c)
373 n = (n << 8) + getc(f);
375 printf("time %.1fs\n", (double) n / 10);
382 extern struct compressor ppp_bsd_compress, ppp_deflate;
384 struct compressor *compressors[] = {
394 handle_ccp(cp, dp, len)
400 struct compressor **comp;
402 if (len < CCP_HDRLEN)
404 clen = CCP_LENGTH(dp);
408 switch (CCP_CODE(dp)) {
410 cp->flags &= ~(CCP_DECOMP_RUN | CCP_ISUP);
411 if (clen < CCP_HDRLEN + CCP_OPT_MINLEN
412 || clen < CCP_HDRLEN + CCP_OPT_LENGTH(dp + CCP_HDRLEN))
416 for (comp = compressors; *comp != NULL; ++comp) {
417 if ((*comp)->compress_proto == dp[0]) {
418 if (cp->state != NULL) {
419 (*cp->comp->decomp_free)(cp->state);
423 cp->state = (*comp)->decomp_alloc(dp, CCP_OPT_LENGTH(dp));
424 cp->flags |= CCP_ISUP;
425 if (cp->state != NULL
426 && (*cp->comp->decomp_init)
427 (cp->state, dp, clen, 0, 0, 8192, 1))
428 cp->flags = (cp->flags & ~CCP_ERR) | CCP_DECOMP_RUN;
436 cp->flags &= ~(CCP_DECOMP_RUN | CCP_ISUP);
440 if (cp->flags & CCP_ISUP) {
441 if (cp->state && (cp->flags & CCP_DECOMP_RUN)) {
442 (*cp->comp->decomp_reset)(cp->state);
443 cp->flags &= ~CCP_ERROR;