debug.c revision 53913
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 53913 1999-11-30 02:45:32Z 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), 10653913Sarchie COOKIE(CISCO), 10753913Sarchie COOKIE(ECHO), 10853913Sarchie COOKIE(ETHER), 10953913Sarchie COOKIE(FRAMERELAY), 11053913Sarchie COOKIE(GENERIC), 11153913Sarchie COOKIE(HOLE), 11253913Sarchie COOKIE(IFACE), 11353913Sarchie COOKIE(KSOCKET), 11453913Sarchie COOKIE(LMI), 11553913Sarchie COOKIE(PPP), 11653913Sarchie COOKIE(PPPOE), 11753913Sarchie COOKIE(RFC1490), 11853913Sarchie COOKIE(SOCKET), 11953913Sarchie COOKIE(TEE), 12053913Sarchie COOKIE(TTY), 12153913Sarchie COOKIE(VJC), 12253913Sarchie#ifdef WHISTLE 12353913Sarchie COOKIE(DF), 12453913Sarchie COOKIE(IPAC), 12553913Sarchie COOKIE(MPPC), 12653913Sarchie COOKIE(PPTPGRE), 12753913Sarchie COOKIE(TN), 12853913Sarchie COOKIE(WFRA), 12953913Sarchie#endif 13053913Sarchie { 0, NULL } 13153913Sarchie}; 13253913Sarchie 13352419Sjulian/* 13452419Sjulian * Set debug level, ie, verbosity, if "level" is non-negative. 13552419Sjulian * Returns old debug level. 13652419Sjulian */ 13752419Sjulianint 13852419SjulianNgSetDebug(int level) 13952419Sjulian{ 14052419Sjulian int old = _gNgDebugLevel; 14152419Sjulian 14252419Sjulian if (level < 0) 14352419Sjulian level = old; 14452419Sjulian _gNgDebugLevel = level; 14552419Sjulian return (old); 14652419Sjulian} 14752419Sjulian 14852419Sjulian/* 14952419Sjulian * Set debug logging functions. 15052419Sjulian */ 15152419Sjulianvoid 15252419SjulianNgSetErrLog(void (*log) (const char *fmt,...), 15352419Sjulian void (*logx) (const char *fmt,...)) 15452419Sjulian{ 15552419Sjulian _NgLog = log; 15652419Sjulian _NgLogx = logx; 15752419Sjulian} 15852419Sjulian 15952419Sjulian/* 16052419Sjulian * Display a netgraph sockaddr 16152419Sjulian */ 16252419Sjulianvoid 16353913Sarchie_NgDebugSockaddr(const struct sockaddr_ng *sg) 16452419Sjulian{ 16552419Sjulian NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", 16652419Sjulian sg->sg_family, sg->sg_len, sg->sg_data); 16752419Sjulian} 16852419Sjulian 16953913Sarchie#define ARGS_BUFSIZE 1024 17053913Sarchie 17152419Sjulian/* 17252419Sjulian * Display a negraph message 17352419Sjulian */ 17452419Sjulianvoid 17553913Sarchie_NgDebugMsg(const struct ng_mesg *msg, const char *path) 17652419Sjulian{ 17753913Sarchie u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; 17853913Sarchie struct ng_mesg *const req = (struct ng_mesg *)buf; 17953913Sarchie struct ng_mesg *const bin = (struct ng_mesg *)req->data; 18053913Sarchie int arglen, debugSave, csock = -1; 18153913Sarchie 18253913Sarchie /* Lower debugging to avoid infinite recursion */ 18353913Sarchie debugSave = _gNgDebugLevel; 18453913Sarchie _gNgDebugLevel -= 4; 18553913Sarchie 18653913Sarchie /* Display header stuff */ 18752419Sjulian NGLOGX("NG_MESG :"); 18852419Sjulian NGLOGX(" vers %d", msg->header.version); 18952419Sjulian NGLOGX(" arglen %d", msg->header.arglen); 19052419Sjulian NGLOGX(" flags %ld", msg->header.flags); 19153913Sarchie NGLOGX(" token %lu", (u_long)msg->header.token); 19253913Sarchie NGLOGX(" cookie %s (%d)", 19353913Sarchie NgCookie(msg->header.typecookie), msg->header.typecookie); 19452419Sjulian 19553913Sarchie /* At lower debugging levels, skip ASCII translation */ 19653913Sarchie if (_gNgDebugLevel <= 2) 19753913Sarchie goto fail2; 19852419Sjulian 19953913Sarchie /* If path is not absolute, don't bother trying to use relative 20053913Sarchie address on a different socket for the ASCII translation */ 20153913Sarchie if (strchr(path, ':') == NULL) 20253913Sarchie goto fail2; 20352419Sjulian 20453913Sarchie /* Get a temporary socket */ 20553913Sarchie if (NgMkSockNode(NULL, &csock, NULL) < 0) 20653913Sarchie goto fail; 20752419Sjulian 20853913Sarchie /* Copy binary message into request message payload */ 20953913Sarchie arglen = msg->header.arglen; 21053913Sarchie if (arglen > ARGS_BUFSIZE) 21153913Sarchie arglen = ARGS_BUFSIZE; 21253913Sarchie memcpy(bin, msg, sizeof(*msg) + arglen); 21353913Sarchie bin->header.arglen = arglen; 21453913Sarchie 21553913Sarchie /* Ask the node to translate the binary message to ASCII for us */ 21653913Sarchie if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, 21753913Sarchie NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) 21853913Sarchie goto fail; 21953913Sarchie if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) 22053913Sarchie goto fail; 22153913Sarchie 22253913Sarchie /* Display command string and arguments */ 22353913Sarchie NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); 22453913Sarchie NGLOGX(" args %s", bin->data); 22553913Sarchie goto done; 22653913Sarchie 22753913Sarchiefail: 22853913Sarchie /* Just display binary version */ 22953913Sarchie NGLOGX(" [error decoding message: %s]", strerror(errno)); 23053913Sarchiefail2: 23153913Sarchie NGLOGX(" cmd %d", msg->header.cmd); 23253913Sarchie NGLOGX(" args (%d bytes)", msg->header.arglen); 23353913Sarchie _NgDebugBytes(msg->data, msg->header.arglen); 23453913Sarchie 23553913Sarchiedone: 23653913Sarchie if (csock != -1) 23753913Sarchie (void)close(csock); 23853913Sarchie _gNgDebugLevel = debugSave; 23952419Sjulian} 24052419Sjulian 24152419Sjulian/* 24253913Sarchie * Return the name of the node type corresponding to the cookie 24352419Sjulian */ 24453913Sarchiestatic const char * 24553913SarchieNgCookie(int cookie) 24652419Sjulian{ 24753913Sarchie int k; 24852419Sjulian 24953913Sarchie for (k = 0; cookies[k].cookie != 0; k++) { 25053913Sarchie if (cookies[k].cookie == cookie) 25153913Sarchie return cookies[k].type; 25252419Sjulian } 25353913Sarchie return "??"; 25452419Sjulian} 25552419Sjulian 25652419Sjulian/* 25752419Sjulian * Dump bytes in hex 25852419Sjulian */ 25952419Sjulianvoid 26053913Sarchie_NgDebugBytes(const u_char *ptr, int len) 26152419Sjulian{ 26252419Sjulian char buf[100]; 26352419Sjulian int k, count; 26452419Sjulian 26552419Sjulian#define BYPERLINE 16 26652419Sjulian 26752419Sjulian for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { 26852419Sjulian 26952419Sjulian /* Do hex */ 27052419Sjulian snprintf(buf, sizeof(buf), "%04x: ", count); 27152419Sjulian for (k = 0; k < BYPERLINE; k++, count++) 27252419Sjulian if (count < len) 27352419Sjulian snprintf(buf + strlen(buf), 27452419Sjulian sizeof(buf) - strlen(buf), "%02x ", ptr[k]); 27552419Sjulian else 27652419Sjulian snprintf(buf + strlen(buf), 27752419Sjulian sizeof(buf) - strlen(buf), " "); 27852419Sjulian snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); 27952419Sjulian count -= BYPERLINE; 28052419Sjulian 28152419Sjulian /* Do ASCII */ 28252419Sjulian for (k = 0; k < BYPERLINE; k++, count++) 28352419Sjulian if (count < len) 28452419Sjulian snprintf(buf + strlen(buf), 28552419Sjulian sizeof(buf) - strlen(buf), 28652419Sjulian "%c", isprint(ptr[k]) ? ptr[k] : '.'); 28752419Sjulian else 28852419Sjulian snprintf(buf + strlen(buf), 28952419Sjulian sizeof(buf) - strlen(buf), " "); 29052419Sjulian count -= BYPERLINE; 29152419Sjulian 29252419Sjulian /* Print it */ 29352419Sjulian NGLOGX("%s", buf); 29452419Sjulian } 29552419Sjulian} 29652419Sjulian 297