10147868eSNuno Antunes /*
20147868eSNuno Antunes * debug.c
30147868eSNuno Antunes *
40147868eSNuno Antunes * Copyright (c) 1996-1999 Whistle Communications, Inc.
50147868eSNuno Antunes * All rights reserved.
60147868eSNuno Antunes *
70147868eSNuno Antunes * Subject to the following obligations and disclaimer of warranty, use and
80147868eSNuno Antunes * redistribution of this software, in source or object code forms, with or
90147868eSNuno Antunes * without modifications are expressly permitted by Whistle Communications;
100147868eSNuno Antunes * provided, however, that:
110147868eSNuno Antunes * 1. Any and all reproductions of the source or object code must include the
120147868eSNuno Antunes * copyright notice above and the following disclaimer of warranties; and
130147868eSNuno Antunes * 2. No rights are granted, in any manner or form, to use Whistle
140147868eSNuno Antunes * Communications, Inc. trademarks, including the mark "WHISTLE
150147868eSNuno Antunes * COMMUNICATIONS" on advertising, endorsements, or otherwise except as
160147868eSNuno Antunes * such appears in the above copyright notice or in the software.
170147868eSNuno Antunes *
180147868eSNuno Antunes * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
190147868eSNuno Antunes * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
200147868eSNuno Antunes * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
210147868eSNuno Antunes * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
220147868eSNuno Antunes * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
230147868eSNuno Antunes * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
240147868eSNuno Antunes * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
250147868eSNuno Antunes * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
260147868eSNuno Antunes * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
270147868eSNuno Antunes * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
280147868eSNuno Antunes * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
290147868eSNuno Antunes * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
300147868eSNuno Antunes * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
310147868eSNuno Antunes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
320147868eSNuno Antunes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
330147868eSNuno Antunes * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
340147868eSNuno Antunes * OF SUCH DAMAGE.
350147868eSNuno Antunes *
360147868eSNuno Antunes * Author: Archie Cobbs <archie@whistle.com>
370147868eSNuno Antunes *
380147868eSNuno Antunes * $FreeBSD: src/lib/libnetgraph/debug.c,v 1.9 2005/10/25 20:58:30 ru Exp $
390147868eSNuno Antunes * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $
400147868eSNuno Antunes */
410147868eSNuno Antunes
420147868eSNuno Antunes #include <sys/types.h>
430147868eSNuno Antunes #include <sys/time.h>
440147868eSNuno Antunes #include <sys/ioctl.h>
450147868eSNuno Antunes
460147868eSNuno Antunes #include <stdarg.h>
470147868eSNuno Antunes
480147868eSNuno Antunes #include <netinet/in.h>
490147868eSNuno Antunes #include <net/ethernet.h>
500147868eSNuno Antunes #include <net/bpf.h>
510147868eSNuno Antunes
520147868eSNuno Antunes #include <netgraph7/ng_message.h>
530147868eSNuno Antunes #include <netgraph7/socket/ng_socket.h>
540147868eSNuno Antunes
550147868eSNuno Antunes #include "netgraph.h"
560147868eSNuno Antunes #include "internal.h"
570147868eSNuno Antunes
580147868eSNuno Antunes #include <netgraph7/UI/ng_UI.h>
590147868eSNuno Antunes #include <netgraph7/async/ng_async.h>
600147868eSNuno Antunes #include <netgraph7/bpf/ng_bpf.h>
610147868eSNuno Antunes #include <netgraph/bridge/ng_bridge.h>
620147868eSNuno Antunes #include <netgraph7/cisco/ng_cisco.h>
63df747d8aSNuno Antunes #include <netgraph7/deflate/ng_deflate.h>
64df747d8aSNuno Antunes #include <netgraph7/echo/ng_echo.h>
65df747d8aSNuno Antunes #include <netgraph7/eiface/ng_eiface.h>
66bb091a26SNuno Antunes #include <netgraph7/etf/ng_etf.h>
670147868eSNuno Antunes #include <netgraph7/ether/ng_ether.h>
680147868eSNuno Antunes /*
69df747d8aSNuno Antunes #include <netgraph7/fec/ng_fec.h>
700147868eSNuno Antunes */
719a8e6225SNuno Antunes #include <netgraph7/frame_relay/ng_frame_relay.h>
720147868eSNuno Antunes #include <netgraph7/hole/ng_hole.h>
73df747d8aSNuno Antunes #include <netgraph7/hub/ng_hub.h>
740147868eSNuno Antunes #include <netgraph7/iface/ng_iface.h>
750147868eSNuno Antunes /*
76df747d8aSNuno Antunes #include <netgraph7/ip_input/ng_ip_input.h>
7749191e0fSNuno Antunes */
78df747d8aSNuno Antunes #include <netgraph7/ksocket/ng_ksocket.h>
79df747d8aSNuno Antunes #include <netgraph7/l2tp/ng_l2tp.h>
80df747d8aSNuno Antunes #include <netgraph7/lmi/ng_lmi.h>
81df747d8aSNuno Antunes #include <netgraph7/mppc/ng_mppc.h>
82df747d8aSNuno Antunes #include <netgraph7/one2many/ng_one2many.h>
83df747d8aSNuno Antunes #include <netgraph7/ppp/ng_ppp.h>
84df747d8aSNuno Antunes #include <netgraph7/pppoe/ng_pppoe.h>
85df747d8aSNuno Antunes #include <netgraph7/pptpgre/ng_pptpgre.h>
86df747d8aSNuno Antunes #include <netgraph7/rfc1490/ng_rfc1490.h>
8755cc8536SNuno Antunes /*
88df747d8aSNuno Antunes #include <netgraph7/socket/ng_socket.h>
89df747d8aSNuno Antunes #include <netgraph7/source/ng_source.h>
90df747d8aSNuno Antunes #include <netgraph7/split/ng_split.h>
910147868eSNuno Antunes */
920a66de84SNuno Antunes #include <netgraph7/tcpmss/ng_tcpmss.h>
930147868eSNuno Antunes #include <netgraph7/tee/ng_tee.h>
94df747d8aSNuno Antunes #include <netgraph7/tty/ng_tty.h>
950147868eSNuno Antunes #include <netgraph7/vjc/ng_vjc.h>
960147868eSNuno Antunes #ifdef WHISTLE
970147868eSNuno Antunes #include <machine/../isa/df_def.h>
980147868eSNuno Antunes #include <machine/../isa/if_wfra.h>
990147868eSNuno Antunes #include <machine/../isa/ipac.h>
1000147868eSNuno Antunes #include <netgraph/ng_df.h>
1010147868eSNuno Antunes #include <netgraph/ng_ipac.h>
1020147868eSNuno Antunes #include <netgraph/ng_tn.h>
1030147868eSNuno Antunes #endif
1040147868eSNuno Antunes
1050147868eSNuno Antunes /* Global debug level */
1060147868eSNuno Antunes int _gNgDebugLevel = 0;
1070147868eSNuno Antunes
1080147868eSNuno Antunes /* Debug printing functions */
1090147868eSNuno Antunes void (*_NgLog) (const char *fmt,...) = warn;
1100147868eSNuno Antunes void (*_NgLogx) (const char *fmt,...) = warnx;
1110147868eSNuno Antunes
1120147868eSNuno Antunes /* Internal functions */
1130147868eSNuno Antunes static const char *NgCookie(int cookie);
1140147868eSNuno Antunes
1150147868eSNuno Antunes /* Known typecookie list */
1160147868eSNuno Antunes struct ng_cookie {
1170147868eSNuno Antunes int cookie;
1180147868eSNuno Antunes const char *type;
1190147868eSNuno Antunes };
1200147868eSNuno Antunes
1210147868eSNuno Antunes #define COOKIE(c) { NGM_ ## c ## _COOKIE, #c }
1220147868eSNuno Antunes
1230147868eSNuno Antunes /* List of known cookies */
1240147868eSNuno Antunes static const struct ng_cookie cookies[] = {
1250147868eSNuno Antunes COOKIE(UI),
1260147868eSNuno Antunes COOKIE(ASYNC),
1270147868eSNuno Antunes COOKIE(BPF),
1280147868eSNuno Antunes COOKIE(BRIDGE),
1290147868eSNuno Antunes COOKIE(CISCO),
130df747d8aSNuno Antunes COOKIE(DEFLATE),
1310147868eSNuno Antunes COOKIE(ECHO),
1329278355dSNuno Antunes /*
1330147868eSNuno Antunes COOKIE(EIFACE),
1340147868eSNuno Antunes */
135bb091a26SNuno Antunes COOKIE(ETF),
1360147868eSNuno Antunes COOKIE(ETHER),
1370147868eSNuno Antunes /*
1380147868eSNuno Antunes COOKIE(FEC),
1399a8e6225SNuno Antunes */
1400147868eSNuno Antunes COOKIE(FRAMERELAY),
1410147868eSNuno Antunes COOKIE(GENERIC),
1420147868eSNuno Antunes COOKIE(HOLE),
1430147868eSNuno Antunes COOKIE(HUB),
1440147868eSNuno Antunes COOKIE(IFACE),
1450147868eSNuno Antunes /*
1460147868eSNuno Antunes COOKIE(IP_INPUT),
14749191e0fSNuno Antunes */
1480147868eSNuno Antunes COOKIE(KSOCKET),
1490147868eSNuno Antunes COOKIE(L2TP),
1500147868eSNuno Antunes COOKIE(LMI),
1510147868eSNuno Antunes COOKIE(MPPC),
1520147868eSNuno Antunes COOKIE(ONE2MANY),
1530147868eSNuno Antunes COOKIE(PPP),
1540147868eSNuno Antunes COOKIE(PPPOE),
1550147868eSNuno Antunes COOKIE(PPTPGRE),
1560147868eSNuno Antunes COOKIE(RFC1490),
1570147868eSNuno Antunes COOKIE(SOCKET),
1580147868eSNuno Antunes /*
1590147868eSNuno Antunes COOKIE(SOURCE),
1600147868eSNuno Antunes COOKIE(SPLIT),
1610147868eSNuno Antunes */
162*8b96223aSNuno Antunes COOKIE(TCPMSS),
1630147868eSNuno Antunes COOKIE(TEE),
1640147868eSNuno Antunes COOKIE(TTY),
1650147868eSNuno Antunes COOKIE(VJC),
1660147868eSNuno Antunes #ifdef WHISTLE
1670147868eSNuno Antunes COOKIE(DF),
1680147868eSNuno Antunes COOKIE(IPAC),
1690147868eSNuno Antunes COOKIE(TN),
1700147868eSNuno Antunes COOKIE(WFRA),
1710147868eSNuno Antunes #endif
1720147868eSNuno Antunes { 0, NULL }
1730147868eSNuno Antunes };
1740147868eSNuno Antunes
1750147868eSNuno Antunes /*
1760147868eSNuno Antunes * Set debug level, ie, verbosity, if "level" is non-negative.
1770147868eSNuno Antunes * Returns old debug level.
1780147868eSNuno Antunes */
1790147868eSNuno Antunes int
NgSetDebug(int level)1800147868eSNuno Antunes NgSetDebug(int level)
1810147868eSNuno Antunes {
1820147868eSNuno Antunes int old = _gNgDebugLevel;
1830147868eSNuno Antunes
1840147868eSNuno Antunes if (level < 0)
1850147868eSNuno Antunes level = old;
1860147868eSNuno Antunes _gNgDebugLevel = level;
1870147868eSNuno Antunes return (old);
1880147868eSNuno Antunes }
1890147868eSNuno Antunes
1900147868eSNuno Antunes /*
1910147868eSNuno Antunes * Set debug logging functions.
1920147868eSNuno Antunes */
1930147868eSNuno Antunes void
NgSetErrLog(void (* log)(const char * fmt,...),void (* logx)(const char * fmt,...))1940147868eSNuno Antunes NgSetErrLog(void (*log) (const char *fmt,...),
1950147868eSNuno Antunes void (*logx) (const char *fmt,...))
1960147868eSNuno Antunes {
1970147868eSNuno Antunes _NgLog = log;
1980147868eSNuno Antunes _NgLogx = logx;
1990147868eSNuno Antunes }
2000147868eSNuno Antunes
2010147868eSNuno Antunes /*
2020147868eSNuno Antunes * Display a netgraph sockaddr
2030147868eSNuno Antunes */
2040147868eSNuno Antunes void
_NgDebugSockaddr(const struct sockaddr_ng * sg)2050147868eSNuno Antunes _NgDebugSockaddr(const struct sockaddr_ng *sg)
2060147868eSNuno Antunes {
2070147868eSNuno Antunes NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }",
2080147868eSNuno Antunes sg->sg_family, sg->sg_len, sg->sg_data);
2090147868eSNuno Antunes }
2100147868eSNuno Antunes
2110147868eSNuno Antunes #define ARGS_BUFSIZE 2048
2120147868eSNuno Antunes #define RECURSIVE_DEBUG_ADJUST 4
2130147868eSNuno Antunes
2140147868eSNuno Antunes /*
2150147868eSNuno Antunes * Display a negraph message
2160147868eSNuno Antunes */
2170147868eSNuno Antunes void
_NgDebugMsg(const struct ng_mesg * msg,const char * path)2180147868eSNuno Antunes _NgDebugMsg(const struct ng_mesg *msg, const char *path)
2190147868eSNuno Antunes {
2200147868eSNuno Antunes u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE];
2210147868eSNuno Antunes struct ng_mesg *const req = (struct ng_mesg *)buf;
2220147868eSNuno Antunes struct ng_mesg *const bin = (struct ng_mesg *)req->data;
2230147868eSNuno Antunes int arglen, csock = -1;
2240147868eSNuno Antunes
2250147868eSNuno Antunes /* Display header stuff */
2260147868eSNuno Antunes NGLOGX("NG_MESG :");
2270147868eSNuno Antunes NGLOGX(" vers %d", msg->header.version);
2280147868eSNuno Antunes NGLOGX(" arglen %d", msg->header.arglen);
2290147868eSNuno Antunes NGLOGX(" flags %ld", msg->header.flags);
2300147868eSNuno Antunes NGLOGX(" token %lu", (u_long)msg->header.token);
2310147868eSNuno Antunes NGLOGX(" cookie %s (%d)",
2320147868eSNuno Antunes NgCookie(msg->header.typecookie), msg->header.typecookie);
2330147868eSNuno Antunes
2340147868eSNuno Antunes /* At lower debugging levels, skip ASCII translation */
2350147868eSNuno Antunes if (_gNgDebugLevel <= 2)
2360147868eSNuno Antunes goto fail2;
2370147868eSNuno Antunes
2380147868eSNuno Antunes /* If path is not absolute, don't bother trying to use relative
2390147868eSNuno Antunes address on a different socket for the ASCII translation */
2400147868eSNuno Antunes if (strchr(path, ':') == NULL)
2410147868eSNuno Antunes goto fail2;
2420147868eSNuno Antunes
2430147868eSNuno Antunes /* Get a temporary socket */
2440147868eSNuno Antunes if (NgMkSockNode(NULL, &csock, NULL) < 0)
2450147868eSNuno Antunes goto fail;
2460147868eSNuno Antunes
2470147868eSNuno Antunes /* Copy binary message into request message payload */
2480147868eSNuno Antunes arglen = msg->header.arglen;
2490147868eSNuno Antunes if (arglen > ARGS_BUFSIZE)
2500147868eSNuno Antunes arglen = ARGS_BUFSIZE;
2510147868eSNuno Antunes memcpy(bin, msg, sizeof(*msg) + arglen);
2520147868eSNuno Antunes bin->header.arglen = arglen;
2530147868eSNuno Antunes
2540147868eSNuno Antunes /* Lower debugging to avoid infinite recursion */
2550147868eSNuno Antunes _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST;
2560147868eSNuno Antunes
2570147868eSNuno Antunes /* Ask the node to translate the binary message to ASCII for us */
2580147868eSNuno Antunes if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE,
2590147868eSNuno Antunes NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) {
2600147868eSNuno Antunes _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
2610147868eSNuno Antunes goto fail;
2620147868eSNuno Antunes }
2630147868eSNuno Antunes if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) {
2640147868eSNuno Antunes _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
2650147868eSNuno Antunes goto fail;
2660147868eSNuno Antunes }
2670147868eSNuno Antunes
2680147868eSNuno Antunes /* Restore debugging level */
2690147868eSNuno Antunes _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST;
2700147868eSNuno Antunes
2710147868eSNuno Antunes /* Display command string and arguments */
2720147868eSNuno Antunes NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd);
2730147868eSNuno Antunes NGLOGX(" args %s", bin->data);
2740147868eSNuno Antunes goto done;
2750147868eSNuno Antunes
2760147868eSNuno Antunes fail:
2770147868eSNuno Antunes /* Just display binary version */
2780147868eSNuno Antunes NGLOGX(" [error decoding message: %s]", strerror(errno));
2790147868eSNuno Antunes fail2:
2800147868eSNuno Antunes NGLOGX(" cmd %d", msg->header.cmd);
2810147868eSNuno Antunes NGLOGX(" args (%d bytes)", msg->header.arglen);
282cf15336dSNuno Antunes _NgDebugBytes(msg->data, msg->header.arglen);
2830147868eSNuno Antunes
2840147868eSNuno Antunes done:
2850147868eSNuno Antunes if (csock != -1)
2860147868eSNuno Antunes (void)close(csock);
2870147868eSNuno Antunes }
2880147868eSNuno Antunes
2890147868eSNuno Antunes /*
2900147868eSNuno Antunes * Return the name of the node type corresponding to the cookie
2910147868eSNuno Antunes */
2920147868eSNuno Antunes static const char *
NgCookie(int cookie)2930147868eSNuno Antunes NgCookie(int cookie)
2940147868eSNuno Antunes {
2950147868eSNuno Antunes int k;
2960147868eSNuno Antunes
2970147868eSNuno Antunes for (k = 0; cookies[k].cookie != 0; k++) {
2980147868eSNuno Antunes if (cookies[k].cookie == cookie)
2990147868eSNuno Antunes return cookies[k].type;
3000147868eSNuno Antunes }
3010147868eSNuno Antunes return "??";
3020147868eSNuno Antunes }
3030147868eSNuno Antunes
3040147868eSNuno Antunes /*
3050147868eSNuno Antunes * Dump bytes in hex
3060147868eSNuno Antunes */
3070147868eSNuno Antunes void
_NgDebugBytes(const u_char * ptr,int len)3080147868eSNuno Antunes _NgDebugBytes(const u_char *ptr, int len)
3090147868eSNuno Antunes {
3100147868eSNuno Antunes char buf[100];
3110147868eSNuno Antunes int k, count;
3120147868eSNuno Antunes
3130147868eSNuno Antunes #define BYPERLINE 16
3140147868eSNuno Antunes
3150147868eSNuno Antunes for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) {
3160147868eSNuno Antunes
3170147868eSNuno Antunes /* Do hex */
3180147868eSNuno Antunes snprintf(buf, sizeof(buf), "%04x: ", count);
3190147868eSNuno Antunes for (k = 0; k < BYPERLINE; k++, count++)
3200147868eSNuno Antunes if (count < len)
3210147868eSNuno Antunes snprintf(buf + strlen(buf),
3220147868eSNuno Antunes sizeof(buf) - strlen(buf), "%02x ", ptr[k]);
3230147868eSNuno Antunes else
3240147868eSNuno Antunes snprintf(buf + strlen(buf),
3250147868eSNuno Antunes sizeof(buf) - strlen(buf), " ");
3260147868eSNuno Antunes snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " ");
3270147868eSNuno Antunes count -= BYPERLINE;
3280147868eSNuno Antunes
3290147868eSNuno Antunes /* Do ASCII */
3300147868eSNuno Antunes for (k = 0; k < BYPERLINE; k++, count++)
3310147868eSNuno Antunes if (count < len)
3320147868eSNuno Antunes snprintf(buf + strlen(buf),
3330147868eSNuno Antunes sizeof(buf) - strlen(buf),
3340147868eSNuno Antunes "%c", isprint(ptr[k]) ? ptr[k] : '.');
3350147868eSNuno Antunes else
3360147868eSNuno Antunes snprintf(buf + strlen(buf),
3370147868eSNuno Antunes sizeof(buf) - strlen(buf), " ");
3380147868eSNuno Antunes count -= BYPERLINE;
3390147868eSNuno Antunes
3400147868eSNuno Antunes /* Print it */
3410147868eSNuno Antunes NGLOGX("%s", buf);
3420147868eSNuno Antunes }
3430147868eSNuno Antunes }
3440147868eSNuno Antunes
345