debug.c revision 54100
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 54100 1999-12-03 23:15:33Z archie $
40 * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
41 */
42
43#include <sys/types.h>
44#include <sys/time.h>
45#include <sys/ioctl.h>
46
47#include <stdarg.h>
48
49#include <netinet/in.h>
50#include <net/ethernet.h>
51#include <net/bpf.h>
52
53#include <netgraph/ng_message.h>
54#include <netgraph/ng_socket.h>
55
56#include "netgraph.h"
57#include "internal.h"
58
59#include <netgraph/ng_UI.h>
60#include <netgraph/ng_async.h>
61#include <netgraph/ng_bpf.h>
62#include <netgraph/ng_cisco.h>
63#include <netgraph/ng_echo.h>
64#include <netgraph/ng_ether.h>
65#include <netgraph/ng_frame_relay.h>
66#include <netgraph/ng_hole.h>
67#include <netgraph/ng_iface.h>
68#include <netgraph/ng_ksocket.h>
69#include <netgraph/ng_lmi.h>
70#include <netgraph/ng_ppp.h>
71#include <netgraph/ng_pppoe.h>
72#include <netgraph/ng_rfc1490.h>
73#include <netgraph/ng_socket.h>
74#include <netgraph/ng_tee.h>
75#include <netgraph/ng_tty.h>
76#include <netgraph/ng_vjc.h>
77#ifdef	WHISTLE
78#include <machine/../isa/df_def.h>
79#include <machine/../isa/if_wfra.h>
80#include <machine/../isa/ipac.h>
81#include <netgraph/ng_df.h>
82#include <netgraph/ng_ipac.h>
83#include <netgraph/ng_mppc.h>
84#include <netgraph/ng_pptpgre.h>
85#include <netgraph/ng_tn.h>
86#endif
87
88/* Global debug level */
89int     _gNgDebugLevel = 0;
90
91/* Debug printing functions */
92void    (*_NgLog) (const char *fmt,...) = warn;
93void    (*_NgLogx) (const char *fmt,...) = warnx;
94
95/* Internal functions */
96static const	char *NgCookie(int cookie);
97
98/* Known typecookie list */
99struct ng_cookie {
100	int		cookie;
101	const char	*type;
102};
103
104#define COOKIE(c)	{ NGM_ ## c ## _COOKIE, #c }
105
106/* List of known cookies */
107static const struct ng_cookie cookies[] = {
108	COOKIE(UI),
109	COOKIE(ASYNC),
110	COOKIE(BPF),
111	COOKIE(CISCO),
112	COOKIE(ECHO),
113	COOKIE(ETHER),
114	COOKIE(FRAMERELAY),
115	COOKIE(GENERIC),
116	COOKIE(HOLE),
117	COOKIE(IFACE),
118	COOKIE(KSOCKET),
119	COOKIE(LMI),
120	COOKIE(PPP),
121	COOKIE(PPPOE),
122	COOKIE(RFC1490),
123	COOKIE(SOCKET),
124	COOKIE(TEE),
125	COOKIE(TTY),
126	COOKIE(VJC),
127#ifdef WHISTLE
128	COOKIE(DF),
129	COOKIE(IPAC),
130	COOKIE(MPPC),
131	COOKIE(PPTPGRE),
132	COOKIE(TN),
133	COOKIE(WFRA),
134#endif
135	{ 0, NULL }
136};
137
138/*
139 * Set debug level, ie, verbosity, if "level" is non-negative.
140 * Returns old debug level.
141 */
142int
143NgSetDebug(int level)
144{
145	int old = _gNgDebugLevel;
146
147	if (level < 0)
148		level = old;
149	_gNgDebugLevel = level;
150	return (old);
151}
152
153/*
154 * Set debug logging functions.
155 */
156void
157NgSetErrLog(void (*log) (const char *fmt,...),
158		void (*logx) (const char *fmt,...))
159{
160	_NgLog = log;
161	_NgLogx = logx;
162}
163
164/*
165 * Display a netgraph sockaddr
166 */
167void
168_NgDebugSockaddr(const struct sockaddr_ng *sg)
169{
170	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
171	       sg->sg_family, sg->sg_len, sg->sg_data);
172}
173
174#define ARGS_BUFSIZE	1024
175
176/*
177 * Display a negraph message
178 */
179void
180_NgDebugMsg(const struct ng_mesg *msg, const char *path)
181{
182	u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
183	struct ng_mesg *const req = (struct ng_mesg *)buf;
184	struct ng_mesg *const bin = (struct ng_mesg *)req->data;
185	int arglen, debugSave, csock = -1;
186
187	/* Lower debugging to avoid infinite recursion */
188	debugSave = _gNgDebugLevel;
189	_gNgDebugLevel -= 4;
190
191	/* Display header stuff */
192	NGLOGX("NG_MESG :");
193	NGLOGX("  vers   %d", msg->header.version);
194	NGLOGX("  arglen %d", msg->header.arglen);
195	NGLOGX("  flags  %ld", msg->header.flags);
196	NGLOGX("  token  %lu", (u_long)msg->header.token);
197	NGLOGX("  cookie %s (%d)",
198	    NgCookie(msg->header.typecookie), msg->header.typecookie);
199
200	/* At lower debugging levels, skip ASCII translation */
201	if (_gNgDebugLevel <= 2)
202		goto fail2;
203
204	/* If path is not absolute, don't bother trying to use relative
205	   address on a different socket for the ASCII translation */
206	if (strchr(path, ':') == NULL)
207		goto fail2;
208
209	/* Get a temporary socket */
210	if (NgMkSockNode(NULL, &csock, NULL) < 0)
211		goto fail;
212
213	/* Copy binary message into request message payload */
214	arglen = msg->header.arglen;
215	if (arglen > ARGS_BUFSIZE)
216		arglen = ARGS_BUFSIZE;
217	memcpy(bin, msg, sizeof(*msg) + arglen);
218	bin->header.arglen = arglen;
219
220	/* Ask the node to translate the binary message to ASCII for us */
221	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
222	    NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0)
223		goto fail;
224	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0)
225		goto fail;
226
227	/* Display command string and arguments */
228	NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
229	NGLOGX("  args   %s", bin->data);
230	goto done;
231
232fail:
233	/* Just display binary version */
234	NGLOGX("  [error decoding message: %s]", strerror(errno));
235fail2:
236	NGLOGX("  cmd    %d", msg->header.cmd);
237	NGLOGX("  args (%d bytes)", msg->header.arglen);
238	_NgDebugBytes(msg->data, msg->header.arglen);
239
240done:
241	if (csock != -1)
242		(void)close(csock);
243	_gNgDebugLevel = debugSave;
244}
245
246/*
247 * Return the name of the node type corresponding to the cookie
248 */
249static const char *
250NgCookie(int cookie)
251{
252	int k;
253
254	for (k = 0; cookies[k].cookie != 0; k++) {
255		if (cookies[k].cookie == cookie)
256			return cookies[k].type;
257	}
258	return "??";
259}
260
261/*
262 * Dump bytes in hex
263 */
264void
265_NgDebugBytes(const u_char *ptr, int len)
266{
267	char    buf[100];
268	int     k, count;
269
270#define BYPERLINE	16
271
272	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
273
274		/* Do hex */
275		snprintf(buf, sizeof(buf), "%04x:  ", count);
276		for (k = 0; k < BYPERLINE; k++, count++)
277			if (count < len)
278				snprintf(buf + strlen(buf),
279				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
280			else
281				snprintf(buf + strlen(buf),
282				    sizeof(buf) - strlen(buf), "   ");
283		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
284		count -= BYPERLINE;
285
286		/* Do ASCII */
287		for (k = 0; k < BYPERLINE; k++, count++)
288			if (count < len)
289				snprintf(buf + strlen(buf),
290				    sizeof(buf) - strlen(buf),
291				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
292			else
293				snprintf(buf + strlen(buf),
294				    sizeof(buf) - strlen(buf), "  ");
295		count -= BYPERLINE;
296
297		/* Print it */
298		NGLOGX("%s", buf);
299	}
300}
301
302