xref: /dragonfly/lib/libnetgraph/debug.c (revision 984263bc)
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 
308