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> 65279052Smav#include <netgraph/ng_car.h> 6652419Sjulian#include <netgraph/ng_cisco.h> 67279052Smav#include <netgraph/ng_deflate.h> 68151677Sru#include <netgraph/ng_device.h> 6953913Sarchie#include <netgraph/ng_echo.h> 70151677Sru#include <netgraph/ng_eiface.h> 71151677Sru#include <netgraph/ng_etf.h> 7253913Sarchie#include <netgraph/ng_ether.h> 73151677Sru#include <netgraph/ng_fec.h> 74279052Smav#include <netgraph/ng_ether_echo.h> 7552419Sjulian#include <netgraph/ng_frame_relay.h> 76151677Sru#include <netgraph/ng_gif.h> 77151677Sru#include <netgraph/ng_gif_demux.h> 7853913Sarchie#include <netgraph/ng_hole.h> 79151677Sru#include <netgraph/ng_hub.h> 8053913Sarchie#include <netgraph/ng_iface.h> 81151677Sru#include <netgraph/ng_ip_input.h> 82151677Sru#include <netgraph/ng_ipfw.h> 8353913Sarchie#include <netgraph/ng_ksocket.h> 84151677Sru#include <netgraph/ng_l2tp.h> 8552419Sjulian#include <netgraph/ng_lmi.h> 86151677Sru#include <netgraph/ng_mppc.h> 87151677Sru#include <netgraph/ng_nat.h> 88279052Smav#include <netgraph/netflow/ng_netflow.h> 89151677Sru#include <netgraph/ng_one2many.h> 90279052Smav#include <netgraph/ng_patch.h> 91279052Smav#include <netgraph/ng_pipe.h> 9253913Sarchie#include <netgraph/ng_ppp.h> 9353913Sarchie#include <netgraph/ng_pppoe.h> 94151677Sru#include <netgraph/ng_pptpgre.h> 95279052Smav#include <netgraph/ng_pred1.h> 9653913Sarchie#include <netgraph/ng_rfc1490.h> 9753913Sarchie#include <netgraph/ng_socket.h> 98151677Sru#include <netgraph/ng_source.h> 99151677Sru#include <netgraph/ng_split.h> 100151677Sru#include <netgraph/ng_sppp.h> 101279052Smav#include <netgraph/ng_tag.h> 102151677Sru#include <netgraph/ng_tcpmss.h> 10353913Sarchie#include <netgraph/ng_tee.h> 10452419Sjulian#include <netgraph/ng_tty.h> 10553913Sarchie#include <netgraph/ng_vjc.h> 106151677Sru#include <netgraph/ng_vlan.h> 10753913Sarchie#ifdef WHISTLE 10853913Sarchie#include <machine/../isa/df_def.h> 10953913Sarchie#include <machine/../isa/if_wfra.h> 11053913Sarchie#include <machine/../isa/ipac.h> 11153913Sarchie#include <netgraph/ng_df.h> 11253913Sarchie#include <netgraph/ng_ipac.h> 11353913Sarchie#include <netgraph/ng_tn.h> 11453913Sarchie#endif 11552419Sjulian 11652419Sjulian/* Global debug level */ 11752419Sjulianint _gNgDebugLevel = 0; 11852419Sjulian 11952419Sjulian/* Debug printing functions */ 12052419Sjulianvoid (*_NgLog) (const char *fmt,...) = warn; 12152419Sjulianvoid (*_NgLogx) (const char *fmt,...) = warnx; 12252419Sjulian 12352419Sjulian/* Internal functions */ 12452419Sjulianstatic const char *NgCookie(int cookie); 12552419Sjulian 12653913Sarchie/* Known typecookie list */ 12753913Sarchiestruct ng_cookie { 12853913Sarchie int cookie; 12953913Sarchie const char *type; 13053913Sarchie}; 13153913Sarchie 13253913Sarchie#define COOKIE(c) { NGM_ ## c ## _COOKIE, #c } 13353913Sarchie 13453913Sarchie/* List of known cookies */ 13553913Sarchiestatic const struct ng_cookie cookies[] = { 13653913Sarchie COOKIE(UI), 13753913Sarchie COOKIE(ASYNC), 138151677Sru COOKIE(ATMLLC), 13954098Sarchie COOKIE(BPF), 140151677Sru COOKIE(BRIDGE), 141279052Smav COOKIE(CAR), 14253913Sarchie COOKIE(CISCO), 143279052Smav COOKIE(DEFLATE), 144151677Sru COOKIE(DEVICE), 14553913Sarchie COOKIE(ECHO), 146151677Sru COOKIE(EIFACE), 147151677Sru COOKIE(ETF), 14853913Sarchie COOKIE(ETHER), 149151677Sru COOKIE(FEC), 150279052Smav COOKIE(ETHER_ECHO), 15153913Sarchie COOKIE(FRAMERELAY), 152151677Sru COOKIE(GIF), 153151677Sru COOKIE(GIF_DEMUX), 15453913Sarchie COOKIE(GENERIC), 15553913Sarchie COOKIE(HOLE), 156151677Sru COOKIE(HUB), 15753913Sarchie COOKIE(IFACE), 158151677Sru COOKIE(IP_INPUT), 159151677Sru COOKIE(IPFW), 16053913Sarchie COOKIE(KSOCKET), 161151677Sru COOKIE(L2TP), 16253913Sarchie COOKIE(LMI), 163151677Sru COOKIE(MPPC), 164151677Sru COOKIE(NAT), 165279052Smav COOKIE(NETFLOW), 166151677Sru COOKIE(ONE2MANY), 167279052Smav COOKIE(PATCH), 168279052Smav COOKIE(PIPE), 16953913Sarchie COOKIE(PPP), 17053913Sarchie COOKIE(PPPOE), 171151677Sru COOKIE(PPTPGRE), 172279052Smav COOKIE(PRED1), 17353913Sarchie COOKIE(RFC1490), 17453913Sarchie COOKIE(SOCKET), 175151677Sru COOKIE(SOURCE), 176151677Sru COOKIE(SPLIT), 177151677Sru COOKIE(SPPP), 178279052Smav COOKIE(TAG), 179151677Sru COOKIE(TCPMSS), 18053913Sarchie COOKIE(TEE), 18153913Sarchie COOKIE(TTY), 18253913Sarchie COOKIE(VJC), 183151677Sru COOKIE(VLAN), 18453913Sarchie#ifdef WHISTLE 18553913Sarchie COOKIE(DF), 18653913Sarchie COOKIE(IPAC), 18753913Sarchie COOKIE(TN), 18853913Sarchie COOKIE(WFRA), 18953913Sarchie#endif 19053913Sarchie { 0, NULL } 19153913Sarchie}; 19253913Sarchie 19352419Sjulian/* 19452419Sjulian * Set debug level, ie, verbosity, if "level" is non-negative. 19552419Sjulian * Returns old debug level. 19652419Sjulian */ 19752419Sjulianint 19852419SjulianNgSetDebug(int level) 19952419Sjulian{ 20052419Sjulian int old = _gNgDebugLevel; 20152419Sjulian 202279052Smav if (level >= 0) 203279052Smav _gNgDebugLevel = level; 20452419Sjulian return (old); 20552419Sjulian} 20652419Sjulian 20752419Sjulian/* 20852419Sjulian * Set debug logging functions. 20952419Sjulian */ 21052419Sjulianvoid 21152419SjulianNgSetErrLog(void (*log) (const char *fmt,...), 21252419Sjulian void (*logx) (const char *fmt,...)) 21352419Sjulian{ 21452419Sjulian _NgLog = log; 21552419Sjulian _NgLogx = logx; 21652419Sjulian} 21752419Sjulian 21852419Sjulian/* 21952419Sjulian * Display a netgraph sockaddr 22052419Sjulian */ 22152419Sjulianvoid 22253913Sarchie_NgDebugSockaddr(const struct sockaddr_ng *sg) 22352419Sjulian{ 22452419Sjulian NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", 22552419Sjulian sg->sg_family, sg->sg_len, sg->sg_data); 22652419Sjulian} 22752419Sjulian 22859732Sarchie#define ARGS_BUFSIZE 2048 22959732Sarchie#define RECURSIVE_DEBUG_ADJUST 4 23053913Sarchie 23152419Sjulian/* 23252419Sjulian * Display a negraph message 23352419Sjulian */ 23452419Sjulianvoid 23553913Sarchie_NgDebugMsg(const struct ng_mesg *msg, const char *path) 23652419Sjulian{ 23753913Sarchie u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; 23853913Sarchie struct ng_mesg *const req = (struct ng_mesg *)buf; 23953913Sarchie struct ng_mesg *const bin = (struct ng_mesg *)req->data; 24059732Sarchie int arglen, csock = -1; 24153913Sarchie 24253913Sarchie /* Display header stuff */ 24352419Sjulian NGLOGX("NG_MESG :"); 24452419Sjulian NGLOGX(" vers %d", msg->header.version); 245279052Smav NGLOGX(" arglen %u", msg->header.arglen); 246279052Smav NGLOGX(" flags %x", msg->header.flags); 247279052Smav NGLOGX(" token %u", msg->header.token); 248279052Smav NGLOGX(" cookie %s (%u)", 24953913Sarchie NgCookie(msg->header.typecookie), msg->header.typecookie); 25052419Sjulian 25153913Sarchie /* At lower debugging levels, skip ASCII translation */ 25253913Sarchie if (_gNgDebugLevel <= 2) 25353913Sarchie goto fail2; 25452419Sjulian 25553913Sarchie /* If path is not absolute, don't bother trying to use relative 25653913Sarchie address on a different socket for the ASCII translation */ 25753913Sarchie if (strchr(path, ':') == NULL) 25853913Sarchie goto fail2; 25952419Sjulian 26053913Sarchie /* Get a temporary socket */ 26153913Sarchie if (NgMkSockNode(NULL, &csock, NULL) < 0) 26253913Sarchie goto fail; 26352419Sjulian 26453913Sarchie /* Copy binary message into request message payload */ 26553913Sarchie arglen = msg->header.arglen; 26653913Sarchie if (arglen > ARGS_BUFSIZE) 26753913Sarchie arglen = ARGS_BUFSIZE; 26853913Sarchie memcpy(bin, msg, sizeof(*msg) + arglen); 26953913Sarchie bin->header.arglen = arglen; 27053913Sarchie 27159732Sarchie /* Lower debugging to avoid infinite recursion */ 27259732Sarchie _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST; 27359732Sarchie 27453913Sarchie /* Ask the node to translate the binary message to ASCII for us */ 27553913Sarchie if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, 27659732Sarchie NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) { 27759732Sarchie _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; 27853913Sarchie goto fail; 27959732Sarchie } 28059732Sarchie if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) { 28159732Sarchie _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; 28253913Sarchie goto fail; 28359732Sarchie } 28453913Sarchie 28559732Sarchie /* Restore debugging level */ 28659732Sarchie _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; 28759732Sarchie 28853913Sarchie /* Display command string and arguments */ 28953913Sarchie NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); 29053913Sarchie NGLOGX(" args %s", bin->data); 29153913Sarchie goto done; 29253913Sarchie 29353913Sarchiefail: 29453913Sarchie /* Just display binary version */ 29553913Sarchie NGLOGX(" [error decoding message: %s]", strerror(errno)); 29653913Sarchiefail2: 29753913Sarchie NGLOGX(" cmd %d", msg->header.cmd); 29853913Sarchie NGLOGX(" args (%d bytes)", msg->header.arglen); 299145546Smux _NgDebugBytes((u_char *)msg->data, msg->header.arglen); 30053913Sarchie 30153913Sarchiedone: 30253913Sarchie if (csock != -1) 30353913Sarchie (void)close(csock); 30452419Sjulian} 30552419Sjulian 30652419Sjulian/* 30753913Sarchie * Return the name of the node type corresponding to the cookie 30852419Sjulian */ 30953913Sarchiestatic const char * 31053913SarchieNgCookie(int cookie) 31152419Sjulian{ 31253913Sarchie int k; 31352419Sjulian 31453913Sarchie for (k = 0; cookies[k].cookie != 0; k++) { 31553913Sarchie if (cookies[k].cookie == cookie) 31653913Sarchie return cookies[k].type; 31752419Sjulian } 31853913Sarchie return "??"; 31952419Sjulian} 32052419Sjulian 32152419Sjulian/* 32252419Sjulian * Dump bytes in hex 32352419Sjulian */ 32452419Sjulianvoid 32553913Sarchie_NgDebugBytes(const u_char *ptr, int len) 32652419Sjulian{ 32752419Sjulian char buf[100]; 32852419Sjulian int k, count; 32952419Sjulian 33052419Sjulian#define BYPERLINE 16 33152419Sjulian 33252419Sjulian for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { 33352419Sjulian 33452419Sjulian /* Do hex */ 33552419Sjulian snprintf(buf, sizeof(buf), "%04x: ", count); 33652419Sjulian for (k = 0; k < BYPERLINE; k++, count++) 33752419Sjulian if (count < len) 33852419Sjulian snprintf(buf + strlen(buf), 33952419Sjulian sizeof(buf) - strlen(buf), "%02x ", ptr[k]); 34052419Sjulian else 34152419Sjulian snprintf(buf + strlen(buf), 34252419Sjulian sizeof(buf) - strlen(buf), " "); 34352419Sjulian snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); 34452419Sjulian count -= BYPERLINE; 34552419Sjulian 34652419Sjulian /* Do ASCII */ 34752419Sjulian for (k = 0; k < BYPERLINE; k++, count++) 34852419Sjulian if (count < len) 34952419Sjulian snprintf(buf + strlen(buf), 35052419Sjulian sizeof(buf) - strlen(buf), 35152419Sjulian "%c", isprint(ptr[k]) ? ptr[k] : '.'); 35252419Sjulian else 35352419Sjulian snprintf(buf + strlen(buf), 35452419Sjulian sizeof(buf) - strlen(buf), " "); 35552419Sjulian count -= BYPERLINE; 35652419Sjulian 35752419Sjulian /* Print it */ 35852419Sjulian NGLOGX("%s", buf); 35952419Sjulian } 36052419Sjulian} 36152419Sjulian 362