Sync with HEAD.
[dragonfly.git] / lib / libnetgraph / debug.c
blob64b7a6afd1ca335c1a739165ae09f1a2f8bbea29
2 /*
3 * debug.c
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.
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.
37 * Author: Archie Cobbs <archie@whistle.com>
39 * $FreeBSD: src/lib/libnetgraph/debug.c,v 1.5.2.1 2000/05/01 18:09:54 archie Exp $
40 * $DragonFly: src/lib/libnetgraph/debug.c,v 1.4 2007/06/17 20:33:14 swildner Exp $
41 * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
44 #include <sys/types.h>
45 #include <sys/time.h>
46 #include <sys/ioctl.h>
48 #include <stdarg.h>
50 #include <netinet/in.h>
51 #include <net/ethernet.h>
52 #include <net/bpf.h>
54 #include <netgraph/ng_message.h>
55 #include <netgraph/socket/ng_socket.h>
57 #include "netgraph.h"
58 #include "internal.h"
60 #include <netgraph/UI/ng_UI.h>
61 #include <netgraph/async/ng_async.h>
62 #include <netgraph/bpf/ng_bpf.h>
63 #include <netgraph/bridge/ng_bridge.h>
64 #include <netgraph/cisco/ng_cisco.h>
65 #include <netgraph/echo/ng_echo.h>
66 #include <netgraph/eiface/ng_eiface.h>
67 #include <netgraph/etf/ng_etf.h>
68 #include <netgraph/ether/ng_ether.h>
69 #include <netgraph/frame_relay/ng_frame_relay.h>
70 #include <netgraph/hole/ng_hole.h>
71 #include <netgraph/iface/ng_iface.h>
72 #include <netgraph/ksocket/ng_ksocket.h>
73 #include <netgraph/l2tp/ng_l2tp.h>
74 #include <netgraph/lmi/ng_lmi.h>
75 #include <netgraph/mppc/ng_mppc.h>
76 #include <netgraph/one2many/ng_one2many.h>
77 #include <netgraph/ppp/ng_ppp.h>
78 #include <netgraph/pppoe/ng_pppoe.h>
79 #include <netgraph/pptpgre/ng_pptpgre.h>
80 #include <netgraph/rfc1490/ng_rfc1490.h>
81 #include <netgraph/socket/ng_socket.h>
82 #include <netgraph/tee/ng_tee.h>
83 #include <netgraph/tty/ng_tty.h>
84 #include <netgraph/vjc/ng_vjc.h>
85 #ifdef WHISTLE
86 #include <machine/../isa/df_def.h>
87 #include <machine/../isa/if_wfra.h>
88 #include <machine/../isa/ipac.h>
89 #include <netgraph/ng_df.h>
90 #include <netgraph/ng_ipac.h>
91 #include <netgraph/ng_tn.h>
92 #endif
94 /* Global debug level */
95 int _gNgDebugLevel = 0;
97 /* Debug printing functions */
98 void (*_NgLog) (const char *fmt,...) = warn;
99 void (*_NgLogx) (const char *fmt,...) = warnx;
101 /* Internal functions */
102 static const char *NgCookie(int cookie);
104 /* Known typecookie list */
105 struct ng_cookie {
106 int cookie;
107 const char *type;
110 #define COOKIE(c) { NGM_ ## c ## _COOKIE, #c }
112 /* List of known cookies */
113 static const struct ng_cookie cookies[] = {
114 COOKIE(UI),
115 COOKIE(ASYNC),
116 COOKIE(BPF),
117 COOKIE(BRIDGE),
118 COOKIE(CISCO),
119 COOKIE(ECHO),
120 COOKIE(EIFACE),
121 COOKIE(ETF),
122 COOKIE(ETHER),
123 COOKIE(FRAMERELAY),
124 COOKIE(GENERIC),
125 COOKIE(HOLE),
126 COOKIE(IFACE),
127 COOKIE(KSOCKET),
128 COOKIE(L2TP),
129 COOKIE(LMI),
130 COOKIE(MPPC),
131 COOKIE(ONE2MANY),
132 COOKIE(PPP),
133 COOKIE(PPPOE),
134 COOKIE(PPTPGRE),
135 COOKIE(RFC1490),
136 COOKIE(SOCKET),
137 COOKIE(TEE),
138 COOKIE(TTY),
139 COOKIE(VJC),
140 #ifdef WHISTLE
141 COOKIE(DF),
142 COOKIE(IPAC),
143 COOKIE(TN),
144 COOKIE(WFRA),
145 #endif
146 { 0, NULL }
150 * Set debug level, ie, verbosity, if "level" is non-negative.
151 * Returns old debug level.
154 NgSetDebug(int level)
156 int old = _gNgDebugLevel;
158 if (level < 0)
159 level = old;
160 _gNgDebugLevel = level;
161 return (old);
165 * Set debug logging functions.
167 void
168 NgSetErrLog(void (*log) (const char *fmt,...),
169 void (*logx) (const char *fmt,...))
171 _NgLog = log;
172 _NgLogx = logx;
176 * Display a netgraph sockaddr
178 void
179 _NgDebugSockaddr(const struct sockaddr_ng *sg)
181 NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
182 sg->sg_family, sg->sg_len, sg->sg_data);
185 #define ARGS_BUFSIZE 2048
186 #define RECURSIVE_DEBUG_ADJUST 4
189 * Display a negraph message
191 void
192 _NgDebugMsg(const struct ng_mesg *msg, const char *path)
194 u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
195 struct ng_mesg *const req = (struct ng_mesg *)buf;
196 struct ng_mesg *const bin = (struct ng_mesg *)req->data;
197 int arglen, csock = -1;
199 /* Display header stuff */
200 NGLOGX("NG_MESG :");
201 NGLOGX(" vers %d", msg->header.version);
202 NGLOGX(" arglen %d", msg->header.arglen);
203 NGLOGX(" flags %ld", msg->header.flags);
204 NGLOGX(" token %lu", (u_long)msg->header.token);
205 NGLOGX(" cookie %s (%d)",
206 NgCookie(msg->header.typecookie), msg->header.typecookie);
208 /* At lower debugging levels, skip ASCII translation */
209 if (_gNgDebugLevel <= 2)
210 goto fail2;
212 /* If path is not absolute, don't bother trying to use relative
213 address on a different socket for the ASCII translation */
214 if (strchr(path, ':') == NULL)
215 goto fail2;
217 /* Get a temporary socket */
218 if (NgMkSockNode(NULL, &csock, NULL) < 0)
219 goto fail;
221 /* Copy binary message into request message payload */
222 arglen = msg->header.arglen;
223 if (arglen > ARGS_BUFSIZE)
224 arglen = ARGS_BUFSIZE;
225 memcpy(bin, msg, sizeof(*msg) + arglen);
226 bin->header.arglen = arglen;
228 /* Lower debugging to avoid infinite recursion */
229 _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
231 /* Ask the node to translate the binary message to ASCII for us */
232 if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
233 NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
234 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
235 goto fail;
237 if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
238 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
239 goto fail;
242 /* Restore debugging level */
243 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
245 /* Display command string and arguments */
246 NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd);
247 NGLOGX(" args %s", bin->data);
248 goto done;
250 fail:
251 /* Just display binary version */
252 NGLOGX(" [error decoding message: %s]", strerror(errno));
253 fail2:
254 NGLOGX(" cmd %d", msg->header.cmd);
255 NGLOGX(" args (%d bytes)", msg->header.arglen);
256 _NgDebugBytes(msg->data, msg->header.arglen);
258 done:
259 if (csock != -1)
260 (void)close(csock);
264 * Return the name of the node type corresponding to the cookie
266 static const char *
267 NgCookie(int cookie)
269 int k;
271 for (k = 0; cookies[k].cookie != 0; k++) {
272 if (cookies[k].cookie == cookie)
273 return cookies[k].type;
275 return "??";
279 * Dump bytes in hex
281 void
282 _NgDebugBytes(const u_char *ptr, int len)
284 char buf[100];
285 int k, count;
287 #define BYPERLINE 16
289 for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
291 /* Do hex */
292 snprintf(buf, sizeof(buf), "%04x: ", count);
293 for (k = 0; k < BYPERLINE; k++, count++)
294 if (count < len)
295 snprintf(buf + strlen(buf),
296 sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
297 else
298 snprintf(buf + strlen(buf),
299 sizeof(buf) - strlen(buf), " ");
300 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " ");
301 count -= BYPERLINE;
303 /* Do ASCII */
304 for (k = 0; k < BYPERLINE; k++, count++)
305 if (count < len)
306 snprintf(buf + strlen(buf),
307 sizeof(buf) - strlen(buf),
308 "%c", isprint(ptr[k]) ? ptr[k] : '.');
309 else
310 snprintf(buf + strlen(buf),
311 sizeof(buf) - strlen(buf), " ");
312 count -= BYPERLINE;
314 /* Print it */
315 NGLOGX("%s", buf);