debug.c revision 201123
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: head/lib/libnetgraph/debug.c 201123 2009-12-28 10:48:01Z luigi $"); 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_cisco.h> 66#include <netgraph/ng_device.h> 67#include <netgraph/ng_echo.h> 68#include <netgraph/ng_eiface.h> 69#include <netgraph/ng_etf.h> 70#include <netgraph/ng_ether.h> 71#include <netgraph/ng_fec.h> 72#include <netgraph/ng_frame_relay.h> 73#include <netgraph/ng_gif.h> 74#include <netgraph/ng_gif_demux.h> 75#include <netgraph/ng_hole.h> 76#include <netgraph/ng_hub.h> 77#include <netgraph/ng_iface.h> 78#include <netgraph/ng_ip_input.h> 79#include <netinet/ip_fw.h> 80#include <netinet/ip_fw_private.h> /* the NGM cookie is here */ 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/ng_one2many.h> 88#include <netgraph/ng_ppp.h> 89#include <netgraph/ng_pppoe.h> 90#include <netgraph/ng_pptpgre.h> 91#include <netgraph/ng_rfc1490.h> 92#include <netgraph/ng_socket.h> 93#include <netgraph/ng_source.h> 94#include <netgraph/ng_split.h> 95#include <netgraph/ng_sppp.h> 96#include <netgraph/ng_tcpmss.h> 97#include <netgraph/ng_tee.h> 98#include <netgraph/ng_tty.h> 99#include <netgraph/ng_vjc.h> 100#include <netgraph/ng_vlan.h> 101#ifdef WHISTLE 102#include <machine/../isa/df_def.h> 103#include <machine/../isa/if_wfra.h> 104#include <machine/../isa/ipac.h> 105#include <netgraph/ng_df.h> 106#include <netgraph/ng_ipac.h> 107#include <netgraph/ng_tn.h> 108#endif 109 110/* Global debug level */ 111int _gNgDebugLevel = 0; 112 113/* Debug printing functions */ 114void (*_NgLog) (const char *fmt,...) = warn; 115void (*_NgLogx) (const char *fmt,...) = warnx; 116 117/* Internal functions */ 118static const char *NgCookie(int cookie); 119 120/* Known typecookie list */ 121struct ng_cookie { 122 int cookie; 123 const char *type; 124}; 125 126#define COOKIE(c) { NGM_ ## c ## _COOKIE, #c } 127 128/* List of known cookies */ 129static const struct ng_cookie cookies[] = { 130 COOKIE(UI), 131 COOKIE(ASYNC), 132 COOKIE(ATMLLC), 133 COOKIE(BPF), 134 COOKIE(BRIDGE), 135 COOKIE(CISCO), 136 COOKIE(DEVICE), 137 COOKIE(ECHO), 138 COOKIE(EIFACE), 139 COOKIE(ETF), 140 COOKIE(ETHER), 141 COOKIE(FEC), 142 COOKIE(FRAMERELAY), 143 COOKIE(GIF), 144 COOKIE(GIF_DEMUX), 145 COOKIE(GENERIC), 146 COOKIE(HOLE), 147 COOKIE(HUB), 148 COOKIE(IFACE), 149 COOKIE(IP_INPUT), 150 COOKIE(IPFW), 151 COOKIE(KSOCKET), 152 COOKIE(L2TP), 153 COOKIE(LMI), 154 COOKIE(MPPC), 155 COOKIE(NAT), 156 COOKIE(ONE2MANY), 157 COOKIE(PPP), 158 COOKIE(PPPOE), 159 COOKIE(PPTPGRE), 160 COOKIE(RFC1490), 161 COOKIE(SOCKET), 162 COOKIE(SOURCE), 163 COOKIE(SPLIT), 164 COOKIE(SPPP), 165 COOKIE(TCPMSS), 166 COOKIE(TEE), 167 COOKIE(TTY), 168 COOKIE(VJC), 169 COOKIE(VLAN), 170#ifdef WHISTLE 171 COOKIE(DF), 172 COOKIE(IPAC), 173 COOKIE(TN), 174 COOKIE(WFRA), 175#endif 176 { 0, NULL } 177}; 178 179/* 180 * Set debug level, ie, verbosity, if "level" is non-negative. 181 * Returns old debug level. 182 */ 183int 184NgSetDebug(int level) 185{ 186 int old = _gNgDebugLevel; 187 188 if (level < 0) 189 level = old; 190 _gNgDebugLevel = level; 191 return (old); 192} 193 194/* 195 * Set debug logging functions. 196 */ 197void 198NgSetErrLog(void (*log) (const char *fmt,...), 199 void (*logx) (const char *fmt,...)) 200{ 201 _NgLog = log; 202 _NgLogx = logx; 203} 204 205/* 206 * Display a netgraph sockaddr 207 */ 208void 209_NgDebugSockaddr(const struct sockaddr_ng *sg) 210{ 211 NGLOGX("SOCKADDR: { fam=%d len=%d addr=\"%s\" }", 212 sg->sg_family, sg->sg_len, sg->sg_data); 213} 214 215#define ARGS_BUFSIZE 2048 216#define RECURSIVE_DEBUG_ADJUST 4 217 218/* 219 * Display a negraph message 220 */ 221void 222_NgDebugMsg(const struct ng_mesg *msg, const char *path) 223{ 224 u_char buf[2 * sizeof(struct ng_mesg) + ARGS_BUFSIZE]; 225 struct ng_mesg *const req = (struct ng_mesg *)buf; 226 struct ng_mesg *const bin = (struct ng_mesg *)req->data; 227 int arglen, csock = -1; 228 229 /* Display header stuff */ 230 NGLOGX("NG_MESG :"); 231 NGLOGX(" vers %d", msg->header.version); 232 NGLOGX(" arglen %d", msg->header.arglen); 233 NGLOGX(" flags %ld", msg->header.flags); 234 NGLOGX(" token %lu", (u_long)msg->header.token); 235 NGLOGX(" cookie %s (%d)", 236 NgCookie(msg->header.typecookie), msg->header.typecookie); 237 238 /* At lower debugging levels, skip ASCII translation */ 239 if (_gNgDebugLevel <= 2) 240 goto fail2; 241 242 /* If path is not absolute, don't bother trying to use relative 243 address on a different socket for the ASCII translation */ 244 if (strchr(path, ':') == NULL) 245 goto fail2; 246 247 /* Get a temporary socket */ 248 if (NgMkSockNode(NULL, &csock, NULL) < 0) 249 goto fail; 250 251 /* Copy binary message into request message payload */ 252 arglen = msg->header.arglen; 253 if (arglen > ARGS_BUFSIZE) 254 arglen = ARGS_BUFSIZE; 255 memcpy(bin, msg, sizeof(*msg) + arglen); 256 bin->header.arglen = arglen; 257 258 /* Lower debugging to avoid infinite recursion */ 259 _gNgDebugLevel -= RECURSIVE_DEBUG_ADJUST; 260 261 /* Ask the node to translate the binary message to ASCII for us */ 262 if (NgSendMsg(csock, path, NGM_GENERIC_COOKIE, 263 NGM_BINARY2ASCII, bin, sizeof(*bin) + bin->header.arglen) < 0) { 264 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; 265 goto fail; 266 } 267 if (NgRecvMsg(csock, req, sizeof(buf), NULL) < 0) { 268 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; 269 goto fail; 270 } 271 272 /* Restore debugging level */ 273 _gNgDebugLevel += RECURSIVE_DEBUG_ADJUST; 274 275 /* Display command string and arguments */ 276 NGLOGX(" cmd %s (%d)", bin->header.cmdstr, bin->header.cmd); 277 NGLOGX(" args %s", bin->data); 278 goto done; 279 280fail: 281 /* Just display binary version */ 282 NGLOGX(" [error decoding message: %s]", strerror(errno)); 283fail2: 284 NGLOGX(" cmd %d", msg->header.cmd); 285 NGLOGX(" args (%d bytes)", msg->header.arglen); 286 _NgDebugBytes((u_char *)msg->data, msg->header.arglen); 287 288done: 289 if (csock != -1) 290 (void)close(csock); 291} 292 293/* 294 * Return the name of the node type corresponding to the cookie 295 */ 296static const char * 297NgCookie(int cookie) 298{ 299 int k; 300 301 for (k = 0; cookies[k].cookie != 0; k++) { 302 if (cookies[k].cookie == cookie) 303 return cookies[k].type; 304 } 305 return "??"; 306} 307 308/* 309 * Dump bytes in hex 310 */ 311void 312_NgDebugBytes(const u_char *ptr, int len) 313{ 314 char buf[100]; 315 int k, count; 316 317#define BYPERLINE 16 318 319 for (count = 0; count < len; ptr += BYPERLINE, count += BYPERLINE) { 320 321 /* Do hex */ 322 snprintf(buf, sizeof(buf), "%04x: ", count); 323 for (k = 0; k < BYPERLINE; k++, count++) 324 if (count < len) 325 snprintf(buf + strlen(buf), 326 sizeof(buf) - strlen(buf), "%02x ", ptr[k]); 327 else 328 snprintf(buf + strlen(buf), 329 sizeof(buf) - strlen(buf), " "); 330 snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " "); 331 count -= BYPERLINE; 332 333 /* Do ASCII */ 334 for (k = 0; k < BYPERLINE; k++, count++) 335 if (count < len) 336 snprintf(buf + strlen(buf), 337 sizeof(buf) - strlen(buf), 338 "%c", isprint(ptr[k]) ? ptr[k] : '.'); 339 else 340 snprintf(buf + strlen(buf), 341 sizeof(buf) - strlen(buf), " "); 342 count -= BYPERLINE; 343 344 /* Print it */ 345 NGLOGX("%s", buf); 346 } 347} 348 349