debug.c revision 54100
1258945Sroberto 2258945Sroberto/* 3258945Sroberto * debug.c 4258945Sroberto * 5258945Sroberto * Copyright (c) 1996-1999 Whistle Communications, Inc. 6258945Sroberto * All rights reserved. 7258945Sroberto * 8258945Sroberto * Subject to the following obligations and disclaimer of warranty, use and 9258945Sroberto * redistribution of this software, in source or object code forms, with or 10258945Sroberto * without modifications are expressly permitted by Whistle Communications; 11258945Sroberto * provided, however, that: 12258945Sroberto * 1. Any and all reproductions of the source or object code must include the 13258945Sroberto * copyright notice above and the following disclaimer of warranties; and 14258945Sroberto * 2. No rights are granted, in any manner or form, to use Whistle 15258945Sroberto * Communications, Inc. trademarks, including the mark "WHISTLE 16258945Sroberto * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 17258945Sroberto * such appears in the above copyright notice or in the software. 18258945Sroberto * 19258945Sroberto * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 20258945Sroberto * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 21258945Sroberto * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 22258945Sroberto * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 23258945Sroberto * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 24258945Sroberto * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 25258945Sroberto * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 26258945Sroberto * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 27258945Sroberto * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 28258945Sroberto * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 29258945Sroberto * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 30258945Sroberto * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 31258945Sroberto * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 32258945Sroberto * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33258945Sroberto * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34258945Sroberto * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 35258945Sroberto * OF SUCH DAMAGE. 36258945Sroberto * 37258945Sroberto * Author: Archie Cobbs <archie@whistle.com> 38258945Sroberto * 39282408Scy * $FreeBSD: head/lib/libnetgraph/debug.c 54100 1999-12-03 23:15:33Z archie $ 40258945Sroberto * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $ 41258945Sroberto */ 42258945Sroberto 43258945Sroberto#include <sys/types.h> 44258945Sroberto#include <sys/time.h> 45258945Sroberto#include <sys/ioctl.h> 46258945Sroberto 47258945Sroberto#include <stdarg.h> 48258945Sroberto 49258945Sroberto#include <netinet/in.h> 50258945Sroberto#include <net/ethernet.h> 51258945Sroberto#include <net/bpf.h> 52258945Sroberto 53258945Sroberto#include <netgraph/ng_message.h> 54258945Sroberto#include <netgraph/ng_socket.h> 55258945Sroberto 56258945Sroberto#include "netgraph.h" 57258945Sroberto#include "internal.h" 58258945Sroberto 59258945Sroberto#include <netgraph/ng_UI.h> 60258945Sroberto#include <netgraph/ng_async.h> 61258945Sroberto#include <netgraph/ng_bpf.h> 62258945Sroberto#include <netgraph/ng_cisco.h> 63258945Sroberto#include <netgraph/ng_echo.h> 64258945Sroberto#include <netgraph/ng_ether.h> 65258945Sroberto#include <netgraph/ng_frame_relay.h> 66258945Sroberto#include <netgraph/ng_hole.h> 67258945Sroberto#include <netgraph/ng_iface.h> 68258945Sroberto#include <netgraph/ng_ksocket.h> 69280849Scy#include <netgraph/ng_lmi.h> 70258945Sroberto#include <netgraph/ng_ppp.h> 71280849Scy#include <netgraph/ng_pppoe.h> 72280849Scy#include <netgraph/ng_rfc1490.h> 73280849Scy#include <netgraph/ng_socket.h> 74280849Scy#include <netgraph/ng_tee.h> 75280849Scy#include <netgraph/ng_tty.h> 76258945Sroberto#include <netgraph/ng_vjc.h> 77258945Sroberto#ifdef WHISTLE 78258945Sroberto#include <machine/../isa/df_def.h> 79258945Sroberto#include <machine/../isa/if_wfra.h> 80258945Sroberto#include <machine/../isa/ipac.h> 81258945Sroberto#include <netgraph/ng_df.h> 82258945Sroberto#include <netgraph/ng_ipac.h> 83258945Sroberto#include <netgraph/ng_mppc.h> 84258945Sroberto#include <netgraph/ng_pptpgre.h> 85258945Sroberto#include <netgraph/ng_tn.h> 86280849Scy#endif 87280849Scy 88280849Scy/* Global debug level */ 89280849Scyint _gNgDebugLevel = 0; 90258945Sroberto 91280849Scy/* Debug printing functions */ 92258945Srobertovoid (*_NgLog) (const char *fmt,...) = warn; 93258945Srobertovoid (*_NgLogx) (const char *fmt,...) = warnx; 94258945Sroberto 95258945Sroberto/* Internal functions */ 96258945Srobertostatic const char *NgCookie(int cookie); 97258945Sroberto 98280849Scy/* Known typecookie list */ 99280849Scystruct ng_cookie { 100280849Scy int cookie; 101280849Scy const char *type; 102280849Scy}; 103258945Sroberto 104280849Scy#define COOKIE(c) { NGM_ ## c ## _COOKIE, #c } 105280849Scy 106280849Scy/* List of known cookies */ 107280849Scystatic const struct ng_cookie cookies[] = { 108280849Scy COOKIE(UI), 109280849Scy COOKIE(ASYNC), 110280849Scy COOKIE(BPF), 111280849Scy COOKIE(CISCO), 112280849Scy COOKIE(ECHO), 113280849Scy COOKIE(ETHER), 114280849Scy COOKIE(FRAMERELAY), 115280849Scy COOKIE(GENERIC), 116280849Scy COOKIE(HOLE), 117280849Scy COOKIE(IFACE), 118280849Scy COOKIE(KSOCKET), 119280849Scy COOKIE(LMI), 120280849Scy COOKIE(PPP), 121280849Scy COOKIE(PPPOE), 122280849Scy COOKIE(RFC1490), 123280849Scy COOKIE(SOCKET), 124280849Scy COOKIE(TEE), 125280849Scy COOKIE(TTY), 126280849Scy COOKIE(VJC), 127280849Scy#ifdef WHISTLE 128280849Scy COOKIE(DF), 129280849Scy COOKIE(IPAC), 130282408Scy COOKIE(MPPC), 131282408Scy COOKIE(PPTPGRE), 132258945Sroberto COOKIE(TN), 133258945Sroberto COOKIE(WFRA), 134280849Scy#endif 135280849Scy { 0, NULL } 136258945Sroberto}; 137258945Sroberto 138280849Scy/* 139280849Scy * Set debug level, ie, verbosity, if "level" is non-negative. 140280849Scy * Returns old debug level. 141280849Scy */ 142280849Scyint 143280849ScyNgSetDebug(int level) 144280849Scy{ 145280849Scy int old = _gNgDebugLevel; 146280849Scy 147280849Scy if (level < 0) 148280849Scy level = old; 149280849Scy _gNgDebugLevel = level; 150280849Scy return (old); 151280849Scy} 152280849Scy 153280849Scy/* 154280849Scy * Set debug logging functions. 155280849Scy */ 156280849Scyvoid 157258945SrobertoNgSetErrLog(void (*log) (const char *fmt,...), 158258945Sroberto void (*logx) (const char *fmt,...)) 159258945Sroberto{ 160258945Sroberto _NgLog = log; 161280849Scy _NgLogx = logx; 162258945Sroberto} 163258945Sroberto 164258945Sroberto/* 165258945Sroberto * Display a netgraph sockaddr 166280849Scy */ 167258945Srobertovoid 168280849Scy_NgDebugSockaddr(const struct sockaddr_ng *sg) 169280849Scy{ 170258945Sroberto NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", 171280849Scy sg->sg_family, sg->sg_len, sg->sg_data); 172280849Scy} 173280849Scy 174280849Scy#define ARGS_BUFSIZE 1024 175280849Scy 176280849Scy/* 177280849Scy * Display a negraph message 178280849Scy */ 179282408Scyvoid 180280849Scy_NgDebugMsg(const struct ng_mesg *msg, const char *path) 181258945Sroberto{ 182258945Sroberto u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; 183258945Sroberto struct ng_mesg *const req = (struct ng_mesg *)buf; 184280849Scy struct ng_mesg *const bin = (struct ng_mesg *)req->data; 185258945Sroberto int arglen, debugSave, csock = -1; 186280849Scy 187258945Sroberto /* Lower debugging to avoid infinite recursion */ 188280849Scy debugSave = _gNgDebugLevel; 189258945Sroberto _gNgDebugLevel -= 4; 190280849Scy 191280849Scy /* Display header stuff */ 192280849Scy NGLOGX("NG_MESG :"); 193280849Scy NGLOGX(" vers %d", msg->header.version); 194280849Scy NGLOGX(" arglen %d", msg->header.arglen); 195280849Scy NGLOGX(" flags %ld", msg->header.flags); 196280849Scy NGLOGX(" token %lu", (u_long)msg->header.token); 197280849Scy NGLOGX(" cookie %s (%d)", 198280849Scy NgCookie(msg->header.typecookie), msg->header.typecookie); 199280849Scy 200280849Scy /* At lower debugging levels, skip ASCII translation */ 201280849Scy if (_gNgDebugLevel <= 2) 202280849Scy goto fail2; 203280849Scy 204280849Scy /* If path is not absolute, don't bother trying to use relative 205280849Scy address on a different socket for the ASCII translation */ 206280849Scy if (strchr(path, ':') == NULL) 207280849Scy goto fail2; 208280849Scy 209280849Scy /* Get a temporary socket */ 210280849Scy if (NgMkSockNode(NULL, &csock, NULL) < 0) 211280849Scy goto fail; 212280849Scy 213280849Scy /* Copy binary message into request message payload */ 214280849Scy arglen = msg->header.arglen; 215280849Scy if (arglen > ARGS_BUFSIZE) 216280849Scy arglen = ARGS_BUFSIZE; 217280849Scy memcpy(bin, msg, sizeof(*msg) + arglen); 218280849Scy bin->header.arglen = arglen; 219280849Scy 220258945Sroberto /* Ask the node to translate the binary message to ASCII for us */ 221258945Sroberto if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, 222258945Sroberto NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) 223258945Sroberto goto fail; 224258945Sroberto if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) 225258945Sroberto goto fail; 226258945Sroberto 227258945Sroberto /* Display command string and arguments */ 228258945Sroberto NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); 229258945Sroberto NGLOGX(" args %s", bin->data); 230280849Scy goto done; 231258945Sroberto 232258945Srobertofail: 233258945Sroberto /* Just display binary version */ 234280849Scy NGLOGX(" [error decoding message: %s]", strerror(errno)); 235258945Srobertofail2: 236258945Sroberto NGLOGX(" cmd %d", msg->header.cmd); 237258945Sroberto NGLOGX(" args (%d bytes)", msg->header.arglen); 238258945Sroberto _NgDebugBytes(msg->data, msg->header.arglen); 239258945Sroberto 240280849Scydone: 241258945Sroberto if (csock != -1) 242280849Scy (void)close(csock); 243280849Scy _gNgDebugLevel = debugSave; 244258945Sroberto} 245280849Scy 246258945Sroberto/* 247258945Sroberto * Return the name of the node type corresponding to the cookie 248280849Scy */ 249258945Srobertostatic const char * 250258945SrobertoNgCookie(int cookie) 251280849Scy{ 252280849Scy int k; 253258945Sroberto 254258945Sroberto for (k = 0; cookies[k].cookie != 0; k++) { 255280849Scy if (cookies[k].cookie == cookie) 256280849Scy return cookies[k].type; 257258945Sroberto } 258258945Sroberto return "??"; 259258945Sroberto} 260258945Sroberto 261280849Scy/* 262258945Sroberto * Dump bytes in hex 263280849Scy */ 264280849Scyvoid 265258945Sroberto_NgDebugBytes(const u_char *ptr, int len) 266280849Scy{ 267280849Scy char buf[100]; 268280849Scy int k, count; 269280849Scy 270280849Scy#define BYPERLINE 16 271280849Scy 272280849Scy for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { 273280849Scy 274258945Sroberto /* Do hex */ 275258945Sroberto snprintf(buf, sizeof(buf), "%04x: ", count); 276280849Scy for (k = 0; k < BYPERLINE; k++, count++) 277280849Scy if (count < len) 278258945Sroberto snprintf(buf + strlen(buf), 279258945Sroberto sizeof(buf) - strlen(buf), "%02x ", ptr[k]); 280258945Sroberto else 281258945Sroberto snprintf(buf + strlen(buf), 282280849Scy sizeof(buf) - strlen(buf), " "); 283258945Sroberto snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); 284280849Scy count -= BYPERLINE; 285280849Scy 286280849Scy /* Do ASCII */ 287280849Scy for (k = 0; k < BYPERLINE; k++, count++) 288280849Scy if (count < len) 289280849Scy snprintf(buf + strlen(buf), 290280849Scy sizeof(buf) - strlen(buf), 291258945Sroberto "%c", isprint(ptr[k]) ? ptr[k] : '.'); 292258945Sroberto else 293280849Scy snprintf(buf + strlen(buf), 294280849Scy sizeof(buf) - strlen(buf), " "); 295258945Sroberto count -= BYPERLINE; 296258945Sroberto 297258945Sroberto /* Print it */ 298258945Sroberto NGLOGX("%s", buf); 299280849Scy } 300258945Sroberto} 301280849Scy 302280849Scy