debug.c revision 54098
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 54098 1999-12-03 23:12:41Z 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(BPF), 107 COOKIE(CISCO), 108 COOKIE(ECHO), 109 COOKIE(ETHER), 110 COOKIE(FRAMERELAY), 111 COOKIE(GENERIC), 112 COOKIE(HOLE), 113 COOKIE(IFACE), 114 COOKIE(KSOCKET), 115 COOKIE(LMI), 116 COOKIE(PPP), 117 COOKIE(PPPOE), 118 COOKIE(RFC1490), 119 COOKIE(SOCKET), 120 COOKIE(TEE), 121 COOKIE(TTY), 122 COOKIE(VJC), 123#ifdef WHISTLE 124 COOKIE(DF), 125 COOKIE(IPAC), 126 COOKIE(MPPC), 127 COOKIE(PPTPGRE), 128 COOKIE(TN), 129 COOKIE(WFRA), 130#endif 131 { 0, NULL } 132}; 133 134/* 135 * Set debug level, ie, verbosity, if "level" is non-negative. 136 * Returns old debug level. 137 */ 138int 139NgSetDebug(int level) 140{ 141 int old = _gNgDebugLevel; 142 143 if (level < 0) 144 level = old; 145 _gNgDebugLevel = level; 146 return (old); 147} 148 149/* 150 * Set debug logging functions. 151 */ 152void 153NgSetErrLog(void (*log) (const char *fmt,...), 154 void (*logx) (const char *fmt,...)) 155{ 156 _NgLog = log; 157 _NgLogx = logx; 158} 159 160/* 161 * Display a netgraph sockaddr 162 */ 163void 164_NgDebugSockaddr(const struct sockaddr_ng *sg) 165{ 166 NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", 167 sg->sg_family, sg->sg_len, sg->sg_data); 168} 169 170#define ARGS_BUFSIZE 1024 171 172/* 173 * Display a negraph message 174 */ 175void 176_NgDebugMsg(const struct ng_mesg *msg, const char *path) 177{ 178 u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; 179 struct ng_mesg *const req = (struct ng_mesg *)buf; 180 struct ng_mesg *const bin = (struct ng_mesg *)req->data; 181 int arglen, debugSave, csock = -1; 182 183 /* Lower debugging to avoid infinite recursion */ 184 debugSave = _gNgDebugLevel; 185 _gNgDebugLevel -= 4; 186 187 /* Display header stuff */ 188 NGLOGX("NG_MESG :"); 189 NGLOGX(" vers %d", msg->header.version); 190 NGLOGX(" arglen %d", msg->header.arglen); 191 NGLOGX(" flags %ld", msg->header.flags); 192 NGLOGX(" token %lu", (u_long)msg->header.token); 193 NGLOGX(" cookie %s (%d)", 194 NgCookie(msg->header.typecookie), msg->header.typecookie); 195 196 /* At lower debugging levels, skip ASCII translation */ 197 if (_gNgDebugLevel <= 2) 198 goto fail2; 199 200 /* If path is not absolute, don't bother trying to use relative 201 address on a different socket for the ASCII translation */ 202 if (strchr(path, ':') == NULL) 203 goto fail2; 204 205 /* Get a temporary socket */ 206 if (NgMkSockNode(NULL, &csock, NULL) < 0) 207 goto fail; 208 209 /* Copy binary message into request message payload */ 210 arglen = msg->header.arglen; 211 if (arglen > ARGS_BUFSIZE) 212 arglen = ARGS_BUFSIZE; 213 memcpy(bin, msg, sizeof(*msg) + arglen); 214 bin->header.arglen = arglen; 215 216 /* Ask the node to translate the binary message to ASCII for us */ 217 if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, 218 NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) 219 goto fail; 220 if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) 221 goto fail; 222 223 /* Display command string and arguments */ 224 NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); 225 NGLOGX(" args %s", bin->data); 226 goto done; 227 228fail: 229 /* Just display binary version */ 230 NGLOGX(" [error decoding message: %s]", strerror(errno)); 231fail2: 232 NGLOGX(" cmd %d", msg->header.cmd); 233 NGLOGX(" args (%d bytes)", msg->header.arglen); 234 _NgDebugBytes(msg->data, msg->header.arglen); 235 236done: 237 if (csock != -1) 238 (void)close(csock); 239 _gNgDebugLevel = debugSave; 240} 241 242/* 243 * Return the name of the node type corresponding to the cookie 244 */ 245static const char * 246NgCookie(int cookie) 247{ 248 int k; 249 250 for (k = 0; cookies[k].cookie != 0; k++) { 251 if (cookies[k].cookie == cookie) 252 return cookies[k].type; 253 } 254 return "??"; 255} 256 257/* 258 * Dump bytes in hex 259 */ 260void 261_NgDebugBytes(const u_char *ptr, int len) 262{ 263 char buf[100]; 264 int k, count; 265 266#define BYPERLINE 16 267 268 for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { 269 270 /* Do hex */ 271 snprintf(buf, sizeof(buf), "%04x: ", count); 272 for (k = 0; k < BYPERLINE; k++, count++) 273 if (count < len) 274 snprintf(buf + strlen(buf), 275 sizeof(buf) - strlen(buf), "%02x ", ptr[k]); 276 else 277 snprintf(buf + strlen(buf), 278 sizeof(buf) - strlen(buf), " "); 279 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); 280 count -= BYPERLINE; 281 282 /* Do ASCII */ 283 for (k = 0; k < BYPERLINE; k++, count++) 284 if (count < len) 285 snprintf(buf + strlen(buf), 286 sizeof(buf) - strlen(buf), 287 "%c", isprint(ptr[k]) ? ptr[k] : '.'); 288 else 289 snprintf(buf + strlen(buf), 290 sizeof(buf) - strlen(buf), " "); 291 count -= BYPERLINE; 292 293 /* Print it */ 294 NGLOGX("%s", buf); 295 } 296} 297 298