xref: /freebsd/lib/libnetgraph/debug.c (revision 41fa1ea96a1c8e170942421c27069006423dc734)
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>
6241fa1ea9SRuslan Ermilov #include <netgraph/ng_atmllc.h>
63baa60a3bSArchie Cobbs #include <netgraph/ng_bpf.h>
6441fa1ea9SRuslan Ermilov #include <netgraph/ng_bridge.h>
65f8307e12SArchie Cobbs #include <netgraph/ng_cisco.h>
6641fa1ea9SRuslan Ermilov #include <netgraph/ng_device.h>
67f8307e12SArchie Cobbs #include <netgraph/ng_echo.h>
6841fa1ea9SRuslan Ermilov #include <netgraph/ng_eiface.h>
6941fa1ea9SRuslan Ermilov #include <netgraph/ng_etf.h>
70f8307e12SArchie Cobbs #include <netgraph/ng_ether.h>
7141fa1ea9SRuslan Ermilov #include <netgraph/ng_fec.h>
724cf49a43SJulian Elischer #include <netgraph/ng_frame_relay.h>
7341fa1ea9SRuslan Ermilov #include <netgraph/ng_gif.h>
7441fa1ea9SRuslan Ermilov #include <netgraph/ng_gif_demux.h>
75f8307e12SArchie Cobbs #include <netgraph/ng_hole.h>
7641fa1ea9SRuslan Ermilov #include <netgraph/ng_hub.h>
77f8307e12SArchie Cobbs #include <netgraph/ng_iface.h>
7841fa1ea9SRuslan Ermilov #include <netgraph/ng_ip_input.h>
7941fa1ea9SRuslan Ermilov #include <netgraph/ng_ipfw.h>
80f8307e12SArchie Cobbs #include <netgraph/ng_ksocket.h>
8141fa1ea9SRuslan Ermilov #include <netgraph/ng_l2tp.h>
824cf49a43SJulian Elischer #include <netgraph/ng_lmi.h>
8341fa1ea9SRuslan Ermilov #include <netgraph/ng_mppc.h>
8441fa1ea9SRuslan Ermilov #include <netgraph/ng_nat.h>
8541fa1ea9SRuslan Ermilov #include <netgraph/ng_one2many.h>
86f8307e12SArchie Cobbs #include <netgraph/ng_ppp.h>
87f8307e12SArchie Cobbs #include <netgraph/ng_pppoe.h>
8841fa1ea9SRuslan Ermilov #include <netgraph/ng_pptpgre.h>
89f8307e12SArchie Cobbs #include <netgraph/ng_rfc1490.h>
90f8307e12SArchie Cobbs #include <netgraph/ng_socket.h>
9141fa1ea9SRuslan Ermilov #include <netgraph/ng_source.h>
9241fa1ea9SRuslan Ermilov #include <netgraph/ng_split.h>
9341fa1ea9SRuslan Ermilov #include <netgraph/ng_sppp.h>
9441fa1ea9SRuslan Ermilov #include <netgraph/ng_tcpmss.h>
95f8307e12SArchie Cobbs #include <netgraph/ng_tee.h>
964cf49a43SJulian Elischer #include <netgraph/ng_tty.h>
97f8307e12SArchie Cobbs #include <netgraph/ng_vjc.h>
9841fa1ea9SRuslan Ermilov #include <netgraph/ng_vlan.h>
99f8307e12SArchie Cobbs #ifdef	WHISTLE
100f8307e12SArchie Cobbs #include <machine/../isa/df_def.h>
101f8307e12SArchie Cobbs #include <machine/../isa/if_wfra.h>
102f8307e12SArchie Cobbs #include <machine/../isa/ipac.h>
103f8307e12SArchie Cobbs #include <netgraph/ng_df.h>
104f8307e12SArchie Cobbs #include <netgraph/ng_ipac.h>
105f8307e12SArchie Cobbs #include <netgraph/ng_tn.h>
106f8307e12SArchie Cobbs #endif
1074cf49a43SJulian Elischer 
1084cf49a43SJulian Elischer /* Global debug level */
1094cf49a43SJulian Elischer int     _gNgDebugLevel = 0;
1104cf49a43SJulian Elischer 
1114cf49a43SJulian Elischer /* Debug printing functions */
1124cf49a43SJulian Elischer void    (*_NgLog) (const char *fmt,...) = warn;
1134cf49a43SJulian Elischer void    (*_NgLogx) (const char *fmt,...) = warnx;
1144cf49a43SJulian Elischer 
1154cf49a43SJulian Elischer /* Internal functions */
1164cf49a43SJulian Elischer static const	char *NgCookie(int cookie);
117f8307e12SArchie Cobbs 
118f8307e12SArchie Cobbs /* Known typecookie list */
119f8307e12SArchie Cobbs struct ng_cookie {
120f8307e12SArchie Cobbs 	int		cookie;
121f8307e12SArchie Cobbs 	const char	*type;
122f8307e12SArchie Cobbs };
123f8307e12SArchie Cobbs 
124f8307e12SArchie Cobbs #define COOKIE(c)	{ NGM_ ## c ## _COOKIE, #c }
125f8307e12SArchie Cobbs 
126f8307e12SArchie Cobbs /* List of known cookies */
127f8307e12SArchie Cobbs static const struct ng_cookie cookies[] = {
128f8307e12SArchie Cobbs 	COOKIE(UI),
129f8307e12SArchie Cobbs 	COOKIE(ASYNC),
13041fa1ea9SRuslan Ermilov 	COOKIE(ATMLLC),
131e489a907SArchie Cobbs 	COOKIE(BPF),
13241fa1ea9SRuslan Ermilov 	COOKIE(BRIDGE),
133f8307e12SArchie Cobbs 	COOKIE(CISCO),
13441fa1ea9SRuslan Ermilov 	COOKIE(DEVICE),
135f8307e12SArchie Cobbs 	COOKIE(ECHO),
13641fa1ea9SRuslan Ermilov 	COOKIE(EIFACE),
13741fa1ea9SRuslan Ermilov 	COOKIE(ETF),
138f8307e12SArchie Cobbs 	COOKIE(ETHER),
13941fa1ea9SRuslan Ermilov 	COOKIE(FEC),
140f8307e12SArchie Cobbs 	COOKIE(FRAMERELAY),
14141fa1ea9SRuslan Ermilov 	COOKIE(GIF),
14241fa1ea9SRuslan Ermilov 	COOKIE(GIF_DEMUX),
143f8307e12SArchie Cobbs 	COOKIE(GENERIC),
144f8307e12SArchie Cobbs 	COOKIE(HOLE),
14541fa1ea9SRuslan Ermilov 	COOKIE(HUB),
146f8307e12SArchie Cobbs 	COOKIE(IFACE),
14741fa1ea9SRuslan Ermilov 	COOKIE(IP_INPUT),
14841fa1ea9SRuslan Ermilov 	COOKIE(IPFW),
149f8307e12SArchie Cobbs 	COOKIE(KSOCKET),
15041fa1ea9SRuslan Ermilov 	COOKIE(L2TP),
151f8307e12SArchie Cobbs 	COOKIE(LMI),
15241fa1ea9SRuslan Ermilov 	COOKIE(MPPC),
15341fa1ea9SRuslan Ermilov 	COOKIE(NAT),
15441fa1ea9SRuslan Ermilov 	COOKIE(ONE2MANY),
155f8307e12SArchie Cobbs 	COOKIE(PPP),
156f8307e12SArchie Cobbs 	COOKIE(PPPOE),
15741fa1ea9SRuslan Ermilov 	COOKIE(PPTPGRE),
158f8307e12SArchie Cobbs 	COOKIE(RFC1490),
159f8307e12SArchie Cobbs 	COOKIE(SOCKET),
16041fa1ea9SRuslan Ermilov 	COOKIE(SOURCE),
16141fa1ea9SRuslan Ermilov 	COOKIE(SPLIT),
16241fa1ea9SRuslan Ermilov 	COOKIE(SPPP),
16341fa1ea9SRuslan Ermilov 	COOKIE(TCPMSS),
164f8307e12SArchie Cobbs 	COOKIE(TEE),
165f8307e12SArchie Cobbs 	COOKIE(TTY),
166f8307e12SArchie Cobbs 	COOKIE(VJC),
16741fa1ea9SRuslan Ermilov 	COOKIE(VLAN),
168f8307e12SArchie Cobbs #ifdef WHISTLE
169f8307e12SArchie Cobbs 	COOKIE(DF),
170f8307e12SArchie Cobbs 	COOKIE(IPAC),
171f8307e12SArchie Cobbs 	COOKIE(TN),
172f8307e12SArchie Cobbs 	COOKIE(WFRA),
173f8307e12SArchie Cobbs #endif
174f8307e12SArchie Cobbs 	{ 0, NULL }
175f8307e12SArchie Cobbs };
1764cf49a43SJulian Elischer 
1774cf49a43SJulian Elischer /*
1784cf49a43SJulian Elischer  * Set debug level, ie, verbosity, if "level" is non-negative.
1794cf49a43SJulian Elischer  * Returns old debug level.
1804cf49a43SJulian Elischer  */
1814cf49a43SJulian Elischer int
1824cf49a43SJulian Elischer NgSetDebug(int level)
1834cf49a43SJulian Elischer {
1844cf49a43SJulian Elischer 	int old = _gNgDebugLevel;
1854cf49a43SJulian Elischer 
1864cf49a43SJulian Elischer 	if (level < 0)
1874cf49a43SJulian Elischer 		level = old;
1884cf49a43SJulian Elischer 	_gNgDebugLevel = level;
1894cf49a43SJulian Elischer 	return (old);
1904cf49a43SJulian Elischer }
1914cf49a43SJulian Elischer 
1924cf49a43SJulian Elischer /*
1934cf49a43SJulian Elischer  * Set debug logging functions.
1944cf49a43SJulian Elischer  */
1954cf49a43SJulian Elischer void
1964cf49a43SJulian Elischer NgSetErrLog(void (*log) (const char *fmt,...),
1974cf49a43SJulian Elischer 		void (*logx) (const char *fmt,...))
1984cf49a43SJulian Elischer {
1994cf49a43SJulian Elischer 	_NgLog = log;
2004cf49a43SJulian Elischer 	_NgLogx = logx;
2014cf49a43SJulian Elischer }
2024cf49a43SJulian Elischer 
2034cf49a43SJulian Elischer /*
2044cf49a43SJulian Elischer  * Display a netgraph sockaddr
2054cf49a43SJulian Elischer  */
2064cf49a43SJulian Elischer void
207f8307e12SArchie Cobbs _NgDebugSockaddr(const struct sockaddr_ng *sg)
2084cf49a43SJulian Elischer {
2094cf49a43SJulian Elischer 	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
2104cf49a43SJulian Elischer 	       sg->sg_family, sg->sg_len, sg->sg_data);
2114cf49a43SJulian Elischer }
2124cf49a43SJulian Elischer 
2131816e452SArchie Cobbs #define ARGS_BUFSIZE		2048
2141816e452SArchie Cobbs #define RECURSIVE_DEBUG_ADJUST	4
215f8307e12SArchie Cobbs 
2164cf49a43SJulian Elischer /*
2174cf49a43SJulian Elischer  * Display a negraph message
2184cf49a43SJulian Elischer  */
2194cf49a43SJulian Elischer void
220f8307e12SArchie Cobbs _NgDebugMsg(const struct ng_mesg *msg, const char *path)
2214cf49a43SJulian Elischer {
222f8307e12SArchie Cobbs 	u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
223f8307e12SArchie Cobbs 	struct ng_mesg *const req = (struct ng_mesg *)buf;
224f8307e12SArchie Cobbs 	struct ng_mesg *const bin = (struct ng_mesg *)req->data;
2251816e452SArchie Cobbs 	int arglen, csock = -1;
226f8307e12SArchie Cobbs 
227f8307e12SArchie Cobbs 	/* Display header stuff */
2284cf49a43SJulian Elischer 	NGLOGX("NG_MESG :");
2294cf49a43SJulian Elischer 	NGLOGX("  vers   %d", msg->header.version);
2304cf49a43SJulian Elischer 	NGLOGX("  arglen %d", msg->header.arglen);
2314cf49a43SJulian Elischer 	NGLOGX("  flags  %ld", msg->header.flags);
2324cf49a43SJulian Elischer 	NGLOGX("  token  %lu", (u_long)msg->header.token);
233f8307e12SArchie Cobbs 	NGLOGX("  cookie %s (%d)",
234f8307e12SArchie Cobbs 	    NgCookie(msg->header.typecookie), msg->header.typecookie);
235f8307e12SArchie Cobbs 
236f8307e12SArchie Cobbs 	/* At lower debugging levels, skip ASCII translation */
237f8307e12SArchie Cobbs 	if (_gNgDebugLevel <= 2)
238f8307e12SArchie Cobbs 		goto fail2;
239f8307e12SArchie Cobbs 
240f8307e12SArchie Cobbs 	/* If path is not absolute, don't bother trying to use relative
241f8307e12SArchie Cobbs 	   address on a different socket for the ASCII translation */
242f8307e12SArchie Cobbs 	if (strchr(path, ':') == NULL)
243f8307e12SArchie Cobbs 		goto fail2;
244f8307e12SArchie Cobbs 
245f8307e12SArchie Cobbs 	/* Get a temporary socket */
246f8307e12SArchie Cobbs 	if (NgMkSockNode(NULL, &csock, NULL) < 0)
247f8307e12SArchie Cobbs 		goto fail;
248f8307e12SArchie Cobbs 
249f8307e12SArchie Cobbs 	/* Copy binary message into request message payload */
250f8307e12SArchie Cobbs 	arglen = msg->header.arglen;
251f8307e12SArchie Cobbs 	if (arglen > ARGS_BUFSIZE)
252f8307e12SArchie Cobbs 		arglen = ARGS_BUFSIZE;
253f8307e12SArchie Cobbs 	memcpy(bin, msg, sizeof(*msg) + arglen);
254f8307e12SArchie Cobbs 	bin->header.arglen = arglen;
255f8307e12SArchie Cobbs 
2561816e452SArchie Cobbs 	/* Lower debugging to avoid infinite recursion */
2571816e452SArchie Cobbs 	_gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
2581816e452SArchie Cobbs 
259f8307e12SArchie Cobbs 	/* Ask the node to translate the binary message to ASCII for us */
260f8307e12SArchie Cobbs 	if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
2611816e452SArchie Cobbs 	    NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
2621816e452SArchie Cobbs 		_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
263f8307e12SArchie Cobbs 		goto fail;
2641816e452SArchie Cobbs 	}
2651816e452SArchie Cobbs 	if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
2661816e452SArchie Cobbs 		_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
267f8307e12SArchie Cobbs 		goto fail;
2681816e452SArchie Cobbs 	}
2691816e452SArchie Cobbs 
2701816e452SArchie Cobbs 	/* Restore debugging level */
2711816e452SArchie Cobbs 	_gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
272f8307e12SArchie Cobbs 
273f8307e12SArchie Cobbs 	/* Display command string and arguments */
274f8307e12SArchie Cobbs 	NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
275f8307e12SArchie Cobbs 	NGLOGX("  args   %s", bin->data);
276f8307e12SArchie Cobbs 	goto done;
277f8307e12SArchie Cobbs 
278f8307e12SArchie Cobbs fail:
279f8307e12SArchie Cobbs 	/* Just display binary version */
280f8307e12SArchie Cobbs 	NGLOGX("  [error decoding message: %s]", strerror(errno));
281f8307e12SArchie Cobbs fail2:
282f8307e12SArchie Cobbs 	NGLOGX("  cmd    %d", msg->header.cmd);
283f8307e12SArchie Cobbs 	NGLOGX("  args (%d bytes)", msg->header.arglen);
284b9236794SMaxime Henrion 	_NgDebugBytes((u_char *)msg->data, msg->header.arglen);
285f8307e12SArchie Cobbs 
286f8307e12SArchie Cobbs done:
287f8307e12SArchie Cobbs 	if (csock != -1)
288f8307e12SArchie Cobbs 		(void)close(csock);
2894cf49a43SJulian Elischer }
2904cf49a43SJulian Elischer 
2914cf49a43SJulian Elischer /*
2924cf49a43SJulian Elischer  * Return the name of the node type corresponding to the cookie
2934cf49a43SJulian Elischer  */
2944cf49a43SJulian Elischer static const char *
2954cf49a43SJulian Elischer NgCookie(int cookie)
2964cf49a43SJulian Elischer {
297f8307e12SArchie Cobbs 	int k;
2984cf49a43SJulian Elischer 
299f8307e12SArchie Cobbs 	for (k = 0; cookies[k].cookie != 0; k++) {
300f8307e12SArchie Cobbs 		if (cookies[k].cookie == cookie)
301f8307e12SArchie Cobbs 			return cookies[k].type;
3024cf49a43SJulian Elischer 	}
303f8307e12SArchie Cobbs 	return "??";
3044cf49a43SJulian Elischer }
3054cf49a43SJulian Elischer 
3064cf49a43SJulian Elischer /*
3074cf49a43SJulian Elischer  * Dump bytes in hex
3084cf49a43SJulian Elischer  */
3094cf49a43SJulian Elischer void
3104cf49a43SJulian Elischer _NgDebugBytes(const u_char *ptr, int len)
3114cf49a43SJulian Elischer {
3124cf49a43SJulian Elischer 	char    buf[100];
3134cf49a43SJulian Elischer 	int     k, count;
3144cf49a43SJulian Elischer 
3154cf49a43SJulian Elischer #define BYPERLINE	16
3164cf49a43SJulian Elischer 
3174cf49a43SJulian Elischer 	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
3184cf49a43SJulian Elischer 
3194cf49a43SJulian Elischer 		/* Do hex */
3204cf49a43SJulian Elischer 		snprintf(buf, sizeof(buf), "%04x:  ", count);
3214cf49a43SJulian Elischer 		for (k = 0; k < BYPERLINE; k++, count++)
3224cf49a43SJulian Elischer 			if (count < len)
3234cf49a43SJulian Elischer 				snprintf(buf + strlen(buf),
3244cf49a43SJulian Elischer 				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
3254cf49a43SJulian Elischer 			else
3264cf49a43SJulian Elischer 				snprintf(buf + strlen(buf),
3274cf49a43SJulian Elischer 				    sizeof(buf) - strlen(buf), "   ");
3284cf49a43SJulian Elischer 		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
3294cf49a43SJulian Elischer 		count -= BYPERLINE;
3304cf49a43SJulian Elischer 
3314cf49a43SJulian Elischer 		/* Do ASCII */
3324cf49a43SJulian Elischer 		for (k = 0; k < BYPERLINE; k++, count++)
3334cf49a43SJulian Elischer 			if (count < len)
3344cf49a43SJulian Elischer 				snprintf(buf + strlen(buf),
3354cf49a43SJulian Elischer 				    sizeof(buf) - strlen(buf),
3364cf49a43SJulian Elischer 				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
3374cf49a43SJulian Elischer 			else
3384cf49a43SJulian Elischer 				snprintf(buf + strlen(buf),
3394cf49a43SJulian Elischer 				    sizeof(buf) - strlen(buf), "  ");
3404cf49a43SJulian Elischer 		count -= BYPERLINE;
3414cf49a43SJulian Elischer 
3424cf49a43SJulian Elischer 		/* Print it */
3434cf49a43SJulian Elischer 		NGLOGX("%s", buf);
3444cf49a43SJulian Elischer 	}
3454cf49a43SJulian Elischer }
3464cf49a43SJulian Elischer 
347