xref: /freebsd/lib/libnetgraph/debug.c (revision b92367948a1777de80dd7ee31a15a90df0b727bf)
14cf49a43SJulian Elischer /*
24cf49a43SJulian Elischer  * debug.c
34cf49a43SJulian Elischer  *
44cf49a43SJulian Elischer  * Copyright (c) 1996-1999 Whistle Communications, Inc.
54cf49a43SJulian Elischer  * All rights reserved.
64cf49a43SJulian Elischer  *
74cf49a43SJulian Elischer  * Subject to the following obligations and disclaimer of warranty, use and
84cf49a43SJulian Elischer  * redistribution of this software, in source or object code forms, with or
94cf49a43SJulian Elischer  * without modifications are expressly permitted by Whistle Communications;
104cf49a43SJulian Elischer  * provided, however, that:
114cf49a43SJulian Elischer  * 1. Any and all reproductions of the source or object code must include the
124cf49a43SJulian Elischer  *    copyright notice above and the following disclaimer of warranties; and
134cf49a43SJulian Elischer  * 2. No rights are granted, in any manner or form, to use Whistle
144cf49a43SJulian Elischer  *    Communications, Inc. trademarks, including the mark "WHISTLE
154cf49a43SJulian Elischer  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
164cf49a43SJulian Elischer  *    such appears in the above copyright notice or in the software.
174cf49a43SJulian Elischer  *
184cf49a43SJulian Elischer  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
194cf49a43SJulian Elischer  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
204cf49a43SJulian Elischer  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
214cf49a43SJulian Elischer  * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
224cf49a43SJulian Elischer  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
234cf49a43SJulian Elischer  * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
244cf49a43SJulian Elischer  * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
254cf49a43SJulian Elischer  * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
264cf49a43SJulian Elischer  * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
274cf49a43SJulian Elischer  * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
284cf49a43SJulian Elischer  * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
294cf49a43SJulian Elischer  * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
304cf49a43SJulian Elischer  * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
314cf49a43SJulian Elischer  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
324cf49a43SJulian Elischer  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
334cf49a43SJulian Elischer  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
344cf49a43SJulian Elischer  * OF SUCH DAMAGE.
354cf49a43SJulian Elischer  *
364cf49a43SJulian Elischer  * Author: Archie Cobbs <archie@whistle.com>
374cf49a43SJulian Elischer  *
384cf49a43SJulian Elischer  * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
394cf49a43SJulian Elischer  */
404cf49a43SJulian Elischer 
41fd0d00c5SMatthew Dillon #include <sys/cdefs.h>
42fd0d00c5SMatthew Dillon __FBSDID("$FreeBSD$");
43fd0d00c5SMatthew Dillon 
444cf49a43SJulian Elischer #include <sys/types.h>
45baa60a3bSArchie Cobbs #include <sys/time.h>
46baa60a3bSArchie Cobbs #include <sys/ioctl.h>
47f8307e12SArchie Cobbs 
484cf49a43SJulian Elischer #include <stdarg.h>
49f8307e12SArchie Cobbs 
50f8307e12SArchie Cobbs #include <netinet/in.h>
51f8307e12SArchie Cobbs #include <net/ethernet.h>
52baa60a3bSArchie Cobbs #include <net/bpf.h>
53f8307e12SArchie Cobbs 
544cf49a43SJulian Elischer #include <netgraph/ng_message.h>
554cf49a43SJulian Elischer #include <netgraph/ng_socket.h>
564cf49a43SJulian Elischer 
574cf49a43SJulian Elischer #include "netgraph.h"
584cf49a43SJulian Elischer #include "internal.h"
594cf49a43SJulian Elischer 
60f8307e12SArchie Cobbs #include <netgraph/ng_UI.h>
614cf49a43SJulian Elischer #include <netgraph/ng_async.h>
62baa60a3bSArchie Cobbs #include <netgraph/ng_bpf.h>
63f8307e12SArchie Cobbs #include <netgraph/ng_cisco.h>
64f8307e12SArchie Cobbs #include <netgraph/ng_echo.h>
65f8307e12SArchie Cobbs #include <netgraph/ng_ether.h>
664cf49a43SJulian Elischer #include <netgraph/ng_frame_relay.h>
67f8307e12SArchie Cobbs #include <netgraph/ng_hole.h>
68f8307e12SArchie Cobbs #include <netgraph/ng_iface.h>
69f8307e12SArchie Cobbs #include <netgraph/ng_ksocket.h>
704cf49a43SJulian Elischer #include <netgraph/ng_lmi.h>
71f8307e12SArchie Cobbs #include <netgraph/ng_ppp.h>
72f8307e12SArchie Cobbs #include <netgraph/ng_pppoe.h>
73f8307e12SArchie Cobbs #include <netgraph/ng_rfc1490.h>
74f8307e12SArchie Cobbs #include <netgraph/ng_socket.h>
75f8307e12SArchie Cobbs #include <netgraph/ng_tee.h>
764cf49a43SJulian Elischer #include <netgraph/ng_tty.h>
77f8307e12SArchie Cobbs #include <netgraph/ng_vjc.h>
78f8307e12SArchie Cobbs #ifdef	WHISTLE
79f8307e12SArchie Cobbs #include <machine/../isa/df_def.h>
80f8307e12SArchie Cobbs #include <machine/../isa/if_wfra.h>
81f8307e12SArchie Cobbs #include <machine/../isa/ipac.h>
82f8307e12SArchie Cobbs #include <netgraph/ng_df.h>
83f8307e12SArchie Cobbs #include <netgraph/ng_ipac.h>
84f8307e12SArchie Cobbs #include <netgraph/ng_mppc.h>
85f8307e12SArchie Cobbs #include <netgraph/ng_pptpgre.h>
86f8307e12SArchie Cobbs #include <netgraph/ng_tn.h>
87f8307e12SArchie Cobbs #endif
884cf49a43SJulian Elischer 
894cf49a43SJulian Elischer /* Global debug level */
904cf49a43SJulian Elischer int     _gNgDebugLevel = 0;
914cf49a43SJulian Elischer 
924cf49a43SJulian Elischer /* Debug printing functions */
934cf49a43SJulian Elischer void    (*_NgLog) (const char *fmt,...) = warn;
944cf49a43SJulian Elischer void    (*_NgLogx) (const char *fmt,...) = warnx;
954cf49a43SJulian Elischer 
964cf49a43SJulian Elischer /* Internal functions */
974cf49a43SJulian Elischer static const	char *NgCookie(int cookie);
98f8307e12SArchie Cobbs 
99f8307e12SArchie Cobbs /* Known typecookie list */
100f8307e12SArchie Cobbs struct ng_cookie {
101f8307e12SArchie Cobbs 	int		cookie;
102f8307e12SArchie Cobbs 	const char	*type;
103f8307e12SArchie Cobbs };
104f8307e12SArchie Cobbs 
105f8307e12SArchie Cobbs #define COOKIE(c)	{ NGM_ ## c ## _COOKIE, #c }
106f8307e12SArchie Cobbs 
107f8307e12SArchie Cobbs /* List of known cookies */
108f8307e12SArchie Cobbs static const struct ng_cookie cookies[] = {
109f8307e12SArchie Cobbs 	COOKIE(UI),
110f8307e12SArchie Cobbs 	COOKIE(ASYNC),
111e489a907SArchie Cobbs 	COOKIE(BPF),
112f8307e12SArchie Cobbs 	COOKIE(CISCO),
113f8307e12SArchie Cobbs 	COOKIE(ECHO),
114f8307e12SArchie Cobbs 	COOKIE(ETHER),
115f8307e12SArchie Cobbs 	COOKIE(FRAMERELAY),
116f8307e12SArchie Cobbs 	COOKIE(GENERIC),
117f8307e12SArchie Cobbs 	COOKIE(HOLE),
118f8307e12SArchie Cobbs 	COOKIE(IFACE),
119f8307e12SArchie Cobbs 	COOKIE(KSOCKET),
120f8307e12SArchie Cobbs 	COOKIE(LMI),
121f8307e12SArchie Cobbs 	COOKIE(PPP),
122f8307e12SArchie Cobbs 	COOKIE(PPPOE),
123f8307e12SArchie Cobbs 	COOKIE(RFC1490),
124f8307e12SArchie Cobbs 	COOKIE(SOCKET),
125f8307e12SArchie Cobbs 	COOKIE(TEE),
126f8307e12SArchie Cobbs 	COOKIE(TTY),
127f8307e12SArchie Cobbs 	COOKIE(VJC),
128f8307e12SArchie Cobbs #ifdef WHISTLE
129f8307e12SArchie Cobbs 	COOKIE(DF),
130f8307e12SArchie Cobbs 	COOKIE(IPAC),
131f8307e12SArchie Cobbs 	COOKIE(MPPC),
132f8307e12SArchie Cobbs 	COOKIE(PPTPGRE),
133f8307e12SArchie Cobbs 	COOKIE(TN),
134f8307e12SArchie Cobbs 	COOKIE(WFRA),
135f8307e12SArchie Cobbs #endif
136f8307e12SArchie Cobbs 	{ 0, NULL }
137f8307e12SArchie Cobbs };
1384cf49a43SJulian Elischer 
1394cf49a43SJulian Elischer /*
1404cf49a43SJulian Elischer  * Set debug level, ie, verbosity, if "level" is non-negative.
1414cf49a43SJulian Elischer  * Returns old debug level.
1424cf49a43SJulian Elischer  */
1434cf49a43SJulian Elischer int
1444cf49a43SJulian Elischer NgSetDebug(int level)
1454cf49a43SJulian Elischer {
1464cf49a43SJulian Elischer 	int old = _gNgDebugLevel;
1474cf49a43SJulian Elischer 
1484cf49a43SJulian Elischer 	if (level < 0)
1494cf49a43SJulian Elischer 		level = old;
1504cf49a43SJulian Elischer 	_gNgDebugLevel = level;
1514cf49a43SJulian Elischer 	return (old);
1524cf49a43SJulian Elischer }
1534cf49a43SJulian Elischer 
1544cf49a43SJulian Elischer /*
1554cf49a43SJulian Elischer  * Set debug logging functions.
1564cf49a43SJulian Elischer  */
1574cf49a43SJulian Elischer void
1584cf49a43SJulian Elischer NgSetErrLog(void (*log) (const char *fmt,...),
1594cf49a43SJulian Elischer 		void (*logx) (const char *fmt,...))
1604cf49a43SJulian Elischer {
1614cf49a43SJulian Elischer 	_NgLog = log;
1624cf49a43SJulian Elischer 	_NgLogx = logx;
1634cf49a43SJulian Elischer }
1644cf49a43SJulian Elischer 
1654cf49a43SJulian Elischer /*
1664cf49a43SJulian Elischer  * Display a netgraph sockaddr
1674cf49a43SJulian Elischer  */
1684cf49a43SJulian Elischer void
169f8307e12SArchie Cobbs _NgDebugSockaddr(const struct sockaddr_ng *sg)
1704cf49a43SJulian Elischer {
1714cf49a43SJulian Elischer 	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
1724cf49a43SJulian Elischer 	       sg->sg_family, sg->sg_len, sg->sg_data);
1734cf49a43SJulian Elischer }
1744cf49a43SJulian Elischer 
1751816e452SArchie Cobbs #define ARGS_BUFSIZE		2048
1761816e452SArchie Cobbs #define RECURSIVE_DEBUG_ADJUST	4
177f8307e12SArchie Cobbs 
1784cf49a43SJulian Elischer /*
1794cf49a43SJulian Elischer  * Display a negraph message
1804cf49a43SJulian Elischer  */
1814cf49a43SJulian Elischer void
182f8307e12SArchie Cobbs _NgDebugMsg(const struct ng_mesg *msg, const char *path)
1834cf49a43SJulian Elischer {
184f8307e12SArchie Cobbs 	u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
185f8307e12SArchie Cobbs 	struct ng_mesg *const req = (struct ng_mesg *)buf;
186f8307e12SArchie Cobbs 	struct ng_mesg *const bin = (struct ng_mesg *)req->data;
1871816e452SArchie Cobbs 	int arglen, csock = -1;
188f8307e12SArchie Cobbs 
189f8307e12SArchie Cobbs 	/* Display header stuff */
1904cf49a43SJulian Elischer 	NGLOGX("NG_MESG :");
1914cf49a43SJulian Elischer 	NGLOGX("  vers   %d", msg->header.version);
1924cf49a43SJulian Elischer 	NGLOGX("  arglen %d", msg->header.arglen);
1934cf49a43SJulian Elischer 	NGLOGX("  flags  %ld", msg->header.flags);
1944cf49a43SJulian Elischer 	NGLOGX("  token  %lu", (u_long)msg->header.token);
195f8307e12SArchie Cobbs 	NGLOGX("  cookie %s (%d)",
196f8307e12SArchie Cobbs 	    NgCookie(msg->header.typecookie), msg->header.typecookie);
197f8307e12SArchie Cobbs 
198f8307e12SArchie Cobbs 	/* At lower debugging levels, skip ASCII translation */
199f8307e12SArchie Cobbs 	if (_gNgDebugLevel <= 2)
200f8307e12SArchie Cobbs 		goto fail2;
201f8307e12SArchie Cobbs 
202f8307e12SArchie Cobbs 	/* If path is not absolute, don't bother trying to use relative
203f8307e12SArchie Cobbs 	   address on a different socket for the ASCII translation */
204f8307e12SArchie Cobbs 	if (strchr(path, ':') == NULL)
205f8307e12SArchie Cobbs 		goto fail2;
206f8307e12SArchie Cobbs 
207f8307e12SArchie Cobbs 	/* Get a temporary socket */
208f8307e12SArchie Cobbs 	if (NgMkSockNode(NULL, &csock, NULL) < 0)
209f8307e12SArchie Cobbs 		goto fail;
210f8307e12SArchie Cobbs 
211f8307e12SArchie Cobbs 	/* Copy binary message into request message payload */
212f8307e12SArchie Cobbs 	arglen = msg->header.arglen;
213f8307e12SArchie Cobbs 	if (arglen > ARGS_BUFSIZE)
214f8307e12SArchie Cobbs 		arglen = ARGS_BUFSIZE;
215f8307e12SArchie Cobbs 	memcpy(bin, msg, sizeof(*msg) + arglen);
216f8307e12SArchie Cobbs 	bin->header.arglen = arglen;
217f8307e12SArchie Cobbs 
2181816e452SArchie Cobbs 	/* Lower debugging to avoid infinite recursion */
2191816e452SArchie Cobbs 	_gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
2201816e452SArchie Cobbs 
221f8307e12SArchie Cobbs 	/* Ask the node to translate the binary message to ASCII for us */
222f8307e12SArchie Cobbs 	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
2231816e452SArchie Cobbs 	    NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
2241816e452SArchie Cobbs 		_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
225f8307e12SArchie Cobbs 		goto fail;
2261816e452SArchie Cobbs 	}
2271816e452SArchie Cobbs 	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
2281816e452SArchie Cobbs 		_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
229f8307e12SArchie Cobbs 		goto fail;
2301816e452SArchie Cobbs 	}
2311816e452SArchie Cobbs 
2321816e452SArchie Cobbs 	/* Restore debugging level */
2331816e452SArchie Cobbs 	_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
234f8307e12SArchie Cobbs 
235f8307e12SArchie Cobbs 	/* Display command string and arguments */
236f8307e12SArchie Cobbs 	NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
237f8307e12SArchie Cobbs 	NGLOGX("  args   %s", bin->data);
238f8307e12SArchie Cobbs 	goto done;
239f8307e12SArchie Cobbs 
240f8307e12SArchie Cobbs fail:
241f8307e12SArchie Cobbs 	/* Just display binary version */
242f8307e12SArchie Cobbs 	NGLOGX("  [error decoding message: %s]", strerror(errno));
243f8307e12SArchie Cobbs fail2:
244f8307e12SArchie Cobbs 	NGLOGX("  cmd    %d", msg->header.cmd);
245f8307e12SArchie Cobbs 	NGLOGX("  args (%d bytes)", msg->header.arglen);
246b9236794SMaxime Henrion 	_NgDebugBytes((u_char *)msg->data, msg->header.arglen);
247f8307e12SArchie Cobbs 
248f8307e12SArchie Cobbs done:
249f8307e12SArchie Cobbs 	if (csock != -1)
250f8307e12SArchie Cobbs 		(void)close(csock);
2514cf49a43SJulian Elischer }
2524cf49a43SJulian Elischer 
2534cf49a43SJulian Elischer /*
2544cf49a43SJulian Elischer  * Return the name of the node type corresponding to the cookie
2554cf49a43SJulian Elischer  */
2564cf49a43SJulian Elischer static const char *
2574cf49a43SJulian Elischer NgCookie(int cookie)
2584cf49a43SJulian Elischer {
259f8307e12SArchie Cobbs 	int k;
2604cf49a43SJulian Elischer 
261f8307e12SArchie Cobbs 	for (k = 0; cookies[k].cookie != 0; k++) {
262f8307e12SArchie Cobbs 		if (cookies[k].cookie == cookie)
263f8307e12SArchie Cobbs 			return cookies[k].type;
2644cf49a43SJulian Elischer 	}
265f8307e12SArchie Cobbs 	return "??";
2664cf49a43SJulian Elischer }
2674cf49a43SJulian Elischer 
2684cf49a43SJulian Elischer /*
2694cf49a43SJulian Elischer  * Dump bytes in hex
2704cf49a43SJulian Elischer  */
2714cf49a43SJulian Elischer void
2724cf49a43SJulian Elischer _NgDebugBytes(const u_char *ptr, int len)
2734cf49a43SJulian Elischer {
2744cf49a43SJulian Elischer 	char    buf[100];
2754cf49a43SJulian Elischer 	int     k, count;
2764cf49a43SJulian Elischer 
2774cf49a43SJulian Elischer #define BYPERLINE	16
2784cf49a43SJulian Elischer 
2794cf49a43SJulian Elischer 	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
2804cf49a43SJulian Elischer 
2814cf49a43SJulian Elischer 		/* Do hex */
2824cf49a43SJulian Elischer 		snprintf(buf, sizeof(buf), "%04x:  ", count);
2834cf49a43SJulian Elischer 		for (k = 0; k < BYPERLINE; k++, count++)
2844cf49a43SJulian Elischer 			if (count < len)
2854cf49a43SJulian Elischer 				snprintf(buf + strlen(buf),
2864cf49a43SJulian Elischer 				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
2874cf49a43SJulian Elischer 			else
2884cf49a43SJulian Elischer 				snprintf(buf + strlen(buf),
2894cf49a43SJulian Elischer 				    sizeof(buf) - strlen(buf), "   ");
2904cf49a43SJulian Elischer 		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
2914cf49a43SJulian Elischer 		count -= BYPERLINE;
2924cf49a43SJulian Elischer 
2934cf49a43SJulian Elischer 		/* Do ASCII */
2944cf49a43SJulian Elischer 		for (k = 0; k < BYPERLINE; k++, count++)
2954cf49a43SJulian Elischer 			if (count < len)
2964cf49a43SJulian Elischer 				snprintf(buf + strlen(buf),
2974cf49a43SJulian Elischer 				    sizeof(buf) - strlen(buf),
2984cf49a43SJulian Elischer 				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
2994cf49a43SJulian Elischer 			else
3004cf49a43SJulian Elischer 				snprintf(buf + strlen(buf),
3014cf49a43SJulian Elischer 				    sizeof(buf) - strlen(buf), "  ");
3024cf49a43SJulian Elischer 		count -= BYPERLINE;
3034cf49a43SJulian Elischer 
3044cf49a43SJulian Elischer 		/* Print it */
3054cf49a43SJulian Elischer 		NGLOGX("%s", buf);
3064cf49a43SJulian Elischer 	}
3074cf49a43SJulian Elischer }
3084cf49a43SJulian Elischer 
309