debug.c revision 53913
1 2/* 3 * debug.c 4 * 5 * Copyright (c) 1996-1999 Whistle Communications, Inc. 6 * All rights reserved. 7 * 8 * Subject to the following obligations and disclaimer of warranty, use and 9 * redistribution of this software, in source or object code forms, with or 10 * without modifications are expressly permitted by Whistle Communications; 11 * provided, however, that: 12 * 1. Any and all reproductions of the source or object code must include the 13 * copyright notice above and the following disclaimer of warranties; and 14 * 2. No rights are granted, in any manner or form, to use Whistle 15 * Communications, Inc. trademarks, including the mark "WHISTLE 16 * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 17 * such appears in the above copyright notice or in the software. 18 * 19 * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 20 * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 21 * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 22 * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 24 * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 25 * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 26 * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 27 * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 28 * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 29 * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 30 * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 31 * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 35 * OF SUCH DAMAGE. 36 * 37 * Author: Archie Cobbs <archie@whistle.com> 38 * 39 * $FreeBSD: head/lib/libnetgraph/debug.c 53913 1999-11-30 02:45:32Z archie $ 40 * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $ 41 */ 42 43#include <sys/types.h> 44 45#include <stdarg.h> 46 47#include <netinet/in.h> 48#include <net/ethernet.h> 49 50#include <netgraph/ng_message.h> 51#include <netgraph/ng_socket.h> 52 53#include "netgraph.h" 54#include "internal.h" 55 56#include <netgraph/ng_UI.h> 57#include <netgraph/ng_async.h> 58#include <netgraph/ng_cisco.h> 59#include <netgraph/ng_echo.h> 60#include <netgraph/ng_ether.h> 61#include <netgraph/ng_frame_relay.h> 62#include <netgraph/ng_hole.h> 63#include <netgraph/ng_iface.h> 64#include <netgraph/ng_ksocket.h> 65#include <netgraph/ng_lmi.h> 66#include <netgraph/ng_ppp.h> 67#include <netgraph/ng_pppoe.h> 68#include <netgraph/ng_rfc1490.h> 69#include <netgraph/ng_socket.h> 70#include <netgraph/ng_tee.h> 71#include <netgraph/ng_tty.h> 72#include <netgraph/ng_vjc.h> 73#ifdef WHISTLE 74#include <machine/../isa/df_def.h> 75#include <machine/../isa/if_wfra.h> 76#include <machine/../isa/ipac.h> 77#include <netgraph/ng_df.h> 78#include <netgraph/ng_ipac.h> 79#include <netgraph/ng_mppc.h> 80#include <netgraph/ng_pptpgre.h> 81#include <netgraph/ng_tn.h> 82#endif 83 84/* Global debug level */ 85int _gNgDebugLevel = 0; 86 87/* Debug printing functions */ 88void (*_NgLog) (const char *fmt,...) = warn; 89void (*_NgLogx) (const char *fmt,...) = warnx; 90 91/* Internal functions */ 92static const char *NgCookie(int cookie); 93 94/* Known typecookie list */ 95struct ng_cookie { 96 int cookie; 97 const char *type; 98}; 99 100#define COOKIE(c) { NGM_ ## c ## _COOKIE, #c } 101 102/* List of known cookies */ 103static const struct ng_cookie cookies[] = { 104 COOKIE(UI), 105 COOKIE(ASYNC), 106 COOKIE(CISCO), 107 COOKIE(ECHO), 108 COOKIE(ETHER), 109 COOKIE(FRAMERELAY), 110 COOKIE(GENERIC), 111 COOKIE(HOLE), 112 COOKIE(IFACE), 113 COOKIE(KSOCKET), 114 COOKIE(LMI), 115 COOKIE(PPP), 116 COOKIE(PPPOE), 117 COOKIE(RFC1490), 118 COOKIE(SOCKET), 119 COOKIE(TEE), 120 COOKIE(TTY), 121 COOKIE(VJC), 122#ifdef WHISTLE 123 COOKIE(DF), 124 COOKIE(IPAC), 125 COOKIE(MPPC), 126 COOKIE(PPTPGRE), 127 COOKIE(TN), 128 COOKIE(WFRA), 129#endif 130 { 0, NULL } 131}; 132 133/* 134 * Set debug level, ie, verbosity, if "level" is non-negative. 135 * Returns old debug level. 136 */ 137int 138NgSetDebug(int level) 139{ 140 int old = _gNgDebugLevel; 141 142 if (level < 0) 143 level = old; 144 _gNgDebugLevel = level; 145 return (old); 146} 147 148/* 149 * Set debug logging functions. 150 */ 151void 152NgSetErrLog(void (*log) (const char *fmt,...), 153 void (*logx) (const char *fmt,...)) 154{ 155 _NgLog = log; 156 _NgLogx = logx; 157} 158 159/* 160 * Display a netgraph sockaddr 161 */ 162void 163_NgDebugSockaddr(const struct sockaddr_ng *sg) 164{ 165 NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", 166 sg->sg_family, sg->sg_len, sg->sg_data); 167} 168 169#define ARGS_BUFSIZE 1024 170 171/* 172 * Display a negraph message 173 */ 174void 175_NgDebugMsg(const struct ng_mesg *msg, const char *path) 176{ 177 u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; 178 struct ng_mesg *const req = (struct ng_mesg *)buf; 179 struct ng_mesg *const bin = (struct ng_mesg *)req->data; 180 int arglen, debugSave, csock = -1; 181 182 /* Lower debugging to avoid infinite recursion */ 183 debugSave = _gNgDebugLevel; 184 _gNgDebugLevel -= 4; 185 186 /* Display header stuff */ 187 NGLOGX("NG_MESG :"); 188 NGLOGX(" vers %d", msg->header.version); 189 NGLOGX(" arglen %d", msg->header.arglen); 190 NGLOGX(" flags %ld", msg->header.flags); 191 NGLOGX(" token %lu", (u_long)msg->header.token); 192 NGLOGX(" cookie %s (%d)", 193 NgCookie(msg->header.typecookie), msg->header.typecookie); 194 195 /* At lower debugging levels, skip ASCII translation */ 196 if (_gNgDebugLevel <= 2) 197 goto fail2; 198 199 /* If path is not absolute, don't bother trying to use relative 200 address on a different socket for the ASCII translation */ 201 if (strchr(path, ':') == NULL) 202 goto fail2; 203 204 /* Get a temporary socket */ 205 if (NgMkSockNode(NULL, &csock, NULL) < 0) 206 goto fail; 207 208 /* Copy binary message into request message payload */ 209 arglen = msg->header.arglen; 210 if (arglen > ARGS_BUFSIZE) 211 arglen = ARGS_BUFSIZE; 212 memcpy(bin, msg, sizeof(*msg) + arglen); 213 bin->header.arglen = arglen; 214 215 /* Ask the node to translate the binary message to ASCII for us */ 216 if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, 217 NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) 218 goto fail; 219 if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) 220 goto fail; 221 222 /* Display command string and arguments */ 223 NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); 224 NGLOGX(" args %s", bin->data); 225 goto done; 226 227fail: 228 /* Just display binary version */ 229 NGLOGX(" [error decoding message: %s]", strerror(errno)); 230fail2: 231 NGLOGX(" cmd %d", msg->header.cmd); 232 NGLOGX(" args (%d bytes)", msg->header.arglen); 233 _NgDebugBytes(msg->data, msg->header.arglen); 234 235done: 236 if (csock != -1) 237 (void)close(csock); 238 _gNgDebugLevel = debugSave; 239} 240 241/* 242 * Return the name of the node type corresponding to the cookie 243 */ 244static const char * 245NgCookie(int cookie) 246{ 247 int k; 248 249 for (k = 0; cookies[k].cookie != 0; k++) { 250 if (cookies[k].cookie == cookie) 251 return cookies[k].type; 252 } 253 return "??"; 254} 255 256/* 257 * Dump bytes in hex 258 */ 259void 260_NgDebugBytes(const u_char *ptr, int len) 261{ 262 char buf[100]; 263 int k, count; 264 265#define BYPERLINE 16 266 267 for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { 268 269 /* Do hex */ 270 snprintf(buf, sizeof(buf), "%04x: ", count); 271 for (k = 0; k < BYPERLINE; k++, count++) 272 if (count < len) 273 snprintf(buf + strlen(buf), 274 sizeof(buf) - strlen(buf), "%02x ", ptr[k]); 275 else 276 snprintf(buf + strlen(buf), 277 sizeof(buf) - strlen(buf), " "); 278 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); 279 count -= BYPERLINE; 280 281 /* Do ASCII */ 282 for (k = 0; k < BYPERLINE; k++, count++) 283 if (count < len) 284 snprintf(buf + strlen(buf), 285 sizeof(buf) - strlen(buf), 286 "%c", isprint(ptr[k]) ? ptr[k] : '.'); 287 else 288 snprintf(buf + strlen(buf), 289 sizeof(buf) - strlen(buf), " "); 290 count -= BYPERLINE; 291 292 /* Print it */ 293 NGLOGX("%s", buf); 294 } 295} 296 297