debug.c revision 54098
152419Sjulian 252419Sjulian/* 352419Sjulian * debug.c 452419Sjulian * 552419Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc. 652419Sjulian * All rights reserved. 752419Sjulian * 852419Sjulian * Subject to the following obligations and disclaimer of warranty, use and 952419Sjulian * redistribution of this software, in source or object code forms, with or 1052419Sjulian * without modifications are expressly permitted by Whistle Communications; 1152419Sjulian * provided, however, that: 1252419Sjulian * 1. Any and all reproductions of the source or object code must include the 1352419Sjulian * copyright notice above and the following disclaimer of warranties; and 1452419Sjulian * 2. No rights are granted, in any manner or form, to use Whistle 1552419Sjulian * Communications, Inc. trademarks, including the mark "WHISTLE 1652419Sjulian * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 1752419Sjulian * such appears in the above copyright notice or in the software. 1852419Sjulian * 1952419Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 2052419Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 2152419Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 2252419Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 2352419Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 2452419Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 2552419Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 2652419Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 2752419Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 2852419Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 2952419Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 3052419Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 3152419Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 3252419Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3352419Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3452419Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 3552419Sjulian * OF SUCH DAMAGE. 3652419Sjulian * 3752419Sjulian * Author: Archie Cobbs <archie@whistle.com> 3852419Sjulian * 3952419Sjulian * $FreeBSD: head/lib/libnetgraph/debug.c 54098 1999-12-03 23:12:41Z archie $ 4052419Sjulian * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $ 4152419Sjulian */ 4252419Sjulian 4352419Sjulian#include <sys/types.h> 4453913Sarchie 4552419Sjulian#include <stdarg.h> 4653913Sarchie 4753913Sarchie#include <netinet/in.h> 4853913Sarchie#include <net/ethernet.h> 4953913Sarchie 5052419Sjulian#include <netgraph/ng_message.h> 5152419Sjulian#include <netgraph/ng_socket.h> 5252419Sjulian 5352419Sjulian#include "netgraph.h" 5452419Sjulian#include "internal.h" 5552419Sjulian 5653913Sarchie#include <netgraph/ng_UI.h> 5753913Sarchie#include <netgraph/ng_async.h> 5852419Sjulian#include <netgraph/ng_cisco.h> 5953913Sarchie#include <netgraph/ng_echo.h> 6053913Sarchie#include <netgraph/ng_ether.h> 6152419Sjulian#include <netgraph/ng_frame_relay.h> 6253913Sarchie#include <netgraph/ng_hole.h> 6353913Sarchie#include <netgraph/ng_iface.h> 6453913Sarchie#include <netgraph/ng_ksocket.h> 6552419Sjulian#include <netgraph/ng_lmi.h> 6653913Sarchie#include <netgraph/ng_ppp.h> 6753913Sarchie#include <netgraph/ng_pppoe.h> 6853913Sarchie#include <netgraph/ng_rfc1490.h> 6953913Sarchie#include <netgraph/ng_socket.h> 7053913Sarchie#include <netgraph/ng_tee.h> 7152419Sjulian#include <netgraph/ng_tty.h> 7253913Sarchie#include <netgraph/ng_vjc.h> 7353913Sarchie#ifdef WHISTLE 7453913Sarchie#include <machine/../isa/df_def.h> 7553913Sarchie#include <machine/../isa/if_wfra.h> 7653913Sarchie#include <machine/../isa/ipac.h> 7753913Sarchie#include <netgraph/ng_df.h> 7853913Sarchie#include <netgraph/ng_ipac.h> 7953913Sarchie#include <netgraph/ng_mppc.h> 8053913Sarchie#include <netgraph/ng_pptpgre.h> 8153913Sarchie#include <netgraph/ng_tn.h> 8253913Sarchie#endif 8352419Sjulian 8452419Sjulian/* Global debug level */ 8552419Sjulianint _gNgDebugLevel = 0; 8652419Sjulian 8752419Sjulian/* Debug printing functions */ 8852419Sjulianvoid (*_NgLog) (const char *fmt,...) = warn; 8952419Sjulianvoid (*_NgLogx) (const char *fmt,...) = warnx; 9052419Sjulian 9152419Sjulian/* Internal functions */ 9252419Sjulianstatic const char *NgCookie(int cookie); 9352419Sjulian 9453913Sarchie/* Known typecookie list */ 9553913Sarchiestruct ng_cookie { 9653913Sarchie int cookie; 9753913Sarchie const char *type; 9853913Sarchie}; 9953913Sarchie 10053913Sarchie#define COOKIE(c) { NGM_ ## c ## _COOKIE, #c } 10153913Sarchie 10253913Sarchie/* List of known cookies */ 10353913Sarchiestatic const struct ng_cookie cookies[] = { 10453913Sarchie COOKIE(UI), 10553913Sarchie COOKIE(ASYNC), 10654098Sarchie COOKIE(BPF), 10753913Sarchie COOKIE(CISCO), 10853913Sarchie COOKIE(ECHO), 10953913Sarchie COOKIE(ETHER), 11053913Sarchie COOKIE(FRAMERELAY), 11153913Sarchie COOKIE(GENERIC), 11253913Sarchie COOKIE(HOLE), 11353913Sarchie COOKIE(IFACE), 11453913Sarchie COOKIE(KSOCKET), 11553913Sarchie COOKIE(LMI), 11653913Sarchie COOKIE(PPP), 11753913Sarchie COOKIE(PPPOE), 11853913Sarchie COOKIE(RFC1490), 11953913Sarchie COOKIE(SOCKET), 12053913Sarchie COOKIE(TEE), 12153913Sarchie COOKIE(TTY), 12253913Sarchie COOKIE(VJC), 12353913Sarchie#ifdef WHISTLE 12453913Sarchie COOKIE(DF), 12553913Sarchie COOKIE(IPAC), 12653913Sarchie COOKIE(MPPC), 12753913Sarchie COOKIE(PPTPGRE), 12853913Sarchie COOKIE(TN), 12953913Sarchie COOKIE(WFRA), 13053913Sarchie#endif 13153913Sarchie { 0, NULL } 13253913Sarchie}; 13353913Sarchie 13452419Sjulian/* 13552419Sjulian * Set debug level, ie, verbosity, if "level" is non-negative. 13652419Sjulian * Returns old debug level. 13752419Sjulian */ 13852419Sjulianint 13952419SjulianNgSetDebug(int level) 14052419Sjulian{ 14152419Sjulian int old = _gNgDebugLevel; 14252419Sjulian 14352419Sjulian if (level < 0) 14452419Sjulian level = old; 14552419Sjulian _gNgDebugLevel = level; 14652419Sjulian return (old); 14752419Sjulian} 14852419Sjulian 14952419Sjulian/* 15052419Sjulian * Set debug logging functions. 15152419Sjulian */ 15252419Sjulianvoid 15352419SjulianNgSetErrLog(void (*log) (const char *fmt,...), 15452419Sjulian void (*logx) (const char *fmt,...)) 15552419Sjulian{ 15652419Sjulian _NgLog = log; 15752419Sjulian _NgLogx = logx; 15852419Sjulian} 15952419Sjulian 16052419Sjulian/* 16152419Sjulian * Display a netgraph sockaddr 16252419Sjulian */ 16352419Sjulianvoid 16453913Sarchie_NgDebugSockaddr(const struct sockaddr_ng *sg) 16552419Sjulian{ 16652419Sjulian NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", 16752419Sjulian sg->sg_family, sg->sg_len, sg->sg_data); 16852419Sjulian} 16952419Sjulian 17053913Sarchie#define ARGS_BUFSIZE 1024 17153913Sarchie 17252419Sjulian/* 17352419Sjulian * Display a negraph message 17452419Sjulian */ 17552419Sjulianvoid 17653913Sarchie_NgDebugMsg(const struct ng_mesg *msg, const char *path) 17752419Sjulian{ 17853913Sarchie u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; 17953913Sarchie struct ng_mesg *const req = (struct ng_mesg *)buf; 18053913Sarchie struct ng_mesg *const bin = (struct ng_mesg *)req->data; 18153913Sarchie int arglen, debugSave, csock = -1; 18253913Sarchie 18353913Sarchie /* Lower debugging to avoid infinite recursion */ 18453913Sarchie debugSave = _gNgDebugLevel; 18553913Sarchie _gNgDebugLevel -= 4; 18653913Sarchie 18753913Sarchie /* Display header stuff */ 18852419Sjulian NGLOGX("NG_MESG :"); 18952419Sjulian NGLOGX(" vers %d", msg->header.version); 19052419Sjulian NGLOGX(" arglen %d", msg->header.arglen); 19152419Sjulian NGLOGX(" flags %ld", msg->header.flags); 19253913Sarchie NGLOGX(" token %lu", (u_long)msg->header.token); 19353913Sarchie NGLOGX(" cookie %s (%d)", 19453913Sarchie NgCookie(msg->header.typecookie), msg->header.typecookie); 19552419Sjulian 19653913Sarchie /* At lower debugging levels, skip ASCII translation */ 19753913Sarchie if (_gNgDebugLevel <= 2) 19853913Sarchie goto fail2; 19952419Sjulian 20053913Sarchie /* If path is not absolute, don't bother trying to use relative 20153913Sarchie address on a different socket for the ASCII translation */ 20253913Sarchie if (strchr(path, ':') == NULL) 20353913Sarchie goto fail2; 20452419Sjulian 20553913Sarchie /* Get a temporary socket */ 20653913Sarchie if (NgMkSockNode(NULL, &csock, NULL) < 0) 20753913Sarchie goto fail; 20852419Sjulian 20953913Sarchie /* Copy binary message into request message payload */ 21053913Sarchie arglen = msg->header.arglen; 21153913Sarchie if (arglen > ARGS_BUFSIZE) 21253913Sarchie arglen = ARGS_BUFSIZE; 21353913Sarchie memcpy(bin, msg, sizeof(*msg) + arglen); 21453913Sarchie bin->header.arglen = arglen; 21553913Sarchie 21653913Sarchie /* Ask the node to translate the binary message to ASCII for us */ 21753913Sarchie if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, 21853913Sarchie NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) 21953913Sarchie goto fail; 22053913Sarchie if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) 22153913Sarchie goto fail; 22253913Sarchie 22353913Sarchie /* Display command string and arguments */ 22453913Sarchie NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); 22553913Sarchie NGLOGX(" args %s", bin->data); 22653913Sarchie goto done; 22753913Sarchie 22853913Sarchiefail: 22953913Sarchie /* Just display binary version */ 23053913Sarchie NGLOGX(" [error decoding message: %s]", strerror(errno)); 23153913Sarchiefail2: 23253913Sarchie NGLOGX(" cmd %d", msg->header.cmd); 23353913Sarchie NGLOGX(" args (%d bytes)", msg->header.arglen); 23453913Sarchie _NgDebugBytes(msg->data, msg->header.arglen); 23553913Sarchie 23653913Sarchiedone: 23753913Sarchie if (csock != -1) 23853913Sarchie (void)close(csock); 23953913Sarchie _gNgDebugLevel = debugSave; 24052419Sjulian} 24152419Sjulian 24252419Sjulian/* 24353913Sarchie * Return the name of the node type corresponding to the cookie 24452419Sjulian */ 24553913Sarchiestatic const char * 24653913SarchieNgCookie(int cookie) 24752419Sjulian{ 24853913Sarchie int k; 24952419Sjulian 25053913Sarchie for (k = 0; cookies[k].cookie != 0; k++) { 25153913Sarchie if (cookies[k].cookie == cookie) 25253913Sarchie return cookies[k].type; 25352419Sjulian } 25453913Sarchie return "??"; 25552419Sjulian} 25652419Sjulian 25752419Sjulian/* 25852419Sjulian * Dump bytes in hex 25952419Sjulian */ 26052419Sjulianvoid 26153913Sarchie_NgDebugBytes(const u_char *ptr, int len) 26252419Sjulian{ 26352419Sjulian char buf[100]; 26452419Sjulian int k, count; 26552419Sjulian 26652419Sjulian#define BYPERLINE 16 26752419Sjulian 26852419Sjulian for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { 26952419Sjulian 27052419Sjulian /* Do hex */ 27152419Sjulian snprintf(buf, sizeof(buf), "%04x: ", count); 27252419Sjulian for (k = 0; k < BYPERLINE; k++, count++) 27352419Sjulian if (count < len) 27452419Sjulian snprintf(buf + strlen(buf), 27552419Sjulian sizeof(buf) - strlen(buf), "%02x ", ptr[k]); 27652419Sjulian else 27752419Sjulian snprintf(buf + strlen(buf), 27852419Sjulian sizeof(buf) - strlen(buf), " "); 27952419Sjulian snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); 28052419Sjulian count -= BYPERLINE; 28152419Sjulian 28252419Sjulian /* Do ASCII */ 28352419Sjulian for (k = 0; k < BYPERLINE; k++, count++) 28452419Sjulian if (count < len) 28552419Sjulian snprintf(buf + strlen(buf), 28652419Sjulian sizeof(buf) - strlen(buf), 28752419Sjulian "%c", isprint(ptr[k]) ? ptr[k] : '.'); 28852419Sjulian else 28952419Sjulian snprintf(buf + strlen(buf), 29052419Sjulian sizeof(buf) - strlen(buf), " "); 29152419Sjulian count -= BYPERLINE; 29252419Sjulian 29352419Sjulian /* Print it */ 29452419Sjulian NGLOGX("%s", buf); 29552419Sjulian } 29652419Sjulian} 29752419Sjulian 298