Merge branch 'vendor/OPENSSL'
[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/socket/ng_socket.h>
55
56 #include "netgraph.h"
57 #include "internal.h"
58
59 #include <netgraph/UI/ng_UI.h>
60 #include <netgraph/async/ng_async.h>
61 #include <netgraph/bpf/ng_bpf.h>
62 #include <netgraph/bridge/ng_bridge.h>
63 #include <netgraph/cisco/ng_cisco.h>
64 #include <netgraph/echo/ng_echo.h>
65 #include <netgraph/eiface/ng_eiface.h>
66 #include <netgraph/etf/ng_etf.h>
67 #include <netgraph/ether/ng_ether.h>
68 #include <netgraph/frame_relay/ng_frame_relay.h>
69 #include <netgraph/hole/ng_hole.h>
70 #include <netgraph/iface/ng_iface.h>
71 #include <netgraph/ksocket/ng_ksocket.h>
72 #include <netgraph/l2tp/ng_l2tp.h>
73 #include <netgraph/lmi/ng_lmi.h>
74 #include <netgraph/mppc/ng_mppc.h>
75 #include <netgraph/one2many/ng_one2many.h>
76 #include <netgraph/ppp/ng_ppp.h>
77 #include <netgraph/pppoe/ng_pppoe.h>
78 #include <netgraph/pptpgre/ng_pptpgre.h>
79 #include <netgraph/rfc1490/ng_rfc1490.h>
80 #include <netgraph/tee/ng_tee.h>
81 #include <netgraph/tty/ng_tty.h>
82 #include <netgraph/vjc/ng_vjc.h>
83 #ifdef  WHISTLE
84 #include <machine/../isa/df_def.h>
85 #include <machine/../isa/if_wfra.h>
86 #include <machine/../isa/ipac.h>
87 #include <netgraph/ng_df.h>
88 #include <netgraph/ng_ipac.h>
89 #include <netgraph/ng_tn.h>
90 #endif
91
92 /* Global debug level */
93 int     _gNgDebugLevel = 0;
94
95 /* Debug printing functions */
96 void    (*_NgLog) (const char *fmt,...) __printflike(1, 2) = warn;
97 void    (*_NgLogx) (const char *fmt,...) __printflike(1, 2) = warnx;
98
99 /* Internal functions */
100 static const    char *NgCookie(int cookie);
101
102 /* Known typecookie list */
103 struct ng_cookie {
104         int             cookie;
105         const char      *type;
106 };
107
108 #define COOKIE(c)       { NGM_ ## c ## _COOKIE, #c }
109
110 /* List of known cookies */
111 static const struct ng_cookie cookies[] = {
112         COOKIE(UI),
113         COOKIE(ASYNC),
114         COOKIE(BPF),
115         COOKIE(BRIDGE),
116         COOKIE(CISCO),
117         COOKIE(ECHO),
118         COOKIE(EIFACE),
119         COOKIE(ETF),
120         COOKIE(ETHER),
121         COOKIE(FRAMERELAY),
122         COOKIE(GENERIC),
123         COOKIE(HOLE),
124         COOKIE(IFACE),
125         COOKIE(KSOCKET),
126         COOKIE(L2TP),
127         COOKIE(LMI),
128         COOKIE(MPPC),
129         COOKIE(ONE2MANY),
130         COOKIE(PPP),
131         COOKIE(PPPOE),
132         COOKIE(PPTPGRE),
133         COOKIE(RFC1490),
134         COOKIE(SOCKET),
135         COOKIE(TEE),
136         COOKIE(TTY),
137         COOKIE(VJC),
138 #ifdef WHISTLE
139         COOKIE(DF),
140         COOKIE(IPAC),
141         COOKIE(TN),
142         COOKIE(WFRA),
143 #endif
144         { 0, NULL }
145 };
146
147 /*
148  * Set debug level, ie, verbosity, if "level" is non-negative.
149  * Returns old debug level.
150  */
151 int
152 NgSetDebug(int level)
153 {
154         int old = _gNgDebugLevel;
155
156         if (level < 0)
157                 level = old;
158         _gNgDebugLevel = level;
159         return (old);
160 }
161
162 /*
163  * Set debug logging functions.
164  */
165 void
166 NgSetErrLog(void (*log) (const char *fmt,...),
167                 void (*logx) (const char *fmt,...))
168 {
169         _NgLog = log;
170         _NgLogx = logx;
171 }
172
173 /*
174  * Display a netgraph sockaddr
175  */
176 void
177 _NgDebugSockaddr(const struct sockaddr_ng *sg)
178 {
179         NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
180                sg->sg_family, sg->sg_len, sg->sg_data);
181 }
182
183 #define ARGS_BUFSIZE            2048
184 #define RECURSIVE_DEBUG_ADJUST  4
185
186 /*
187  * Display a negraph message
188  */
189 void
190 _NgDebugMsg(const struct ng_mesg *msg, const char *path)
191 {
192         u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
193         struct ng_mesg *const req = (struct ng_mesg *)buf;
194         struct ng_mesg *const bin = (struct ng_mesg *)req->data;
195         int arglen, csock = -1;
196
197         /* Display header stuff */
198         NGLOGX("NG_MESG :");
199         NGLOGX("  vers   %d", msg->header.version);
200         NGLOGX("  arglen %d", msg->header.arglen);
201         NGLOGX("  flags  %u", msg->header.flags);
202         NGLOGX("  token  %u", msg->header.token);
203         NGLOGX("  cookie %s (%d)",
204             NgCookie(msg->header.typecookie), msg->header.typecookie);
205
206         /* At lower debugging levels, skip ASCII translation */
207         if (_gNgDebugLevel <= 2)
208                 goto fail2;
209
210         /* If path is not absolute, don't bother trying to use relative
211            address on a different socket for the ASCII translation */
212         if (strchr(path, ':') == NULL)
213                 goto fail2;
214
215         /* Get a temporary socket */
216         if (NgMkSockNode(NULL, &csock, NULL) < 0)
217                 goto fail;
218
219         /* Copy binary message into request message payload */
220         arglen = msg->header.arglen;
221         if (arglen > ARGS_BUFSIZE)
222                 arglen = ARGS_BUFSIZE;
223         memcpy(bin, msg, sizeof(*msg) + arglen);
224         bin->header.arglen = arglen;
225
226         /* Lower debugging to avoid infinite recursion */
227         _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
228
229         /* Ask the node to translate the binary message to ASCII for us */
230         if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
231             NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
232                 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
233                 goto fail;
234         }
235         if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
236                 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
237                 goto fail;
238         }
239
240         /* Restore debugging level */
241         _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
242
243         /* Display command string and arguments */
244         NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
245         NGLOGX("  args   %s", bin->data);
246         goto done;
247
248 fail:
249         /* Just display binary version */
250         NGLOGX("  [error decoding message: %s]", strerror(errno));
251 fail2:
252         NGLOGX("  cmd    %d", msg->header.cmd);
253         NGLOGX("  args (%d bytes)", msg->header.arglen);
254         _NgDebugBytes(msg->data, msg->header.arglen);
255
256 done:
257         if (csock != -1)
258                 (void)close(csock);
259 }
260
261 /*
262  * Return the name of the node type corresponding to the cookie
263  */
264 static const char *
265 NgCookie(int cookie)
266 {
267         int k;
268
269         for (k = 0; cookies[k].cookie != 0; k++) {
270                 if (cookies[k].cookie == cookie)
271                         return cookies[k].type;
272         }
273         return "??";
274 }
275
276 /*
277  * Dump bytes in hex
278  */
279 void
280 _NgDebugBytes(const u_char *ptr, int len)
281 {
282         char    buf[100];
283         int     k, count;
284
285 #define BYPERLINE       16
286
287         for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
288
289                 /* Do hex */
290                 snprintf(buf, sizeof(buf), "%04x:  ", count);
291                 for (k = 0; k < BYPERLINE; k++, count++)
292                         if (count < len)
293                                 snprintf(buf + strlen(buf),
294                                     sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
295                         else
296                                 snprintf(buf + strlen(buf),
297                                     sizeof(buf) - strlen(buf), "   ");
298                 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
299                 count -= BYPERLINE;
300
301                 /* Do ASCII */
302                 for (k = 0; k < BYPERLINE; k++, count++)
303                         if (count < len)
304                                 snprintf(buf + strlen(buf),
305                                     sizeof(buf) - strlen(buf),
306                                     "%c", isprint(ptr[k]) ? ptr[k] : '.');
307                         else
308                                 snprintf(buf + strlen(buf),
309                                     sizeof(buf) - strlen(buf), "  ");
310                 count -= BYPERLINE;
311
312                 /* Print it */
313                 NGLOGX("%s", buf);
314         }
315 }
316