debug.c revision 54098
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: head/lib/libnetgraph/debug.c 54098 1999-12-03 23:12:41Z archie $
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 */
85int     _gNgDebugLevel = 0;
86
87/* Debug printing functions */
88void    (*_NgLog) (const char *fmt,...) = warn;
89void    (*_NgLogx) (const char *fmt,...) = warnx;
90
91/* Internal functions */
92static const	char *NgCookie(int cookie);
93
94/* Known typecookie list */
95struct 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 */
103static 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 */
138int
139NgSetDebug(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 */
152void
153NgSetErrLog(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 */
163void
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 */
175void
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
228fail:
229	/* Just display binary version */
230	NGLOGX("  [error decoding message: %s]", strerror(errno));
231fail2:
232	NGLOGX("  cmd    %d", msg->header.cmd);
233	NGLOGX("  args (%d bytes)", msg->header.arglen);
234	_NgDebugBytes(msg->data, msg->header.arglen);
235
236done:
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 */
245static const char *
246NgCookie(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 */
260void
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