debug.c revision 52419
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 52419 1999-10-21 09:06:11Z julian $
40 * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
41 */
42
43#include <sys/types.h>
44#include <stdarg.h>
45#include <netgraph/ng_message.h>
46#include <netgraph/ng_socket.h>
47
48#include "netgraph.h"
49#include "internal.h"
50
51#include <netgraph/ng_socket.h>
52#include <netgraph/ng_message.h>
53#include <netgraph/ng_iface.h>
54#include <netgraph/ng_rfc1490.h>
55#include <netgraph/ng_cisco.h>
56#include <netgraph/ng_async.h>
57#include <netgraph/ng_ppp.h>
58#include <netgraph/ng_frame_relay.h>
59#include <netgraph/ng_lmi.h>
60#include <netgraph/ng_tty.h>
61#include <netgraph/ng_tty.h>
62
63/* Global debug level */
64int     _gNgDebugLevel = 0;
65
66/* Debug printing functions */
67void    (*_NgLog) (const char *fmt,...) = warn;
68void    (*_NgLogx) (const char *fmt,...) = warnx;
69
70/* Internal functions */
71static const	char *NgCookie(int cookie);
72static const	char *NgCmd(int cookie, int cmd);
73static void	NgArgs(int cookie, int cmd, int resp, void *args, int arglen);
74
75/*
76 * Set debug level, ie, verbosity, if "level" is non-negative.
77 * Returns old debug level.
78 */
79int
80NgSetDebug(int level)
81{
82	int old = _gNgDebugLevel;
83
84	if (level < 0)
85		level = old;
86	_gNgDebugLevel = level;
87	return (old);
88}
89
90/*
91 * Set debug logging functions.
92 */
93void
94NgSetErrLog(void (*log) (const char *fmt,...),
95		void (*logx) (const char *fmt,...))
96{
97	_NgLog = log;
98	_NgLogx = logx;
99}
100
101/*
102 * Display a netgraph sockaddr
103 */
104void
105_NgDebugSockaddr(struct sockaddr_ng *sg)
106{
107	NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
108	       sg->sg_family, sg->sg_len, sg->sg_data);
109}
110
111/*
112 * Display a negraph message
113 */
114void
115_NgDebugMsg(struct ng_mesg * msg)
116{
117	NGLOGX("NG_MESG :");
118	NGLOGX("  vers   %d", msg->header.version);
119	NGLOGX("  arglen %d", msg->header.arglen);
120	NGLOGX("  flags  %ld", msg->header.flags);
121	NGLOGX("  token  %lu", (u_long) msg->header.token);
122	NGLOGX("  cookie %s", NgCookie(msg->header.typecookie));
123	NGLOGX("  cmd    %s", NgCmd(msg->header.typecookie, msg->header.cmd));
124	NgArgs(msg->header.typecookie, msg->header.cmd,
125	       (msg->header.flags & NGF_RESP), msg->data, msg->header.arglen);
126}
127
128/*
129 * Return the name of the node type corresponding to the cookie
130 */
131static const char *
132NgCookie(int cookie)
133{
134	static char buf[20];
135
136	switch (cookie) {
137	case NGM_GENERIC_COOKIE:
138		return "generic";
139	case NGM_TTY_COOKIE:
140		return "tty";
141	case NGM_ASYNC_COOKIE:
142		return "async";
143	case NGM_IFACE_COOKIE:
144		return "iface";
145	case NGM_FRAMERELAY_COOKIE:
146		return "frame_relay";
147	case NGM_LMI_COOKIE:
148		return "lmi";
149	case NGM_CISCO_COOKIE:
150		return "cisco";
151	case NGM_PPP_COOKIE:
152		return "ppp";
153	case NGM_RFC1490_NODE_COOKIE:
154		return "rfc1490";
155	case NGM_SOCKET_COOKIE:
156		return "socket";
157	}
158	snprintf(buf, sizeof(buf), "?? (%d)", cookie);
159	return buf;
160}
161
162/*
163 * Return the name of the command
164 */
165static const char *
166NgCmd(int cookie, int cmd)
167{
168	static char buf[20];
169
170	switch (cookie) {
171	case NGM_GENERIC_COOKIE:
172		switch (cmd) {
173		case NGM_SHUTDOWN:
174			return "shutdown";
175		case NGM_MKPEER:
176			return "mkpeer";
177		case NGM_CONNECT:
178			return "connect";
179		case NGM_NAME:
180			return "name";
181		case NGM_RMHOOK:
182			return "rmhook";
183		case NGM_NODEINFO:
184			return "nodeinfo";
185		case NGM_LISTHOOKS:
186			return "listhooks";
187		case NGM_LISTNAMES:
188			return "listnames";
189		case NGM_LISTNODES:
190			return "listnodes";
191		case NGM_TEXT_STATUS:
192			return "text_status";
193		}
194		break;
195	case NGM_TTY_COOKIE:
196		switch (cmd) {
197		case NGM_TTY_GET_HOTCHAR:
198			return "getHotChar";
199		case NGM_TTY_SET_HOTCHAR:
200			return "setHotChar";
201		}
202		break;
203	case NGM_ASYNC_COOKIE:
204		switch (cmd) {
205		case NGM_ASYNC_CMD_GET_STATS:
206			return "getStats";
207		case NGM_ASYNC_CMD_CLR_STATS:
208			return "setStats";
209		case NGM_ASYNC_CMD_SET_CONFIG:
210			return "setConfig";
211		case NGM_ASYNC_CMD_GET_CONFIG:
212			return "getConfig";
213		}
214		break;
215	case NGM_IFACE_COOKIE:
216		switch (cmd) {
217		case NGM_IFACE_GET_IFNAME:
218			return "getIfName";
219		case NGM_IFACE_GET_IFADDRS:
220			return "getIfAddrs";
221		}
222		break;
223	case NGM_LMI_COOKIE:
224		switch (cmd) {
225		case NGM_LMI_GET_STATUS:
226			return "get-status";
227		}
228		break;
229	}
230	snprintf(buf, sizeof(buf), "?? (%d)", cmd);
231	return buf;
232}
233
234/*
235 * Decode message arguments
236 */
237static void
238NgArgs(int cookie, int cmd, int resp, void *args, int arglen)
239{
240
241switch (cookie) {
242case NGM_GENERIC_COOKIE:
243	switch (cmd) {
244	case NGM_SHUTDOWN:
245		return;
246	case NGM_MKPEER:
247	    {
248		struct ngm_mkpeer *const mkp = (struct ngm_mkpeer *) args;
249
250		if (resp)
251			return;
252		NGLOGX("    type     \"%s\"", mkp->type);
253		NGLOGX("    ourhook  \"%s\"", mkp->ourhook);
254		NGLOGX("    peerhook \"%s\"", mkp->peerhook);
255		return;
256	    }
257	case NGM_CONNECT:
258	    {
259		struct ngm_connect *const ngc = (struct ngm_connect *) args;
260
261		if (resp)
262			return;
263		NGLOGX("    path     \"%s\"", ngc->path);
264		NGLOGX("    ourhook  \"%s\"", ngc->ourhook);
265		NGLOGX("    peerhook \"%s\"", ngc->peerhook);
266		return;
267	    }
268	case NGM_NAME:
269	    {
270		struct ngm_name *const ngn = (struct ngm_name *) args;
271
272		if (resp)
273			return;
274		NGLOGX("    name \"%s\"", ngn->name);
275		return;
276	    }
277	case NGM_RMHOOK:
278	    {
279		struct ngm_rmhook *const ngr = (struct ngm_rmhook *) args;
280
281		if (resp)
282			return;
283		NGLOGX("    hook \"%s\"", ngr->ourhook);
284		return;
285	    }
286	case NGM_NODEINFO:
287		return;
288	case NGM_LISTHOOKS:
289		return;
290	case NGM_LISTNAMES:
291	case NGM_LISTNODES:
292		return;
293	case NGM_TEXT_STATUS:
294		if (!resp)
295			return;
296		NGLOGX("    status \"%s\"", (char *) args);
297	    	return;
298	}
299	break;
300
301case NGM_TTY_COOKIE:
302	switch (cmd) {
303	case NGM_TTY_GET_HOTCHAR:
304		if (!resp)
305			return;
306		NGLOGX("    char 0x%02x", *((int *) args));
307		return;
308	case NGM_TTY_SET_HOTCHAR:
309		NGLOGX("    char 0x%02x", *((int *) args));
310		return;
311	}
312	break;
313
314case NGM_ASYNC_COOKIE:
315	switch (cmd) {
316	case NGM_ASYNC_CMD_GET_STATS:
317	    {
318		struct ng_async_stat *const as = (struct ng_async_stat *) args;
319
320		if (!resp)
321			return;
322		NGLOGX("    syncOctets = %lu", as->syncOctets);
323		NGLOGX("    syncFrames = %lu", as->syncFrames);
324		NGLOGX("    syncOverflows = %lu", as->syncOverflows);
325		NGLOGX("    asyncOctets = %lu", as->asyncOctets);
326		NGLOGX("    asyncFrames = %lu", as->asyncFrames);
327		NGLOGX("    asyncRunts = %lu", as->asyncRunts);
328		NGLOGX("    asyncOverflows = %lu", as->asyncOverflows);
329		NGLOGX("    asyncBadCheckSums = %lu", as->asyncBadCheckSums);
330		return;
331	    }
332	case NGM_ASYNC_CMD_GET_CONFIG:
333	case NGM_ASYNC_CMD_SET_CONFIG:
334	    {
335		struct ng_async_cfg *const ac = (struct ng_async_cfg *) args;
336
337		if (!resp ^ (cmd != NGM_ASYNC_CMD_GET_CONFIG))
338			return;
339		NGLOGX("    enabled   %s", ac->enabled ? "YES" : "NO");
340		NGLOGX("    acfcomp   %s", ac->acfcomp ? "YES" : "NO");
341		NGLOGX("    Async MRU %u", ac->amru);
342		NGLOGX("    Sync MRU  %u", ac->smru);
343		NGLOGX("    ACCM      0x%08x", ac->accm);
344		return;
345	    }
346	case NGM_ASYNC_CMD_CLR_STATS:
347		return;
348	}
349	break;
350
351case NGM_IFACE_COOKIE:
352	switch (cmd) {
353	case NGM_IFACE_GET_IFNAME:
354		return;
355	case NGM_IFACE_GET_IFADDRS:
356		return;
357	}
358	break;
359
360	}
361	_NgDebugBytes(args, arglen);
362}
363
364/*
365 * Dump bytes in hex
366 */
367void
368_NgDebugBytes(const u_char * ptr, int len)
369{
370	char    buf[100];
371	int     k, count;
372
373#define BYPERLINE	16
374
375	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
376
377		/* Do hex */
378		snprintf(buf, sizeof(buf), "%04x:  ", count);
379		for (k = 0; k < BYPERLINE; k++, count++)
380			if (count < len)
381				snprintf(buf + strlen(buf),
382				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
383			else
384				snprintf(buf + strlen(buf),
385				    sizeof(buf) - strlen(buf), "   ");
386		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
387		count -= BYPERLINE;
388
389		/* Do ASCII */
390		for (k = 0; k < BYPERLINE; k++, count++)
391			if (count < len)
392				snprintf(buf + strlen(buf),
393				    sizeof(buf) - strlen(buf),
394				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
395			else
396				snprintf(buf + strlen(buf),
397				    sizeof(buf) - strlen(buf), "  ");
398		count -= BYPERLINE;
399
400		/* Print it */
401		NGLOGX("%s", buf);
402	}
403}
404
405