debug.c revision 54098
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 54098 1999-12-03 23:12:41Z 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),
10654098Sarchie	COOKIE(BPF),
10753913Sarchie	COOKIE(CISCO),
10853913Sarchie	COOKIE(ECHO),
10953913Sarchie	COOKIE(ETHER),
11053913Sarchie	COOKIE(FRAMERELAY),
11153913Sarchie	COOKIE(GENERIC),
11253913Sarchie	COOKIE(HOLE),
11353913Sarchie	COOKIE(IFACE),
11453913Sarchie	COOKIE(KSOCKET),
11553913Sarchie	COOKIE(LMI),
11653913Sarchie	COOKIE(PPP),
11753913Sarchie	COOKIE(PPPOE),
11853913Sarchie	COOKIE(RFC1490),
11953913Sarchie	COOKIE(SOCKET),
12053913Sarchie	COOKIE(TEE),
12153913Sarchie	COOKIE(TTY),
12253913Sarchie	COOKIE(VJC),
12353913Sarchie#ifdef WHISTLE
12453913Sarchie	COOKIE(DF),
12553913Sarchie	COOKIE(IPAC),
12653913Sarchie	COOKIE(MPPC),
12753913Sarchie	COOKIE(PPTPGRE),
12853913Sarchie	COOKIE(TN),
12953913Sarchie	COOKIE(WFRA),
13053913Sarchie#endif
13153913Sarchie	{ 0, NULL }
13253913Sarchie};
13353913Sarchie
13452419Sjulian/*
13552419Sjulian * Set debug level, ie, verbosity, if "level" is non-negative.
13652419Sjulian * Returns old debug level.
13752419Sjulian */
13852419Sjulianint
13952419SjulianNgSetDebug(int level)
14052419Sjulian{
14152419Sjulian	int old = _gNgDebugLevel;
14252419Sjulian
14352419Sjulian	if (level < 0)
14452419Sjulian		level = old;
14552419Sjulian	_gNgDebugLevel = level;
14652419Sjulian	return (old);
14752419Sjulian}
14852419Sjulian
14952419Sjulian/*
15052419Sjulian * Set debug logging functions.
15152419Sjulian */
15252419Sjulianvoid
15352419SjulianNgSetErrLog(void (*log) (const char *fmt,...),
15452419Sjulian		void (*logx) (const char *fmt,...))
15552419Sjulian{
15652419Sjulian	_NgLog = log;
15752419Sjulian	_NgLogx = logx;
15852419Sjulian}
15952419Sjulian
16052419Sjulian/*
16152419Sjulian * Display a netgraph sockaddr
16252419Sjulian */
16352419Sjulianvoid
16453913Sarchie_NgDebugSockaddr(const struct sockaddr_ng *sg)
16552419Sjulian{
16652419Sjulian	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
16752419Sjulian	       sg->sg_family, sg->sg_len, sg->sg_data);
16852419Sjulian}
16952419Sjulian
17053913Sarchie#define ARGS_BUFSIZE	1024
17153913Sarchie
17252419Sjulian/*
17352419Sjulian * Display a negraph message
17452419Sjulian */
17552419Sjulianvoid
17653913Sarchie_NgDebugMsg(const struct ng_mesg *msg, const char *path)
17752419Sjulian{
17853913Sarchie	u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
17953913Sarchie	struct ng_mesg *const req = (struct ng_mesg *)buf;
18053913Sarchie	struct ng_mesg *const bin = (struct ng_mesg *)req->data;
18153913Sarchie	int arglen, debugSave, csock = -1;
18253913Sarchie
18353913Sarchie	/* Lower debugging to avoid infinite recursion */
18453913Sarchie	debugSave = _gNgDebugLevel;
18553913Sarchie	_gNgDebugLevel -= 4;
18653913Sarchie
18753913Sarchie	/* Display header stuff */
18852419Sjulian	NGLOGX("NG_MESG :");
18952419Sjulian	NGLOGX("  vers   %d", msg->header.version);
19052419Sjulian	NGLOGX("  arglen %d", msg->header.arglen);
19152419Sjulian	NGLOGX("  flags  %ld", msg->header.flags);
19253913Sarchie	NGLOGX("  token  %lu", (u_long)msg->header.token);
19353913Sarchie	NGLOGX("  cookie %s (%d)",
19453913Sarchie	    NgCookie(msg->header.typecookie), msg->header.typecookie);
19552419Sjulian
19653913Sarchie	/* At lower debugging levels, skip ASCII translation */
19753913Sarchie	if (_gNgDebugLevel <= 2)
19853913Sarchie		goto fail2;
19952419Sjulian
20053913Sarchie	/* If path is not absolute, don't bother trying to use relative
20153913Sarchie	   address on a different socket for the ASCII translation */
20253913Sarchie	if (strchr(path, ':') == NULL)
20353913Sarchie		goto fail2;
20452419Sjulian
20553913Sarchie	/* Get a temporary socket */
20653913Sarchie	if (NgMkSockNode(NULL, &csock, NULL) < 0)
20753913Sarchie		goto fail;
20852419Sjulian
20953913Sarchie	/* Copy binary message into request message payload */
21053913Sarchie	arglen = msg->header.arglen;
21153913Sarchie	if (arglen > ARGS_BUFSIZE)
21253913Sarchie		arglen = ARGS_BUFSIZE;
21353913Sarchie	memcpy(bin, msg, sizeof(*msg) + arglen);
21453913Sarchie	bin->header.arglen = arglen;
21553913Sarchie
21653913Sarchie	/* Ask the node to translate the binary message to ASCII for us */
21753913Sarchie	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
21853913Sarchie	    NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0)
21953913Sarchie		goto fail;
22053913Sarchie	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0)
22153913Sarchie		goto fail;
22253913Sarchie
22353913Sarchie	/* Display command string and arguments */
22453913Sarchie	NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
22553913Sarchie	NGLOGX("  args   %s", bin->data);
22653913Sarchie	goto done;
22753913Sarchie
22853913Sarchiefail:
22953913Sarchie	/* Just display binary version */
23053913Sarchie	NGLOGX("  [error decoding message: %s]", strerror(errno));
23153913Sarchiefail2:
23253913Sarchie	NGLOGX("  cmd    %d", msg->header.cmd);
23353913Sarchie	NGLOGX("  args (%d bytes)", msg->header.arglen);
23453913Sarchie	_NgDebugBytes(msg->data, msg->header.arglen);
23553913Sarchie
23653913Sarchiedone:
23753913Sarchie	if (csock != -1)
23853913Sarchie		(void)close(csock);
23953913Sarchie	_gNgDebugLevel = debugSave;
24052419Sjulian}
24152419Sjulian
24252419Sjulian/*
24353913Sarchie * Return the name of the node type corresponding to the cookie
24452419Sjulian */
24553913Sarchiestatic const char *
24653913SarchieNgCookie(int cookie)
24752419Sjulian{
24853913Sarchie	int k;
24952419Sjulian
25053913Sarchie	for (k = 0; cookies[k].cookie != 0; k++) {
25153913Sarchie		if (cookies[k].cookie == cookie)
25253913Sarchie			return cookies[k].type;
25352419Sjulian	}
25453913Sarchie	return "??";
25552419Sjulian}
25652419Sjulian
25752419Sjulian/*
25852419Sjulian * Dump bytes in hex
25952419Sjulian */
26052419Sjulianvoid
26153913Sarchie_NgDebugBytes(const u_char *ptr, int len)
26252419Sjulian{
26352419Sjulian	char    buf[100];
26452419Sjulian	int     k, count;
26552419Sjulian
26652419Sjulian#define BYPERLINE	16
26752419Sjulian
26852419Sjulian	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
26952419Sjulian
27052419Sjulian		/* Do hex */
27152419Sjulian		snprintf(buf, sizeof(buf), "%04x:  ", count);
27252419Sjulian		for (k = 0; k < BYPERLINE; k++, count++)
27352419Sjulian			if (count < len)
27452419Sjulian				snprintf(buf + strlen(buf),
27552419Sjulian				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
27652419Sjulian			else
27752419Sjulian				snprintf(buf + strlen(buf),
27852419Sjulian				    sizeof(buf) - strlen(buf), "   ");
27952419Sjulian		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
28052419Sjulian		count -= BYPERLINE;
28152419Sjulian
28252419Sjulian		/* Do ASCII */
28352419Sjulian		for (k = 0; k < BYPERLINE; k++, count++)
28452419Sjulian			if (count < len)
28552419Sjulian				snprintf(buf + strlen(buf),
28652419Sjulian				    sizeof(buf) - strlen(buf),
28752419Sjulian				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
28852419Sjulian			else
28952419Sjulian				snprintf(buf + strlen(buf),
29052419Sjulian				    sizeof(buf) - strlen(buf), "  ");
29152419Sjulian		count -= BYPERLINE;
29252419Sjulian
29352419Sjulian		/* Print it */
29452419Sjulian		NGLOGX("%s", buf);
29552419Sjulian	}
29652419Sjulian}
29752419Sjulian
298