]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libnetgraph/debug.c
MFuser/marcel/mkimg:
[FreeBSD/FreeBSD.git] / lib / libnetgraph / debug.c
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  * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
39  */
40
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #include <sys/types.h>
45 #include <sys/time.h>
46 #include <sys/ioctl.h>
47
48 #include <stdarg.h>
49
50 #include <netinet/in.h>
51 #include <net/ethernet.h>
52 #include <net/bpf.h>
53
54 #include <netgraph/ng_message.h>
55 #include <netgraph/ng_socket.h>
56
57 #include "netgraph.h"
58 #include "internal.h"
59
60 #include <netgraph/ng_UI.h>
61 #include <netgraph/ng_async.h>
62 #include <netgraph/ng_atmllc.h>
63 #include <netgraph/ng_bpf.h>
64 #include <netgraph/ng_bridge.h>
65 #include <netgraph/ng_cisco.h>
66 #include <netgraph/ng_device.h>
67 #include <netgraph/ng_echo.h>
68 #include <netgraph/ng_eiface.h>
69 #include <netgraph/ng_etf.h>
70 #include <netgraph/ng_ether.h>
71 #include <netgraph/ng_frame_relay.h>
72 #include <netgraph/ng_gif.h>
73 #include <netgraph/ng_gif_demux.h>
74 #include <netgraph/ng_hole.h>
75 #include <netgraph/ng_hub.h>
76 #include <netgraph/ng_iface.h>
77 #include <netgraph/ng_ip_input.h>
78 #include <netgraph/ng_ipfw.h>
79 #include <netgraph/ng_ksocket.h>
80 #include <netgraph/ng_l2tp.h>
81 #include <netgraph/ng_lmi.h>
82 #include <netgraph/ng_mppc.h>
83 #include <netgraph/ng_nat.h>
84 #include <netgraph/ng_one2many.h>
85 #include <netgraph/ng_ppp.h>
86 #include <netgraph/ng_pppoe.h>
87 #include <netgraph/ng_pptpgre.h>
88 #include <netgraph/ng_rfc1490.h>
89 #include <netgraph/ng_socket.h>
90 #include <netgraph/ng_source.h>
91 #include <netgraph/ng_split.h>
92 #include <netgraph/ng_sppp.h>
93 #include <netgraph/ng_tcpmss.h>
94 #include <netgraph/ng_tee.h>
95 #include <netgraph/ng_tty.h>
96 #include <netgraph/ng_vjc.h>
97 #include <netgraph/ng_vlan.h>
98 #ifdef  WHISTLE
99 #include <machine/../isa/df_def.h>
100 #include <machine/../isa/if_wfra.h>
101 #include <machine/../isa/ipac.h>
102 #include <netgraph/ng_df.h>
103 #include <netgraph/ng_ipac.h>
104 #include <netgraph/ng_tn.h>
105 #endif
106
107 /* Global debug level */
108 int     _gNgDebugLevel = 0;
109
110 /* Debug printing functions */
111 void    (*_NgLog) (const char *fmt,...) = warn;
112 void    (*_NgLogx) (const char *fmt,...) = warnx;
113
114 /* Internal functions */
115 static const    char *NgCookie(int cookie);
116
117 /* Known typecookie list */
118 struct ng_cookie {
119         int             cookie;
120         const char      *type;
121 };
122
123 #define COOKIE(c)       { NGM_ ## c ## _COOKIE, #c }
124
125 /* List of known cookies */
126 static const struct ng_cookie cookies[] = {
127         COOKIE(UI),
128         COOKIE(ASYNC),
129         COOKIE(ATMLLC),
130         COOKIE(BPF),
131         COOKIE(BRIDGE),
132         COOKIE(CISCO),
133         COOKIE(DEVICE),
134         COOKIE(ECHO),
135         COOKIE(EIFACE),
136         COOKIE(ETF),
137         COOKIE(ETHER),
138         COOKIE(FRAMERELAY),
139         COOKIE(GIF),
140         COOKIE(GIF_DEMUX),
141         COOKIE(GENERIC),
142         COOKIE(HOLE),
143         COOKIE(HUB),
144         COOKIE(IFACE),
145         COOKIE(IP_INPUT),
146         COOKIE(IPFW),
147         COOKIE(KSOCKET),
148         COOKIE(L2TP),
149         COOKIE(LMI),
150         COOKIE(MPPC),
151         COOKIE(NAT),
152         COOKIE(ONE2MANY),
153         COOKIE(PPP),
154         COOKIE(PPPOE),
155         COOKIE(PPTPGRE),
156         COOKIE(RFC1490),
157         COOKIE(SOCKET),
158         COOKIE(SOURCE),
159         COOKIE(SPLIT),
160         COOKIE(SPPP),
161         COOKIE(TCPMSS),
162         COOKIE(TEE),
163         COOKIE(TTY),
164         COOKIE(VJC),
165         COOKIE(VLAN),
166 #ifdef WHISTLE
167         COOKIE(DF),
168         COOKIE(IPAC),
169         COOKIE(TN),
170         COOKIE(WFRA),
171 #endif
172         { 0, NULL }
173 };
174
175 /*
176  * Set debug level, ie, verbosity, if "level" is non-negative.
177  * Returns old debug level.
178  */
179 int
180 NgSetDebug(int level)
181 {
182         int old = _gNgDebugLevel;
183
184         if (level < 0)
185                 level = old;
186         _gNgDebugLevel = level;
187         return (old);
188 }
189
190 /*
191  * Set debug logging functions.
192  */
193 void
194 NgSetErrLog(void (*log) (const char *fmt,...),
195                 void (*logx) (const char *fmt,...))
196 {
197         _NgLog = log;
198         _NgLogx = logx;
199 }
200
201 /*
202  * Display a netgraph sockaddr
203  */
204 void
205 _NgDebugSockaddr(const struct sockaddr_ng *sg)
206 {
207         NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
208                sg->sg_family, sg->sg_len, sg->sg_data);
209 }
210
211 #define ARGS_BUFSIZE            2048
212 #define RECURSIVE_DEBUG_ADJUST  4
213
214 /*
215  * Display a negraph message
216  */
217 void
218 _NgDebugMsg(const struct ng_mesg *msg, const char *path)
219 {
220         u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
221         struct ng_mesg *const req = (struct ng_mesg *)buf;
222         struct ng_mesg *const bin = (struct ng_mesg *)req->data;
223         int arglen, csock = -1;
224
225         /* Display header stuff */
226         NGLOGX("NG_MESG :");
227         NGLOGX("  vers   %d", msg->header.version);
228         NGLOGX("  arglen %d", msg->header.arglen);
229         NGLOGX("  flags  %ld", msg->header.flags);
230         NGLOGX("  token  %lu", (u_long)msg->header.token);
231         NGLOGX("  cookie %s (%d)",
232             NgCookie(msg->header.typecookie), msg->header.typecookie);
233
234         /* At lower debugging levels, skip ASCII translation */
235         if (_gNgDebugLevel <= 2)
236                 goto fail2;
237
238         /* If path is not absolute, don't bother trying to use relative
239            address on a different socket for the ASCII translation */
240         if (strchr(path, ':') == NULL)
241                 goto fail2;
242
243         /* Get a temporary socket */
244         if (NgMkSockNode(NULL, &csock, NULL) < 0)
245                 goto fail;
246
247         /* Copy binary message into request message payload */
248         arglen = msg->header.arglen;
249         if (arglen > ARGS_BUFSIZE)
250                 arglen = ARGS_BUFSIZE;
251         memcpy(bin, msg, sizeof(*msg) + arglen);
252         bin->header.arglen = arglen;
253
254         /* Lower debugging to avoid infinite recursion */
255         _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
256
257         /* Ask the node to translate the binary message to ASCII for us */
258         if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
259             NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
260                 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
261                 goto fail;
262         }
263         if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
264                 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
265                 goto fail;
266         }
267
268         /* Restore debugging level */
269         _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
270
271         /* Display command string and arguments */
272         NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
273         NGLOGX("  args   %s", bin->data);
274         goto done;
275
276 fail:
277         /* Just display binary version */
278         NGLOGX("  [error decoding message: %s]", strerror(errno));
279 fail2:
280         NGLOGX("  cmd    %d", msg->header.cmd);
281         NGLOGX("  args (%d bytes)", msg->header.arglen);
282         _NgDebugBytes((u_char *)msg->data, msg->header.arglen);
283
284 done:
285         if (csock != -1)
286                 (void)close(csock);
287 }
288
289 /*
290  * Return the name of the node type corresponding to the cookie
291  */
292 static const char *
293 NgCookie(int cookie)
294 {
295         int k;
296
297         for (k = 0; cookies[k].cookie != 0; k++) {
298                 if (cookies[k].cookie == cookie)
299                         return cookies[k].type;
300         }
301         return "??";
302 }
303
304 /*
305  * Dump bytes in hex
306  */
307 void
308 _NgDebugBytes(const u_char *ptr, int len)
309 {
310         char    buf[100];
311         int     k, count;
312
313 #define BYPERLINE       16
314
315         for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
316
317                 /* Do hex */
318                 snprintf(buf, sizeof(buf), "%04x:  ", count);
319                 for (k = 0; k < BYPERLINE; k++, count++)
320                         if (count < len)
321                                 snprintf(buf + strlen(buf),
322                                     sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
323                         else
324                                 snprintf(buf + strlen(buf),
325                                     sizeof(buf) - strlen(buf), "   ");
326                 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
327                 count -= BYPERLINE;
328
329                 /* Do ASCII */
330                 for (k = 0; k < BYPERLINE; k++, count++)
331                         if (count < len)
332                                 snprintf(buf + strlen(buf),
333                                     sizeof(buf) - strlen(buf),
334                                     "%c", isprint(ptr[k]) ? ptr[k] : '.');
335                         else
336                                 snprintf(buf + strlen(buf),
337                                     sizeof(buf) - strlen(buf), "  ");
338                 count -= BYPERLINE;
339
340                 /* Print it */
341                 NGLOGX("%s", buf);
342         }
343 }
344