debug.c revision 54100
1258945Sroberto
2258945Sroberto/*
3258945Sroberto * debug.c
4258945Sroberto *
5258945Sroberto * Copyright (c) 1996-1999 Whistle Communications, Inc.
6258945Sroberto * All rights reserved.
7258945Sroberto *
8258945Sroberto * Subject to the following obligations and disclaimer of warranty, use and
9258945Sroberto * redistribution of this software, in source or object code forms, with or
10258945Sroberto * without modifications are expressly permitted by Whistle Communications;
11258945Sroberto * provided, however, that:
12258945Sroberto * 1. Any and all reproductions of the source or object code must include the
13258945Sroberto *    copyright notice above and the following disclaimer of warranties; and
14258945Sroberto * 2. No rights are granted, in any manner or form, to use Whistle
15258945Sroberto *    Communications, Inc. trademarks, including the mark "WHISTLE
16258945Sroberto *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
17258945Sroberto *    such appears in the above copyright notice or in the software.
18258945Sroberto *
19258945Sroberto * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
20258945Sroberto * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
21258945Sroberto * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
22258945Sroberto * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
23258945Sroberto * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
24258945Sroberto * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
25258945Sroberto * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
26258945Sroberto * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
27258945Sroberto * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
28258945Sroberto * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
29258945Sroberto * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
30258945Sroberto * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
31258945Sroberto * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
32258945Sroberto * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33258945Sroberto * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34258945Sroberto * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
35258945Sroberto * OF SUCH DAMAGE.
36258945Sroberto *
37258945Sroberto * Author: Archie Cobbs <archie@whistle.com>
38258945Sroberto *
39282408Scy * $FreeBSD: head/lib/libnetgraph/debug.c 54100 1999-12-03 23:15:33Z archie $
40258945Sroberto * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
41258945Sroberto */
42258945Sroberto
43258945Sroberto#include <sys/types.h>
44258945Sroberto#include <sys/time.h>
45258945Sroberto#include <sys/ioctl.h>
46258945Sroberto
47258945Sroberto#include <stdarg.h>
48258945Sroberto
49258945Sroberto#include <netinet/in.h>
50258945Sroberto#include <net/ethernet.h>
51258945Sroberto#include <net/bpf.h>
52258945Sroberto
53258945Sroberto#include <netgraph/ng_message.h>
54258945Sroberto#include <netgraph/ng_socket.h>
55258945Sroberto
56258945Sroberto#include "netgraph.h"
57258945Sroberto#include "internal.h"
58258945Sroberto
59258945Sroberto#include <netgraph/ng_UI.h>
60258945Sroberto#include <netgraph/ng_async.h>
61258945Sroberto#include <netgraph/ng_bpf.h>
62258945Sroberto#include <netgraph/ng_cisco.h>
63258945Sroberto#include <netgraph/ng_echo.h>
64258945Sroberto#include <netgraph/ng_ether.h>
65258945Sroberto#include <netgraph/ng_frame_relay.h>
66258945Sroberto#include <netgraph/ng_hole.h>
67258945Sroberto#include <netgraph/ng_iface.h>
68258945Sroberto#include <netgraph/ng_ksocket.h>
69280849Scy#include <netgraph/ng_lmi.h>
70258945Sroberto#include <netgraph/ng_ppp.h>
71280849Scy#include <netgraph/ng_pppoe.h>
72280849Scy#include <netgraph/ng_rfc1490.h>
73280849Scy#include <netgraph/ng_socket.h>
74280849Scy#include <netgraph/ng_tee.h>
75280849Scy#include <netgraph/ng_tty.h>
76258945Sroberto#include <netgraph/ng_vjc.h>
77258945Sroberto#ifdef	WHISTLE
78258945Sroberto#include <machine/../isa/df_def.h>
79258945Sroberto#include <machine/../isa/if_wfra.h>
80258945Sroberto#include <machine/../isa/ipac.h>
81258945Sroberto#include <netgraph/ng_df.h>
82258945Sroberto#include <netgraph/ng_ipac.h>
83258945Sroberto#include <netgraph/ng_mppc.h>
84258945Sroberto#include <netgraph/ng_pptpgre.h>
85258945Sroberto#include <netgraph/ng_tn.h>
86280849Scy#endif
87280849Scy
88280849Scy/* Global debug level */
89280849Scyint     _gNgDebugLevel = 0;
90258945Sroberto
91280849Scy/* Debug printing functions */
92258945Srobertovoid    (*_NgLog) (const char *fmt,...) = warn;
93258945Srobertovoid    (*_NgLogx) (const char *fmt,...) = warnx;
94258945Sroberto
95258945Sroberto/* Internal functions */
96258945Srobertostatic const	char *NgCookie(int cookie);
97258945Sroberto
98280849Scy/* Known typecookie list */
99280849Scystruct ng_cookie {
100280849Scy	int		cookie;
101280849Scy	const char	*type;
102280849Scy};
103258945Sroberto
104280849Scy#define COOKIE(c)	{ NGM_ ## c ## _COOKIE, #c }
105280849Scy
106280849Scy/* List of known cookies */
107280849Scystatic const struct ng_cookie cookies[] = {
108280849Scy	COOKIE(UI),
109280849Scy	COOKIE(ASYNC),
110280849Scy	COOKIE(BPF),
111280849Scy	COOKIE(CISCO),
112280849Scy	COOKIE(ECHO),
113280849Scy	COOKIE(ETHER),
114280849Scy	COOKIE(FRAMERELAY),
115280849Scy	COOKIE(GENERIC),
116280849Scy	COOKIE(HOLE),
117280849Scy	COOKIE(IFACE),
118280849Scy	COOKIE(KSOCKET),
119280849Scy	COOKIE(LMI),
120280849Scy	COOKIE(PPP),
121280849Scy	COOKIE(PPPOE),
122280849Scy	COOKIE(RFC1490),
123280849Scy	COOKIE(SOCKET),
124280849Scy	COOKIE(TEE),
125280849Scy	COOKIE(TTY),
126280849Scy	COOKIE(VJC),
127280849Scy#ifdef WHISTLE
128280849Scy	COOKIE(DF),
129280849Scy	COOKIE(IPAC),
130282408Scy	COOKIE(MPPC),
131282408Scy	COOKIE(PPTPGRE),
132258945Sroberto	COOKIE(TN),
133258945Sroberto	COOKIE(WFRA),
134280849Scy#endif
135280849Scy	{ 0, NULL }
136258945Sroberto};
137258945Sroberto
138280849Scy/*
139280849Scy * Set debug level, ie, verbosity, if "level" is non-negative.
140280849Scy * Returns old debug level.
141280849Scy */
142280849Scyint
143280849ScyNgSetDebug(int level)
144280849Scy{
145280849Scy	int old = _gNgDebugLevel;
146280849Scy
147280849Scy	if (level < 0)
148280849Scy		level = old;
149280849Scy	_gNgDebugLevel = level;
150280849Scy	return (old);
151280849Scy}
152280849Scy
153280849Scy/*
154280849Scy * Set debug logging functions.
155280849Scy */
156280849Scyvoid
157258945SrobertoNgSetErrLog(void (*log) (const char *fmt,...),
158258945Sroberto		void (*logx) (const char *fmt,...))
159258945Sroberto{
160258945Sroberto	_NgLog = log;
161280849Scy	_NgLogx = logx;
162258945Sroberto}
163258945Sroberto
164258945Sroberto/*
165258945Sroberto * Display a netgraph sockaddr
166280849Scy */
167258945Srobertovoid
168280849Scy_NgDebugSockaddr(const struct sockaddr_ng *sg)
169280849Scy{
170258945Sroberto	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
171280849Scy	       sg->sg_family, sg->sg_len, sg->sg_data);
172280849Scy}
173280849Scy
174280849Scy#define ARGS_BUFSIZE	1024
175280849Scy
176280849Scy/*
177280849Scy * Display a negraph message
178280849Scy */
179282408Scyvoid
180280849Scy_NgDebugMsg(const struct ng_mesg *msg, const char *path)
181258945Sroberto{
182258945Sroberto	u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
183258945Sroberto	struct ng_mesg *const req = (struct ng_mesg *)buf;
184280849Scy	struct ng_mesg *const bin = (struct ng_mesg *)req->data;
185258945Sroberto	int arglen, debugSave, csock = -1;
186280849Scy
187258945Sroberto	/* Lower debugging to avoid infinite recursion */
188280849Scy	debugSave = _gNgDebugLevel;
189258945Sroberto	_gNgDebugLevel -= 4;
190280849Scy
191280849Scy	/* Display header stuff */
192280849Scy	NGLOGX("NG_MESG :");
193280849Scy	NGLOGX("  vers   %d", msg->header.version);
194280849Scy	NGLOGX("  arglen %d", msg->header.arglen);
195280849Scy	NGLOGX("  flags  %ld", msg->header.flags);
196280849Scy	NGLOGX("  token  %lu", (u_long)msg->header.token);
197280849Scy	NGLOGX("  cookie %s (%d)",
198280849Scy	    NgCookie(msg->header.typecookie), msg->header.typecookie);
199280849Scy
200280849Scy	/* At lower debugging levels, skip ASCII translation */
201280849Scy	if (_gNgDebugLevel <= 2)
202280849Scy		goto fail2;
203280849Scy
204280849Scy	/* If path is not absolute, don't bother trying to use relative
205280849Scy	   address on a different socket for the ASCII translation */
206280849Scy	if (strchr(path, ':') == NULL)
207280849Scy		goto fail2;
208280849Scy
209280849Scy	/* Get a temporary socket */
210280849Scy	if (NgMkSockNode(NULL, &csock, NULL) < 0)
211280849Scy		goto fail;
212280849Scy
213280849Scy	/* Copy binary message into request message payload */
214280849Scy	arglen = msg->header.arglen;
215280849Scy	if (arglen > ARGS_BUFSIZE)
216280849Scy		arglen = ARGS_BUFSIZE;
217280849Scy	memcpy(bin, msg, sizeof(*msg) + arglen);
218280849Scy	bin->header.arglen = arglen;
219280849Scy
220258945Sroberto	/* Ask the node to translate the binary message to ASCII for us */
221258945Sroberto	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
222258945Sroberto	    NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0)
223258945Sroberto		goto fail;
224258945Sroberto	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0)
225258945Sroberto		goto fail;
226258945Sroberto
227258945Sroberto	/* Display command string and arguments */
228258945Sroberto	NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
229258945Sroberto	NGLOGX("  args   %s", bin->data);
230280849Scy	goto done;
231258945Sroberto
232258945Srobertofail:
233258945Sroberto	/* Just display binary version */
234280849Scy	NGLOGX("  [error decoding message: %s]", strerror(errno));
235258945Srobertofail2:
236258945Sroberto	NGLOGX("  cmd    %d", msg->header.cmd);
237258945Sroberto	NGLOGX("  args (%d bytes)", msg->header.arglen);
238258945Sroberto	_NgDebugBytes(msg->data, msg->header.arglen);
239258945Sroberto
240280849Scydone:
241258945Sroberto	if (csock != -1)
242280849Scy		(void)close(csock);
243280849Scy	_gNgDebugLevel = debugSave;
244258945Sroberto}
245280849Scy
246258945Sroberto/*
247258945Sroberto * Return the name of the node type corresponding to the cookie
248280849Scy */
249258945Srobertostatic const char *
250258945SrobertoNgCookie(int cookie)
251280849Scy{
252280849Scy	int k;
253258945Sroberto
254258945Sroberto	for (k = 0; cookies[k].cookie != 0; k++) {
255280849Scy		if (cookies[k].cookie == cookie)
256280849Scy			return cookies[k].type;
257258945Sroberto	}
258258945Sroberto	return "??";
259258945Sroberto}
260258945Sroberto
261280849Scy/*
262258945Sroberto * Dump bytes in hex
263280849Scy */
264280849Scyvoid
265258945Sroberto_NgDebugBytes(const u_char *ptr, int len)
266280849Scy{
267280849Scy	char    buf[100];
268280849Scy	int     k, count;
269280849Scy
270280849Scy#define BYPERLINE	16
271280849Scy
272280849Scy	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
273280849Scy
274258945Sroberto		/* Do hex */
275258945Sroberto		snprintf(buf, sizeof(buf), "%04x:  ", count);
276280849Scy		for (k = 0; k < BYPERLINE; k++, count++)
277280849Scy			if (count < len)
278258945Sroberto				snprintf(buf + strlen(buf),
279258945Sroberto				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
280258945Sroberto			else
281258945Sroberto				snprintf(buf + strlen(buf),
282280849Scy				    sizeof(buf) - strlen(buf), "   ");
283258945Sroberto		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
284280849Scy		count -= BYPERLINE;
285280849Scy
286280849Scy		/* Do ASCII */
287280849Scy		for (k = 0; k < BYPERLINE; k++, count++)
288280849Scy			if (count < len)
289280849Scy				snprintf(buf + strlen(buf),
290280849Scy				    sizeof(buf) - strlen(buf),
291258945Sroberto				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
292258945Sroberto			else
293280849Scy				snprintf(buf + strlen(buf),
294280849Scy				    sizeof(buf) - strlen(buf), "  ");
295258945Sroberto		count -= BYPERLINE;
296258945Sroberto
297258945Sroberto		/* Print it */
298258945Sroberto		NGLOGX("%s", buf);
299280849Scy	}
300258945Sroberto}
301280849Scy
302280849Scy