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