Commit | Line | Data |
---|---|---|
0147868e NA |
1 | /* |
2 | * debug.c | |
3 | * | |
4 | * Copyright (c) 1996-1999 Whistle Communications, Inc. | |
5 | * All rights reserved. | |
6 | * | |
7 | * Subject to the following obligations and disclaimer of warranty, use and | |
8 | * redistribution of this software, in source or object code forms, with or | |
9 | * without modifications are expressly permitted by Whistle Communications; | |
10 | * provided, however, that: | |
11 | * 1. Any and all reproductions of the source or object code must include the | |
12 | * copyright notice above and the following disclaimer of warranties; and | |
13 | * 2. No rights are granted, in any manner or form, to use Whistle | |
14 | * Communications, Inc. trademarks, including the mark "WHISTLE | |
15 | * COMMUNICATIONS" on advertising, endorsements, or otherwise except as | |
16 | * such appears in the above copyright notice or in the software. | |
17 | * | |
18 | * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND | |
19 | * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO | |
20 | * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, | |
21 | * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF | |
22 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. | |
23 | * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY | |
24 | * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS | |
25 | * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. | |
26 | * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES | |
27 | * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING | |
28 | * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, | |
29 | * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR | |
30 | * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY | |
31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
33 | * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY | |
34 | * OF SUCH DAMAGE. | |
35 | * | |
36 | * Author: Archie Cobbs <archie@whistle.com> | |
37 | * | |
38 | * $FreeBSD: src/lib/libnetgraph/debug.c,v 1.9 2005/10/25 20:58:30 ru Exp $ | |
39 | * $DragonFly: src/lib/libnetgraph/debug.c,v 1.4 2007/06/17 20:33:14 swildner Exp $ | |
40 | * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $ | |
41 | */ | |
42 | ||
43 | #include <sys/types.h> | |
44 | #include <sys/time.h> | |
45 | #include <sys/ioctl.h> | |
46 | ||
47 | #include <stdarg.h> | |
48 | ||
49 | #include <netinet/in.h> | |
50 | #include <net/ethernet.h> | |
51 | #include <net/bpf.h> | |
52 | ||
53 | #include <netgraph7/ng_message.h> | |
54 | #include <netgraph7/socket/ng_socket.h> | |
55 | ||
56 | #include "netgraph.h" | |
57 | #include "internal.h" | |
58 | ||
59 | #include <netgraph7/UI/ng_UI.h> | |
60 | #include <netgraph7/async/ng_async.h> | |
61 | #include <netgraph7/atmllc/ng_atmllc.h> | |
62 | #include <netgraph7/bpf/ng_bpf.h> | |
0147868e | 63 | #include <netgraph/bridge/ng_bridge.h> |
0147868e | 64 | #include <netgraph7/cisco/ng_cisco.h> |
df747d8a | 65 | #include <netgraph7/deflate/ng_deflate.h> |
0147868e | 66 | /* |
df747d8a NA |
67 | #include <netgraph7/echo/ng_echo.h> |
68 | #include <netgraph7/eiface/ng_eiface.h> | |
69 | #include <netgraph7/etf/ng_etf.h> | |
0147868e NA |
70 | */ |
71 | #include <netgraph7/ether/ng_ether.h> | |
72 | /* | |
df747d8a NA |
73 | #include <netgraph7/fec/ng_fec.h> |
74 | #include <netgraph7/frame_relay/ng_frame_relay.h> | |
0147868e NA |
75 | */ |
76 | #include <netgraph7/hole/ng_hole.h> | |
77 | /* | |
df747d8a | 78 | #include <netgraph7/hub/ng_hub.h> |
0147868e NA |
79 | */ |
80 | #include <netgraph7/iface/ng_iface.h> | |
81 | /* | |
df747d8a NA |
82 | #include <netgraph7/ip_input/ng_ip_input.h> |
83 | #include <netgraph7/ksocket/ng_ksocket.h> | |
84 | #include <netgraph7/l2tp/ng_l2tp.h> | |
85 | #include <netgraph7/lmi/ng_lmi.h> | |
86 | #include <netgraph7/mppc/ng_mppc.h> | |
87 | #include <netgraph7/one2many/ng_one2many.h> | |
88 | #include <netgraph7/ppp/ng_ppp.h> | |
89 | #include <netgraph7/pppoe/ng_pppoe.h> | |
90 | #include <netgraph7/pptpgre/ng_pptpgre.h> | |
91 | #include <netgraph7/rfc1490/ng_rfc1490.h> | |
92 | #include <netgraph7/socket/ng_socket.h> | |
93 | #include <netgraph7/source/ng_source.h> | |
94 | #include <netgraph7/split/ng_split.h> | |
95 | #include <netgraph7/tcpmss/ng_tcpmss.h> | |
0147868e NA |
96 | */ |
97 | #include <netgraph7/tee/ng_tee.h> | |
98 | /* | |
df747d8a | 99 | #include <netgraph7/tty/ng_tty.h> |
0147868e NA |
100 | */ |
101 | #include <netgraph7/vjc/ng_vjc.h> | |
102 | #ifdef WHISTLE | |
103 | #include <machine/../isa/df_def.h> | |
104 | #include <machine/../isa/if_wfra.h> | |
105 | #include <machine/../isa/ipac.h> | |
106 | #include <netgraph/ng_df.h> | |
107 | #include <netgraph/ng_ipac.h> | |
108 | #include <netgraph/ng_tn.h> | |
109 | #endif | |
110 | ||
111 | /* Global debug level */ | |
112 | int _gNgDebugLevel = 0; | |
113 | ||
114 | /* Debug printing functions */ | |
115 | void (*_NgLog) (const char *fmt,...) = warn; | |
116 | void (*_NgLogx) (const char *fmt,...) = warnx; | |
117 | ||
118 | /* Internal functions */ | |
119 | static const char *NgCookie(int cookie); | |
120 | ||
121 | /* Known typecookie list */ | |
122 | struct ng_cookie { | |
123 | int cookie; | |
124 | const char *type; | |
125 | }; | |
126 | ||
127 | #define COOKIE(c) { NGM_ ## c ## _COOKIE, #c } | |
128 | ||
129 | /* List of known cookies */ | |
130 | static const struct ng_cookie cookies[] = { | |
131 | COOKIE(UI), | |
132 | COOKIE(ASYNC), | |
133 | COOKIE(ATMLLC), | |
134 | COOKIE(BPF), | |
0147868e | 135 | COOKIE(BRIDGE), |
0147868e | 136 | COOKIE(CISCO), |
df747d8a | 137 | COOKIE(DEFLATE), |
0147868e NA |
138 | /* |
139 | COOKIE(ECHO), | |
140 | COOKIE(EIFACE), | |
141 | COOKIE(ETF), | |
142 | */ | |
143 | COOKIE(ETHER), | |
144 | /* | |
145 | COOKIE(FEC), | |
146 | COOKIE(FRAMERELAY), | |
147 | COOKIE(GENERIC), | |
148 | */ | |
149 | COOKIE(HOLE), | |
150 | /* | |
151 | COOKIE(HUB), | |
152 | */ | |
153 | COOKIE(IFACE), | |
154 | /* | |
155 | COOKIE(IP_INPUT), | |
156 | COOKIE(KSOCKET), | |
157 | COOKIE(L2TP), | |
158 | COOKIE(LMI), | |
159 | COOKIE(MPPC), | |
160 | COOKIE(ONE2MANY), | |
161 | COOKIE(PPP), | |
162 | COOKIE(PPPOE), | |
163 | COOKIE(PPTPGRE), | |
164 | COOKIE(RFC1490), | |
165 | */ | |
166 | COOKIE(SOCKET), | |
167 | /* | |
168 | COOKIE(SOURCE), | |
169 | COOKIE(SPLIT), | |
170 | COOKIE(TCPMSS), | |
171 | */ | |
172 | COOKIE(TEE), | |
173 | /* | |
174 | COOKIE(TTY), | |
175 | */ | |
176 | COOKIE(VJC), | |
177 | #ifdef WHISTLE | |
178 | COOKIE(DF), | |
179 | COOKIE(IPAC), | |
180 | COOKIE(TN), | |
181 | COOKIE(WFRA), | |
182 | #endif | |
183 | { 0, NULL } | |
184 | }; | |
185 | ||
186 | /* | |
187 | * Set debug level, ie, verbosity, if "level" is non-negative. | |
188 | * Returns old debug level. | |
189 | */ | |
190 | int | |
191 | NgSetDebug(int level) | |
192 | { | |
193 | int old = _gNgDebugLevel; | |
194 | ||
195 | if (level < 0) | |
196 | level = old; | |
197 | _gNgDebugLevel = level; | |
198 | return (old); | |
199 | } | |
200 | ||
201 | /* | |
202 | * Set debug logging functions. | |
203 | */ | |
204 | void | |
205 | NgSetErrLog(void (*log) (const char *fmt,...), | |
206 | void (*logx) (const char *fmt,...)) | |
207 | { | |
208 | _NgLog = log; | |
209 | _NgLogx = logx; | |
210 | } | |
211 | ||
212 | /* | |
213 | * Display a netgraph sockaddr | |
214 | */ | |
215 | void | |
216 | _NgDebugSockaddr(const struct sockaddr_ng *sg) | |
217 | { | |
218 | NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", | |
219 | sg->sg_family, sg->sg_len, sg->sg_data); | |
220 | } | |
221 | ||
222 | #define ARGS_BUFSIZE 2048 | |
223 | #define RECURSIVE_DEBUG_ADJUST 4 | |
224 | ||
225 | /* | |
226 | * Display a negraph message | |
227 | */ | |
228 | void | |
229 | _NgDebugMsg(const struct ng_mesg *msg, const char *path) | |
230 | { | |
231 | u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; | |
232 | struct ng_mesg *const req = (struct ng_mesg *)buf; | |
233 | struct ng_mesg *const bin = (struct ng_mesg *)req->data; | |
234 | int arglen, csock = -1; | |
235 | ||
236 | /* Display header stuff */ | |
237 | NGLOGX("NG_MESG :"); | |
238 | NGLOGX(" vers %d", msg->header.version); | |
239 | NGLOGX(" arglen %d", msg->header.arglen); | |
240 | NGLOGX(" flags %ld", msg->header.flags); | |
241 | NGLOGX(" token %lu", (u_long)msg->header.token); | |
242 | NGLOGX(" cookie %s (%d)", | |
243 | NgCookie(msg->header.typecookie), msg->header.typecookie); | |
244 | ||
245 | /* At lower debugging levels, skip ASCII translation */ | |
246 | if (_gNgDebugLevel <= 2) | |
247 | goto fail2; | |
248 | ||
249 | /* If path is not absolute, don't bother trying to use relative | |
250 | address on a different socket for the ASCII translation */ | |
251 | if (strchr(path, ':') == NULL) | |
252 | goto fail2; | |
253 | ||
254 | /* Get a temporary socket */ | |
255 | if (NgMkSockNode(NULL, &csock, NULL) < 0) | |
256 | goto fail; | |
257 | ||
258 | /* Copy binary message into request message payload */ | |
259 | arglen = msg->header.arglen; | |
260 | if (arglen > ARGS_BUFSIZE) | |
261 | arglen = ARGS_BUFSIZE; | |
262 | memcpy(bin, msg, sizeof(*msg) + arglen); | |
263 | bin->header.arglen = arglen; | |
264 | ||
265 | /* Lower debugging to avoid infinite recursion */ | |
266 | _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST; | |
267 | ||
268 | /* Ask the node to translate the binary message to ASCII for us */ | |
269 | if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, | |
270 | NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) { | |
271 | _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; | |
272 | goto fail; | |
273 | } | |
274 | if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) { | |
275 | _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; | |
276 | goto fail; | |
277 | } | |
278 | ||
279 | /* Restore debugging level */ | |
280 | _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; | |
281 | ||
282 | /* Display command string and arguments */ | |
283 | NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); | |
284 | NGLOGX(" args %s", bin->data); | |
285 | goto done; | |
286 | ||
287 | fail: | |
288 | /* Just display binary version */ | |
289 | NGLOGX(" [error decoding message: %s]", strerror(errno)); | |
290 | fail2: | |
291 | NGLOGX(" cmd %d", msg->header.cmd); | |
292 | NGLOGX(" args (%d bytes)", msg->header.arglen); | |
cf15336d | 293 | _NgDebugBytes(msg->data, msg->header.arglen); |
0147868e NA |
294 | |
295 | done: | |
296 | if (csock != -1) | |
297 | (void)close(csock); | |
298 | } | |
299 | ||
300 | /* | |
301 | * Return the name of the node type corresponding to the cookie | |
302 | */ | |
303 | static const char * | |
304 | NgCookie(int cookie) | |
305 | { | |
306 | int k; | |
307 | ||
308 | for (k = 0; cookies[k].cookie != 0; k++) { | |
309 | if (cookies[k].cookie == cookie) | |
310 | return cookies[k].type; | |
311 | } | |
312 | return "??"; | |
313 | } | |
314 | ||
315 | /* | |
316 | * Dump bytes in hex | |
317 | */ | |
318 | void | |
319 | _NgDebugBytes(const u_char *ptr, int len) | |
320 | { | |
321 | char buf[100]; | |
322 | int k, count; | |
323 | ||
324 | #define BYPERLINE 16 | |
325 | ||
326 | for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { | |
327 | ||
328 | /* Do hex */ | |
329 | snprintf(buf, sizeof(buf), "%04x: ", count); | |
330 | for (k = 0; k < BYPERLINE; k++, count++) | |
331 | if (count < len) | |
332 | snprintf(buf + strlen(buf), | |
333 | sizeof(buf) - strlen(buf), "%02x ", ptr[k]); | |
334 | else | |
335 | snprintf(buf + strlen(buf), | |
336 | sizeof(buf) - strlen(buf), " "); | |
337 | snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); | |
338 | count -= BYPERLINE; | |
339 | ||
340 | /* Do ASCII */ | |
341 | for (k = 0; k < BYPERLINE; k++, count++) | |
342 | if (count < len) | |
343 | snprintf(buf + strlen(buf), | |
344 | sizeof(buf) - strlen(buf), | |
345 | "%c", isprint(ptr[k]) ? ptr[k] : '.'); | |
346 | else | |
347 | snprintf(buf + strlen(buf), | |
348 | sizeof(buf) - strlen(buf), " "); | |
349 | count -= BYPERLINE; | |
350 | ||
351 | /* Print it */ | |
352 | NGLOGX("%s", buf); | |
353 | } | |
354 | } | |
355 |