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