]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - lib/libnetgraph/debug.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / lib / libnetgraph / debug.c
1 /*
2  * debug.c
3  *
4  * Copyright (c) 1996-1999 Whistle Communications, Inc.
5  * All rights reserved.
6  * 
7  * Subject to the following obligations and disclaimer of warranty, use and
8  * redistribution of this software, in source or object code forms, with or
9  * without modifications are expressly permitted by Whistle Communications;
10  * provided, however, that:
11  * 1. Any and all reproductions of the source or object code must include the
12  *    copyright notice above and the following disclaimer of warranties; and
13  * 2. No rights are granted, in any manner or form, to use Whistle
14  *    Communications, Inc. trademarks, including the mark "WHISTLE
15  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
16  *    such appears in the above copyright notice or in the software.
17  * 
18  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
19  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
20  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
21  * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
23  * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
24  * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
25  * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
26  * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
27  * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
28  * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
29  * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
30  * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
34  * OF SUCH DAMAGE.
35  *
36  * Author: Archie Cobbs <archie@whistle.com>
37  *
38  * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
39  */
40
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
43
44 #include <sys/types.h>
45 #include <sys/time.h>
46 #include <sys/ioctl.h>
47
48 #include <stdarg.h>
49
50 #include <netinet/in.h>
51 #include <net/ethernet.h>
52 #include <net/bpf.h>
53
54 #include <netgraph/ng_message.h>
55 #include <netgraph/ng_socket.h>
56
57 #include "netgraph.h"
58 #include "internal.h"
59
60 #include <netgraph/ng_UI.h>
61 #include <netgraph/ng_async.h>
62 #include <netgraph/ng_atmllc.h>
63 #include <netgraph/ng_bpf.h>
64 #include <netgraph/ng_bridge.h>
65 #include <netgraph/ng_car.h>
66 #include <netgraph/ng_cisco.h>
67 #include <netgraph/ng_deflate.h>
68 #include <netgraph/ng_device.h>
69 #include <netgraph/ng_echo.h>
70 #include <netgraph/ng_eiface.h>
71 #include <netgraph/ng_etf.h>
72 #include <netgraph/ng_ether.h>
73 #include <netgraph/ng_fec.h>
74 #include <netgraph/ng_ether_echo.h>
75 #include <netgraph/ng_frame_relay.h>
76 #include <netgraph/ng_gif.h>
77 #include <netgraph/ng_gif_demux.h>
78 #include <netgraph/ng_hole.h>
79 #include <netgraph/ng_hub.h>
80 #include <netgraph/ng_iface.h>
81 #include <netgraph/ng_ip_input.h>
82 #include <netgraph/ng_ipfw.h>
83 #include <netgraph/ng_ksocket.h>
84 #include <netgraph/ng_l2tp.h>
85 #include <netgraph/ng_lmi.h>
86 #include <netgraph/ng_mppc.h>
87 #include <netgraph/ng_nat.h>
88 #include <netgraph/netflow/ng_netflow.h>
89 #include <netgraph/ng_one2many.h>
90 #include <netgraph/ng_patch.h>
91 #include <netgraph/ng_pipe.h>
92 #include <netgraph/ng_ppp.h>
93 #include <netgraph/ng_pppoe.h>
94 #include <netgraph/ng_pptpgre.h>
95 #include <netgraph/ng_pred1.h>
96 #include <netgraph/ng_rfc1490.h>
97 #include <netgraph/ng_socket.h>
98 #include <netgraph/ng_source.h>
99 #include <netgraph/ng_split.h>
100 #include <netgraph/ng_sppp.h>
101 #include <netgraph/ng_tag.h>
102 #include <netgraph/ng_tcpmss.h>
103 #include <netgraph/ng_tee.h>
104 #include <netgraph/ng_tty.h>
105 #include <netgraph/ng_vjc.h>
106 #include <netgraph/ng_vlan.h>
107 #ifdef  WHISTLE
108 #include <machine/../isa/df_def.h>
109 #include <machine/../isa/if_wfra.h>
110 #include <machine/../isa/ipac.h>
111 #include <netgraph/ng_df.h>
112 #include <netgraph/ng_ipac.h>
113 #include <netgraph/ng_tn.h>
114 #endif
115
116 /* Global debug level */
117 int     _gNgDebugLevel = 0;
118
119 /* Debug printing functions */
120 void    (*_NgLog) (const char *fmt,...) = warn;
121 void    (*_NgLogx) (const char *fmt,...) = warnx;
122
123 /* Internal functions */
124 static const    char *NgCookie(int cookie);
125
126 /* Known typecookie list */
127 struct ng_cookie {
128         int             cookie;
129         const char      *type;
130 };
131
132 #define COOKIE(c)       { NGM_ ## c ## _COOKIE, #c }
133
134 /* List of known cookies */
135 static const struct ng_cookie cookies[] = {
136         COOKIE(UI),
137         COOKIE(ASYNC),
138         COOKIE(ATMLLC),
139         COOKIE(BPF),
140         COOKIE(BRIDGE),
141         COOKIE(CAR),
142         COOKIE(CISCO),
143         COOKIE(DEFLATE),
144         COOKIE(DEVICE),
145         COOKIE(ECHO),
146         COOKIE(EIFACE),
147         COOKIE(ETF),
148         COOKIE(ETHER),
149         COOKIE(FEC),
150         COOKIE(ETHER_ECHO),
151         COOKIE(FRAMERELAY),
152         COOKIE(GIF),
153         COOKIE(GIF_DEMUX),
154         COOKIE(GENERIC),
155         COOKIE(HOLE),
156         COOKIE(HUB),
157         COOKIE(IFACE),
158         COOKIE(IP_INPUT),
159         COOKIE(IPFW),
160         COOKIE(KSOCKET),
161         COOKIE(L2TP),
162         COOKIE(LMI),
163         COOKIE(MPPC),
164         COOKIE(NAT),
165         COOKIE(NETFLOW),
166         COOKIE(ONE2MANY),
167         COOKIE(PATCH),
168         COOKIE(PIPE),
169         COOKIE(PPP),
170         COOKIE(PPPOE),
171         COOKIE(PPTPGRE),
172         COOKIE(PRED1),
173         COOKIE(RFC1490),
174         COOKIE(SOCKET),
175         COOKIE(SOURCE),
176         COOKIE(SPLIT),
177         COOKIE(SPPP),
178         COOKIE(TAG),
179         COOKIE(TCPMSS),
180         COOKIE(TEE),
181         COOKIE(TTY),
182         COOKIE(VJC),
183         COOKIE(VLAN),
184 #ifdef WHISTLE
185         COOKIE(DF),
186         COOKIE(IPAC),
187         COOKIE(TN),
188         COOKIE(WFRA),
189 #endif
190         { 0, NULL }
191 };
192
193 /*
194  * Set debug level, ie, verbosity, if "level" is non-negative.
195  * Returns old debug level.
196  */
197 int
198 NgSetDebug(int level)
199 {
200         int old = _gNgDebugLevel;
201
202         if (level >= 0)
203                 _gNgDebugLevel = level;
204         return (old);
205 }
206
207 /*
208  * Set debug logging functions.
209  */
210 void
211 NgSetErrLog(void (*log) (const char *fmt,...),
212                 void (*logx) (const char *fmt,...))
213 {
214         _NgLog = log;
215         _NgLogx = logx;
216 }
217
218 /*
219  * Display a netgraph sockaddr
220  */
221 void
222 _NgDebugSockaddr(const struct sockaddr_ng *sg)
223 {
224         NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
225                sg->sg_family, sg->sg_len, sg->sg_data);
226 }
227
228 #define ARGS_BUFSIZE            2048
229 #define RECURSIVE_DEBUG_ADJUST  4
230
231 /*
232  * Display a negraph message
233  */
234 void
235 _NgDebugMsg(const struct ng_mesg *msg, const char *path)
236 {
237         u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
238         struct ng_mesg *const req = (struct ng_mesg *)buf;
239         struct ng_mesg *const bin = (struct ng_mesg *)req->data;
240         int arglen, csock = -1;
241
242         /* Display header stuff */
243         NGLOGX("NG_MESG :");
244         NGLOGX("  vers   %d", msg->header.version);
245         NGLOGX("  arglen %u", msg->header.arglen);
246         NGLOGX("  flags  %x", msg->header.flags);
247         NGLOGX("  token  %u", msg->header.token);
248         NGLOGX("  cookie %s (%u)",
249             NgCookie(msg->header.typecookie), msg->header.typecookie);
250
251         /* At lower debugging levels, skip ASCII translation */
252         if (_gNgDebugLevel <= 2)
253                 goto fail2;
254
255         /* If path is not absolute, don't bother trying to use relative
256            address on a different socket for the ASCII translation */
257         if (strchr(path, ':') == NULL)
258                 goto fail2;
259
260         /* Get a temporary socket */
261         if (NgMkSockNode(NULL, &csock, NULL) < 0)
262                 goto fail;
263
264         /* Copy binary message into request message payload */
265         arglen = msg->header.arglen;
266         if (arglen > ARGS_BUFSIZE)
267                 arglen = ARGS_BUFSIZE;
268         memcpy(bin, msg, sizeof(*msg) + arglen);
269         bin->header.arglen = arglen;
270
271         /* Lower debugging to avoid infinite recursion */
272         _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
273
274         /* Ask the node to translate the binary message to ASCII for us */
275         if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
276             NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
277                 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
278                 goto fail;
279         }
280         if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
281                 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
282                 goto fail;
283         }
284
285         /* Restore debugging level */
286         _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
287
288         /* Display command string and arguments */
289         NGLOGX("  cmd    %s (%d)", bin->header.cmdstr, bin->header.cmd);
290         NGLOGX("  args   %s", bin->data);
291         goto done;
292
293 fail:
294         /* Just display binary version */
295         NGLOGX("  [error decoding message: %s]", strerror(errno));
296 fail2:
297         NGLOGX("  cmd    %d", msg->header.cmd);
298         NGLOGX("  args (%d bytes)", msg->header.arglen);
299         _NgDebugBytes((u_char *)msg->data, msg->header.arglen);
300
301 done:
302         if (csock != -1)
303                 (void)close(csock);
304 }
305
306 /*
307  * Return the name of the node type corresponding to the cookie
308  */
309 static const char *
310 NgCookie(int cookie)
311 {
312         int k;
313
314         for (k = 0; cookies[k].cookie != 0; k++) {
315                 if (cookies[k].cookie == cookie)
316                         return cookies[k].type;
317         }
318         return "??";
319 }
320
321 /*
322  * Dump bytes in hex
323  */
324 void
325 _NgDebugBytes(const u_char *ptr, int len)
326 {
327         char    buf[100];
328         int     k, count;
329
330 #define BYPERLINE       16
331
332         for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
333
334                 /* Do hex */
335                 snprintf(buf, sizeof(buf), "%04x:  ", count);
336                 for (k = 0; k < BYPERLINE; k++, count++)
337                         if (count < len)
338                                 snprintf(buf + strlen(buf),
339                                     sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
340                         else
341                                 snprintf(buf + strlen(buf),
342                                     sizeof(buf) - strlen(buf), "   ");
343                 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "  ");
344                 count -= BYPERLINE;
345
346                 /* Do ASCII */
347                 for (k = 0; k < BYPERLINE; k++, count++)
348                         if (count < len)
349                                 snprintf(buf + strlen(buf),
350                                     sizeof(buf) - strlen(buf),
351                                     "%c", isprint(ptr[k]) ? ptr[k] : '.');
352                         else
353                                 snprintf(buf + strlen(buf),
354                                     sizeof(buf) - strlen(buf), "  ");
355                 count -= BYPERLINE;
356
357                 /* Print it */
358                 NGLOGX("%s", buf);
359         }
360 }
361