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