152419Sjulian/* 252419Sjulian * debug.c 352419Sjulian * 452419Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc. 552419Sjulian * All rights reserved. 652419Sjulian * 752419Sjulian * Subject to the following obligations and disclaimer of warranty, use and 852419Sjulian * redistribution of this software, in source or object code forms, with or 952419Sjulian * without modifications are expressly permitted by Whistle Communications; 1052419Sjulian * provided, however, that: 1152419Sjulian * 1. Any and all reproductions of the source or object code must include the 1252419Sjulian * copyright notice above and the following disclaimer of warranties; and 1352419Sjulian * 2. No rights are granted, in any manner or form, to use Whistle 1452419Sjulian * Communications, Inc. trademarks, including the mark "WHISTLE 1552419Sjulian * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 1652419Sjulian * such appears in the above copyright notice or in the software. 1752419Sjulian * 1852419Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 1952419Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 2052419Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 2152419Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 2252419Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 2352419Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 2452419Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 2552419Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 2652419Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 2752419Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 2852419Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 2952419Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 3052419Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 3152419Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3252419Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3352419Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 3452419Sjulian * OF SUCH DAMAGE. 3552419Sjulian * 3652419Sjulian * Author: Archie Cobbs <archie@whistle.com> 3752419Sjulian * 3852419Sjulian * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $ 3952419Sjulian */ 4052419Sjulian 4184215Sdillon#include <sys/cdefs.h> 4284215Sdillon__FBSDID("$FreeBSD$"); 4384215Sdillon 4452419Sjulian#include <sys/types.h> 4554100Sarchie#include <sys/time.h> 4654100Sarchie#include <sys/ioctl.h> 4753913Sarchie 4852419Sjulian#include <stdarg.h> 4953913Sarchie 5053913Sarchie#include <netinet/in.h> 5153913Sarchie#include <net/ethernet.h> 5254100Sarchie#include <net/bpf.h> 5353913Sarchie 5452419Sjulian#include <netgraph/ng_message.h> 5552419Sjulian#include <netgraph/ng_socket.h> 5652419Sjulian 5752419Sjulian#include "netgraph.h" 5852419Sjulian#include "internal.h" 5952419Sjulian 6053913Sarchie#include <netgraph/ng_UI.h> 6153913Sarchie#include <netgraph/ng_async.h> 62151677Sru#include <netgraph/ng_atmllc.h> 6354100Sarchie#include <netgraph/ng_bpf.h> 64151677Sru#include <netgraph/ng_bridge.h> 6552419Sjulian#include <netgraph/ng_cisco.h> 66151677Sru#include <netgraph/ng_device.h> 6753913Sarchie#include <netgraph/ng_echo.h> 68151677Sru#include <netgraph/ng_eiface.h> 69151677Sru#include <netgraph/ng_etf.h> 7053913Sarchie#include <netgraph/ng_ether.h> 71151677Sru#include <netgraph/ng_fec.h> 7252419Sjulian#include <netgraph/ng_frame_relay.h> 73151677Sru#include <netgraph/ng_gif.h> 74151677Sru#include <netgraph/ng_gif_demux.h> 7553913Sarchie#include <netgraph/ng_hole.h> 76151677Sru#include <netgraph/ng_hub.h> 7753913Sarchie#include <netgraph/ng_iface.h> 78151677Sru#include <netgraph/ng_ip_input.h> 79151677Sru#include <netgraph/ng_ipfw.h> 8053913Sarchie#include <netgraph/ng_ksocket.h> 81151677Sru#include <netgraph/ng_l2tp.h> 8252419Sjulian#include <netgraph/ng_lmi.h> 83151677Sru#include <netgraph/ng_mppc.h> 84151677Sru#include <netgraph/ng_nat.h> 85151677Sru#include <netgraph/ng_one2many.h> 8653913Sarchie#include <netgraph/ng_ppp.h> 8753913Sarchie#include <netgraph/ng_pppoe.h> 88151677Sru#include <netgraph/ng_pptpgre.h> 8953913Sarchie#include <netgraph/ng_rfc1490.h> 9053913Sarchie#include <netgraph/ng_socket.h> 91151677Sru#include <netgraph/ng_source.h> 92151677Sru#include <netgraph/ng_split.h> 93151677Sru#include <netgraph/ng_sppp.h> 94151677Sru#include <netgraph/ng_tcpmss.h> 9553913Sarchie#include <netgraph/ng_tee.h> 9652419Sjulian#include <netgraph/ng_tty.h> 9753913Sarchie#include <netgraph/ng_vjc.h> 98151677Sru#include <netgraph/ng_vlan.h> 9953913Sarchie#ifdef WHISTLE 10053913Sarchie#include <machine/../isa/df_def.h> 10153913Sarchie#include <machine/../isa/if_wfra.h> 10253913Sarchie#include <machine/../isa/ipac.h> 10353913Sarchie#include <netgraph/ng_df.h> 10453913Sarchie#include <netgraph/ng_ipac.h> 10553913Sarchie#include <netgraph/ng_tn.h> 10653913Sarchie#endif 10752419Sjulian 10852419Sjulian/* Global debug level */ 10952419Sjulianint _gNgDebugLevel = 0; 11052419Sjulian 11152419Sjulian/* Debug printing functions */ 11252419Sjulianvoid (*_NgLog) (const char *fmt,...) = warn; 11352419Sjulianvoid (*_NgLogx) (const char *fmt,...) = warnx; 11452419Sjulian 11552419Sjulian/* Internal functions */ 11652419Sjulianstatic const char *NgCookie(int cookie); 11752419Sjulian 11853913Sarchie/* Known typecookie list */ 11953913Sarchiestruct ng_cookie { 12053913Sarchie int cookie; 12153913Sarchie const char *type; 12253913Sarchie}; 12353913Sarchie 12453913Sarchie#define COOKIE(c) { NGM_ ## c ## _COOKIE, #c } 12553913Sarchie 12653913Sarchie/* List of known cookies */ 12753913Sarchiestatic const struct ng_cookie cookies[] = { 12853913Sarchie COOKIE(UI), 12953913Sarchie COOKIE(ASYNC), 130151677Sru COOKIE(ATMLLC), 13154098Sarchie COOKIE(BPF), 132151677Sru COOKIE(BRIDGE), 13353913Sarchie COOKIE(CISCO), 134151677Sru COOKIE(DEVICE), 13553913Sarchie COOKIE(ECHO), 136151677Sru COOKIE(EIFACE), 137151677Sru COOKIE(ETF), 13853913Sarchie COOKIE(ETHER), 139151677Sru COOKIE(FEC), 14053913Sarchie COOKIE(FRAMERELAY), 141151677Sru COOKIE(GIF), 142151677Sru COOKIE(GIF_DEMUX), 14353913Sarchie COOKIE(GENERIC), 14453913Sarchie COOKIE(HOLE), 145151677Sru COOKIE(HUB), 14653913Sarchie COOKIE(IFACE), 147151677Sru COOKIE(IP_INPUT), 148151677Sru COOKIE(IPFW), 14953913Sarchie COOKIE(KSOCKET), 150151677Sru COOKIE(L2TP), 15153913Sarchie COOKIE(LMI), 152151677Sru COOKIE(MPPC), 153151677Sru COOKIE(NAT), 154151677Sru COOKIE(ONE2MANY), 15553913Sarchie COOKIE(PPP), 15653913Sarchie COOKIE(PPPOE), 157151677Sru COOKIE(PPTPGRE), 15853913Sarchie COOKIE(RFC1490), 15953913Sarchie COOKIE(SOCKET), 160151677Sru COOKIE(SOURCE), 161151677Sru COOKIE(SPLIT), 162151677Sru COOKIE(SPPP), 163151677Sru COOKIE(TCPMSS), 16453913Sarchie COOKIE(TEE), 16553913Sarchie COOKIE(TTY), 16653913Sarchie COOKIE(VJC), 167151677Sru COOKIE(VLAN), 16853913Sarchie#ifdef WHISTLE 16953913Sarchie COOKIE(DF), 17053913Sarchie COOKIE(IPAC), 17153913Sarchie COOKIE(TN), 17253913Sarchie COOKIE(WFRA), 17353913Sarchie#endif 17453913Sarchie { 0, NULL } 17553913Sarchie}; 17653913Sarchie 17752419Sjulian/* 17852419Sjulian * Set debug level, ie, verbosity, if "level" is non-negative. 17952419Sjulian * Returns old debug level. 18052419Sjulian */ 18152419Sjulianint 18252419SjulianNgSetDebug(int level) 18352419Sjulian{ 18452419Sjulian int old = _gNgDebugLevel; 18552419Sjulian 18652419Sjulian if (level < 0) 18752419Sjulian level = old; 18852419Sjulian _gNgDebugLevel = level; 18952419Sjulian return (old); 19052419Sjulian} 19152419Sjulian 19252419Sjulian/* 19352419Sjulian * Set debug logging functions. 19452419Sjulian */ 19552419Sjulianvoid 19652419SjulianNgSetErrLog(void (*log) (const char *fmt,...), 19752419Sjulian void (*logx) (const char *fmt,...)) 19852419Sjulian{ 19952419Sjulian _NgLog = log; 20052419Sjulian _NgLogx = logx; 20152419Sjulian} 20252419Sjulian 20352419Sjulian/* 20452419Sjulian * Display a netgraph sockaddr 20552419Sjulian */ 20652419Sjulianvoid 20753913Sarchie_NgDebugSockaddr(const struct sockaddr_ng *sg) 20852419Sjulian{ 20952419Sjulian NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", 21052419Sjulian sg->sg_family, sg->sg_len, sg->sg_data); 21152419Sjulian} 21252419Sjulian 21359732Sarchie#define ARGS_BUFSIZE 2048 21459732Sarchie#define RECURSIVE_DEBUG_ADJUST 4 21553913Sarchie 21652419Sjulian/* 21752419Sjulian * Display a negraph message 21852419Sjulian */ 21952419Sjulianvoid 22053913Sarchie_NgDebugMsg(const struct ng_mesg *msg, const char *path) 22152419Sjulian{ 22253913Sarchie u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; 22353913Sarchie struct ng_mesg *const req = (struct ng_mesg *)buf; 22453913Sarchie struct ng_mesg *const bin = (struct ng_mesg *)req->data; 22559732Sarchie int arglen, csock = -1; 22653913Sarchie 22753913Sarchie /* Display header stuff */ 22852419Sjulian NGLOGX("NG_MESG :"); 22952419Sjulian NGLOGX(" vers %d", msg->header.version); 23052419Sjulian NGLOGX(" arglen %d", msg->header.arglen); 23152419Sjulian NGLOGX(" flags %ld", msg->header.flags); 23253913Sarchie NGLOGX(" token %lu", (u_long)msg->header.token); 23353913Sarchie NGLOGX(" cookie %s (%d)", 23453913Sarchie NgCookie(msg->header.typecookie), msg->header.typecookie); 23552419Sjulian 23653913Sarchie /* At lower debugging levels, skip ASCII translation */ 23753913Sarchie if (_gNgDebugLevel <= 2) 23853913Sarchie goto fail2; 23952419Sjulian 24053913Sarchie /* If path is not absolute, don't bother trying to use relative 24153913Sarchie address on a different socket for the ASCII translation */ 24253913Sarchie if (strchr(path, ':') == NULL) 24353913Sarchie goto fail2; 24452419Sjulian 24553913Sarchie /* Get a temporary socket */ 24653913Sarchie if (NgMkSockNode(NULL, &csock, NULL) < 0) 24753913Sarchie goto fail; 24852419Sjulian 24953913Sarchie /* Copy binary message into request message payload */ 25053913Sarchie arglen = msg->header.arglen; 25153913Sarchie if (arglen > ARGS_BUFSIZE) 25253913Sarchie arglen = ARGS_BUFSIZE; 25353913Sarchie memcpy(bin, msg, sizeof(*msg) + arglen); 25453913Sarchie bin->header.arglen = arglen; 25553913Sarchie 25659732Sarchie /* Lower debugging to avoid infinite recursion */ 25759732Sarchie _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST; 25859732Sarchie 25953913Sarchie /* Ask the node to translate the binary message to ASCII for us */ 26053913Sarchie if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, 26159732Sarchie NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) { 26259732Sarchie _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; 26353913Sarchie goto fail; 26459732Sarchie } 26559732Sarchie if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) { 26659732Sarchie _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; 26753913Sarchie goto fail; 26859732Sarchie } 26953913Sarchie 27059732Sarchie /* Restore debugging level */ 27159732Sarchie _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; 27259732Sarchie 27353913Sarchie /* Display command string and arguments */ 27453913Sarchie NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); 27553913Sarchie NGLOGX(" args %s", bin->data); 27653913Sarchie goto done; 27753913Sarchie 27853913Sarchiefail: 27953913Sarchie /* Just display binary version */ 28053913Sarchie NGLOGX(" [error decoding message: %s]", strerror(errno)); 28153913Sarchiefail2: 28253913Sarchie NGLOGX(" cmd %d", msg->header.cmd); 28353913Sarchie NGLOGX(" args (%d bytes)", msg->header.arglen); 284145546Smux _NgDebugBytes((u_char *)msg->data, msg->header.arglen); 28553913Sarchie 28653913Sarchiedone: 28753913Sarchie if (csock != -1) 28853913Sarchie (void)close(csock); 28952419Sjulian} 29052419Sjulian 29152419Sjulian/* 29253913Sarchie * Return the name of the node type corresponding to the cookie 29352419Sjulian */ 29453913Sarchiestatic const char * 29553913SarchieNgCookie(int cookie) 29652419Sjulian{ 29753913Sarchie int k; 29852419Sjulian 29953913Sarchie for (k = 0; cookies[k].cookie != 0; k++) { 30053913Sarchie if (cookies[k].cookie == cookie) 30153913Sarchie return cookies[k].type; 30252419Sjulian } 30353913Sarchie return "??"; 30452419Sjulian} 30552419Sjulian 30652419Sjulian/* 30752419Sjulian * Dump bytes in hex 30852419Sjulian */ 30952419Sjulianvoid 31053913Sarchie_NgDebugBytes(const u_char *ptr, int len) 31152419Sjulian{ 31252419Sjulian char buf[100]; 31352419Sjulian int k, count; 31452419Sjulian 31552419Sjulian#define BYPERLINE 16 31652419Sjulian 31752419Sjulian for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { 31852419Sjulian 31952419Sjulian /* Do hex */ 32052419Sjulian snprintf(buf, sizeof(buf), "%04x: ", count); 32152419Sjulian for (k = 0; k < BYPERLINE; k++, count++) 32252419Sjulian if (count < len) 32352419Sjulian snprintf(buf + strlen(buf), 32452419Sjulian sizeof(buf) - strlen(buf), "%02x ", ptr[k]); 32552419Sjulian else 32652419Sjulian snprintf(buf + strlen(buf), 32752419Sjulian sizeof(buf) - strlen(buf), " "); 32852419Sjulian snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); 32952419Sjulian count -= BYPERLINE; 33052419Sjulian 33152419Sjulian /* Do ASCII */ 33252419Sjulian for (k = 0; k < BYPERLINE; k++, count++) 33352419Sjulian if (count < len) 33452419Sjulian snprintf(buf + strlen(buf), 33552419Sjulian sizeof(buf) - strlen(buf), 33652419Sjulian "%c", isprint(ptr[k]) ? ptr[k] : '.'); 33752419Sjulian else 33852419Sjulian snprintf(buf + strlen(buf), 33952419Sjulian sizeof(buf) - strlen(buf), " "); 34052419Sjulian count -= BYPERLINE; 34152419Sjulian 34252419Sjulian /* Print it */ 34352419Sjulian NGLOGX("%s", buf); 34452419Sjulian } 34552419Sjulian} 34652419Sjulian 347