]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libnetgraph/debug.c
zfs: merge openzfs/zfs@431083f75
[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_bpf.h>
63 #include <netgraph/ng_bridge.h>
64 #include <netgraph/ng_car.h>
65 #include <netgraph/ng_cisco.h>
66 #include <netgraph/ng_deflate.h>
67 #include <netgraph/ng_device.h>
68 #include <netgraph/ng_echo.h>
69 #include <netgraph/ng_eiface.h>
70 #include <netgraph/ng_etf.h>
71 #include <netgraph/ng_ether.h>
72 #include <netgraph/ng_ether_echo.h>
73 #include <netgraph/ng_frame_relay.h>
74 #include <netgraph/ng_gif.h>
75 #include <netgraph/ng_gif_demux.h>
76 #include <netgraph/ng_hole.h>
77 #include <netgraph/ng_hub.h>
78 #include <netgraph/ng_iface.h>
79 #include <netgraph/ng_ip_input.h>
80 #include <netgraph/ng_ipfw.h>
81 #include <netgraph/ng_ksocket.h>
82 #include <netgraph/ng_l2tp.h>
83 #include <netgraph/ng_lmi.h>
84 #include <netgraph/ng_mppc.h>
85 #include <netgraph/ng_nat.h>
86 #include <netgraph/netflow/ng_netflow.h>
87 #include <netgraph/ng_one2many.h>
88 #include <netgraph/ng_patch.h>
89 #include <netgraph/ng_pipe.h>
90 #include <netgraph/ng_ppp.h>
91 #include <netgraph/ng_pppoe.h>
92 #include <netgraph/ng_pptpgre.h>
93 #include <netgraph/ng_pred1.h>
94 #include <netgraph/ng_rfc1490.h>
95 #include <netgraph/ng_socket.h>
96 #include <netgraph/ng_source.h>
97 #include <netgraph/ng_split.h>
98 #include <netgraph/ng_tag.h>
99 #include <netgraph/ng_tcpmss.h>
100 #include <netgraph/ng_tee.h>
101 #include <netgraph/ng_tty.h>
102 #include <netgraph/ng_vjc.h>
103 #include <netgraph/ng_vlan.h>
104 #ifdef  WHISTLE
105 #include <machine/../isa/df_def.h>
106 #include <machine/../isa/if_wfra.h>
107 #include <machine/../isa/ipac.h>
108 #include <netgraph/ng_df.h>
109 #include <netgraph/ng_ipac.h>
110 #include <netgraph/ng_tn.h>
111 #endif
112
113 /* Global debug level */
114 int     _gNgDebugLevel = 0;
115
116 /* Debug printing functions */
117 void    (*_NgLog) (const char *fmt,...) = warn;
118 void    (*_NgLogx) (const char *fmt,...) = warnx;
119
120 /* Internal functions */
121 static const    char *NgCookie(int cookie);
122
123 /* Known typecookie list */
124 struct ng_cookie {
125         int             cookie;
126         const char      *type;
127 };
128
129 #define COOKIE(c)       { NGM_ ## c ## _COOKIE, #c }
130
131 /* List of known cookies */
132 static const struct ng_cookie cookies[] = {
133         COOKIE(UI),
134         COOKIE(ASYNC),
135         COOKIE(BPF),
136         COOKIE(BRIDGE),
137         COOKIE(CAR),
138         COOKIE(CISCO),
139         COOKIE(DEFLATE),
140         COOKIE(DEVICE),
141         COOKIE(ECHO),
142         COOKIE(EIFACE),
143         COOKIE(ETF),
144         COOKIE(ETHER),
145         COOKIE(ETHER_ECHO),
146         COOKIE(FRAMERELAY),
147         COOKIE(GIF),
148         COOKIE(GIF_DEMUX),
149         COOKIE(GENERIC),
150         COOKIE(HOLE),
151         COOKIE(HUB),
152         COOKIE(IFACE),
153         COOKIE(IP_INPUT),
154         COOKIE(IPFW),
155         COOKIE(KSOCKET),
156         COOKIE(L2TP),
157         COOKIE(LMI),
158         COOKIE(MPPC),
159         COOKIE(NAT),
160         COOKIE(NETFLOW),
161         COOKIE(ONE2MANY),
162         COOKIE(PATCH),
163         COOKIE(PIPE),
164         COOKIE(PPP),
165         COOKIE(PPPOE),
166         COOKIE(PPTPGRE),
167         COOKIE(PRED1),
168         COOKIE(RFC1490),
169         COOKIE(SOCKET),
170         COOKIE(SOURCE),
171         COOKIE(SPLIT),
172         COOKIE(TAG),
173         COOKIE(TCPMSS),
174         COOKIE(TEE),
175         COOKIE(TTY),
176         COOKIE(VJC),
177         COOKIE(VLAN),
178 #ifdef WHISTLE
179         COOKIE(DF),
180         COOKIE(IPAC),
181         COOKIE(TN),
182         COOKIE(WFRA),
183 #endif
184         { 0, NULL }
185 };
186
187 /*
188  * Set debug level, ie, verbosity, if "level" is non-negative.
189  * Returns old debug level.
190  */
191 int
192 NgSetDebug(int level)
193 {
194         int old = _gNgDebugLevel;
195
196         if (level >= 0)
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 %u", msg->header.arglen);
240         NGLOGX("  flags  %x", msg->header.flags);
241         NGLOGX("  token  %u", msg->header.token);
242         NGLOGX("  cookie %s (%u)",
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);
293         _NgDebugBytes((u_char *)msg->data, msg->header.arglen);
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