xref: /freebsd/lib/libnetgraph/debug.c (revision a704009d8ae8531057cef91face602cab4d1941f)
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$
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 */
64 int     _gNgDebugLevel = 0;
65 
66 /* Debug printing functions */
67 void    (*_NgLog) (const char *fmt,...) = warn;
68 void    (*_NgLogx) (const char *fmt,...) = warnx;
69 
70 /* Internal functions */
71 static const	char *NgCookie(int cookie);
72 static const	char *NgCmd(int cookie, int cmd);
73 static 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  */
79 int
80 NgSetDebug(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  */
93 void
94 NgSetErrLog(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  */
104 void
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  */
114 void
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  */
131 static const char *
132 NgCookie(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  */
165 static const char *
166 NgCmd(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  */
237 static void
238 NgArgs(int cookie, int cmd, int resp, void *args, int arglen)
239 {
240 
241 switch (cookie) {
242 case 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 
301 case 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 
314 case 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("    Async MRU %u", ac->amru);
341 		NGLOGX("    Sync MRU  %u", ac->smru);
342 		NGLOGX("    ACCM      0x%08x", ac->accm);
343 		return;
344 	    }
345 	case NGM_ASYNC_CMD_CLR_STATS:
346 		return;
347 	}
348 	break;
349 
350 case NGM_IFACE_COOKIE:
351 	switch (cmd) {
352 	case NGM_IFACE_GET_IFNAME:
353 		return;
354 	case NGM_IFACE_GET_IFADDRS:
355 		return;
356 	}
357 	break;
358 
359 	}
360 	_NgDebugBytes(args, arglen);
361 }
362 
363 /*
364  * Dump bytes in hex
365  */
366 void
367 _NgDebugBytes(const u_char * ptr, int len)
368 {
369 	char    buf[100];
370 	int     k, count;
371 
372 #define BYPERLINE	16
373 
374 	for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
375 
376 		/* Do hex */
377 		snprintf(buf, sizeof(buf), "%04x:  ", count);
378 		for (k = 0; k < BYPERLINE; k++, count++)
379 			if (count < len)
380 				snprintf(buf + strlen(buf),
381 				    sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
382 			else
383 				snprintf(buf + strlen(buf),
384 				    sizeof(buf) - strlen(buf), "   ");
385 		snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
386 		count -= BYPERLINE;
387 
388 		/* Do ASCII */
389 		for (k = 0; k < BYPERLINE; k++, count++)
390 			if (count < len)
391 				snprintf(buf + strlen(buf),
392 				    sizeof(buf) - strlen(buf),
393 				    "%c", isprint(ptr[k]) ? ptr[k] : '.');
394 			else
395 				snprintf(buf + strlen(buf),
396 				    sizeof(buf) - strlen(buf), "  ");
397 		count -= BYPERLINE;
398 
399 		/* Print it */
400 		NGLOGX("%s", buf);
401 	}
402 }
403 
404