debug.c revision 53913
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 53913 1999-11-30 02:45:32Z 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(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 */
137int
138NgSetDebug(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 */
151void
152NgSetErrLog(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 */
162void
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 */
174void
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
227fail:
228	/* Just display binary version */
229	NGLOGX("  [error decoding message: %s]", strerror(errno));
230fail2:
231	NGLOGX("  cmd    %d", msg->header.cmd);
232	NGLOGX("  args (%d bytes)", msg->header.arglen);
233	_NgDebugBytes(msg->data, msg->header.arglen);
234
235done:
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 */
244static const char *
245NgCookie(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 */
259void
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