Initial import from FreeBSD RELENG_4:
[dragonfly.git] / lib / libnetgraph / debug.c
1
2 /*
3  * debug.c
4  *
5  * Copyright (c) 1996-1999 Whistle Communications, Inc.
6  * All rights reserved.
7  * 
8  * Subject to the following obligations and disclaimer of warranty, use and
9  * redistribution of this software, in source or object code forms, with or
10  * without modifications are expressly permitted by Whistle Communications;
11  * provided, however, that:
12  * 1. Any and all reproductions of the source or object code must include the
13  *    copyright notice above and the following disclaimer of warranties; and
14  * 2. No rights are granted, in any manner or form, to use Whistle
15  *    Communications, Inc. trademarks, including the mark "WHISTLE
16  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
17  *    such appears in the above copyright notice or in the software.
18  * 
19  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
20  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
21  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
22  * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
23  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
24  * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
25  * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
26  * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
27  * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
28  * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
29  * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30  * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
31  * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
35  * OF SUCH DAMAGE.
36  *
37  * Author: Archie Cobbs <archie@whistle.com>
38  *
39  * $FreeBSD: src/lib/libnetgraph/debug.c,v 1.5.2.1 2000/05/01 18:09:54 archie Exp $
40  * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
41  */
42
43 #include <sys/types.h>
44 #include <sys/time.h>
45 #include <sys/ioctl.h>
46
47 #include <stdarg.h>
48
49 #include <netinet/in.h>
50 #include <net/ethernet.h>
51 #include <net/bpf.h>
52
53 #include <netgraph/ng_message.h>
54 #include <netgraph/ng_socket.h>
55
56 #include "netgraph.h"
57 #include "internal.h"
58
59 #include <netgraph/ng_UI.h>
60 #include <netgraph/ng_async.h>
61 #include <netgraph/ng_bpf.h>
62 #include <netgraph/ng_cisco.h>
63 #include <netgraph/ng_echo.h>
64 #include <netgraph/ng_ether.h>
65 #include <netgraph/ng_frame_relay.h>
66 #include <netgraph/ng_hole.h>
67 #include <netgraph/ng_iface.h>
68 #include <netgraph/ng_ksocket.h>
69 #include <netgraph/ng_lmi.h>
70 #include <netgraph/ng_ppp.h>
71 #include <netgraph/ng_pppoe.h>
72 #include <netgraph/ng_rfc1490.h>
73 #include <netgraph/ng_socket.h>
74 #include <netgraph/ng_tee.h>
75 #include <netgraph/ng_tty.h>
76 #include <netgraph/ng_vjc.h>
77 #ifdef  WHISTLE
78 #include <machine/../isa/df_def.h>
79 #include <machine/../isa/if_wfra.h>
80 #include <machine/../isa/ipac.h>
81 #include <netgraph/ng_df.h>
82 #include <netgraph/ng_ipac.h>
83 #include <netgraph/ng_mppc.h>
84 #include <netgraph/ng_pptpgre.h>
85 #include <netgraph/ng_tn.h>
86 #endif
87
88 /* Global debug level */
89 int     _gNgDebugLevel = 0;
90
91 /* Debug printing functions */
92 void    (*_NgLog) (const char *fmt,...) = warn;
93 void    (*_NgLogx) (const char *fmt,...) = warnx;
94
95 /* Internal functions */
96 static const    char *NgCookie(int cookie);
97
98 /* Known typecookie list */
99 struct ng_cookie {
100         int             cookie;
101         const char      *type;
102 };
103
104 #define COOKIE(c)       { NGM_ ## c ## _COOKIE, #c }
105
106 /* List of known cookies */
107 static const struct ng_cookie cookies[] = {
108         COOKIE(UI),
109         COOKIE(ASYNC),
110         COOKIE(BPF),
111         COOKIE(CISCO),
112         COOKIE(ECHO),
113         COOKIE(ETHER),
114         COOKIE(FRAMERELAY),
115         COOKIE(GENERIC),
116         COOKIE(HOLE),
117         COOKIE(IFACE),
118         COOKIE(KSOCKET),
119         COOKIE(LMI),
120         COOKIE(PPP),
121         COOKIE(PPPOE),
122         COOKIE(RFC1490),
123         COOKIE(SOCKET),
124         COOKIE(TEE),
125         COOKIE(TTY),
126         COOKIE(VJC),
127 #ifdef WHISTLE
128         COOKIE(DF),
129         COOKIE(IPAC),
130         COOKIE(MPPC),
131         COOKIE(PPTPGRE),
132         COOKIE(TN),
133         COOKIE(WFRA),
134 #endif
135         { 0, NULL }
136 };
137
138 /*
139  * Set debug level, ie, verbosity, if "level" is non-negative.
140  * Returns old debug level.
141  */
142 int
143 NgSetDebug(int level)
144 {
145         int old = _gNgDebugLevel;
146
147         if (level < 0)
148                 level = old;
149         _gNgDebugLevel = level;
150         return (old);
151 }
152
153 /*
154  * Set debug logging functions.
155  */
156 void
157 NgSetErrLog(void (*log) (const char *fmt,...),
158                 void (*logx) (const char *fmt,...))
159 {
160         _NgLog = log;
161         _NgLogx = logx;
162 }
163
164 /*
165  * Display a netgraph sockaddr
166  */
167 void
168 _NgDebugSockaddr(const struct sockaddr_ng *sg)
169 {
170         NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
171                sg->sg_family, sg->sg_len, sg->sg_data);
172 }
173
174 #define ARGS_BUFSIZE            2048
175 #define RECURSIVE_DEBUG_ADJUST  4
176
177 /*
178  * Display a negraph message
179  */
180 void
181 _NgDebugMsg(const struct ng_mesg *msg, const char *path)
182 {
183         u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
184         struct ng_mesg *const req = (struct ng_mesg *)buf;
185         struct ng_mesg *const bin = (struct ng_mesg *)req->data;
186         int arglen, csock = -1;
187
188         /* Display header stuff */
189         NGLOGX("NG_MESG :");
190         NGLOGX("  vers   %d", msg->header.version);
191         NGLOGX("  arglen %d", msg->header.arglen);
192         NGLOGX("  flags  %ld", msg->header.flags);
193         NGLOGX("  token  %lu", (u_long)msg->header.token);
194         NGLOGX("  cookie %s (%d)",
195             NgCookie(msg->header.typecookie), msg->header.typecookie);
196
197         /* At lower debugging levels, skip ASCII translation */
198         if (_gNgDebugLevel <= 2)
199                 goto fail2;
200
201         /* If path is not absolute, don't bother trying to use relative
202            address on a different socket for the ASCII translation */
203         if (strchr(path, ':') == NULL)
204                 goto fail2;
205
206         /* Get a temporary socket */
207         if (NgMkSockNode(NULL, &csock, NULL) < 0)
208                 goto fail;
209
210         /* Copy binary message into request message payload */
211         arglen = msg->header.arglen;
212         if (arglen > ARGS_BUFSIZE)
213                 arglen = ARGS_BUFSIZE;
214         memcpy(bin, msg, sizeof(*msg) + arglen);
215         bin->header.arglen = arglen;
216
217         /* Lower debugging to avoid infinite recursion */
218         _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
219
220         /* Ask the node to translate the binary message to ASCII for us */
221         if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
222             NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
223                 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
224                 goto fail;
225         }
226         if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
227                 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
228                 goto fail;
229         }
230
231         /* Restore debugging level */
232         _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
233
234         /* Display command string and arguments */
235         NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
236         NGLOGX("  args   %s", bin->data);
237         goto done;
238
239 fail:
240         /* Just display binary version */
241         NGLOGX("  [error decoding message: %s]", strerror(errno));
242 fail2:
243         NGLOGX("  cmd    %d", msg->header.cmd);
244         NGLOGX("  args (%d bytes)", msg->header.arglen);
245         _NgDebugBytes(msg->data, msg->header.arglen);
246
247 done:
248         if (csock != -1)
249                 (void)close(csock);
250 }
251
252 /*
253  * Return the name of the node type corresponding to the cookie
254  */
255 static const char *
256 NgCookie(int cookie)
257 {
258         int k;
259
260         for (k = 0; cookies[k].cookie != 0; k++) {
261                 if (cookies[k].cookie == cookie)
262                         return cookies[k].type;
263         }
264         return "??";
265 }
266
267 /*
268  * Dump bytes in hex
269  */
270 void
271 _NgDebugBytes(const u_char *ptr, int len)
272 {
273         char    buf[100];
274         int     k, count;
275
276 #define BYPERLINE       16
277
278         for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
279
280                 /* Do hex */
281                 snprintf(buf, sizeof(buf), "%04x:  ", count);
282                 for (k = 0; k < BYPERLINE; k++, count++)
283                         if (count < len)
284                                 snprintf(buf + strlen(buf),
285                                     sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
286                         else
287                                 snprintf(buf + strlen(buf),
288                                     sizeof(buf) - strlen(buf), "   ");
289                 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
290                 count -= BYPERLINE;
291
292                 /* Do ASCII */
293                 for (k = 0; k < BYPERLINE; k++, count++)
294                         if (count < len)
295                                 snprintf(buf + strlen(buf),
296                                     sizeof(buf) - strlen(buf),
297                                     "%c", isprint(ptr[k]) ? ptr[k] : '.');
298                         else
299                                 snprintf(buf + strlen(buf),
300                                     sizeof(buf) - strlen(buf), "  ");
301                 count -= BYPERLINE;
302
303                 /* Print it */
304                 NGLOGX("%s", buf);
305         }
306 }
307