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