xref: /freebsd/lib/libnetgraph/debug.c (revision f8307e1233657707bc582110f07373c96d91943b)
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(CISCO),
107 	COOKIE(ECHO),
108 	COOKIE(ETHER),
109 	COOKIE(FRAMERELAY),
110 	COOKIE(GENERIC),
111 	COOKIE(HOLE),
112 	COOKIE(IFACE),
113 	COOKIE(KSOCKET),
114 	COOKIE(LMI),
115 	COOKIE(PPP),
116 	COOKIE(PPPOE),
117 	COOKIE(RFC1490),
118 	COOKIE(SOCKET),
119 	COOKIE(TEE),
120 	COOKIE(TTY),
121 	COOKIE(VJC),
122 #ifdef WHISTLE
123 	COOKIE(DF),
124 	COOKIE(IPAC),
125 	COOKIE(MPPC),
126 	COOKIE(PPTPGRE),
127 	COOKIE(TN),
128 	COOKIE(WFRA),
129 #endif
130 	{ 0, NULL }
131 };
132 
133 /*
134  * Set debug level, ie, verbosity, if "level" is non-negative.
135  * Returns old debug level.
136  */
137 int
138 NgSetDebug(int level)
139 {
140 	int old = _gNgDebugLevel;
141 
142 	if (level < 0)
143 		level = old;
144 	_gNgDebugLevel = level;
145 	return (old);
146 }
147 
148 /*
149  * Set debug logging functions.
150  */
151 void
152 NgSetErrLog(void (*log) (const char *fmt,...),
153 		void (*logx) (const char *fmt,...))
154 {
155 	_NgLog = log;
156 	_NgLogx = logx;
157 }
158 
159 /*
160  * Display a netgraph sockaddr
161  */
162 void
163 _NgDebugSockaddr(const struct sockaddr_ng *sg)
164 {
165 	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
166 	       sg->sg_family, sg->sg_len, sg->sg_data);
167 }
168 
169 #define ARGS_BUFSIZE	1024
170 
171 /*
172  * Display a negraph message
173  */
174 void
175 _NgDebugMsg(const struct ng_mesg *msg, const char *path)
176 {
177 	u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
178 	struct ng_mesg *const req = (struct ng_mesg *)buf;
179 	struct ng_mesg *const bin = (struct ng_mesg *)req->data;
180 	int arglen, debugSave, csock = -1;
181 
182 	/* Lower debugging to avoid infinite recursion */
183 	debugSave = _gNgDebugLevel;
184 	_gNgDebugLevel -= 4;
185 
186 	/* Display header stuff */
187 	NGLOGX("NG_MESG :");
188 	NGLOGX("  vers   %d", msg->header.version);
189 	NGLOGX("  arglen %d", msg->header.arglen);
190 	NGLOGX("  flags  %ld", msg->header.flags);
191 	NGLOGX("  token  %lu", (u_long)msg->header.token);
192 	NGLOGX("  cookie %s (%d)",
193 	    NgCookie(msg->header.typecookie), msg->header.typecookie);
194 
195 	/* At lower debugging levels, skip ASCII translation */
196 	if (_gNgDebugLevel <= 2)
197 		goto fail2;
198 
199 	/* If path is not absolute, don't bother trying to use relative
200 	   address on a different socket for the ASCII translation */
201 	if (strchr(path, ':') == NULL)
202 		goto fail2;
203 
204 	/* Get a temporary socket */
205 	if (NgMkSockNode(NULL, &csock, NULL) < 0)
206 		goto fail;
207 
208 	/* Copy binary message into request message payload */
209 	arglen = msg->header.arglen;
210 	if (arglen > ARGS_BUFSIZE)
211 		arglen = ARGS_BUFSIZE;
212 	memcpy(bin, msg, sizeof(*msg) + arglen);
213 	bin->header.arglen = arglen;
214 
215 	/* Ask the node to translate the binary message to ASCII for us */
216 	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
217 	    NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0)
218 		goto fail;
219 	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0)
220 		goto fail;
221 
222 	/* Display command string and arguments */
223 	NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
224 	NGLOGX("  args   %s", bin->data);
225 	goto done;
226 
227 fail:
228 	/* Just display binary version */
229 	NGLOGX("  [error decoding message: %s]", strerror(errno));
230 fail2:
231 	NGLOGX("  cmd    %d", msg->header.cmd);
232 	NGLOGX("  args (%d bytes)", msg->header.arglen);
233 	_NgDebugBytes(msg->data, msg->header.arglen);
234 
235 done:
236 	if (csock != -1)
237 		(void)close(csock);
238 	_gNgDebugLevel = debugSave;
239 }
240 
241 /*
242  * Return the name of the node type corresponding to the cookie
243  */
244 static const char *
245 NgCookie(int cookie)
246 {
247 	int k;
248 
249 	for (k = 0; cookies[k].cookie != 0; k++) {
250 		if (cookies[k].cookie == cookie)
251 			return cookies[k].type;
252 	}
253 	return "??";
254 }
255 
256 /*
257  * Dump bytes in hex
258  */
259 void
260 _NgDebugBytes(const u_char *ptr, int len)
261 {
262 	char    buf[100];
263 	int     k, count;
264 
265 #define BYPERLINE	16
266 
267 	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
268 
269 		/* Do hex */
270 		snprintf(buf, sizeof(buf), "%04x:  ", count);
271 		for (k = 0; k < BYPERLINE; k++, count++)
272 			if (count < len)
273 				snprintf(buf + strlen(buf),
274 				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
275 			else
276 				snprintf(buf + strlen(buf),
277 				    sizeof(buf) - strlen(buf), "   ");
278 		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
279 		count -= BYPERLINE;
280 
281 		/* Do ASCII */
282 		for (k = 0; k < BYPERLINE; k++, count++)
283 			if (count < len)
284 				snprintf(buf + strlen(buf),
285 				    sizeof(buf) - strlen(buf),
286 				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
287 			else
288 				snprintf(buf + strlen(buf),
289 				    sizeof(buf) - strlen(buf), "  ");
290 		count -= BYPERLINE;
291 
292 		/* Print it */
293 		NGLOGX("%s", buf);
294 	}
295 }
296 
297