xref: /trueos/lib/libnetgraph/debug.c (revision f3fa4bdf8b98edb697d801e65b8b2bd542f15787)
1 /*
2  * debug.c
3  *
4  * Copyright (c) 1996-1999 Whistle Communications, Inc.
5  * All rights reserved.
6  *
7  * Subject to the following obligations and disclaimer of warranty, use and
8  * redistribution of this software, in source or object code forms, with or
9  * without modifications are expressly permitted by Whistle Communications;
10  * provided, however, that:
11  * 1. Any and all reproductions of the source or object code must include the
12  *    copyright notice above and the following disclaimer of warranties; and
13  * 2. No rights are granted, in any manner or form, to use Whistle
14  *    Communications, Inc. trademarks, including the mark "WHISTLE
15  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
16  *    such appears in the above copyright notice or in the software.
17  *
18  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
19  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
20  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
21  * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
23  * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
24  * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
25  * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
26  * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
27  * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
28  * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
29  * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
30  * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
34  * OF SUCH DAMAGE.
35  *
36  * Author: Archie Cobbs <archie@whistle.com>
37  *
38  * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
39  */
40 
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43 
44 #include <sys/types.h>
45 #include <sys/time.h>
46 #include <sys/ioctl.h>
47 
48 #include <stdarg.h>
49 
50 #include <netinet/in.h>
51 #include <net/ethernet.h>
52 #include <net/bpf.h>
53 
54 #include <netgraph/ng_message.h>
55 #include <netgraph/ng_socket.h>
56 
57 #include "netgraph.h"
58 #include "internal.h"
59 
60 #include <netgraph/ng_UI.h>
61 #include <netgraph/ng_async.h>
62 #include <netgraph/ng_atmllc.h>
63 #include <netgraph/ng_bpf.h>
64 #include <netgraph/ng_bridge.h>
65 #include <netgraph/ng_car.h>
66 #include <netgraph/ng_cisco.h>
67 #include <netgraph/ng_deflate.h>
68 #include <netgraph/ng_device.h>
69 #include <netgraph/ng_echo.h>
70 #include <netgraph/ng_eiface.h>
71 #include <netgraph/ng_etf.h>
72 #include <netgraph/ng_ether.h>
73 #include <netgraph/ng_fec.h>
74 #include <netgraph/ng_ether_echo.h>
75 #include <netgraph/ng_frame_relay.h>
76 #include <netgraph/ng_gif.h>
77 #include <netgraph/ng_gif_demux.h>
78 #include <netgraph/ng_hole.h>
79 #include <netgraph/ng_hub.h>
80 #include <netgraph/ng_iface.h>
81 #include <netgraph/ng_ip_input.h>
82 #include <netgraph/ng_ipfw.h>
83 #include <netgraph/ng_ksocket.h>
84 #include <netgraph/ng_l2tp.h>
85 #include <netgraph/ng_lmi.h>
86 #include <netgraph/ng_mppc.h>
87 #include <netgraph/ng_nat.h>
88 #include <netgraph/netflow/ng_netflow.h>
89 #include <netgraph/ng_one2many.h>
90 #include <netgraph/ng_patch.h>
91 #include <netgraph/ng_pipe.h>
92 #include <netgraph/ng_ppp.h>
93 #include <netgraph/ng_pppoe.h>
94 #include <netgraph/ng_pptpgre.h>
95 #include <netgraph/ng_pred1.h>
96 #include <netgraph/ng_rfc1490.h>
97 #include <netgraph/ng_socket.h>
98 #include <netgraph/ng_source.h>
99 #include <netgraph/ng_split.h>
100 #include <netgraph/ng_sppp.h>
101 #include <netgraph/ng_tag.h>
102 #include <netgraph/ng_tcpmss.h>
103 #include <netgraph/ng_tee.h>
104 #include <netgraph/ng_tty.h>
105 #include <netgraph/ng_vjc.h>
106 #include <netgraph/ng_vlan.h>
107 #ifdef	WHISTLE
108 #include <machine/../isa/df_def.h>
109 #include <machine/../isa/if_wfra.h>
110 #include <machine/../isa/ipac.h>
111 #include <netgraph/ng_df.h>
112 #include <netgraph/ng_ipac.h>
113 #include <netgraph/ng_tn.h>
114 #endif
115 
116 /* Global debug level */
117 int     _gNgDebugLevel = 0;
118 
119 /* Debug printing functions */
120 void    (*_NgLog) (const char *fmt,...) = warn;
121 void    (*_NgLogx) (const char *fmt,...) = warnx;
122 
123 /* Internal functions */
124 static const	char *NgCookie(int cookie);
125 
126 /* Known typecookie list */
127 struct ng_cookie {
128 	int		cookie;
129 	const char	*type;
130 };
131 
132 #define COOKIE(c)	{ NGM_ ## c ## _COOKIE, #c }
133 
134 /* List of known cookies */
135 static const struct ng_cookie cookies[] = {
136 	COOKIE(UI),
137 	COOKIE(ASYNC),
138 	COOKIE(ATMLLC),
139 	COOKIE(BPF),
140 	COOKIE(BRIDGE),
141 	COOKIE(CAR),
142 	COOKIE(CISCO),
143 	COOKIE(DEFLATE),
144 	COOKIE(DEVICE),
145 	COOKIE(ECHO),
146 	COOKIE(EIFACE),
147 	COOKIE(ETF),
148 	COOKIE(ETHER),
149 	COOKIE(FEC),
150 	COOKIE(ETHER_ECHO),
151 	COOKIE(FRAMERELAY),
152 	COOKIE(GIF),
153 	COOKIE(GIF_DEMUX),
154 	COOKIE(GENERIC),
155 	COOKIE(HOLE),
156 	COOKIE(HUB),
157 	COOKIE(IFACE),
158 	COOKIE(IP_INPUT),
159 	COOKIE(IPFW),
160 	COOKIE(KSOCKET),
161 	COOKIE(L2TP),
162 	COOKIE(LMI),
163 	COOKIE(MPPC),
164 	COOKIE(NAT),
165 	COOKIE(NETFLOW),
166 	COOKIE(ONE2MANY),
167 	COOKIE(PATCH),
168 	COOKIE(PIPE),
169 	COOKIE(PPP),
170 	COOKIE(PPPOE),
171 	COOKIE(PPTPGRE),
172 	COOKIE(PRED1),
173 	COOKIE(RFC1490),
174 	COOKIE(SOCKET),
175 	COOKIE(SOURCE),
176 	COOKIE(SPLIT),
177 	COOKIE(SPPP),
178 	COOKIE(TAG),
179 	COOKIE(TCPMSS),
180 	COOKIE(TEE),
181 	COOKIE(TTY),
182 	COOKIE(VJC),
183 	COOKIE(VLAN),
184 #ifdef WHISTLE
185 	COOKIE(DF),
186 	COOKIE(IPAC),
187 	COOKIE(TN),
188 	COOKIE(WFRA),
189 #endif
190 	{ 0, NULL }
191 };
192 
193 /*
194  * Set debug level, ie, verbosity, if "level" is non-negative.
195  * Returns old debug level.
196  */
197 int
NgSetDebug(int level)198 NgSetDebug(int level)
199 {
200 	int old = _gNgDebugLevel;
201 
202 	if (level >= 0)
203 		_gNgDebugLevel = level;
204 	return (old);
205 }
206 
207 /*
208  * Set debug logging functions.
209  */
210 void
NgSetErrLog(void (* log)(const char * fmt,...),void (* logx)(const char * fmt,...))211 NgSetErrLog(void (*log) (const char *fmt,...),
212 		void (*logx) (const char *fmt,...))
213 {
214 	_NgLog = log;
215 	_NgLogx = logx;
216 }
217 
218 /*
219  * Display a netgraph sockaddr
220  */
221 void
_NgDebugSockaddr(const struct sockaddr_ng * sg)222 _NgDebugSockaddr(const struct sockaddr_ng *sg)
223 {
224 	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
225 	       sg->sg_family, sg->sg_len, sg->sg_data);
226 }
227 
228 #define ARGS_BUFSIZE		2048
229 #define RECURSIVE_DEBUG_ADJUST	4
230 
231 /*
232  * Display a negraph message
233  */
234 void
_NgDebugMsg(const struct ng_mesg * msg,const char * path)235 _NgDebugMsg(const struct ng_mesg *msg, const char *path)
236 {
237 	u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
238 	struct ng_mesg *const req = (struct ng_mesg *)buf;
239 	struct ng_mesg *const bin = (struct ng_mesg *)req->data;
240 	int arglen, csock = -1;
241 
242 	/* Display header stuff */
243 	NGLOGX("NG_MESG :");
244 	NGLOGX("  vers   %d", msg->header.version);
245 	NGLOGX("  arglen %u", msg->header.arglen);
246 	NGLOGX("  flags  %x", msg->header.flags);
247 	NGLOGX("  token  %u", msg->header.token);
248 	NGLOGX("  cookie %s (%u)",
249 	    NgCookie(msg->header.typecookie), msg->header.typecookie);
250 
251 	/* At lower debugging levels, skip ASCII translation */
252 	if (_gNgDebugLevel <= 2)
253 		goto fail2;
254 
255 	/* If path is not absolute, don't bother trying to use relative
256 	   address on a different socket for the ASCII translation */
257 	if (strchr(path, ':') == NULL)
258 		goto fail2;
259 
260 	/* Get a temporary socket */
261 	if (NgMkSockNode(NULL, &csock, NULL) < 0)
262 		goto fail;
263 
264 	/* Copy binary message into request message payload */
265 	arglen = msg->header.arglen;
266 	if (arglen > ARGS_BUFSIZE)
267 		arglen = ARGS_BUFSIZE;
268 	memcpy(bin, msg, sizeof(*msg) + arglen);
269 	bin->header.arglen = arglen;
270 
271 	/* Lower debugging to avoid infinite recursion */
272 	_gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
273 
274 	/* Ask the node to translate the binary message to ASCII for us */
275 	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
276 	    NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
277 		_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
278 		goto fail;
279 	}
280 	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
281 		_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
282 		goto fail;
283 	}
284 
285 	/* Restore debugging level */
286 	_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
287 
288 	/* Display command string and arguments */
289 	NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
290 	NGLOGX("  args   %s", bin->data);
291 	goto done;
292 
293 fail:
294 	/* Just display binary version */
295 	NGLOGX("  [error decoding message: %s]", strerror(errno));
296 fail2:
297 	NGLOGX("  cmd    %d", msg->header.cmd);
298 	NGLOGX("  args (%d bytes)", msg->header.arglen);
299 	_NgDebugBytes((u_char *)msg->data, msg->header.arglen);
300 
301 done:
302 	if (csock != -1)
303 		(void)close(csock);
304 }
305 
306 /*
307  * Return the name of the node type corresponding to the cookie
308  */
309 static const char *
NgCookie(int cookie)310 NgCookie(int cookie)
311 {
312 	int k;
313 
314 	for (k = 0; cookies[k].cookie != 0; k++) {
315 		if (cookies[k].cookie == cookie)
316 			return cookies[k].type;
317 	}
318 	return "??";
319 }
320 
321 /*
322  * Dump bytes in hex
323  */
324 void
_NgDebugBytes(const u_char * ptr,int len)325 _NgDebugBytes(const u_char *ptr, int len)
326 {
327 	char    buf[100];
328 	int     k, count;
329 
330 #define BYPERLINE	16
331 
332 	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
333 
334 		/* Do hex */
335 		snprintf(buf, sizeof(buf), "%04x:  ", count);
336 		for (k = 0; k < BYPERLINE; k++, count++)
337 			if (count < len)
338 				snprintf(buf + strlen(buf),
339 				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
340 			else
341 				snprintf(buf + strlen(buf),
342 				    sizeof(buf) - strlen(buf), "   ");
343 		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
344 		count -= BYPERLINE;
345 
346 		/* Do ASCII */
347 		for (k = 0; k < BYPERLINE; k++, count++)
348 			if (count < len)
349 				snprintf(buf + strlen(buf),
350 				    sizeof(buf) - strlen(buf),
351 				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
352 			else
353 				snprintf(buf + strlen(buf),
354 				    sizeof(buf) - strlen(buf), "  ");
355 		count -= BYPERLINE;
356 
357 		/* Print it */
358 		NGLOGX("%s", buf);
359 	}
360 }
361 
362