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