debug.c revision 302408
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: stable/11/lib/libnetgraph/debug.c 278311 2015-02-06 09:41:16Z mav $");
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_ether_echo.h>
74#include <netgraph/ng_frame_relay.h>
75#include <netgraph/ng_gif.h>
76#include <netgraph/ng_gif_demux.h>
77#include <netgraph/ng_hole.h>
78#include <netgraph/ng_hub.h>
79#include <netgraph/ng_iface.h>
80#include <netgraph/ng_ip_input.h>
81#include <netgraph/ng_ipfw.h>
82#include <netgraph/ng_ksocket.h>
83#include <netgraph/ng_l2tp.h>
84#include <netgraph/ng_lmi.h>
85#include <netgraph/ng_mppc.h>
86#include <netgraph/ng_nat.h>
87#include <netgraph/netflow/ng_netflow.h>
88#include <netgraph/ng_one2many.h>
89#include <netgraph/ng_patch.h>
90#include <netgraph/ng_pipe.h>
91#include <netgraph/ng_ppp.h>
92#include <netgraph/ng_pppoe.h>
93#include <netgraph/ng_pptpgre.h>
94#include <netgraph/ng_pred1.h>
95#include <netgraph/ng_rfc1490.h>
96#include <netgraph/ng_socket.h>
97#include <netgraph/ng_source.h>
98#include <netgraph/ng_split.h>
99#include <netgraph/ng_sppp.h>
100#include <netgraph/ng_tag.h>
101#include <netgraph/ng_tcpmss.h>
102#include <netgraph/ng_tee.h>
103#include <netgraph/ng_tty.h>
104#include <netgraph/ng_vjc.h>
105#include <netgraph/ng_vlan.h>
106#ifdef	WHISTLE
107#include <machine/../isa/df_def.h>
108#include <machine/../isa/if_wfra.h>
109#include <machine/../isa/ipac.h>
110#include <netgraph/ng_df.h>
111#include <netgraph/ng_ipac.h>
112#include <netgraph/ng_tn.h>
113#endif
114
115/* Global debug level */
116int     _gNgDebugLevel = 0;
117
118/* Debug printing functions */
119void    (*_NgLog) (const char *fmt,...) = warn;
120void    (*_NgLogx) (const char *fmt,...) = warnx;
121
122/* Internal functions */
123static const	char *NgCookie(int cookie);
124
125/* Known typecookie list */
126struct ng_cookie {
127	int		cookie;
128	const char	*type;
129};
130
131#define COOKIE(c)	{ NGM_ ## c ## _COOKIE, #c }
132
133/* List of known cookies */
134static const struct ng_cookie cookies[] = {
135	COOKIE(UI),
136	COOKIE(ASYNC),
137	COOKIE(ATMLLC),
138	COOKIE(BPF),
139	COOKIE(BRIDGE),
140	COOKIE(CAR),
141	COOKIE(CISCO),
142	COOKIE(DEFLATE),
143	COOKIE(DEVICE),
144	COOKIE(ECHO),
145	COOKIE(EIFACE),
146	COOKIE(ETF),
147	COOKIE(ETHER),
148	COOKIE(ETHER_ECHO),
149	COOKIE(FRAMERELAY),
150	COOKIE(GIF),
151	COOKIE(GIF_DEMUX),
152	COOKIE(GENERIC),
153	COOKIE(HOLE),
154	COOKIE(HUB),
155	COOKIE(IFACE),
156	COOKIE(IP_INPUT),
157	COOKIE(IPFW),
158	COOKIE(KSOCKET),
159	COOKIE(L2TP),
160	COOKIE(LMI),
161	COOKIE(MPPC),
162	COOKIE(NAT),
163	COOKIE(NETFLOW),
164	COOKIE(ONE2MANY),
165	COOKIE(PATCH),
166	COOKIE(PIPE),
167	COOKIE(PPP),
168	COOKIE(PPPOE),
169	COOKIE(PPTPGRE),
170	COOKIE(PRED1),
171	COOKIE(RFC1490),
172	COOKIE(SOCKET),
173	COOKIE(SOURCE),
174	COOKIE(SPLIT),
175	COOKIE(SPPP),
176	COOKIE(TAG),
177	COOKIE(TCPMSS),
178	COOKIE(TEE),
179	COOKIE(TTY),
180	COOKIE(VJC),
181	COOKIE(VLAN),
182#ifdef WHISTLE
183	COOKIE(DF),
184	COOKIE(IPAC),
185	COOKIE(TN),
186	COOKIE(WFRA),
187#endif
188	{ 0, NULL }
189};
190
191/*
192 * Set debug level, ie, verbosity, if "level" is non-negative.
193 * Returns old debug level.
194 */
195int
196NgSetDebug(int level)
197{
198	int old = _gNgDebugLevel;
199
200	if (level >= 0)
201		_gNgDebugLevel = level;
202	return (old);
203}
204
205/*
206 * Set debug logging functions.
207 */
208void
209NgSetErrLog(void (*log) (const char *fmt,...),
210		void (*logx) (const char *fmt,...))
211{
212	_NgLog = log;
213	_NgLogx = logx;
214}
215
216/*
217 * Display a netgraph sockaddr
218 */
219void
220_NgDebugSockaddr(const struct sockaddr_ng *sg)
221{
222	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
223	       sg->sg_family, sg->sg_len, sg->sg_data);
224}
225
226#define ARGS_BUFSIZE		2048
227#define RECURSIVE_DEBUG_ADJUST	4
228
229/*
230 * Display a negraph message
231 */
232void
233_NgDebugMsg(const struct ng_mesg *msg, const char *path)
234{
235	u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
236	struct ng_mesg *const req = (struct ng_mesg *)buf;
237	struct ng_mesg *const bin = (struct ng_mesg *)req->data;
238	int arglen, csock = -1;
239
240	/* Display header stuff */
241	NGLOGX("NG_MESG :");
242	NGLOGX("  vers   %d", msg->header.version);
243	NGLOGX("  arglen %u", msg->header.arglen);
244	NGLOGX("  flags  %x", msg->header.flags);
245	NGLOGX("  token  %u", msg->header.token);
246	NGLOGX("  cookie %s (%u)",
247	    NgCookie(msg->header.typecookie), msg->header.typecookie);
248
249	/* At lower debugging levels, skip ASCII translation */
250	if (_gNgDebugLevel <= 2)
251		goto fail2;
252
253	/* If path is not absolute, don't bother trying to use relative
254	   address on a different socket for the ASCII translation */
255	if (strchr(path, ':') == NULL)
256		goto fail2;
257
258	/* Get a temporary socket */
259	if (NgMkSockNode(NULL, &csock, NULL) < 0)
260		goto fail;
261
262	/* Copy binary message into request message payload */
263	arglen = msg->header.arglen;
264	if (arglen > ARGS_BUFSIZE)
265		arglen = ARGS_BUFSIZE;
266	memcpy(bin, msg, sizeof(*msg) + arglen);
267	bin->header.arglen = arglen;
268
269	/* Lower debugging to avoid infinite recursion */
270	_gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
271
272	/* Ask the node to translate the binary message to ASCII for us */
273	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
274	    NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
275		_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
276		goto fail;
277	}
278	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
279		_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
280		goto fail;
281	}
282
283	/* Restore debugging level */
284	_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
285
286	/* Display command string and arguments */
287	NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
288	NGLOGX("  args   %s", bin->data);
289	goto done;
290
291fail:
292	/* Just display binary version */
293	NGLOGX("  [error decoding message: %s]", strerror(errno));
294fail2:
295	NGLOGX("  cmd    %d", msg->header.cmd);
296	NGLOGX("  args (%d bytes)", msg->header.arglen);
297	_NgDebugBytes((u_char *)msg->data, msg->header.arglen);
298
299done:
300	if (csock != -1)
301		(void)close(csock);
302}
303
304/*
305 * Return the name of the node type corresponding to the cookie
306 */
307static const char *
308NgCookie(int cookie)
309{
310	int k;
311
312	for (k = 0; cookies[k].cookie != 0; k++) {
313		if (cookies[k].cookie == cookie)
314			return cookies[k].type;
315	}
316	return "??";
317}
318
319/*
320 * Dump bytes in hex
321 */
322void
323_NgDebugBytes(const u_char *ptr, int len)
324{
325	char    buf[100];
326	int     k, count;
327
328#define BYPERLINE	16
329
330	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
331
332		/* Do hex */
333		snprintf(buf, sizeof(buf), "%04x:  ", count);
334		for (k = 0; k < BYPERLINE; k++, count++)
335			if (count < len)
336				snprintf(buf + strlen(buf),
337				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
338			else
339				snprintf(buf + strlen(buf),
340				    sizeof(buf) - strlen(buf), "   ");
341		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
342		count -= BYPERLINE;
343
344		/* Do ASCII */
345		for (k = 0; k < BYPERLINE; k++, count++)
346			if (count < len)
347				snprintf(buf + strlen(buf),
348				    sizeof(buf) - strlen(buf),
349				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
350			else
351				snprintf(buf + strlen(buf),
352				    sizeof(buf) - strlen(buf), "  ");
353		count -= BYPERLINE;
354
355		/* Print it */
356		NGLOGX("%s", buf);
357	}
358}
359
360