1 /***********************************************************************
2 *
3 * debug.c
4 *
5 * Implementation of user-space PPPoE redirector for Linux.
6 *
7 * Functions for printing debugging information
8 *
9 * Copyright (C) 2000 by Roaring Penguin Software Inc.
10 *
11 * This program may be distributed according to the terms of the GNU
12 * General Public License, version 2 or (at your option) any later version.
13 *
14 ***********************************************************************/
15 
16 static char const RCSID[] =
17 "$Id: debug.c,v 1.2 2008/06/09 08:34:23 paulus Exp $";
18 
19 #include "pppoe.h"
20 #include <sys/time.h>
21 #include <time.h>
22 #include <unistd.h>
23 #include <ctype.h>
24 
25 /**********************************************************************
26 *%FUNCTION: dumpHex
27 *%ARGUMENTS:
28 * fp -- file to dump to
29 * buf -- buffer to dump
30 * len -- length of data
31 *%RETURNS:
32 * Nothing
33 *%DESCRIPTION:
34 * Dumps buffer to fp in an easy-to-read format
35 ***********************************************************************/
36 void
dumpHex(FILE * fp,unsigned char const * buf,int len)37 dumpHex(FILE *fp, unsigned char const *buf, int len)
38 {
39     int i;
40     int base;
41 
42     if (!fp) return;
43 
44     /* do NOT dump PAP packets */
45     if (len >= 2 && buf[0] == 0xC0 && buf[1] == 0x23) {
46 	fprintf(fp, "(PAP Authentication Frame -- Contents not dumped)\n");
47 	return;
48     }
49 
50     for (base=0; base<len; base += 16) {
51 	for (i=base; i<base+16; i++) {
52 	    if (i < len) {
53 		fprintf(fp, "%02x ", (unsigned) buf[i]);
54 	    } else {
55 		fprintf(fp, "   ");
56 	    }
57 	}
58 	fprintf(fp, "  ");
59 	for (i=base; i<base+16; i++) {
60 	    if (i < len) {
61 		if (isprint(buf[i])) {
62 		    fprintf(fp, "%c", buf[i]);
63 		} else {
64 		    fprintf(fp, ".");
65 		}
66 	    } else {
67 		break;
68 	    }
69 	}
70 	fprintf(fp, "\n");
71     }
72 }
73 
74 /**********************************************************************
75 *%FUNCTION: dumpPacket
76 *%ARGUMENTS:
77 * fp -- file to dump to
78 * packet -- a PPPoE packet
79 * dir -- either SENT or RCVD
80 *%RETURNS:
81 * Nothing
82 *%DESCRIPTION:
83 * Dumps the PPPoE packet to fp in an easy-to-read format
84 ***********************************************************************/
85 void
dumpPacket(FILE * fp,PPPoEPacket * packet,char const * dir)86 dumpPacket(FILE *fp, PPPoEPacket *packet, char const *dir)
87 {
88     int len = ntohs(packet->length);
89 
90     /* Sheesh... printing times is a pain... */
91     struct timeval tv;
92     time_t now;
93     int millisec;
94     struct tm *lt;
95     char timebuf[256];
96 
97     UINT16_t type = etherType(packet);
98     if (!fp) return;
99     gettimeofday(&tv, NULL);
100     now = (time_t) tv.tv_sec;
101     millisec = tv.tv_usec / 1000;
102     lt = localtime(&now);
103     strftime(timebuf, 256, "%H:%M:%S", lt);
104     fprintf(fp, "%s.%03d %s PPPoE ", timebuf, millisec, dir);
105     if (type == Eth_PPPOE_Discovery) {
106 	fprintf(fp, "Discovery (%x) ", (unsigned) type);
107     } else if (type == Eth_PPPOE_Session) {
108 	fprintf(fp, "Session (%x) ", (unsigned) type);
109     } else {
110 	fprintf(fp, "Unknown (%x) ", (unsigned) type);
111     }
112 
113     switch(packet->code) {
114     case CODE_PADI: fprintf(fp, "PADI "); break;
115     case CODE_PADO: fprintf(fp, "PADO "); break;
116     case CODE_PADR: fprintf(fp, "PADR "); break;
117     case CODE_PADS: fprintf(fp, "PADS "); break;
118     case CODE_PADT: fprintf(fp, "PADT "); break;
119     case CODE_PADM: fprintf(fp, "PADM "); break;
120     case CODE_PADN: fprintf(fp, "PADN "); break;
121     case CODE_SESS: fprintf(fp, "SESS "); break;
122     }
123 
124     fprintf(fp, "sess-id %d length %d\n",
125 	    (int) ntohs(packet->session),
126 	    len);
127 
128     /* Ugly... I apologize... */
129     fprintf(fp,
130 	    "SourceAddr %02x:%02x:%02x:%02x:%02x:%02x "
131 	    "DestAddr %02x:%02x:%02x:%02x:%02x:%02x\n",
132 	    (unsigned) packet->ethHdr.h_source[0],
133 	    (unsigned) packet->ethHdr.h_source[1],
134 	    (unsigned) packet->ethHdr.h_source[2],
135 	    (unsigned) packet->ethHdr.h_source[3],
136 	    (unsigned) packet->ethHdr.h_source[4],
137 	    (unsigned) packet->ethHdr.h_source[5],
138 	    (unsigned) packet->ethHdr.h_dest[0],
139 	    (unsigned) packet->ethHdr.h_dest[1],
140 	    (unsigned) packet->ethHdr.h_dest[2],
141 	    (unsigned) packet->ethHdr.h_dest[3],
142 	    (unsigned) packet->ethHdr.h_dest[4],
143 	    (unsigned) packet->ethHdr.h_dest[5]);
144     dumpHex(fp, packet->payload, ntohs(packet->length));
145 }
146