debug.c revision 53913
152419Sjulian
252419Sjulian/*
352419Sjulian * debug.c
452419Sjulian *
552419Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc.
652419Sjulian * All rights reserved.
752419Sjulian *
852419Sjulian * Subject to the following obligations and disclaimer of warranty, use and
952419Sjulian * redistribution of this software, in source or object code forms, with or
1052419Sjulian * without modifications are expressly permitted by Whistle Communications;
1152419Sjulian * provided, however, that:
1252419Sjulian * 1. Any and all reproductions of the source or object code must include the
1352419Sjulian *    copyright notice above and the following disclaimer of warranties; and
1452419Sjulian * 2. No rights are granted, in any manner or form, to use Whistle
1552419Sjulian *    Communications, Inc. trademarks, including the mark "WHISTLE
1652419Sjulian *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
1752419Sjulian *    such appears in the above copyright notice or in the software.
1852419Sjulian *
1952419Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
2052419Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
2152419Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
2252419Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
2352419Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
2452419Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
2552419Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
2652419Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
2752419Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
2852419Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
2952419Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
3052419Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
3152419Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
3252419Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3352419Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3452419Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
3552419Sjulian * OF SUCH DAMAGE.
3652419Sjulian *
3752419Sjulian * Author: Archie Cobbs <archie@whistle.com>
3852419Sjulian *
3952419Sjulian * $FreeBSD: head/lib/libnetgraph/debug.c 53913 1999-11-30 02:45:32Z archie $
4052419Sjulian * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
4152419Sjulian */
4252419Sjulian
4352419Sjulian#include <sys/types.h>
4453913Sarchie
4552419Sjulian#include <stdarg.h>
4653913Sarchie
4753913Sarchie#include <netinet/in.h>
4853913Sarchie#include <net/ethernet.h>
4953913Sarchie
5052419Sjulian#include <netgraph/ng_message.h>
5152419Sjulian#include <netgraph/ng_socket.h>
5252419Sjulian
5352419Sjulian#include "netgraph.h"
5452419Sjulian#include "internal.h"
5552419Sjulian
5653913Sarchie#include <netgraph/ng_UI.h>
5753913Sarchie#include <netgraph/ng_async.h>
5852419Sjulian#include <netgraph/ng_cisco.h>
5953913Sarchie#include <netgraph/ng_echo.h>
6053913Sarchie#include <netgraph/ng_ether.h>
6152419Sjulian#include <netgraph/ng_frame_relay.h>
6253913Sarchie#include <netgraph/ng_hole.h>
6353913Sarchie#include <netgraph/ng_iface.h>
6453913Sarchie#include <netgraph/ng_ksocket.h>
6552419Sjulian#include <netgraph/ng_lmi.h>
6653913Sarchie#include <netgraph/ng_ppp.h>
6753913Sarchie#include <netgraph/ng_pppoe.h>
6853913Sarchie#include <netgraph/ng_rfc1490.h>
6953913Sarchie#include <netgraph/ng_socket.h>
7053913Sarchie#include <netgraph/ng_tee.h>
7152419Sjulian#include <netgraph/ng_tty.h>
7253913Sarchie#include <netgraph/ng_vjc.h>
7353913Sarchie#ifdef	WHISTLE
7453913Sarchie#include <machine/../isa/df_def.h>
7553913Sarchie#include <machine/../isa/if_wfra.h>
7653913Sarchie#include <machine/../isa/ipac.h>
7753913Sarchie#include <netgraph/ng_df.h>
7853913Sarchie#include <netgraph/ng_ipac.h>
7953913Sarchie#include <netgraph/ng_mppc.h>
8053913Sarchie#include <netgraph/ng_pptpgre.h>
8153913Sarchie#include <netgraph/ng_tn.h>
8253913Sarchie#endif
8352419Sjulian
8452419Sjulian/* Global debug level */
8552419Sjulianint     _gNgDebugLevel = 0;
8652419Sjulian
8752419Sjulian/* Debug printing functions */
8852419Sjulianvoid    (*_NgLog) (const char *fmt,...) = warn;
8952419Sjulianvoid    (*_NgLogx) (const char *fmt,...) = warnx;
9052419Sjulian
9152419Sjulian/* Internal functions */
9252419Sjulianstatic const	char *NgCookie(int cookie);
9352419Sjulian
9453913Sarchie/* Known typecookie list */
9553913Sarchiestruct ng_cookie {
9653913Sarchie	int		cookie;
9753913Sarchie	const char	*type;
9853913Sarchie};
9953913Sarchie
10053913Sarchie#define COOKIE(c)	{ NGM_ ## c ## _COOKIE, #c }
10153913Sarchie
10253913Sarchie/* List of known cookies */
10353913Sarchiestatic const struct ng_cookie cookies[] = {
10453913Sarchie	COOKIE(UI),
10553913Sarchie	COOKIE(ASYNC),
10653913Sarchie	COOKIE(CISCO),
10753913Sarchie	COOKIE(ECHO),
10853913Sarchie	COOKIE(ETHER),
10953913Sarchie	COOKIE(FRAMERELAY),
11053913Sarchie	COOKIE(GENERIC),
11153913Sarchie	COOKIE(HOLE),
11253913Sarchie	COOKIE(IFACE),
11353913Sarchie	COOKIE(KSOCKET),
11453913Sarchie	COOKIE(LMI),
11553913Sarchie	COOKIE(PPP),
11653913Sarchie	COOKIE(PPPOE),
11753913Sarchie	COOKIE(RFC1490),
11853913Sarchie	COOKIE(SOCKET),
11953913Sarchie	COOKIE(TEE),
12053913Sarchie	COOKIE(TTY),
12153913Sarchie	COOKIE(VJC),
12253913Sarchie#ifdef WHISTLE
12353913Sarchie	COOKIE(DF),
12453913Sarchie	COOKIE(IPAC),
12553913Sarchie	COOKIE(MPPC),
12653913Sarchie	COOKIE(PPTPGRE),
12753913Sarchie	COOKIE(TN),
12853913Sarchie	COOKIE(WFRA),
12953913Sarchie#endif
13053913Sarchie	{ 0, NULL }
13153913Sarchie};
13253913Sarchie
13352419Sjulian/*
13452419Sjulian * Set debug level, ie, verbosity, if "level" is non-negative.
13552419Sjulian * Returns old debug level.
13652419Sjulian */
13752419Sjulianint
13852419SjulianNgSetDebug(int level)
13952419Sjulian{
14052419Sjulian	int old = _gNgDebugLevel;
14152419Sjulian
14252419Sjulian	if (level < 0)
14352419Sjulian		level = old;
14452419Sjulian	_gNgDebugLevel = level;
14552419Sjulian	return (old);
14652419Sjulian}
14752419Sjulian
14852419Sjulian/*
14952419Sjulian * Set debug logging functions.
15052419Sjulian */
15152419Sjulianvoid
15252419SjulianNgSetErrLog(void (*log) (const char *fmt,...),
15352419Sjulian		void (*logx) (const char *fmt,...))
15452419Sjulian{
15552419Sjulian	_NgLog = log;
15652419Sjulian	_NgLogx = logx;
15752419Sjulian}
15852419Sjulian
15952419Sjulian/*
16052419Sjulian * Display a netgraph sockaddr
16152419Sjulian */
16252419Sjulianvoid
16353913Sarchie_NgDebugSockaddr(const struct sockaddr_ng *sg)
16452419Sjulian{
16552419Sjulian	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
16652419Sjulian	       sg->sg_family, sg->sg_len, sg->sg_data);
16752419Sjulian}
16852419Sjulian
16953913Sarchie#define ARGS_BUFSIZE	1024
17053913Sarchie
17152419Sjulian/*
17252419Sjulian * Display a negraph message
17352419Sjulian */
17452419Sjulianvoid
17553913Sarchie_NgDebugMsg(const struct ng_mesg *msg, const char *path)
17652419Sjulian{
17753913Sarchie	u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
17853913Sarchie	struct ng_mesg *const req = (struct ng_mesg *)buf;
17953913Sarchie	struct ng_mesg *const bin = (struct ng_mesg *)req->data;
18053913Sarchie	int arglen, debugSave, csock = -1;
18153913Sarchie
18253913Sarchie	/* Lower debugging to avoid infinite recursion */
18353913Sarchie	debugSave = _gNgDebugLevel;
18453913Sarchie	_gNgDebugLevel -= 4;
18553913Sarchie
18653913Sarchie	/* Display header stuff */
18752419Sjulian	NGLOGX("NG_MESG :");
18852419Sjulian	NGLOGX("  vers   %d", msg->header.version);
18952419Sjulian	NGLOGX("  arglen %d", msg->header.arglen);
19052419Sjulian	NGLOGX("  flags  %ld", msg->header.flags);
19153913Sarchie	NGLOGX("  token  %lu", (u_long)msg->header.token);
19253913Sarchie	NGLOGX("  cookie %s (%d)",
19353913Sarchie	    NgCookie(msg->header.typecookie), msg->header.typecookie);
19452419Sjulian
19553913Sarchie	/* At lower debugging levels, skip ASCII translation */
19653913Sarchie	if (_gNgDebugLevel <= 2)
19753913Sarchie		goto fail2;
19852419Sjulian
19953913Sarchie	/* If path is not absolute, don't bother trying to use relative
20053913Sarchie	   address on a different socket for the ASCII translation */
20153913Sarchie	if (strchr(path, ':') == NULL)
20253913Sarchie		goto fail2;
20352419Sjulian
20453913Sarchie	/* Get a temporary socket */
20553913Sarchie	if (NgMkSockNode(NULL, &csock, NULL) < 0)
20653913Sarchie		goto fail;
20752419Sjulian
20853913Sarchie	/* Copy binary message into request message payload */
20953913Sarchie	arglen = msg->header.arglen;
21053913Sarchie	if (arglen > ARGS_BUFSIZE)
21153913Sarchie		arglen = ARGS_BUFSIZE;
21253913Sarchie	memcpy(bin, msg, sizeof(*msg) + arglen);
21353913Sarchie	bin->header.arglen = arglen;
21453913Sarchie
21553913Sarchie	/* Ask the node to translate the binary message to ASCII for us */
21653913Sarchie	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
21753913Sarchie	    NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0)
21853913Sarchie		goto fail;
21953913Sarchie	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0)
22053913Sarchie		goto fail;
22153913Sarchie
22253913Sarchie	/* Display command string and arguments */
22353913Sarchie	NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
22453913Sarchie	NGLOGX("  args   %s", bin->data);
22553913Sarchie	goto done;
22653913Sarchie
22753913Sarchiefail:
22853913Sarchie	/* Just display binary version */
22953913Sarchie	NGLOGX("  [error decoding message: %s]", strerror(errno));
23053913Sarchiefail2:
23153913Sarchie	NGLOGX("  cmd    %d", msg->header.cmd);
23253913Sarchie	NGLOGX("  args (%d bytes)", msg->header.arglen);
23353913Sarchie	_NgDebugBytes(msg->data, msg->header.arglen);
23453913Sarchie
23553913Sarchiedone:
23653913Sarchie	if (csock != -1)
23753913Sarchie		(void)close(csock);
23853913Sarchie	_gNgDebugLevel = debugSave;
23952419Sjulian}
24052419Sjulian
24152419Sjulian/*
24253913Sarchie * Return the name of the node type corresponding to the cookie
24352419Sjulian */
24453913Sarchiestatic const char *
24553913SarchieNgCookie(int cookie)
24652419Sjulian{
24753913Sarchie	int k;
24852419Sjulian
24953913Sarchie	for (k = 0; cookies[k].cookie != 0; k++) {
25053913Sarchie		if (cookies[k].cookie == cookie)
25153913Sarchie			return cookies[k].type;
25252419Sjulian	}
25353913Sarchie	return "??";
25452419Sjulian}
25552419Sjulian
25652419Sjulian/*
25752419Sjulian * Dump bytes in hex
25852419Sjulian */
25952419Sjulianvoid
26053913Sarchie_NgDebugBytes(const u_char *ptr, int len)
26152419Sjulian{
26252419Sjulian	char    buf[100];
26352419Sjulian	int     k, count;
26452419Sjulian
26552419Sjulian#define BYPERLINE	16
26652419Sjulian
26752419Sjulian	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
26852419Sjulian
26952419Sjulian		/* Do hex */
27052419Sjulian		snprintf(buf, sizeof(buf), "%04x:  ", count);
27152419Sjulian		for (k = 0; k < BYPERLINE; k++, count++)
27252419Sjulian			if (count < len)
27352419Sjulian				snprintf(buf + strlen(buf),
27452419Sjulian				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
27552419Sjulian			else
27652419Sjulian				snprintf(buf + strlen(buf),
27752419Sjulian				    sizeof(buf) - strlen(buf), "   ");
27852419Sjulian		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
27952419Sjulian		count -= BYPERLINE;
28052419Sjulian
28152419Sjulian		/* Do ASCII */
28252419Sjulian		for (k = 0; k < BYPERLINE; k++, count++)
28352419Sjulian			if (count < len)
28452419Sjulian				snprintf(buf + strlen(buf),
28552419Sjulian				    sizeof(buf) - strlen(buf),
28652419Sjulian				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
28752419Sjulian			else
28852419Sjulian				snprintf(buf + strlen(buf),
28952419Sjulian				    sizeof(buf) - strlen(buf), "  ");
29052419Sjulian		count -= BYPERLINE;
29152419Sjulian
29252419Sjulian		/* Print it */
29352419Sjulian		NGLOGX("%s", buf);
29452419Sjulian	}
29552419Sjulian}
29652419Sjulian
297