xref: /freebsd/lib/libnetgraph/debug.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
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$
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	1024
175 
176 /*
177  * Display a negraph message
178  */
179 void
180 _NgDebugMsg(const struct ng_mesg *msg, const char *path)
181 {
182 	u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
183 	struct ng_mesg *const req = (struct ng_mesg *)buf;
184 	struct ng_mesg *const bin = (struct ng_mesg *)req->data;
185 	int arglen, debugSave, csock = -1;
186 
187 	/* Lower debugging to avoid infinite recursion */
188 	debugSave = _gNgDebugLevel;
189 	_gNgDebugLevel -= 4;
190 
191 	/* Display header stuff */
192 	NGLOGX("NG_MESG :");
193 	NGLOGX("  vers   %d", msg->header.version);
194 	NGLOGX("  arglen %d", msg->header.arglen);
195 	NGLOGX("  flags  %ld", msg->header.flags);
196 	NGLOGX("  token  %lu", (u_long)msg->header.token);
197 	NGLOGX("  cookie %s (%d)",
198 	    NgCookie(msg->header.typecookie), msg->header.typecookie);
199 
200 	/* At lower debugging levels, skip ASCII translation */
201 	if (_gNgDebugLevel <= 2)
202 		goto fail2;
203 
204 	/* If path is not absolute, don't bother trying to use relative
205 	   address on a different socket for the ASCII translation */
206 	if (strchr(path, ':') == NULL)
207 		goto fail2;
208 
209 	/* Get a temporary socket */
210 	if (NgMkSockNode(NULL, &csock, NULL) < 0)
211 		goto fail;
212 
213 	/* Copy binary message into request message payload */
214 	arglen = msg->header.arglen;
215 	if (arglen > ARGS_BUFSIZE)
216 		arglen = ARGS_BUFSIZE;
217 	memcpy(bin, msg, sizeof(*msg) + arglen);
218 	bin->header.arglen = arglen;
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 		goto fail;
224 	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0)
225 		goto fail;
226 
227 	/* Display command string and arguments */
228 	NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
229 	NGLOGX("  args   %s", bin->data);
230 	goto done;
231 
232 fail:
233 	/* Just display binary version */
234 	NGLOGX("  [error decoding message: %s]", strerror(errno));
235 fail2:
236 	NGLOGX("  cmd    %d", msg->header.cmd);
237 	NGLOGX("  args (%d bytes)", msg->header.arglen);
238 	_NgDebugBytes(msg->data, msg->header.arglen);
239 
240 done:
241 	if (csock != -1)
242 		(void)close(csock);
243 	_gNgDebugLevel = debugSave;
244 }
245 
246 /*
247  * Return the name of the node type corresponding to the cookie
248  */
249 static const char *
250 NgCookie(int cookie)
251 {
252 	int k;
253 
254 	for (k = 0; cookies[k].cookie != 0; k++) {
255 		if (cookies[k].cookie == cookie)
256 			return cookies[k].type;
257 	}
258 	return "??";
259 }
260 
261 /*
262  * Dump bytes in hex
263  */
264 void
265 _NgDebugBytes(const u_char *ptr, int len)
266 {
267 	char    buf[100];
268 	int     k, count;
269 
270 #define BYPERLINE	16
271 
272 	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
273 
274 		/* Do hex */
275 		snprintf(buf, sizeof(buf), "%04x:  ", count);
276 		for (k = 0; k < BYPERLINE; k++, count++)
277 			if (count < len)
278 				snprintf(buf + strlen(buf),
279 				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
280 			else
281 				snprintf(buf + strlen(buf),
282 				    sizeof(buf) - strlen(buf), "   ");
283 		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
284 		count -= BYPERLINE;
285 
286 		/* Do ASCII */
287 		for (k = 0; k < BYPERLINE; k++, count++)
288 			if (count < len)
289 				snprintf(buf + strlen(buf),
290 				    sizeof(buf) - strlen(buf),
291 				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
292 			else
293 				snprintf(buf + strlen(buf),
294 				    sizeof(buf) - strlen(buf), "  ");
295 		count -= BYPERLINE;
296 
297 		/* Print it */
298 		NGLOGX("%s", buf);
299 	}
300 }
301 
302