17b6ab19dSGarrett Wollman /* 27b6ab19dSGarrett Wollman * Copyright (c) 1983, 1988, 1993 37b6ab19dSGarrett Wollman * The Regents of the University of California. All rights reserved. 47b6ab19dSGarrett Wollman * 57b6ab19dSGarrett Wollman * Redistribution and use in source and binary forms, with or without 67b6ab19dSGarrett Wollman * modification, are permitted provided that the following conditions 77b6ab19dSGarrett Wollman * are met: 87b6ab19dSGarrett Wollman * 1. Redistributions of source code must retain the above copyright 97b6ab19dSGarrett Wollman * notice, this list of conditions and the following disclaimer. 107b6ab19dSGarrett Wollman * 2. Redistributions in binary form must reproduce the above copyright 117b6ab19dSGarrett Wollman * notice, this list of conditions and the following disclaimer in the 127b6ab19dSGarrett Wollman * documentation and/or other materials provided with the distribution. 137b6ab19dSGarrett Wollman * 4. Neither the name of the University nor the names of its contributors 147b6ab19dSGarrett Wollman * may be used to endorse or promote products derived from this software 157b6ab19dSGarrett Wollman * without specific prior written permission. 167b6ab19dSGarrett Wollman * 177b6ab19dSGarrett Wollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 187b6ab19dSGarrett Wollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 197b6ab19dSGarrett Wollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 207b6ab19dSGarrett Wollman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 217b6ab19dSGarrett Wollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 227b6ab19dSGarrett Wollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 237b6ab19dSGarrett Wollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 247b6ab19dSGarrett Wollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 257b6ab19dSGarrett Wollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 267b6ab19dSGarrett Wollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 277b6ab19dSGarrett Wollman * SUCH DAMAGE. 28c90fe7dcSMark Murray * 297f3dea24SPeter Wemm * $FreeBSD$ 307b6ab19dSGarrett Wollman */ 317b6ab19dSGarrett Wollman 327b6ab19dSGarrett Wollman #define RIPCMDS 337b6ab19dSGarrett Wollman #include "defs.h" 347b6ab19dSGarrett Wollman #include "pathnames.h" 357b6ab19dSGarrett Wollman #include <sys/stat.h> 367b6ab19dSGarrett Wollman #include <sys/signal.h> 377b6ab19dSGarrett Wollman #include <fcntl.h> 387b6ab19dSGarrett Wollman 39caa79e36SBruce M Simpson #ifdef __NetBSD__ 402c7a9781SMark Murray __RCSID("$NetBSD$"); 41caa79e36SBruce M Simpson #elif defined(__FreeBSD__) 42caa79e36SBruce M Simpson __RCSID("$FreeBSD$"); 43caa79e36SBruce M Simpson #else 44caa79e36SBruce M Simpson __RCSID("$Revision: 2.27 $"); 45caa79e36SBruce M Simpson #ident "$Revision: 2.27 $" 462c7a9781SMark Murray #endif 472c7a9781SMark Murray 487b6ab19dSGarrett Wollman 497b6ab19dSGarrett Wollman #ifdef sgi 507b6ab19dSGarrett Wollman /* use *stat64 for files on large file systems */ 517b6ab19dSGarrett Wollman #define stat stat64 527b6ab19dSGarrett Wollman #endif 537b6ab19dSGarrett Wollman 5471965874SGarrett Wollman int tracelevel, new_tracelevel; 5598815cc7SPeter Wemm FILE *ftrace; /* output trace file */ 562c7a9781SMark Murray static const char *sigtrace_pat = "%s"; 57534734edSWarner Losh static char savetracename[PATH_MAX]; 58534734edSWarner Losh char inittracename[PATH_MAX]; 59f2ca6d8aSPoul-Henning Kamp static int file_trace; /* 1=tracing to file, not stdout */ 607b6ab19dSGarrett Wollman 617b6ab19dSGarrett Wollman static void trace_dump(void); 622c7a9781SMark Murray static void tmsg(const char *, ...) PATTRIB(1,2); 637b6ab19dSGarrett Wollman 647b6ab19dSGarrett Wollman 65d5b718b3SGarrett Wollman /* convert string to printable characters 66d5b718b3SGarrett Wollman */ 67d5b718b3SGarrett Wollman static char * 68d5b718b3SGarrett Wollman qstring(u_char *s, int len) 69d5b718b3SGarrett Wollman { 70d5b718b3SGarrett Wollman static char buf[8*20+1]; 71d5b718b3SGarrett Wollman char *p; 72d5b718b3SGarrett Wollman u_char *s2, c; 73d5b718b3SGarrett Wollman 74d5b718b3SGarrett Wollman 75d5b718b3SGarrett Wollman for (p = buf; len != 0 && p < &buf[sizeof(buf)-1]; len--) { 76d5b718b3SGarrett Wollman c = *s++; 77d5b718b3SGarrett Wollman if (c == '\0') { 78d5b718b3SGarrett Wollman for (s2 = s+1; s2 < &s[len]; s2++) { 79d5b718b3SGarrett Wollman if (*s2 != '\0') 80d5b718b3SGarrett Wollman break; 81d5b718b3SGarrett Wollman } 82d5b718b3SGarrett Wollman if (s2 >= &s[len]) 83d5b718b3SGarrett Wollman goto exit; 84d5b718b3SGarrett Wollman } 85d5b718b3SGarrett Wollman 86d5b718b3SGarrett Wollman if (c >= ' ' && c < 0x7f && c != '\\') { 87d5b718b3SGarrett Wollman *p++ = c; 88d5b718b3SGarrett Wollman continue; 89d5b718b3SGarrett Wollman } 90d5b718b3SGarrett Wollman *p++ = '\\'; 91d5b718b3SGarrett Wollman switch (c) { 92d5b718b3SGarrett Wollman case '\\': 93d5b718b3SGarrett Wollman *p++ = '\\'; 94d5b718b3SGarrett Wollman break; 95d5b718b3SGarrett Wollman case '\n': 96d5b718b3SGarrett Wollman *p++= 'n'; 97d5b718b3SGarrett Wollman break; 98d5b718b3SGarrett Wollman case '\r': 99d5b718b3SGarrett Wollman *p++= 'r'; 100d5b718b3SGarrett Wollman break; 101d5b718b3SGarrett Wollman case '\t': 102d5b718b3SGarrett Wollman *p++ = 't'; 103d5b718b3SGarrett Wollman break; 104d5b718b3SGarrett Wollman case '\b': 105d5b718b3SGarrett Wollman *p++ = 'b'; 106d5b718b3SGarrett Wollman break; 107d5b718b3SGarrett Wollman default: 108d5b718b3SGarrett Wollman p += sprintf(p,"%o",c); 109d5b718b3SGarrett Wollman break; 110d5b718b3SGarrett Wollman } 111d5b718b3SGarrett Wollman } 112d5b718b3SGarrett Wollman exit: 113d5b718b3SGarrett Wollman *p = '\0'; 114d5b718b3SGarrett Wollman return buf; 115d5b718b3SGarrett Wollman } 116d5b718b3SGarrett Wollman 117d5b718b3SGarrett Wollman 1187b6ab19dSGarrett Wollman /* convert IP address to a string, but not into a single buffer 1197b6ab19dSGarrett Wollman */ 1207b6ab19dSGarrett Wollman char * 1217b6ab19dSGarrett Wollman naddr_ntoa(naddr a) 1227b6ab19dSGarrett Wollman { 1237b6ab19dSGarrett Wollman #define NUM_BUFS 4 1247b6ab19dSGarrett Wollman static int bufno; 1257b6ab19dSGarrett Wollman static struct { 1267b6ab19dSGarrett Wollman char str[16]; /* xxx.xxx.xxx.xxx\0 */ 1277b6ab19dSGarrett Wollman } bufs[NUM_BUFS]; 1287b6ab19dSGarrett Wollman char *s; 1297b6ab19dSGarrett Wollman struct in_addr addr; 1307b6ab19dSGarrett Wollman 1317b6ab19dSGarrett Wollman addr.s_addr = a; 1327b6ab19dSGarrett Wollman s = strcpy(bufs[bufno].str, inet_ntoa(addr)); 1337b6ab19dSGarrett Wollman bufno = (bufno+1) % NUM_BUFS; 1347b6ab19dSGarrett Wollman return s; 1357b6ab19dSGarrett Wollman #undef NUM_BUFS 1367b6ab19dSGarrett Wollman } 1377b6ab19dSGarrett Wollman 1387b6ab19dSGarrett Wollman 1392c7a9781SMark Murray const char * 1407b6ab19dSGarrett Wollman saddr_ntoa(struct sockaddr *sa) 1417b6ab19dSGarrett Wollman { 142*562c5a82SPedro F. Giffuni return (sa == NULL) ? "?" : naddr_ntoa(S_ADDR(sa)); 1437b6ab19dSGarrett Wollman } 1447b6ab19dSGarrett Wollman 1457b6ab19dSGarrett Wollman 1467b6ab19dSGarrett Wollman static char * 1477b6ab19dSGarrett Wollman ts(time_t secs) { 1487b6ab19dSGarrett Wollman static char s[20]; 1497b6ab19dSGarrett Wollman 1507b6ab19dSGarrett Wollman secs += epoch.tv_sec; 1517b6ab19dSGarrett Wollman #ifdef sgi 1527b6ab19dSGarrett Wollman (void)cftime(s, "%T", &secs); 1537b6ab19dSGarrett Wollman #else 1542c7a9781SMark Murray memcpy(s, ctime(&secs)+11, 8); 1557b6ab19dSGarrett Wollman s[8] = '\0'; 1567b6ab19dSGarrett Wollman #endif 1577b6ab19dSGarrett Wollman return s; 1587b6ab19dSGarrett Wollman } 1597b6ab19dSGarrett Wollman 1607b6ab19dSGarrett Wollman 1617b6ab19dSGarrett Wollman /* On each event, display a time stamp. 1627b6ab19dSGarrett Wollman * This assumes that 'now' is update once for each event, and 1637b6ab19dSGarrett Wollman * that at least now.tv_usec changes. 1647b6ab19dSGarrett Wollman */ 16571965874SGarrett Wollman static struct timeval lastlog_time; 16671965874SGarrett Wollman 1677b6ab19dSGarrett Wollman void 1687b6ab19dSGarrett Wollman lastlog(void) 1697b6ab19dSGarrett Wollman { 17071965874SGarrett Wollman if (lastlog_time.tv_sec != now.tv_sec 17171965874SGarrett Wollman || lastlog_time.tv_usec != now.tv_usec) { 1727b6ab19dSGarrett Wollman (void)fprintf(ftrace, "-- %s --\n", ts(now.tv_sec)); 17371965874SGarrett Wollman lastlog_time = now; 1747b6ab19dSGarrett Wollman } 1757b6ab19dSGarrett Wollman } 1767b6ab19dSGarrett Wollman 1777b6ab19dSGarrett Wollman 1787b6ab19dSGarrett Wollman static void 1792c7a9781SMark Murray tmsg(const char *p, ...) 1807b6ab19dSGarrett Wollman { 1817b6ab19dSGarrett Wollman va_list args; 1827b6ab19dSGarrett Wollman 183*562c5a82SPedro F. Giffuni if (ftrace != NULL) { 1847b6ab19dSGarrett Wollman lastlog(); 1857b6ab19dSGarrett Wollman va_start(args, p); 1867b6ab19dSGarrett Wollman vfprintf(ftrace, p, args); 187caa79e36SBruce M Simpson va_end(args); 1882c7a9781SMark Murray (void)fputc('\n',ftrace); 1897b6ab19dSGarrett Wollman fflush(ftrace); 1907b6ab19dSGarrett Wollman } 1917b6ab19dSGarrett Wollman } 1927b6ab19dSGarrett Wollman 1937b6ab19dSGarrett Wollman 1942c7a9781SMark Murray void 1952c7a9781SMark Murray trace_close(int zap_stdio) 1967b6ab19dSGarrett Wollman { 1977b6ab19dSGarrett Wollman int fd; 1987b6ab19dSGarrett Wollman 1997b6ab19dSGarrett Wollman 2007b6ab19dSGarrett Wollman fflush(stdout); 2017b6ab19dSGarrett Wollman fflush(stderr); 2027b6ab19dSGarrett Wollman 203*562c5a82SPedro F. Giffuni if (ftrace != NULL && zap_stdio) { 20471965874SGarrett Wollman if (ftrace != stdout) 20571965874SGarrett Wollman fclose(ftrace); 206*562c5a82SPedro F. Giffuni ftrace = NULL; 2077b6ab19dSGarrett Wollman fd = open(_PATH_DEVNULL, O_RDWR); 2082c7a9781SMark Murray if (isatty(STDIN_FILENO)) 20971965874SGarrett Wollman (void)dup2(fd, STDIN_FILENO); 2102c7a9781SMark Murray if (isatty(STDOUT_FILENO)) 2117b6ab19dSGarrett Wollman (void)dup2(fd, STDOUT_FILENO); 2122c7a9781SMark Murray if (isatty(STDERR_FILENO)) 2137b6ab19dSGarrett Wollman (void)dup2(fd, STDERR_FILENO); 2147b6ab19dSGarrett Wollman (void)close(fd); 2157b6ab19dSGarrett Wollman } 21671965874SGarrett Wollman lastlog_time.tv_sec = 0; 2177b6ab19dSGarrett Wollman } 2187b6ab19dSGarrett Wollman 2197b6ab19dSGarrett Wollman 2207b6ab19dSGarrett Wollman void 2217b6ab19dSGarrett Wollman trace_flush(void) 2227b6ab19dSGarrett Wollman { 223*562c5a82SPedro F. Giffuni if (ftrace != NULL) { 2247b6ab19dSGarrett Wollman fflush(ftrace); 2257b6ab19dSGarrett Wollman if (ferror(ftrace)) 2262c7a9781SMark Murray trace_off("tracing off: %s", strerror(ferror(ftrace))); 2277b6ab19dSGarrett Wollman } 2287b6ab19dSGarrett Wollman } 2297b6ab19dSGarrett Wollman 2307b6ab19dSGarrett Wollman 2317b6ab19dSGarrett Wollman void 2322c7a9781SMark Murray trace_off(const char *p, ...) 2337b6ab19dSGarrett Wollman { 2347b6ab19dSGarrett Wollman va_list args; 2357b6ab19dSGarrett Wollman 2367b6ab19dSGarrett Wollman 237*562c5a82SPedro F. Giffuni if (ftrace != NULL) { 2387b6ab19dSGarrett Wollman lastlog(); 2397b6ab19dSGarrett Wollman va_start(args, p); 2407b6ab19dSGarrett Wollman vfprintf(ftrace, p, args); 241caa79e36SBruce M Simpson va_end(args); 2422c7a9781SMark Murray (void)fputc('\n',ftrace); 2437b6ab19dSGarrett Wollman } 2442c7a9781SMark Murray trace_close(file_trace); 2457b6ab19dSGarrett Wollman 2467b6ab19dSGarrett Wollman new_tracelevel = tracelevel = 0; 2477b6ab19dSGarrett Wollman } 2487b6ab19dSGarrett Wollman 2497b6ab19dSGarrett Wollman 25071965874SGarrett Wollman /* log a change in tracing 2517b6ab19dSGarrett Wollman */ 2527b6ab19dSGarrett Wollman void 2532c7a9781SMark Murray tracelevel_msg(const char *pat, 25471965874SGarrett Wollman int dump) /* -1=no dump, 0=default, 1=force */ 2557b6ab19dSGarrett Wollman { 256a3e04ddcSPoul-Henning Kamp static const char * const off_msgs[MAX_TRACELEVEL] = { 2577b6ab19dSGarrett Wollman "Tracing actions stopped", 2587b6ab19dSGarrett Wollman "Tracing packets stopped", 2597b6ab19dSGarrett Wollman "Tracing packet contents stopped", 2607b6ab19dSGarrett Wollman "Tracing kernel changes stopped", 2617b6ab19dSGarrett Wollman }; 262a3e04ddcSPoul-Henning Kamp static const char * const on_msgs[MAX_TRACELEVEL] = { 2637b6ab19dSGarrett Wollman "Tracing actions started", 2647b6ab19dSGarrett Wollman "Tracing packets started", 2657b6ab19dSGarrett Wollman "Tracing packet contents started", 2667b6ab19dSGarrett Wollman "Tracing kernel changes started", 2677b6ab19dSGarrett Wollman }; 26871965874SGarrett Wollman u_int old_tracelevel = tracelevel; 2697b6ab19dSGarrett Wollman 2707b6ab19dSGarrett Wollman 27171965874SGarrett Wollman if (new_tracelevel < 0) 27271965874SGarrett Wollman new_tracelevel = 0; 27371965874SGarrett Wollman else if (new_tracelevel > MAX_TRACELEVEL) 2747b6ab19dSGarrett Wollman new_tracelevel = MAX_TRACELEVEL; 27571965874SGarrett Wollman 27671965874SGarrett Wollman if (new_tracelevel < tracelevel) { 27771965874SGarrett Wollman if (new_tracelevel <= 0) { 27871965874SGarrett Wollman trace_off(pat, off_msgs[0]); 27971965874SGarrett Wollman } else do { 28071965874SGarrett Wollman tmsg(pat, off_msgs[tracelevel]); 28171965874SGarrett Wollman } 28271965874SGarrett Wollman while (--tracelevel != new_tracelevel); 28371965874SGarrett Wollman 28471965874SGarrett Wollman } else if (new_tracelevel > tracelevel) { 28571965874SGarrett Wollman do { 28671965874SGarrett Wollman tmsg(pat, on_msgs[tracelevel++]); 28771965874SGarrett Wollman } while (tracelevel != new_tracelevel); 28871965874SGarrett Wollman } 28971965874SGarrett Wollman 29071965874SGarrett Wollman if (dump > 0 29171965874SGarrett Wollman || (dump == 0 && old_tracelevel == 0 && tracelevel != 0)) 29271965874SGarrett Wollman trace_dump(); 29371965874SGarrett Wollman } 29471965874SGarrett Wollman 29571965874SGarrett Wollman 29671965874SGarrett Wollman void 2972c7a9781SMark Murray set_tracefile(const char *filename, 2982c7a9781SMark Murray const char *pat, 29971965874SGarrett Wollman int dump) /* -1=no dump, 0=default, 1=force */ 30071965874SGarrett Wollman { 30171965874SGarrett Wollman struct stat stbuf; 30271965874SGarrett Wollman FILE *n_ftrace; 3032c7a9781SMark Murray const char *fn; 30471965874SGarrett Wollman 30571965874SGarrett Wollman 30671965874SGarrett Wollman /* Allow a null filename to increase the level if the trace file 30771965874SGarrett Wollman * is already open or if coming from a trusted source, such as 30871965874SGarrett Wollman * a signal or the command line. 30971965874SGarrett Wollman */ 310*562c5a82SPedro F. Giffuni if (filename == NULL || filename[0] == '\0') { 311*562c5a82SPedro F. Giffuni filename = NULL; 312*562c5a82SPedro F. Giffuni if (ftrace == NULL) { 31371965874SGarrett Wollman if (inittracename[0] == '\0') { 31471965874SGarrett Wollman msglog("missing trace file name"); 3157b6ab19dSGarrett Wollman return; 3167b6ab19dSGarrett Wollman } 31771965874SGarrett Wollman fn = inittracename; 31871965874SGarrett Wollman } else { 319*562c5a82SPedro F. Giffuni fn = NULL; 3207b6ab19dSGarrett Wollman } 321d5b718b3SGarrett Wollman 32271965874SGarrett Wollman } else if (!strcmp(filename,"dump/../table")) { 32371965874SGarrett Wollman trace_dump(); 32471965874SGarrett Wollman return; 32571965874SGarrett Wollman 3267b6ab19dSGarrett Wollman } else { 32771965874SGarrett Wollman /* Allow the file specified with "-T file" to be reopened, 32871965874SGarrett Wollman * but require all other names specified over the net to 32971965874SGarrett Wollman * match the official path. The path can specify a directory 33071965874SGarrett Wollman * in which the file is to be created. 33171965874SGarrett Wollman */ 33271965874SGarrett Wollman if (strcmp(filename, inittracename) 33371965874SGarrett Wollman #ifdef _PATH_TRACE 33471965874SGarrett Wollman && (strncmp(filename, _PATH_TRACE, sizeof(_PATH_TRACE)-1) 33571965874SGarrett Wollman || strstr(filename,"../") 33671965874SGarrett Wollman || 0 > stat(_PATH_TRACE, &stbuf)) 33771965874SGarrett Wollman #endif 33871965874SGarrett Wollman ) { 33971965874SGarrett Wollman msglog("wrong trace file \"%s\"", filename); 34071965874SGarrett Wollman return; 3417b6ab19dSGarrett Wollman } 34271965874SGarrett Wollman 34371965874SGarrett Wollman /* If the new tracefile exists, it must be a regular file. 34471965874SGarrett Wollman */ 3452c7a9781SMark Murray if (stat(filename, &stbuf) >= 0 && !S_ISREG(stbuf.st_mode)) { 34671965874SGarrett Wollman msglog("wrong type (%#x) of trace file \"%s\"", 34771965874SGarrett Wollman stbuf.st_mode, filename); 34871965874SGarrett Wollman return; 3497b6ab19dSGarrett Wollman } 35071965874SGarrett Wollman 35171965874SGarrett Wollman fn = filename; 3527b6ab19dSGarrett Wollman } 35371965874SGarrett Wollman 354*562c5a82SPedro F. Giffuni if (fn != NULL) { 35571965874SGarrett Wollman n_ftrace = fopen(fn, "a"); 356*562c5a82SPedro F. Giffuni if (n_ftrace == NULL) { 35771965874SGarrett Wollman msglog("failed to open trace file \"%s\" %s", 35871965874SGarrett Wollman fn, strerror(errno)); 35971965874SGarrett Wollman if (fn == inittracename) 36071965874SGarrett Wollman inittracename[0] = '\0'; 36171965874SGarrett Wollman return; 36271965874SGarrett Wollman } 36371965874SGarrett Wollman 3642c7a9781SMark Murray tmsg("switch to trace file %s", fn); 36571965874SGarrett Wollman 3662c7a9781SMark Murray trace_close(file_trace = 1); 36771965874SGarrett Wollman 36871965874SGarrett Wollman if (fn != savetracename) 36971965874SGarrett Wollman strncpy(savetracename, fn, sizeof(savetracename)-1); 37071965874SGarrett Wollman ftrace = n_ftrace; 37171965874SGarrett Wollman 37271965874SGarrett Wollman fflush(stdout); 37371965874SGarrett Wollman fflush(stderr); 37471965874SGarrett Wollman dup2(fileno(ftrace), STDOUT_FILENO); 37571965874SGarrett Wollman dup2(fileno(ftrace), STDERR_FILENO); 37671965874SGarrett Wollman } 37771965874SGarrett Wollman 378*562c5a82SPedro F. Giffuni if (new_tracelevel == 0 || filename == NULL) 37971965874SGarrett Wollman new_tracelevel++; 380*562c5a82SPedro F. Giffuni tracelevel_msg(pat, dump != 0 ? dump : (filename != NULL)); 38171965874SGarrett Wollman } 38271965874SGarrett Wollman 38371965874SGarrett Wollman 38471965874SGarrett Wollman /* ARGSUSED */ 38571965874SGarrett Wollman void 3862c7a9781SMark Murray sigtrace_on(int s UNUSED) 38771965874SGarrett Wollman { 38871965874SGarrett Wollman new_tracelevel++; 3892c7a9781SMark Murray sigtrace_pat = "SIGUSR1: %s"; 39071965874SGarrett Wollman } 39171965874SGarrett Wollman 39271965874SGarrett Wollman 39371965874SGarrett Wollman /* ARGSUSED */ 39471965874SGarrett Wollman void 3952c7a9781SMark Murray sigtrace_off(int s UNUSED) 39671965874SGarrett Wollman { 39771965874SGarrett Wollman new_tracelevel--; 3982c7a9781SMark Murray sigtrace_pat = "SIGUSR2: %s"; 39971965874SGarrett Wollman } 40071965874SGarrett Wollman 40171965874SGarrett Wollman 40271965874SGarrett Wollman /* Set tracing after a signal. 40371965874SGarrett Wollman */ 40471965874SGarrett Wollman void 40571965874SGarrett Wollman set_tracelevel(void) 40671965874SGarrett Wollman { 40771965874SGarrett Wollman if (new_tracelevel == tracelevel) 40871965874SGarrett Wollman return; 40971965874SGarrett Wollman 41071965874SGarrett Wollman /* If tracing entirely off, and there was no tracefile specified 41171965874SGarrett Wollman * on the command line, then leave it off. 41271965874SGarrett Wollman */ 413*562c5a82SPedro F. Giffuni if (new_tracelevel > tracelevel && ftrace == NULL) { 41471965874SGarrett Wollman if (savetracename[0] != '\0') { 41571965874SGarrett Wollman set_tracefile(savetracename,sigtrace_pat,0); 41671965874SGarrett Wollman } else if (inittracename[0] != '\0') { 41771965874SGarrett Wollman set_tracefile(inittracename,sigtrace_pat,0); 41871965874SGarrett Wollman } else { 41971965874SGarrett Wollman new_tracelevel = 0; 42071965874SGarrett Wollman return; 42171965874SGarrett Wollman } 42271965874SGarrett Wollman } else { 42371965874SGarrett Wollman tracelevel_msg(sigtrace_pat, 0); 42471965874SGarrett Wollman } 4257b6ab19dSGarrett Wollman } 4267b6ab19dSGarrett Wollman 4277b6ab19dSGarrett Wollman 4287b6ab19dSGarrett Wollman /* display an address 4297b6ab19dSGarrett Wollman */ 4307b6ab19dSGarrett Wollman char * 4317b6ab19dSGarrett Wollman addrname(naddr addr, /* in network byte order */ 4327b6ab19dSGarrett Wollman naddr mask, 4337b6ab19dSGarrett Wollman int force) /* 0=show mask if nonstandard, */ 4347b6ab19dSGarrett Wollman { /* 1=always show mask, 2=never */ 4357b6ab19dSGarrett Wollman #define NUM_BUFS 4 4367b6ab19dSGarrett Wollman static int bufno; 4377b6ab19dSGarrett Wollman static struct { 4387b6ab19dSGarrett Wollman char str[15+20]; 4397b6ab19dSGarrett Wollman } bufs[NUM_BUFS]; 4407b6ab19dSGarrett Wollman char *s, *sp; 4417b6ab19dSGarrett Wollman naddr dmask; 4427b6ab19dSGarrett Wollman int i; 4437b6ab19dSGarrett Wollman 4447b6ab19dSGarrett Wollman s = strcpy(bufs[bufno].str, naddr_ntoa(addr)); 4457b6ab19dSGarrett Wollman bufno = (bufno+1) % NUM_BUFS; 4467b6ab19dSGarrett Wollman 4477b6ab19dSGarrett Wollman if (force == 1 || (force == 0 && mask != std_mask(addr))) { 4487b6ab19dSGarrett Wollman sp = &s[strlen(s)]; 4497b6ab19dSGarrett Wollman 4507b6ab19dSGarrett Wollman dmask = mask & -mask; 4517b6ab19dSGarrett Wollman if (mask + dmask == 0) { 4527b6ab19dSGarrett Wollman for (i = 0; i != 32 && ((1<<i) & mask) == 0; i++) 4537b6ab19dSGarrett Wollman continue; 4547b6ab19dSGarrett Wollman (void)sprintf(sp, "/%d", 32-i); 4557b6ab19dSGarrett Wollman 4567b6ab19dSGarrett Wollman } else { 4577b6ab19dSGarrett Wollman (void)sprintf(sp, " (mask %#x)", (u_int)mask); 4587b6ab19dSGarrett Wollman } 4597b6ab19dSGarrett Wollman } 4607b6ab19dSGarrett Wollman 4617b6ab19dSGarrett Wollman return s; 4627b6ab19dSGarrett Wollman #undef NUM_BUFS 4637b6ab19dSGarrett Wollman } 4647b6ab19dSGarrett Wollman 4657b6ab19dSGarrett Wollman 4667b6ab19dSGarrett Wollman /* display a bit-field 4677b6ab19dSGarrett Wollman */ 4687b6ab19dSGarrett Wollman struct bits { 4692c7a9781SMark Murray u_int bits_mask; 4702c7a9781SMark Murray u_int bits_clear; 4712c7a9781SMark Murray const char *bits_name; 4727b6ab19dSGarrett Wollman }; 4737b6ab19dSGarrett Wollman 474a3e04ddcSPoul-Henning Kamp static const struct bits if_bits[] = { 4757b6ab19dSGarrett Wollman { IFF_LOOPBACK, 0, "LOOPBACK" }, 4767b6ab19dSGarrett Wollman { IFF_POINTOPOINT, 0, "PT-TO-PT" }, 4777b6ab19dSGarrett Wollman { 0, 0, 0} 4787b6ab19dSGarrett Wollman }; 4797b6ab19dSGarrett Wollman 480a3e04ddcSPoul-Henning Kamp static const struct bits is_bits[] = { 481d5b718b3SGarrett Wollman { IS_ALIAS, 0, "ALIAS" }, 4827b6ab19dSGarrett Wollman { IS_SUBNET, 0, "" }, 483d5b718b3SGarrett Wollman { IS_REMOTE, (IS_NO_RDISC 484d5b718b3SGarrett Wollman | IS_BCAST_RDISC), "REMOTE" }, 4857b6ab19dSGarrett Wollman { IS_PASSIVE, (IS_NO_RDISC 4867b6ab19dSGarrett Wollman | IS_NO_RIP 4877b6ab19dSGarrett Wollman | IS_NO_SUPER_AG 4887b6ab19dSGarrett Wollman | IS_PM_RDISC 4897b6ab19dSGarrett Wollman | IS_NO_AG), "PASSIVE" }, 4907b6ab19dSGarrett Wollman { IS_EXTERNAL, 0, "EXTERNAL" }, 4917b6ab19dSGarrett Wollman { IS_CHECKED, 0, "" }, 4927b6ab19dSGarrett Wollman { IS_ALL_HOSTS, 0, "" }, 4937b6ab19dSGarrett Wollman { IS_ALL_ROUTERS, 0, "" }, 494d5b718b3SGarrett Wollman { IS_DISTRUST, 0, "DISTRUST" }, 4957b6ab19dSGarrett Wollman { IS_BROKE, IS_SICK, "BROKEN" }, 4967b6ab19dSGarrett Wollman { IS_SICK, 0, "SICK" }, 497d5b718b3SGarrett Wollman { IS_DUP, 0, "DUPLICATE" }, 49871965874SGarrett Wollman { IS_REDIRECT_OK, 0, "REDIRECT_OK" }, 4997b6ab19dSGarrett Wollman { IS_NEED_NET_SYN, 0, "" }, 5007b6ab19dSGarrett Wollman { IS_NO_AG, IS_NO_SUPER_AG, "NO_AG" }, 5017b6ab19dSGarrett Wollman { IS_NO_SUPER_AG, 0, "NO_SUPER_AG" }, 5027b6ab19dSGarrett Wollman { (IS_NO_RIPV1_IN 5037b6ab19dSGarrett Wollman | IS_NO_RIPV2_IN 5047b6ab19dSGarrett Wollman | IS_NO_RIPV1_OUT 5057b6ab19dSGarrett Wollman | IS_NO_RIPV2_OUT), 0, "NO_RIP" }, 5067b6ab19dSGarrett Wollman { (IS_NO_RIPV1_IN 5077b6ab19dSGarrett Wollman | IS_NO_RIPV1_OUT), 0, "RIPV2" }, 5087b6ab19dSGarrett Wollman { IS_NO_RIPV1_IN, 0, "NO_RIPV1_IN" }, 5097b6ab19dSGarrett Wollman { IS_NO_RIPV2_IN, 0, "NO_RIPV2_IN" }, 5107b6ab19dSGarrett Wollman { IS_NO_RIPV1_OUT, 0, "NO_RIPV1_OUT" }, 5117b6ab19dSGarrett Wollman { IS_NO_RIPV2_OUT, 0, "NO_RIPV2_OUT" }, 5127b6ab19dSGarrett Wollman { (IS_NO_ADV_IN 5137b6ab19dSGarrett Wollman | IS_NO_SOL_OUT 5147b6ab19dSGarrett Wollman | IS_NO_ADV_OUT), IS_BCAST_RDISC, "NO_RDISC" }, 5157b6ab19dSGarrett Wollman { IS_NO_SOL_OUT, 0, "NO_SOLICIT" }, 5167b6ab19dSGarrett Wollman { IS_SOL_OUT, 0, "SEND_SOLICIT" }, 5177b6ab19dSGarrett Wollman { IS_NO_ADV_OUT, IS_BCAST_RDISC, "NO_RDISC_ADV" }, 5187b6ab19dSGarrett Wollman { IS_ADV_OUT, 0, "RDISC_ADV" }, 5197b6ab19dSGarrett Wollman { IS_BCAST_RDISC, 0, "BCAST_RDISC" }, 520d5b718b3SGarrett Wollman { IS_PM_RDISC, 0, "" }, 5217b6ab19dSGarrett Wollman { 0, 0, "%#x"} 5227b6ab19dSGarrett Wollman }; 5237b6ab19dSGarrett Wollman 524a3e04ddcSPoul-Henning Kamp static const struct bits rs_bits[] = { 5257b6ab19dSGarrett Wollman { RS_IF, 0, "IF" }, 5267b6ab19dSGarrett Wollman { RS_NET_INT, RS_NET_SYN, "NET_INT" }, 5277b6ab19dSGarrett Wollman { RS_NET_SYN, 0, "NET_SYN" }, 5287b6ab19dSGarrett Wollman { RS_SUBNET, 0, "" }, 5297b6ab19dSGarrett Wollman { RS_LOCAL, 0, "LOCAL" }, 5307b6ab19dSGarrett Wollman { RS_MHOME, 0, "MHOME" }, 5317b6ab19dSGarrett Wollman { RS_STATIC, 0, "STATIC" }, 5327b6ab19dSGarrett Wollman { RS_RDISC, 0, "RDISC" }, 5337b6ab19dSGarrett Wollman { 0, 0, "%#x"} 5347b6ab19dSGarrett Wollman }; 5357b6ab19dSGarrett Wollman 5367b6ab19dSGarrett Wollman 5377b6ab19dSGarrett Wollman static void 5382c7a9781SMark Murray trace_bits(const struct bits *tbl, 5397b6ab19dSGarrett Wollman u_int field, 5407b6ab19dSGarrett Wollman int force) 5417b6ab19dSGarrett Wollman { 5422c7a9781SMark Murray u_int b; 5437b6ab19dSGarrett Wollman char c; 5447b6ab19dSGarrett Wollman 5457b6ab19dSGarrett Wollman if (force) { 5467b6ab19dSGarrett Wollman (void)putc('<', ftrace); 5477b6ab19dSGarrett Wollman c = 0; 5487b6ab19dSGarrett Wollman } else { 5497b6ab19dSGarrett Wollman c = '<'; 5507b6ab19dSGarrett Wollman } 5517b6ab19dSGarrett Wollman 5527b6ab19dSGarrett Wollman while (field != 0 5537b6ab19dSGarrett Wollman && (b = tbl->bits_mask) != 0) { 5547b6ab19dSGarrett Wollman if ((b & field) == b) { 5557b6ab19dSGarrett Wollman if (tbl->bits_name[0] != '\0') { 5567b6ab19dSGarrett Wollman if (c) 5577b6ab19dSGarrett Wollman (void)putc(c, ftrace); 5587b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%s", tbl->bits_name); 5597b6ab19dSGarrett Wollman c = '|'; 5607b6ab19dSGarrett Wollman } 5617b6ab19dSGarrett Wollman if (0 == (field &= ~(b | tbl->bits_clear))) 5627b6ab19dSGarrett Wollman break; 5637b6ab19dSGarrett Wollman } 5647b6ab19dSGarrett Wollman tbl++; 5657b6ab19dSGarrett Wollman } 566*562c5a82SPedro F. Giffuni if (field != 0 && tbl->bits_name != NULL) { 5677b6ab19dSGarrett Wollman if (c) 5687b6ab19dSGarrett Wollman (void)putc(c, ftrace); 5697b6ab19dSGarrett Wollman (void)fprintf(ftrace, tbl->bits_name, field); 5707b6ab19dSGarrett Wollman c = '|'; 5717b6ab19dSGarrett Wollman } 5727b6ab19dSGarrett Wollman 5737b6ab19dSGarrett Wollman if (c != '<' || force) 5747b6ab19dSGarrett Wollman (void)fputs("> ", ftrace); 5757b6ab19dSGarrett Wollman } 5767b6ab19dSGarrett Wollman 5777b6ab19dSGarrett Wollman 5782c7a9781SMark Murray char * 5792c7a9781SMark Murray rtname(naddr dst, 5807b6ab19dSGarrett Wollman naddr mask, 5812c7a9781SMark Murray naddr gate) 5827b6ab19dSGarrett Wollman { 5837b6ab19dSGarrett Wollman static char buf[3*4+3+1+2+3 /* "xxx.xxx.xxx.xxx/xx-->" */ 5847b6ab19dSGarrett Wollman +3*4+3+1]; /* "xxx.xxx.xxx.xxx" */ 5857b6ab19dSGarrett Wollman int i; 5867b6ab19dSGarrett Wollman 5877b6ab19dSGarrett Wollman i = sprintf(buf, "%-16s-->", addrname(dst, mask, 0)); 5882c7a9781SMark Murray (void)sprintf(&buf[i], "%-*s", 15+20-MAX(20,i), naddr_ntoa(gate)); 5897b6ab19dSGarrett Wollman return buf; 5907b6ab19dSGarrett Wollman } 5917b6ab19dSGarrett Wollman 5927b6ab19dSGarrett Wollman 59371965874SGarrett Wollman static void 59471965874SGarrett Wollman print_rts(struct rt_spare *rts, 59571965874SGarrett Wollman int force_metric, /* -1=suppress, 0=default */ 59671965874SGarrett Wollman int force_ifp, /* -1=suppress, 0=default */ 59771965874SGarrett Wollman int force_router, /* -1=suppress, 0=default, 1=display */ 59871965874SGarrett Wollman int force_tag, /* -1=suppress, 0=default, 1=display */ 59971965874SGarrett Wollman int force_time) /* 0=suppress, 1=display */ 60071965874SGarrett Wollman { 6012c7a9781SMark Murray int i; 6022c7a9781SMark Murray 6032c7a9781SMark Murray 60471965874SGarrett Wollman if (force_metric >= 0) 60571965874SGarrett Wollman (void)fprintf(ftrace, "metric=%-2d ", rts->rts_metric); 60671965874SGarrett Wollman if (force_ifp >= 0) 607*562c5a82SPedro F. Giffuni (void)fprintf(ftrace, "%s ", (rts->rts_ifp == NULL ? 60871965874SGarrett Wollman "if?" : rts->rts_ifp->int_name)); 60971965874SGarrett Wollman if (force_router > 0 61071965874SGarrett Wollman || (force_router == 0 && rts->rts_router != rts->rts_gate)) 61171965874SGarrett Wollman (void)fprintf(ftrace, "router=%s ", 61271965874SGarrett Wollman naddr_ntoa(rts->rts_router)); 61371965874SGarrett Wollman if (force_time > 0) 61471965874SGarrett Wollman (void)fprintf(ftrace, "%s ", ts(rts->rts_time)); 61571965874SGarrett Wollman if (force_tag > 0 61671965874SGarrett Wollman || (force_tag == 0 && rts->rts_tag != 0)) 6172c7a9781SMark Murray (void)fprintf(ftrace, "tag=%#x ", ntohs(rts->rts_tag)); 6182c7a9781SMark Murray if (rts->rts_de_ag != 0) { 6192c7a9781SMark Murray for (i = 1; (u_int)(1 << i) <= rts->rts_de_ag; i++) 6202c7a9781SMark Murray continue; 6212c7a9781SMark Murray (void)fprintf(ftrace, "de_ag=%d ", i); 6222c7a9781SMark Murray } 6232c7a9781SMark Murray 62471965874SGarrett Wollman } 62571965874SGarrett Wollman 62671965874SGarrett Wollman 6277b6ab19dSGarrett Wollman void 6282c7a9781SMark Murray trace_if(const char *act, 6297b6ab19dSGarrett Wollman struct interface *ifp) 6307b6ab19dSGarrett Wollman { 631*562c5a82SPedro F. Giffuni if (!TRACEACTIONS || ftrace == NULL) 6327b6ab19dSGarrett Wollman return; 6337b6ab19dSGarrett Wollman 6347b6ab19dSGarrett Wollman lastlog(); 635d5b718b3SGarrett Wollman (void)fprintf(ftrace, "%-3s interface %-4s ", act, ifp->int_name); 6367b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%-15s-->%-15s ", 6377b6ab19dSGarrett Wollman naddr_ntoa(ifp->int_addr), 638d5b718b3SGarrett Wollman addrname(((ifp->int_if_flags & IFF_POINTOPOINT) 6397b6ab19dSGarrett Wollman ? ifp->int_dstaddr 640d5b718b3SGarrett Wollman : htonl(ifp->int_net)), 6417b6ab19dSGarrett Wollman ifp->int_mask, 1)); 6427b6ab19dSGarrett Wollman if (ifp->int_metric != 0) 6437b6ab19dSGarrett Wollman (void)fprintf(ftrace, "metric=%d ", ifp->int_metric); 644caa79e36SBruce M Simpson if (ifp->int_adj_inmetric != 0) 645caa79e36SBruce M Simpson (void)fprintf(ftrace, "adj_inmetric=%u ", 646caa79e36SBruce M Simpson ifp->int_adj_inmetric); 647caa79e36SBruce M Simpson if (ifp->int_adj_outmetric != 0) 648caa79e36SBruce M Simpson (void)fprintf(ftrace, "adj_outmetric=%u ", 649caa79e36SBruce M Simpson ifp->int_adj_outmetric); 650d5b718b3SGarrett Wollman if (!IS_RIP_OUT_OFF(ifp->int_state) 651d5b718b3SGarrett Wollman && ifp->int_d_metric != 0) 652caa79e36SBruce M Simpson (void)fprintf(ftrace, "fake_default=%u ", ifp->int_d_metric); 6537b6ab19dSGarrett Wollman trace_bits(if_bits, ifp->int_if_flags, 0); 6547b6ab19dSGarrett Wollman trace_bits(is_bits, ifp->int_state, 0); 6557b6ab19dSGarrett Wollman (void)fputc('\n',ftrace); 6567b6ab19dSGarrett Wollman } 6577b6ab19dSGarrett Wollman 6587b6ab19dSGarrett Wollman 6597b6ab19dSGarrett Wollman void 6607b6ab19dSGarrett Wollman trace_upslot(struct rt_entry *rt, 6617b6ab19dSGarrett Wollman struct rt_spare *rts, 6622c7a9781SMark Murray struct rt_spare *new) 6637b6ab19dSGarrett Wollman { 664*562c5a82SPedro F. Giffuni if (!TRACEACTIONS || ftrace == NULL) 6657b6ab19dSGarrett Wollman return; 66671965874SGarrett Wollman 6672c7a9781SMark Murray if (rts->rts_gate == new->rts_gate 6682c7a9781SMark Murray && rts->rts_router == new->rts_router 6692c7a9781SMark Murray && rts->rts_metric == new->rts_metric 6702c7a9781SMark Murray && rts->rts_tag == new->rts_tag 6712c7a9781SMark Murray && rts->rts_de_ag == new->rts_de_ag) 6727b6ab19dSGarrett Wollman return; 6737b6ab19dSGarrett Wollman 6747b6ab19dSGarrett Wollman lastlog(); 6752c7a9781SMark Murray if (new->rts_gate == 0) { 6762c7a9781SMark Murray (void)fprintf(ftrace, "Del #%d %-35s ", 6772c7a9781SMark Murray (int)(rts - rt->rt_spares), 6782c7a9781SMark Murray rtname(rt->rt_dst, rt->rt_mask, rts->rts_gate)); 6792c7a9781SMark Murray print_rts(rts, 0,0,0,0, 6802c7a9781SMark Murray (rts != rt->rt_spares 6812c7a9781SMark Murray || AGE_RT(rt->rt_state,new->rts_ifp))); 6822c7a9781SMark Murray 6832c7a9781SMark Murray } else if (rts->rts_gate != RIP_DEFAULT) { 6847b6ab19dSGarrett Wollman (void)fprintf(ftrace, "Chg #%d %-35s ", 6852c7a9781SMark Murray (int)(rts - rt->rt_spares), 6862c7a9781SMark Murray rtname(rt->rt_dst, rt->rt_mask, rts->rts_gate)); 68771965874SGarrett Wollman print_rts(rts, 0,0, 6882c7a9781SMark Murray rts->rts_gate != new->rts_gate, 6892c7a9781SMark Murray rts->rts_tag != new->rts_tag, 69071965874SGarrett Wollman rts != rt->rt_spares || AGE_RT(rt->rt_state, 69171965874SGarrett Wollman rt->rt_ifp)); 6927b6ab19dSGarrett Wollman 69371965874SGarrett Wollman (void)fprintf(ftrace, "\n %19s%-16s ", "", 6942c7a9781SMark Murray (new->rts_gate != rts->rts_gate 6952c7a9781SMark Murray ? naddr_ntoa(new->rts_gate) : "")); 6962c7a9781SMark Murray print_rts(new, 6972c7a9781SMark Murray -(new->rts_metric == rts->rts_metric), 6982c7a9781SMark Murray -(new->rts_ifp == rts->rts_ifp), 69971965874SGarrett Wollman 0, 7002c7a9781SMark Murray rts->rts_tag != new->rts_tag, 7012c7a9781SMark Murray (new->rts_time != rts->rts_time 7022c7a9781SMark Murray && (rts != rt->rt_spares 7032c7a9781SMark Murray || AGE_RT(rt->rt_state, new->rts_ifp)))); 7047b6ab19dSGarrett Wollman 7057b6ab19dSGarrett Wollman } else { 7067b6ab19dSGarrett Wollman (void)fprintf(ftrace, "Add #%d %-35s ", 7072c7a9781SMark Murray (int)(rts - rt->rt_spares), 7082c7a9781SMark Murray rtname(rt->rt_dst, rt->rt_mask, new->rts_gate)); 7092c7a9781SMark Murray print_rts(new, 0,0,0,0, 7102c7a9781SMark Murray (rts != rt->rt_spares 7112c7a9781SMark Murray || AGE_RT(rt->rt_state,new->rts_ifp))); 7127b6ab19dSGarrett Wollman } 71371965874SGarrett Wollman (void)fputc('\n',ftrace); 7147b6ab19dSGarrett Wollman } 7157b6ab19dSGarrett Wollman 7167b6ab19dSGarrett Wollman 7172c7a9781SMark Murray /* miscellaneous message checked by the caller 7187b6ab19dSGarrett Wollman */ 7197b6ab19dSGarrett Wollman void 7202c7a9781SMark Murray trace_misc(const char *p, ...) 7217b6ab19dSGarrett Wollman { 7227b6ab19dSGarrett Wollman va_list args; 7237b6ab19dSGarrett Wollman 724*562c5a82SPedro F. Giffuni if (ftrace == NULL) 7257b6ab19dSGarrett Wollman return; 7267b6ab19dSGarrett Wollman 7277b6ab19dSGarrett Wollman lastlog(); 7287b6ab19dSGarrett Wollman va_start(args, p); 7297b6ab19dSGarrett Wollman vfprintf(ftrace, p, args); 730caa79e36SBruce M Simpson va_end(args); 7312c7a9781SMark Murray (void)fputc('\n',ftrace); 7327b6ab19dSGarrett Wollman } 7337b6ab19dSGarrett Wollman 7347b6ab19dSGarrett Wollman 7357b6ab19dSGarrett Wollman /* display a message if tracing actions 7367b6ab19dSGarrett Wollman */ 7377b6ab19dSGarrett Wollman void 7382c7a9781SMark Murray trace_act(const char *p, ...) 7397b6ab19dSGarrett Wollman { 7407b6ab19dSGarrett Wollman va_list args; 7417b6ab19dSGarrett Wollman 742*562c5a82SPedro F. Giffuni if (!TRACEACTIONS || ftrace == NULL) 7437b6ab19dSGarrett Wollman return; 7447b6ab19dSGarrett Wollman 7457b6ab19dSGarrett Wollman lastlog(); 7467b6ab19dSGarrett Wollman va_start(args, p); 7477b6ab19dSGarrett Wollman vfprintf(ftrace, p, args); 748caa79e36SBruce M Simpson va_end(args); 749d5b718b3SGarrett Wollman (void)fputc('\n',ftrace); 7507b6ab19dSGarrett Wollman } 7517b6ab19dSGarrett Wollman 7527b6ab19dSGarrett Wollman 7537b6ab19dSGarrett Wollman /* display a message if tracing packets 7547b6ab19dSGarrett Wollman */ 7557b6ab19dSGarrett Wollman void 7562c7a9781SMark Murray trace_pkt(const char *p, ...) 7577b6ab19dSGarrett Wollman { 7587b6ab19dSGarrett Wollman va_list args; 7597b6ab19dSGarrett Wollman 760*562c5a82SPedro F. Giffuni if (!TRACEPACKETS || ftrace == NULL) 7617b6ab19dSGarrett Wollman return; 7627b6ab19dSGarrett Wollman 7637b6ab19dSGarrett Wollman lastlog(); 7647b6ab19dSGarrett Wollman va_start(args, p); 7657b6ab19dSGarrett Wollman vfprintf(ftrace, p, args); 766caa79e36SBruce M Simpson va_end(args); 767d5b718b3SGarrett Wollman (void)fputc('\n',ftrace); 7687b6ab19dSGarrett Wollman } 7697b6ab19dSGarrett Wollman 7707b6ab19dSGarrett Wollman 7717b6ab19dSGarrett Wollman void 7727b6ab19dSGarrett Wollman trace_change(struct rt_entry *rt, 7737b6ab19dSGarrett Wollman u_int state, 7742c7a9781SMark Murray struct rt_spare *new, 7752c7a9781SMark Murray const char *label) 7767b6ab19dSGarrett Wollman { 777*562c5a82SPedro F. Giffuni if (ftrace == NULL) 7787b6ab19dSGarrett Wollman return; 7797b6ab19dSGarrett Wollman 7802c7a9781SMark Murray if (rt->rt_metric == new->rts_metric 7812c7a9781SMark Murray && rt->rt_gate == new->rts_gate 7822c7a9781SMark Murray && rt->rt_router == new->rts_router 7837b6ab19dSGarrett Wollman && rt->rt_state == state 7842c7a9781SMark Murray && rt->rt_tag == new->rts_tag 7852c7a9781SMark Murray && rt->rt_de_ag == new->rts_de_ag) 7867b6ab19dSGarrett Wollman return; 7877b6ab19dSGarrett Wollman 7887b6ab19dSGarrett Wollman lastlog(); 78971965874SGarrett Wollman (void)fprintf(ftrace, "%s %-35s ", 7907b6ab19dSGarrett Wollman label, 7912c7a9781SMark Murray rtname(rt->rt_dst, rt->rt_mask, rt->rt_gate)); 79271965874SGarrett Wollman print_rts(rt->rt_spares, 79371965874SGarrett Wollman 0,0,0,0, AGE_RT(rt->rt_state, rt->rt_ifp)); 7947b6ab19dSGarrett Wollman trace_bits(rs_bits, rt->rt_state, rt->rt_state != state); 7957b6ab19dSGarrett Wollman 79671965874SGarrett Wollman (void)fprintf(ftrace, "\n%*s %19s%-16s ", 7972c7a9781SMark Murray (int)strlen(label), "", "", 7982c7a9781SMark Murray (rt->rt_gate != new->rts_gate 7992c7a9781SMark Murray ? naddr_ntoa(new->rts_gate) : "")); 8002c7a9781SMark Murray print_rts(new, 8012c7a9781SMark Murray -(new->rts_metric == rt->rt_metric), 8022c7a9781SMark Murray -(new->rts_ifp == rt->rt_ifp), 80371965874SGarrett Wollman 0, 8042c7a9781SMark Murray rt->rt_tag != new->rts_tag, 8052c7a9781SMark Murray (rt->rt_time != new->rts_time 8062c7a9781SMark Murray && AGE_RT(rt->rt_state,new->rts_ifp))); 8077b6ab19dSGarrett Wollman if (rt->rt_state != state) 8087b6ab19dSGarrett Wollman trace_bits(rs_bits, state, 1); 80971965874SGarrett Wollman (void)fputc('\n',ftrace); 8107b6ab19dSGarrett Wollman } 8117b6ab19dSGarrett Wollman 8127b6ab19dSGarrett Wollman 8137b6ab19dSGarrett Wollman void 8142c7a9781SMark Murray trace_add_del(const char * action, struct rt_entry *rt) 8157b6ab19dSGarrett Wollman { 816*562c5a82SPedro F. Giffuni if (ftrace == NULL) 8177b6ab19dSGarrett Wollman return; 8187b6ab19dSGarrett Wollman 8197b6ab19dSGarrett Wollman lastlog(); 82071965874SGarrett Wollman (void)fprintf(ftrace, "%s %-35s ", 8217b6ab19dSGarrett Wollman action, 8222c7a9781SMark Murray rtname(rt->rt_dst, rt->rt_mask, rt->rt_gate)); 82371965874SGarrett Wollman print_rts(rt->rt_spares, 0,0,0,0,AGE_RT(rt->rt_state,rt->rt_ifp)); 82471965874SGarrett Wollman trace_bits(rs_bits, rt->rt_state, 0); 82571965874SGarrett Wollman (void)fputc('\n',ftrace); 8267b6ab19dSGarrett Wollman } 8277b6ab19dSGarrett Wollman 8287b6ab19dSGarrett Wollman 8297b6ab19dSGarrett Wollman /* ARGSUSED */ 8307b6ab19dSGarrett Wollman static int 8317b6ab19dSGarrett Wollman walk_trace(struct radix_node *rn, 8322c7a9781SMark Murray struct walkarg *w UNUSED) 8337b6ab19dSGarrett Wollman { 8347b6ab19dSGarrett Wollman #define RT ((struct rt_entry *)rn) 8357b6ab19dSGarrett Wollman struct rt_spare *rts; 8362c7a9781SMark Murray int i; 8377b6ab19dSGarrett Wollman 8382c7a9781SMark Murray (void)fprintf(ftrace, " %-35s ", 8392c7a9781SMark Murray rtname(RT->rt_dst, RT->rt_mask, RT->rt_gate)); 8402c7a9781SMark Murray print_rts(&RT->rt_spares[0], 0,0,0,0, AGE_RT(RT->rt_state, RT->rt_ifp)); 8417b6ab19dSGarrett Wollman trace_bits(rs_bits, RT->rt_state, 0); 84271965874SGarrett Wollman if (RT->rt_poison_time >= now_garbage 84371965874SGarrett Wollman && RT->rt_poison_metric < RT->rt_metric) 84471965874SGarrett Wollman (void)fprintf(ftrace, "pm=%d@%s", 8452c7a9781SMark Murray RT->rt_poison_metric, ts(RT->rt_poison_time)); 8467b6ab19dSGarrett Wollman 8477b6ab19dSGarrett Wollman rts = &RT->rt_spares[1]; 8487b6ab19dSGarrett Wollman for (i = 1; i < NUM_SPARES; i++, rts++) { 84971965874SGarrett Wollman if (rts->rts_gate != RIP_DEFAULT) { 85071965874SGarrett Wollman (void)fprintf(ftrace,"\n #%d%15s%-16s ", 85171965874SGarrett Wollman i, "", naddr_ntoa(rts->rts_gate)); 85271965874SGarrett Wollman print_rts(rts, 0,0,0,0,1); 8537b6ab19dSGarrett Wollman } 8547b6ab19dSGarrett Wollman } 8557b6ab19dSGarrett Wollman (void)fputc('\n',ftrace); 8567b6ab19dSGarrett Wollman 8577b6ab19dSGarrett Wollman return 0; 8587b6ab19dSGarrett Wollman } 8597b6ab19dSGarrett Wollman 8607b6ab19dSGarrett Wollman 8617b6ab19dSGarrett Wollman static void 8627b6ab19dSGarrett Wollman trace_dump(void) 8637b6ab19dSGarrett Wollman { 864d5b718b3SGarrett Wollman struct interface *ifp; 865d5b718b3SGarrett Wollman 866*562c5a82SPedro F. Giffuni if (ftrace == NULL) 8677b6ab19dSGarrett Wollman return; 8687b6ab19dSGarrett Wollman lastlog(); 8697b6ab19dSGarrett Wollman 87071965874SGarrett Wollman (void)fputs("current daemon state:\n", ftrace); 87138ae6523SPoul-Henning Kamp LIST_FOREACH(ifp, &ifnet, int_list) 872d5b718b3SGarrett Wollman trace_if("", ifp); 8737b6ab19dSGarrett Wollman (void)rn_walktree(rhead, walk_trace, 0); 8747b6ab19dSGarrett Wollman } 8757b6ab19dSGarrett Wollman 8767b6ab19dSGarrett Wollman 8777b6ab19dSGarrett Wollman void 8782c7a9781SMark Murray trace_rip(const char *dir1, const char *dir2, 8797b6ab19dSGarrett Wollman struct sockaddr_in *who, 8807b6ab19dSGarrett Wollman struct interface *ifp, 8817b6ab19dSGarrett Wollman struct rip *msg, 8827b6ab19dSGarrett Wollman int size) /* total size of message */ 8837b6ab19dSGarrett Wollman { 8847b6ab19dSGarrett Wollman struct netinfo *n, *lim; 8852c7a9781SMark Murray # define NA ((struct netauth*)n) 886d5b718b3SGarrett Wollman int i, seen_route; 8877b6ab19dSGarrett Wollman 888*562c5a82SPedro F. Giffuni if (!TRACEPACKETS || ftrace == NULL) 8897b6ab19dSGarrett Wollman return; 8907b6ab19dSGarrett Wollman 8917b6ab19dSGarrett Wollman lastlog(); 8927b6ab19dSGarrett Wollman if (msg->rip_cmd >= RIPCMD_MAX 8937b6ab19dSGarrett Wollman || msg->rip_vers == 0) { 8947b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%s bad RIPv%d cmd=%d %s" 8957b6ab19dSGarrett Wollman " %s.%d size=%d\n", 8967b6ab19dSGarrett Wollman dir1, msg->rip_vers, msg->rip_cmd, dir2, 8977b6ab19dSGarrett Wollman naddr_ntoa(who->sin_addr.s_addr), 8987b6ab19dSGarrett Wollman ntohs(who->sin_port), 8997b6ab19dSGarrett Wollman size); 9007b6ab19dSGarrett Wollman return; 9017b6ab19dSGarrett Wollman } 9027b6ab19dSGarrett Wollman 9037b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%s RIPv%d %s %s %s.%d%s%s\n", 9047b6ab19dSGarrett Wollman dir1, msg->rip_vers, ripcmds[msg->rip_cmd], dir2, 9057b6ab19dSGarrett Wollman naddr_ntoa(who->sin_addr.s_addr), ntohs(who->sin_port), 9067b6ab19dSGarrett Wollman ifp ? " via " : "", ifp ? ifp->int_name : ""); 9077b6ab19dSGarrett Wollman if (!TRACECONTENTS) 9087b6ab19dSGarrett Wollman return; 9097b6ab19dSGarrett Wollman 910d5b718b3SGarrett Wollman seen_route = 0; 9117b6ab19dSGarrett Wollman switch (msg->rip_cmd) { 9127b6ab19dSGarrett Wollman case RIPCMD_REQUEST: 9137b6ab19dSGarrett Wollman case RIPCMD_RESPONSE: 9147b6ab19dSGarrett Wollman n = msg->rip_nets; 9157b6ab19dSGarrett Wollman lim = (struct netinfo *)((char*)msg + size); 9167b6ab19dSGarrett Wollman for (; n < lim; n++) { 917d5b718b3SGarrett Wollman if (!seen_route 918d5b718b3SGarrett Wollman && n->n_family == RIP_AF_UNSPEC 9197b6ab19dSGarrett Wollman && ntohl(n->n_metric) == HOPCNT_INFINITY 920d5b718b3SGarrett Wollman && msg->rip_cmd == RIPCMD_REQUEST 921d5b718b3SGarrett Wollman && (n+1 == lim 922d5b718b3SGarrett Wollman || (n+2 == lim 923d5b718b3SGarrett Wollman && (n+1)->n_family == RIP_AF_AUTH))) { 9247b6ab19dSGarrett Wollman (void)fputs("\tQUERY ", ftrace); 9257b6ab19dSGarrett Wollman if (n->n_dst != 0) 9267b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%s ", 9277b6ab19dSGarrett Wollman naddr_ntoa(n->n_dst)); 9287b6ab19dSGarrett Wollman if (n->n_mask != 0) 9297b6ab19dSGarrett Wollman (void)fprintf(ftrace, "mask=%#x ", 9307b6ab19dSGarrett Wollman (u_int)ntohl(n->n_mask)); 9317b6ab19dSGarrett Wollman if (n->n_nhop != 0) 9327b6ab19dSGarrett Wollman (void)fprintf(ftrace, "nhop=%s ", 9337b6ab19dSGarrett Wollman naddr_ntoa(n->n_nhop)); 9347b6ab19dSGarrett Wollman if (n->n_tag != 0) 9357b6ab19dSGarrett Wollman (void)fprintf(ftrace, "tag=%#x ", 9367b6ab19dSGarrett Wollman ntohs(n->n_tag)); 9377b6ab19dSGarrett Wollman (void)fputc('\n',ftrace); 9387b6ab19dSGarrett Wollman continue; 9397b6ab19dSGarrett Wollman } 9407b6ab19dSGarrett Wollman 9417b6ab19dSGarrett Wollman if (n->n_family == RIP_AF_AUTH) { 942d5b718b3SGarrett Wollman if (NA->a_type == RIP_AUTH_PW 943d5b718b3SGarrett Wollman && n == msg->rip_nets) { 944d5b718b3SGarrett Wollman (void)fprintf(ftrace, "\tPassword" 945d5b718b3SGarrett Wollman " Authentication:" 946d5b718b3SGarrett Wollman " \"%s\"\n", 947d5b718b3SGarrett Wollman qstring(NA->au.au_pw, 948d5b718b3SGarrett Wollman RIP_AUTH_PW_LEN)); 949d5b718b3SGarrett Wollman continue; 950d5b718b3SGarrett Wollman } 951d5b718b3SGarrett Wollman 952d5b718b3SGarrett Wollman if (NA->a_type == RIP_AUTH_MD5 953d5b718b3SGarrett Wollman && n == msg->rip_nets) { 9547b6ab19dSGarrett Wollman (void)fprintf(ftrace, 9552c7a9781SMark Murray "\tMD5 Auth" 9562c7a9781SMark Murray " pkt_len=%d KeyID=%u" 9572c7a9781SMark Murray " auth_len=%d" 9582c7a9781SMark Murray " seqno=%#x" 959d5b718b3SGarrett Wollman " rsvd=%#x,%#x\n", 9602c7a9781SMark Murray ntohs(NA->au.a_md5.md5_pkt_len), 961d5b718b3SGarrett Wollman NA->au.a_md5.md5_keyid, 9622c7a9781SMark Murray NA->au.a_md5.md5_auth_len, 9632c7a9781SMark Murray (int)ntohl(NA->au.a_md5.md5_seqno), 9642c7a9781SMark Murray (int)ntohs(NA->au.a_md5.rsvd[0]), 9652c7a9781SMark Murray (int)ntohs(NA->au.a_md5.rsvd[1])); 966d5b718b3SGarrett Wollman continue; 967d5b718b3SGarrett Wollman } 968d5b718b3SGarrett Wollman (void)fprintf(ftrace, 9692c7a9781SMark Murray "\tAuthentication type %d: ", 970d5b718b3SGarrett Wollman ntohs(NA->a_type)); 9717b6ab19dSGarrett Wollman for (i = 0; 9722c7a9781SMark Murray i < (int)sizeof(NA->au.au_pw); 9737b6ab19dSGarrett Wollman i++) 9747b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%02x ", 975d5b718b3SGarrett Wollman NA->au.au_pw[i]); 9767b6ab19dSGarrett Wollman (void)fputc('\n',ftrace); 9777b6ab19dSGarrett Wollman continue; 9787b6ab19dSGarrett Wollman } 9797b6ab19dSGarrett Wollman 980d5b718b3SGarrett Wollman seen_route = 1; 9817b6ab19dSGarrett Wollman if (n->n_family != RIP_AF_INET) { 9827b6ab19dSGarrett Wollman (void)fprintf(ftrace, 9837b6ab19dSGarrett Wollman "\t(af %d) %-18s mask=%#x ", 9847b6ab19dSGarrett Wollman ntohs(n->n_family), 9857b6ab19dSGarrett Wollman naddr_ntoa(n->n_dst), 9867b6ab19dSGarrett Wollman (u_int)ntohl(n->n_mask)); 9877b6ab19dSGarrett Wollman } else if (msg->rip_vers == RIPv1) { 9887b6ab19dSGarrett Wollman (void)fprintf(ftrace, "\t%-18s ", 9897b6ab19dSGarrett Wollman addrname(n->n_dst, 9907b6ab19dSGarrett Wollman ntohl(n->n_mask), 9917b6ab19dSGarrett Wollman n->n_mask==0 ? 2 : 1)); 9927b6ab19dSGarrett Wollman } else { 9937b6ab19dSGarrett Wollman (void)fprintf(ftrace, "\t%-18s ", 9947b6ab19dSGarrett Wollman addrname(n->n_dst, 9957b6ab19dSGarrett Wollman ntohl(n->n_mask), 9967b6ab19dSGarrett Wollman n->n_mask==0 ? 2 : 0)); 9977b6ab19dSGarrett Wollman } 9987b6ab19dSGarrett Wollman (void)fprintf(ftrace, "metric=%-2d ", 9997b6ab19dSGarrett Wollman (u_int)ntohl(n->n_metric)); 10007b6ab19dSGarrett Wollman if (n->n_nhop != 0) 10017b6ab19dSGarrett Wollman (void)fprintf(ftrace, " nhop=%s ", 10027b6ab19dSGarrett Wollman naddr_ntoa(n->n_nhop)); 10037b6ab19dSGarrett Wollman if (n->n_tag != 0) 10047b6ab19dSGarrett Wollman (void)fprintf(ftrace, "tag=%#x", 10057b6ab19dSGarrett Wollman ntohs(n->n_tag)); 10067b6ab19dSGarrett Wollman (void)fputc('\n',ftrace); 10077b6ab19dSGarrett Wollman } 10087b6ab19dSGarrett Wollman if (size != (char *)n - (char *)msg) 10097b6ab19dSGarrett Wollman (void)fprintf(ftrace, "truncated record, len %d\n", 10107b6ab19dSGarrett Wollman size); 10117b6ab19dSGarrett Wollman break; 10127b6ab19dSGarrett Wollman 10137b6ab19dSGarrett Wollman case RIPCMD_TRACEON: 101471965874SGarrett Wollman fprintf(ftrace, "\tfile=\"%.*s\"\n", size-4, 101571965874SGarrett Wollman msg->rip_tracefile); 10167b6ab19dSGarrett Wollman break; 10177b6ab19dSGarrett Wollman 10187b6ab19dSGarrett Wollman case RIPCMD_TRACEOFF: 10197b6ab19dSGarrett Wollman break; 10207b6ab19dSGarrett Wollman } 10217b6ab19dSGarrett Wollman } 1022