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