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$ 40 * $Whistle: debug.c,v 1.24 1999/01/24 01:15:33 archie Exp $ 41 */ 42 43 #include <sys/types.h> 44 #include <sys/time.h> 45 #include <sys/ioctl.h> 46 47 #include <stdarg.h> 48 49 #include <netinet/in.h> 50 #include <net/ethernet.h> 51 #include <net/bpf.h> 52 53 #include <netgraph/ng_message.h> 54 #include <netgraph/ng_socket.h> 55 56 #include "netgraph.h" 57 #include "internal.h" 58 59 #include <netgraph/ng_UI.h> 60 #include <netgraph/ng_async.h> 61 #include <netgraph/ng_bpf.h> 62 #include <netgraph/ng_cisco.h> 63 #include <netgraph/ng_echo.h> 64 #include <netgraph/ng_ether.h> 65 #include <netgraph/ng_frame_relay.h> 66 #include <netgraph/ng_hole.h> 67 #include <netgraph/ng_iface.h> 68 #include <netgraph/ng_ksocket.h> 69 #include <netgraph/ng_lmi.h> 70 #include <netgraph/ng_ppp.h> 71 #include <netgraph/ng_pppoe.h> 72 #include <netgraph/ng_rfc1490.h> 73 #include <netgraph/ng_socket.h> 74 #include <netgraph/ng_tee.h> 75 #include <netgraph/ng_tty.h> 76 #include <netgraph/ng_vjc.h> 77 #ifdef WHISTLE 78 #include <machine/../isa/df_def.h> 79 #include <machine/../isa/if_wfra.h> 80 #include <machine/../isa/ipac.h> 81 #include <netgraph/ng_df.h> 82 #include <netgraph/ng_ipac.h> 83 #include <netgraph/ng_mppc.h> 84 #include <netgraph/ng_pptpgre.h> 85 #include <netgraph/ng_tn.h> 86 #endif 87 88 /* Global debug level */ 89 int _gNgDebugLevel = 0; 90 91 /* Debug printing functions */ 92 void (*_NgLog) (const char *fmt,...) = warn; 93 void (*_NgLogx) (const char *fmt,...) = warnx; 94 95 /* Internal functions */ 96 static const char *NgCookie(int cookie); 97 98 /* Known typecookie list */ 99 struct ng_cookie { 100 int cookie; 101 const char *type; 102 }; 103 104 #define COOKIE(c) { NGM_ ## c ## _COOKIE, #c } 105 106 /* List of known cookies */ 107 static const struct ng_cookie cookies[] = { 108 COOKIE(UI), 109 COOKIE(ASYNC), 110 COOKIE(BPF), 111 COOKIE(CISCO), 112 COOKIE(ECHO), 113 COOKIE(ETHER), 114 COOKIE(FRAMERELAY), 115 COOKIE(GENERIC), 116 COOKIE(HOLE), 117 COOKIE(IFACE), 118 COOKIE(KSOCKET), 119 COOKIE(LMI), 120 COOKIE(PPP), 121 COOKIE(PPPOE), 122 COOKIE(RFC1490), 123 COOKIE(SOCKET), 124 COOKIE(TEE), 125 COOKIE(TTY), 126 COOKIE(VJC), 127 #ifdef WHISTLE 128 COOKIE(DF), 129 COOKIE(IPAC), 130 COOKIE(MPPC), 131 COOKIE(PPTPGRE), 132 COOKIE(TN), 133 COOKIE(WFRA), 134 #endif 135 { 0, NULL } 136 }; 137 138 /* 139 * Set debug level, ie, verbosity, if "level" is non-negative. 140 * Returns old debug level. 141 */ 142 int 143 NgSetDebug(int level) 144 { 145 int old = _gNgDebugLevel; 146 147 if (level < 0) 148 level = old; 149 _gNgDebugLevel = level; 150 return (old); 151 } 152 153 /* 154 * Set debug logging functions. 155 */ 156 void 157 NgSetErrLog(void (*log) (const char *fmt,...), 158 void (*logx) (const char *fmt,...)) 159 { 160 _NgLog = log; 161 _NgLogx = logx; 162 } 163 164 /* 165 * Display a netgraph sockaddr 166 */ 167 void 168 _NgDebugSockaddr(const struct sockaddr_ng *sg) 169 { 170 NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", 171 sg->sg_family, sg->sg_len, sg->sg_data); 172 } 173 174 #define ARGS_BUFSIZE 1024 175 176 /* 177 * Display a negraph message 178 */ 179 void 180 _NgDebugMsg(const struct ng_mesg *msg, const char *path) 181 { 182 u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; 183 struct ng_mesg *const req = (struct ng_mesg *)buf; 184 struct ng_mesg *const bin = (struct ng_mesg *)req->data; 185 int arglen, debugSave, csock = -1; 186 187 /* Lower debugging to avoid infinite recursion */ 188 debugSave = _gNgDebugLevel; 189 _gNgDebugLevel -= 4; 190 191 /* Display header stuff */ 192 NGLOGX("NG_MESG :"); 193 NGLOGX(" vers %d", msg->header.version); 194 NGLOGX(" arglen %d", msg->header.arglen); 195 NGLOGX(" flags %ld", msg->header.flags); 196 NGLOGX(" token %lu", (u_long)msg->header.token); 197 NGLOGX(" cookie %s (%d)", 198 NgCookie(msg->header.typecookie), msg->header.typecookie); 199 200 /* At lower debugging levels, skip ASCII translation */ 201 if (_gNgDebugLevel <= 2) 202 goto fail2; 203 204 /* If path is not absolute, don't bother trying to use relative 205 address on a different socket for the ASCII translation */ 206 if (strchr(path, ':') == NULL) 207 goto fail2; 208 209 /* Get a temporary socket */ 210 if (NgMkSockNode(NULL, &csock, NULL) < 0) 211 goto fail; 212 213 /* Copy binary message into request message payload */ 214 arglen = msg->header.arglen; 215 if (arglen > ARGS_BUFSIZE) 216 arglen = ARGS_BUFSIZE; 217 memcpy(bin, msg, sizeof(*msg) + arglen); 218 bin->header.arglen = arglen; 219 220 /* Ask the node to translate the binary message to ASCII for us */ 221 if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, 222 NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) 223 goto fail; 224 if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) 225 goto fail; 226 227 /* Display command string and arguments */ 228 NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); 229 NGLOGX(" args %s", bin->data); 230 goto done; 231 232 fail: 233 /* Just display binary version */ 234 NGLOGX(" [error decoding message: %s]", strerror(errno)); 235 fail2: 236 NGLOGX(" cmd %d", msg->header.cmd); 237 NGLOGX(" args (%d bytes)", msg->header.arglen); 238 _NgDebugBytes(msg->data, msg->header.arglen); 239 240 done: 241 if (csock != -1) 242 (void)close(csock); 243 _gNgDebugLevel = debugSave; 244 } 245 246 /* 247 * Return the name of the node type corresponding to the cookie 248 */ 249 static const char * 250 NgCookie(int cookie) 251 { 252 int k; 253 254 for (k = 0; cookies[k].cookie != 0; k++) { 255 if (cookies[k].cookie == cookie) 256 return cookies[k].type; 257 } 258 return "??"; 259 } 260 261 /* 262 * Dump bytes in hex 263 */ 264 void 265 _NgDebugBytes(const u_char *ptr, int len) 266 { 267 char buf[100]; 268 int k, count; 269 270 #define BYPERLINE 16 271 272 for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { 273 274 /* Do hex */ 275 snprintf(buf, sizeof(buf), "%04x: ", count); 276 for (k = 0; k < BYPERLINE; k++, count++) 277 if (count < len) 278 snprintf(buf + strlen(buf), 279 sizeof(buf) - strlen(buf), "%02x ", ptr[k]); 280 else 281 snprintf(buf + strlen(buf), 282 sizeof(buf) - strlen(buf), " "); 283 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); 284 count -= BYPERLINE; 285 286 /* Do ASCII */ 287 for (k = 0; k < BYPERLINE; k++, count++) 288 if (count < len) 289 snprintf(buf + strlen(buf), 290 sizeof(buf) - strlen(buf), 291 "%c", isprint(ptr[k]) ? ptr[k] : '.'); 292 else 293 snprintf(buf + strlen(buf), 294 sizeof(buf) - strlen(buf), " "); 295 count -= BYPERLINE; 296 297 /* Print it */ 298 NGLOGX("%s", buf); 299 } 300 } 301 302