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 * 3. All advertising materials mentioning features or use of this software 142c7a9781SMark Murray * must display the following acknowledgment: 157b6ab19dSGarrett Wollman * This product includes software developed by the University of 167b6ab19dSGarrett Wollman * California, Berkeley and its contributors. 177b6ab19dSGarrett Wollman * 4. Neither the name of the University nor the names of its contributors 187b6ab19dSGarrett Wollman * may be used to endorse or promote products derived from this software 197b6ab19dSGarrett Wollman * without specific prior written permission. 207b6ab19dSGarrett Wollman * 217b6ab19dSGarrett Wollman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 227b6ab19dSGarrett Wollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 237b6ab19dSGarrett Wollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 247b6ab19dSGarrett Wollman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 257b6ab19dSGarrett Wollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 267b6ab19dSGarrett Wollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 277b6ab19dSGarrett Wollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 287b6ab19dSGarrett Wollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 297b6ab19dSGarrett Wollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 307b6ab19dSGarrett Wollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 317b6ab19dSGarrett Wollman * SUCH DAMAGE. 327b6ab19dSGarrett Wollman */ 337b6ab19dSGarrett Wollman 347b6ab19dSGarrett Wollman #define RIPCMDS 357b6ab19dSGarrett Wollman #include "defs.h" 367b6ab19dSGarrett Wollman #include "pathnames.h" 377b6ab19dSGarrett Wollman #include <sys/stat.h> 387b6ab19dSGarrett Wollman #include <sys/signal.h> 397b6ab19dSGarrett Wollman #include <fcntl.h> 407b6ab19dSGarrett Wollman 41caa79e36SBruce M Simpson #ifdef __NetBSD__ 422c7a9781SMark Murray __RCSID("$NetBSD$"); 43caa79e36SBruce M Simpson #elif defined(__FreeBSD__) 44caa79e36SBruce M Simpson __RCSID("$FreeBSD$"); 45caa79e36SBruce M Simpson #else 46caa79e36SBruce M Simpson __RCSID("$Revision: 2.27 $"); 47caa79e36SBruce M Simpson #ident "$Revision: 2.27 $" 482c7a9781SMark Murray #endif 492c7a9781SMark Murray 507b6ab19dSGarrett Wollman 517b6ab19dSGarrett Wollman #ifdef sgi 527b6ab19dSGarrett Wollman /* use *stat64 for files on large filesystems */ 537b6ab19dSGarrett Wollman #define stat stat64 547b6ab19dSGarrett Wollman #endif 557b6ab19dSGarrett Wollman 567b6ab19dSGarrett Wollman #define NRECORDS 50 /* size of circular trace buffer */ 577b6ab19dSGarrett Wollman 5871965874SGarrett Wollman int tracelevel, new_tracelevel; 597b6ab19dSGarrett Wollman FILE *ftrace = stdout; /* output trace file */ 602c7a9781SMark Murray static const char *sigtrace_pat = "%s"; 6171965874SGarrett Wollman static char savetracename[MAXPATHLEN+1]; 6271965874SGarrett Wollman char inittracename[MAXPATHLEN+1]; 6371965874SGarrett Wollman int file_trace; /* 1=tracing to file, not stdout */ 647b6ab19dSGarrett Wollman 657b6ab19dSGarrett Wollman static void trace_dump(void); 662c7a9781SMark Murray static void tmsg(const char *, ...) PATTRIB(1,2); 677b6ab19dSGarrett Wollman 687b6ab19dSGarrett Wollman 69d5b718b3SGarrett Wollman /* convert string to printable characters 70d5b718b3SGarrett Wollman */ 71d5b718b3SGarrett Wollman static char * 72d5b718b3SGarrett Wollman qstring(u_char *s, int len) 73d5b718b3SGarrett Wollman { 74d5b718b3SGarrett Wollman static char buf[8*20+1]; 75d5b718b3SGarrett Wollman char *p; 76d5b718b3SGarrett Wollman u_char *s2, c; 77d5b718b3SGarrett Wollman 78d5b718b3SGarrett Wollman 79d5b718b3SGarrett Wollman for (p = buf; len != 0 && p < &buf[sizeof(buf)-1]; len--) { 80d5b718b3SGarrett Wollman c = *s++; 81d5b718b3SGarrett Wollman if (c == '\0') { 82d5b718b3SGarrett Wollman for (s2 = s+1; s2 < &s[len]; s2++) { 83d5b718b3SGarrett Wollman if (*s2 != '\0') 84d5b718b3SGarrett Wollman break; 85d5b718b3SGarrett Wollman } 86d5b718b3SGarrett Wollman if (s2 >= &s[len]) 87d5b718b3SGarrett Wollman goto exit; 88d5b718b3SGarrett Wollman } 89d5b718b3SGarrett Wollman 90d5b718b3SGarrett Wollman if (c >= ' ' && c < 0x7f && c != '\\') { 91d5b718b3SGarrett Wollman *p++ = c; 92d5b718b3SGarrett Wollman continue; 93d5b718b3SGarrett Wollman } 94d5b718b3SGarrett Wollman *p++ = '\\'; 95d5b718b3SGarrett Wollman switch (c) { 96d5b718b3SGarrett Wollman case '\\': 97d5b718b3SGarrett Wollman *p++ = '\\'; 98d5b718b3SGarrett Wollman break; 99d5b718b3SGarrett Wollman case '\n': 100d5b718b3SGarrett Wollman *p++= 'n'; 101d5b718b3SGarrett Wollman break; 102d5b718b3SGarrett Wollman case '\r': 103d5b718b3SGarrett Wollman *p++= 'r'; 104d5b718b3SGarrett Wollman break; 105d5b718b3SGarrett Wollman case '\t': 106d5b718b3SGarrett Wollman *p++ = 't'; 107d5b718b3SGarrett Wollman break; 108d5b718b3SGarrett Wollman case '\b': 109d5b718b3SGarrett Wollman *p++ = 'b'; 110d5b718b3SGarrett Wollman break; 111d5b718b3SGarrett Wollman default: 112d5b718b3SGarrett Wollman p += sprintf(p,"%o",c); 113d5b718b3SGarrett Wollman break; 114d5b718b3SGarrett Wollman } 115d5b718b3SGarrett Wollman } 116d5b718b3SGarrett Wollman exit: 117d5b718b3SGarrett Wollman *p = '\0'; 118d5b718b3SGarrett Wollman return buf; 119d5b718b3SGarrett Wollman } 120d5b718b3SGarrett Wollman 121d5b718b3SGarrett Wollman 1227b6ab19dSGarrett Wollman /* convert IP address to a string, but not into a single buffer 1237b6ab19dSGarrett Wollman */ 1247b6ab19dSGarrett Wollman char * 1257b6ab19dSGarrett Wollman naddr_ntoa(naddr a) 1267b6ab19dSGarrett Wollman { 1277b6ab19dSGarrett Wollman #define NUM_BUFS 4 1287b6ab19dSGarrett Wollman static int bufno; 1297b6ab19dSGarrett Wollman static struct { 1307b6ab19dSGarrett Wollman char str[16]; /* xxx.xxx.xxx.xxx\0 */ 1317b6ab19dSGarrett Wollman } bufs[NUM_BUFS]; 1327b6ab19dSGarrett Wollman char *s; 1337b6ab19dSGarrett Wollman struct in_addr addr; 1347b6ab19dSGarrett Wollman 1357b6ab19dSGarrett Wollman addr.s_addr = a; 1367b6ab19dSGarrett Wollman s = strcpy(bufs[bufno].str, inet_ntoa(addr)); 1377b6ab19dSGarrett Wollman bufno = (bufno+1) % NUM_BUFS; 1387b6ab19dSGarrett Wollman return s; 1397b6ab19dSGarrett Wollman #undef NUM_BUFS 1407b6ab19dSGarrett Wollman } 1417b6ab19dSGarrett Wollman 1427b6ab19dSGarrett Wollman 1432c7a9781SMark Murray const char * 1447b6ab19dSGarrett Wollman saddr_ntoa(struct sockaddr *sa) 1457b6ab19dSGarrett Wollman { 1467b6ab19dSGarrett Wollman return (sa == 0) ? "?" : naddr_ntoa(S_ADDR(sa)); 1477b6ab19dSGarrett Wollman } 1487b6ab19dSGarrett Wollman 1497b6ab19dSGarrett Wollman 1507b6ab19dSGarrett Wollman static char * 1517b6ab19dSGarrett Wollman ts(time_t secs) { 1527b6ab19dSGarrett Wollman static char s[20]; 1537b6ab19dSGarrett Wollman 1547b6ab19dSGarrett Wollman secs += epoch.tv_sec; 1557b6ab19dSGarrett Wollman #ifdef sgi 1567b6ab19dSGarrett Wollman (void)cftime(s, "%T", &secs); 1577b6ab19dSGarrett Wollman #else 1582c7a9781SMark Murray memcpy(s, ctime(&secs)+11, 8); 1597b6ab19dSGarrett Wollman s[8] = '\0'; 1607b6ab19dSGarrett Wollman #endif 1617b6ab19dSGarrett Wollman return s; 1627b6ab19dSGarrett Wollman } 1637b6ab19dSGarrett Wollman 1647b6ab19dSGarrett Wollman 1657b6ab19dSGarrett Wollman /* On each event, display a time stamp. 1667b6ab19dSGarrett Wollman * This assumes that 'now' is update once for each event, and 1677b6ab19dSGarrett Wollman * that at least now.tv_usec changes. 1687b6ab19dSGarrett Wollman */ 16971965874SGarrett Wollman static struct timeval lastlog_time; 17071965874SGarrett Wollman 1717b6ab19dSGarrett Wollman void 1727b6ab19dSGarrett Wollman lastlog(void) 1737b6ab19dSGarrett Wollman { 17471965874SGarrett Wollman if (lastlog_time.tv_sec != now.tv_sec 17571965874SGarrett Wollman || lastlog_time.tv_usec != now.tv_usec) { 1767b6ab19dSGarrett Wollman (void)fprintf(ftrace, "-- %s --\n", ts(now.tv_sec)); 17771965874SGarrett Wollman lastlog_time = now; 1787b6ab19dSGarrett Wollman } 1797b6ab19dSGarrett Wollman } 1807b6ab19dSGarrett Wollman 1817b6ab19dSGarrett Wollman 1827b6ab19dSGarrett Wollman static void 1832c7a9781SMark Murray tmsg(const char *p, ...) 1847b6ab19dSGarrett Wollman { 1857b6ab19dSGarrett Wollman va_list args; 1867b6ab19dSGarrett Wollman 1877b6ab19dSGarrett Wollman if (ftrace != 0) { 1887b6ab19dSGarrett Wollman lastlog(); 1897b6ab19dSGarrett Wollman va_start(args, p); 1907b6ab19dSGarrett Wollman vfprintf(ftrace, p, args); 191caa79e36SBruce M Simpson va_end(args); 1922c7a9781SMark Murray (void)fputc('\n',ftrace); 1937b6ab19dSGarrett Wollman fflush(ftrace); 1947b6ab19dSGarrett Wollman } 1957b6ab19dSGarrett Wollman } 1967b6ab19dSGarrett Wollman 1977b6ab19dSGarrett Wollman 1982c7a9781SMark Murray void 1992c7a9781SMark Murray trace_close(int zap_stdio) 2007b6ab19dSGarrett Wollman { 2017b6ab19dSGarrett Wollman int fd; 2027b6ab19dSGarrett Wollman 2037b6ab19dSGarrett Wollman 2047b6ab19dSGarrett Wollman fflush(stdout); 2057b6ab19dSGarrett Wollman fflush(stderr); 2067b6ab19dSGarrett Wollman 2072c7a9781SMark Murray if (ftrace != 0 && zap_stdio) { 20871965874SGarrett Wollman if (ftrace != stdout) 20971965874SGarrett Wollman fclose(ftrace); 21071965874SGarrett Wollman ftrace = 0; 2117b6ab19dSGarrett Wollman fd = open(_PATH_DEVNULL, O_RDWR); 2122c7a9781SMark Murray if (isatty(STDIN_FILENO)) 21371965874SGarrett Wollman (void)dup2(fd, STDIN_FILENO); 2142c7a9781SMark Murray if (isatty(STDOUT_FILENO)) 2157b6ab19dSGarrett Wollman (void)dup2(fd, STDOUT_FILENO); 2162c7a9781SMark Murray if (isatty(STDERR_FILENO)) 2177b6ab19dSGarrett Wollman (void)dup2(fd, STDERR_FILENO); 2187b6ab19dSGarrett Wollman (void)close(fd); 2197b6ab19dSGarrett Wollman } 22071965874SGarrett Wollman lastlog_time.tv_sec = 0; 2217b6ab19dSGarrett Wollman } 2227b6ab19dSGarrett Wollman 2237b6ab19dSGarrett Wollman 2247b6ab19dSGarrett Wollman void 2257b6ab19dSGarrett Wollman trace_flush(void) 2267b6ab19dSGarrett Wollman { 2277b6ab19dSGarrett Wollman if (ftrace != 0) { 2287b6ab19dSGarrett Wollman fflush(ftrace); 2297b6ab19dSGarrett Wollman if (ferror(ftrace)) 2302c7a9781SMark Murray trace_off("tracing off: %s", strerror(ferror(ftrace))); 2317b6ab19dSGarrett Wollman } 2327b6ab19dSGarrett Wollman } 2337b6ab19dSGarrett Wollman 2347b6ab19dSGarrett Wollman 2357b6ab19dSGarrett Wollman void 2362c7a9781SMark Murray trace_off(const char *p, ...) 2377b6ab19dSGarrett Wollman { 2387b6ab19dSGarrett Wollman va_list args; 2397b6ab19dSGarrett Wollman 2407b6ab19dSGarrett Wollman 2417b6ab19dSGarrett Wollman if (ftrace != 0) { 2427b6ab19dSGarrett Wollman lastlog(); 2437b6ab19dSGarrett Wollman va_start(args, p); 2447b6ab19dSGarrett Wollman vfprintf(ftrace, p, args); 245caa79e36SBruce M Simpson va_end(args); 2462c7a9781SMark Murray (void)fputc('\n',ftrace); 2477b6ab19dSGarrett Wollman } 2482c7a9781SMark Murray trace_close(file_trace); 2497b6ab19dSGarrett Wollman 2507b6ab19dSGarrett Wollman new_tracelevel = tracelevel = 0; 2517b6ab19dSGarrett Wollman } 2527b6ab19dSGarrett Wollman 2537b6ab19dSGarrett Wollman 25471965874SGarrett Wollman /* log a change in tracing 2557b6ab19dSGarrett Wollman */ 2567b6ab19dSGarrett Wollman void 2572c7a9781SMark Murray tracelevel_msg(const char *pat, 25871965874SGarrett Wollman int dump) /* -1=no dump, 0=default, 1=force */ 2597b6ab19dSGarrett Wollman { 2602c7a9781SMark Murray static const char *off_msgs[MAX_TRACELEVEL] = { 2617b6ab19dSGarrett Wollman "Tracing actions stopped", 2627b6ab19dSGarrett Wollman "Tracing packets stopped", 2637b6ab19dSGarrett Wollman "Tracing packet contents stopped", 2647b6ab19dSGarrett Wollman "Tracing kernel changes stopped", 2657b6ab19dSGarrett Wollman }; 2662c7a9781SMark Murray static const char *on_msgs[MAX_TRACELEVEL] = { 2677b6ab19dSGarrett Wollman "Tracing actions started", 2687b6ab19dSGarrett Wollman "Tracing packets started", 2697b6ab19dSGarrett Wollman "Tracing packet contents started", 2707b6ab19dSGarrett Wollman "Tracing kernel changes started", 2717b6ab19dSGarrett Wollman }; 27271965874SGarrett Wollman u_int old_tracelevel = tracelevel; 2737b6ab19dSGarrett Wollman 2747b6ab19dSGarrett Wollman 27571965874SGarrett Wollman if (new_tracelevel < 0) 27671965874SGarrett Wollman new_tracelevel = 0; 27771965874SGarrett Wollman else if (new_tracelevel > MAX_TRACELEVEL) 2787b6ab19dSGarrett Wollman new_tracelevel = MAX_TRACELEVEL; 27971965874SGarrett Wollman 28071965874SGarrett Wollman if (new_tracelevel < tracelevel) { 28171965874SGarrett Wollman if (new_tracelevel <= 0) { 28271965874SGarrett Wollman trace_off(pat, off_msgs[0]); 28371965874SGarrett Wollman } else do { 28471965874SGarrett Wollman tmsg(pat, off_msgs[tracelevel]); 28571965874SGarrett Wollman } 28671965874SGarrett Wollman while (--tracelevel != new_tracelevel); 28771965874SGarrett Wollman 28871965874SGarrett Wollman } else if (new_tracelevel > tracelevel) { 28971965874SGarrett Wollman do { 29071965874SGarrett Wollman tmsg(pat, on_msgs[tracelevel++]); 29171965874SGarrett Wollman } while (tracelevel != new_tracelevel); 29271965874SGarrett Wollman } 29371965874SGarrett Wollman 29471965874SGarrett Wollman if (dump > 0 29571965874SGarrett Wollman || (dump == 0 && old_tracelevel == 0 && tracelevel != 0)) 29671965874SGarrett Wollman trace_dump(); 29771965874SGarrett Wollman } 29871965874SGarrett Wollman 29971965874SGarrett Wollman 30071965874SGarrett Wollman void 3012c7a9781SMark Murray set_tracefile(const char *filename, 3022c7a9781SMark Murray const char *pat, 30371965874SGarrett Wollman int dump) /* -1=no dump, 0=default, 1=force */ 30471965874SGarrett Wollman { 30571965874SGarrett Wollman struct stat stbuf; 30671965874SGarrett Wollman FILE *n_ftrace; 3072c7a9781SMark Murray const char *fn; 30871965874SGarrett Wollman 30971965874SGarrett Wollman 31071965874SGarrett Wollman /* Allow a null filename to increase the level if the trace file 31171965874SGarrett Wollman * is already open or if coming from a trusted source, such as 31271965874SGarrett Wollman * a signal or the command line. 31371965874SGarrett Wollman */ 31471965874SGarrett Wollman if (filename == 0 || filename[0] == '\0') { 31571965874SGarrett Wollman filename = 0; 31671965874SGarrett Wollman if (ftrace == 0) { 31771965874SGarrett Wollman if (inittracename[0] == '\0') { 31871965874SGarrett Wollman msglog("missing trace file name"); 3197b6ab19dSGarrett Wollman return; 3207b6ab19dSGarrett Wollman } 32171965874SGarrett Wollman fn = inittracename; 32271965874SGarrett Wollman } else { 32371965874SGarrett Wollman fn = 0; 3247b6ab19dSGarrett Wollman } 325d5b718b3SGarrett Wollman 32671965874SGarrett Wollman } else if (!strcmp(filename,"dump/../table")) { 32771965874SGarrett Wollman trace_dump(); 32871965874SGarrett Wollman return; 32971965874SGarrett Wollman 3307b6ab19dSGarrett Wollman } else { 33171965874SGarrett Wollman /* Allow the file specified with "-T file" to be reopened, 33271965874SGarrett Wollman * but require all other names specified over the net to 33371965874SGarrett Wollman * match the official path. The path can specify a directory 33471965874SGarrett Wollman * in which the file is to be created. 33571965874SGarrett Wollman */ 33671965874SGarrett Wollman if (strcmp(filename, inittracename) 33771965874SGarrett Wollman #ifdef _PATH_TRACE 33871965874SGarrett Wollman && (strncmp(filename, _PATH_TRACE, sizeof(_PATH_TRACE)-1) 33971965874SGarrett Wollman || strstr(filename,"../") 34071965874SGarrett Wollman || 0 > stat(_PATH_TRACE, &stbuf)) 34171965874SGarrett Wollman #endif 34271965874SGarrett Wollman ) { 34371965874SGarrett Wollman msglog("wrong trace file \"%s\"", filename); 34471965874SGarrett Wollman return; 3457b6ab19dSGarrett Wollman } 34671965874SGarrett Wollman 34771965874SGarrett Wollman /* If the new tracefile exists, it must be a regular file. 34871965874SGarrett Wollman */ 3492c7a9781SMark Murray if (stat(filename, &stbuf) >= 0 && !S_ISREG(stbuf.st_mode)) { 35071965874SGarrett Wollman msglog("wrong type (%#x) of trace file \"%s\"", 35171965874SGarrett Wollman stbuf.st_mode, filename); 35271965874SGarrett Wollman return; 3537b6ab19dSGarrett Wollman } 35471965874SGarrett Wollman 35571965874SGarrett Wollman fn = filename; 3567b6ab19dSGarrett Wollman } 35771965874SGarrett Wollman 35871965874SGarrett Wollman if (fn != 0) { 35971965874SGarrett Wollman n_ftrace = fopen(fn, "a"); 36071965874SGarrett Wollman if (n_ftrace == 0) { 36171965874SGarrett Wollman msglog("failed to open trace file \"%s\" %s", 36271965874SGarrett Wollman fn, strerror(errno)); 36371965874SGarrett Wollman if (fn == inittracename) 36471965874SGarrett Wollman inittracename[0] = '\0'; 36571965874SGarrett Wollman return; 36671965874SGarrett Wollman } 36771965874SGarrett Wollman 3682c7a9781SMark Murray tmsg("switch to trace file %s", fn); 36971965874SGarrett Wollman 3702c7a9781SMark Murray trace_close(file_trace = 1); 37171965874SGarrett Wollman 37271965874SGarrett Wollman if (fn != savetracename) 37371965874SGarrett Wollman strncpy(savetracename, fn, sizeof(savetracename)-1); 37471965874SGarrett Wollman ftrace = n_ftrace; 37571965874SGarrett Wollman 37671965874SGarrett Wollman fflush(stdout); 37771965874SGarrett Wollman fflush(stderr); 37871965874SGarrett Wollman dup2(fileno(ftrace), STDOUT_FILENO); 37971965874SGarrett Wollman dup2(fileno(ftrace), STDERR_FILENO); 38071965874SGarrett Wollman } 38171965874SGarrett Wollman 38271965874SGarrett Wollman if (new_tracelevel == 0 || filename == 0) 38371965874SGarrett Wollman new_tracelevel++; 38471965874SGarrett Wollman tracelevel_msg(pat, dump != 0 ? dump : (filename != 0)); 38571965874SGarrett Wollman } 38671965874SGarrett Wollman 38771965874SGarrett Wollman 38871965874SGarrett Wollman /* ARGSUSED */ 38971965874SGarrett Wollman void 3902c7a9781SMark Murray sigtrace_on(int s UNUSED) 39171965874SGarrett Wollman { 39271965874SGarrett Wollman new_tracelevel++; 3932c7a9781SMark Murray sigtrace_pat = "SIGUSR1: %s"; 39471965874SGarrett Wollman } 39571965874SGarrett Wollman 39671965874SGarrett Wollman 39771965874SGarrett Wollman /* ARGSUSED */ 39871965874SGarrett Wollman void 3992c7a9781SMark Murray sigtrace_off(int s UNUSED) 40071965874SGarrett Wollman { 40171965874SGarrett Wollman new_tracelevel--; 4022c7a9781SMark Murray sigtrace_pat = "SIGUSR2: %s"; 40371965874SGarrett Wollman } 40471965874SGarrett Wollman 40571965874SGarrett Wollman 40671965874SGarrett Wollman /* Set tracing after a signal. 40771965874SGarrett Wollman */ 40871965874SGarrett Wollman void 40971965874SGarrett Wollman set_tracelevel(void) 41071965874SGarrett Wollman { 41171965874SGarrett Wollman if (new_tracelevel == tracelevel) 41271965874SGarrett Wollman return; 41371965874SGarrett Wollman 41471965874SGarrett Wollman /* If tracing entirely off, and there was no tracefile specified 41571965874SGarrett Wollman * on the command line, then leave it off. 41671965874SGarrett Wollman */ 41771965874SGarrett Wollman if (new_tracelevel > tracelevel && ftrace == 0) { 41871965874SGarrett Wollman if (savetracename[0] != '\0') { 41971965874SGarrett Wollman set_tracefile(savetracename,sigtrace_pat,0); 42071965874SGarrett Wollman } else if (inittracename[0] != '\0') { 42171965874SGarrett Wollman set_tracefile(inittracename,sigtrace_pat,0); 42271965874SGarrett Wollman } else { 42371965874SGarrett Wollman new_tracelevel = 0; 42471965874SGarrett Wollman return; 42571965874SGarrett Wollman } 42671965874SGarrett Wollman } else { 42771965874SGarrett Wollman tracelevel_msg(sigtrace_pat, 0); 42871965874SGarrett Wollman } 4297b6ab19dSGarrett Wollman } 4307b6ab19dSGarrett Wollman 4317b6ab19dSGarrett Wollman 4327b6ab19dSGarrett Wollman /* display an address 4337b6ab19dSGarrett Wollman */ 4347b6ab19dSGarrett Wollman char * 4357b6ab19dSGarrett Wollman addrname(naddr addr, /* in network byte order */ 4367b6ab19dSGarrett Wollman naddr mask, 4377b6ab19dSGarrett Wollman int force) /* 0=show mask if nonstandard, */ 4387b6ab19dSGarrett Wollman { /* 1=always show mask, 2=never */ 4397b6ab19dSGarrett Wollman #define NUM_BUFS 4 4407b6ab19dSGarrett Wollman static int bufno; 4417b6ab19dSGarrett Wollman static struct { 4427b6ab19dSGarrett Wollman char str[15+20]; 4437b6ab19dSGarrett Wollman } bufs[NUM_BUFS]; 4447b6ab19dSGarrett Wollman char *s, *sp; 4457b6ab19dSGarrett Wollman naddr dmask; 4467b6ab19dSGarrett Wollman int i; 4477b6ab19dSGarrett Wollman 4487b6ab19dSGarrett Wollman s = strcpy(bufs[bufno].str, naddr_ntoa(addr)); 4497b6ab19dSGarrett Wollman bufno = (bufno+1) % NUM_BUFS; 4507b6ab19dSGarrett Wollman 4517b6ab19dSGarrett Wollman if (force == 1 || (force == 0 && mask != std_mask(addr))) { 4527b6ab19dSGarrett Wollman sp = &s[strlen(s)]; 4537b6ab19dSGarrett Wollman 4547b6ab19dSGarrett Wollman dmask = mask & -mask; 4557b6ab19dSGarrett Wollman if (mask + dmask == 0) { 4567b6ab19dSGarrett Wollman for (i = 0; i != 32 && ((1<<i) & mask) == 0; i++) 4577b6ab19dSGarrett Wollman continue; 4587b6ab19dSGarrett Wollman (void)sprintf(sp, "/%d", 32-i); 4597b6ab19dSGarrett Wollman 4607b6ab19dSGarrett Wollman } else { 4617b6ab19dSGarrett Wollman (void)sprintf(sp, " (mask %#x)", (u_int)mask); 4627b6ab19dSGarrett Wollman } 4637b6ab19dSGarrett Wollman } 4647b6ab19dSGarrett Wollman 4657b6ab19dSGarrett Wollman return s; 4667b6ab19dSGarrett Wollman #undef NUM_BUFS 4677b6ab19dSGarrett Wollman } 4687b6ab19dSGarrett Wollman 4697b6ab19dSGarrett Wollman 4707b6ab19dSGarrett Wollman /* display a bit-field 4717b6ab19dSGarrett Wollman */ 4727b6ab19dSGarrett Wollman struct bits { 4732c7a9781SMark Murray u_int bits_mask; 4742c7a9781SMark Murray u_int bits_clear; 4752c7a9781SMark Murray const char *bits_name; 4767b6ab19dSGarrett Wollman }; 4777b6ab19dSGarrett Wollman 4787b6ab19dSGarrett Wollman static struct bits if_bits[] = { 4797b6ab19dSGarrett Wollman { IFF_LOOPBACK, 0, "LOOPBACK" }, 4807b6ab19dSGarrett Wollman { IFF_POINTOPOINT, 0, "PT-TO-PT" }, 4817b6ab19dSGarrett Wollman { 0, 0, 0} 4827b6ab19dSGarrett Wollman }; 4837b6ab19dSGarrett Wollman 4847b6ab19dSGarrett Wollman static struct bits is_bits[] = { 485d5b718b3SGarrett Wollman { IS_ALIAS, 0, "ALIAS" }, 4867b6ab19dSGarrett Wollman { IS_SUBNET, 0, "" }, 487d5b718b3SGarrett Wollman { IS_REMOTE, (IS_NO_RDISC 488d5b718b3SGarrett Wollman | IS_BCAST_RDISC), "REMOTE" }, 4897b6ab19dSGarrett Wollman { IS_PASSIVE, (IS_NO_RDISC 4907b6ab19dSGarrett Wollman | IS_NO_RIP 4917b6ab19dSGarrett Wollman | IS_NO_SUPER_AG 4927b6ab19dSGarrett Wollman | IS_PM_RDISC 4937b6ab19dSGarrett Wollman | IS_NO_AG), "PASSIVE" }, 4947b6ab19dSGarrett Wollman { IS_EXTERNAL, 0, "EXTERNAL" }, 4957b6ab19dSGarrett Wollman { IS_CHECKED, 0, "" }, 4967b6ab19dSGarrett Wollman { IS_ALL_HOSTS, 0, "" }, 4977b6ab19dSGarrett Wollman { IS_ALL_ROUTERS, 0, "" }, 498d5b718b3SGarrett Wollman { IS_DISTRUST, 0, "DISTRUST" }, 4997b6ab19dSGarrett Wollman { IS_BROKE, IS_SICK, "BROKEN" }, 5007b6ab19dSGarrett Wollman { IS_SICK, 0, "SICK" }, 501d5b718b3SGarrett Wollman { IS_DUP, 0, "DUPLICATE" }, 50271965874SGarrett Wollman { IS_REDIRECT_OK, 0, "REDIRECT_OK" }, 5037b6ab19dSGarrett Wollman { IS_NEED_NET_SYN, 0, "" }, 5047b6ab19dSGarrett Wollman { IS_NO_AG, IS_NO_SUPER_AG, "NO_AG" }, 5057b6ab19dSGarrett Wollman { IS_NO_SUPER_AG, 0, "NO_SUPER_AG" }, 5067b6ab19dSGarrett Wollman { (IS_NO_RIPV1_IN 5077b6ab19dSGarrett Wollman | IS_NO_RIPV2_IN 5087b6ab19dSGarrett Wollman | IS_NO_RIPV1_OUT 5097b6ab19dSGarrett Wollman | IS_NO_RIPV2_OUT), 0, "NO_RIP" }, 5107b6ab19dSGarrett Wollman { (IS_NO_RIPV1_IN 5117b6ab19dSGarrett Wollman | IS_NO_RIPV1_OUT), 0, "RIPV2" }, 5127b6ab19dSGarrett Wollman { IS_NO_RIPV1_IN, 0, "NO_RIPV1_IN" }, 5137b6ab19dSGarrett Wollman { IS_NO_RIPV2_IN, 0, "NO_RIPV2_IN" }, 5147b6ab19dSGarrett Wollman { IS_NO_RIPV1_OUT, 0, "NO_RIPV1_OUT" }, 5157b6ab19dSGarrett Wollman { IS_NO_RIPV2_OUT, 0, "NO_RIPV2_OUT" }, 5167b6ab19dSGarrett Wollman { (IS_NO_ADV_IN 5177b6ab19dSGarrett Wollman | IS_NO_SOL_OUT 5187b6ab19dSGarrett Wollman | IS_NO_ADV_OUT), IS_BCAST_RDISC, "NO_RDISC" }, 5197b6ab19dSGarrett Wollman { IS_NO_SOL_OUT, 0, "NO_SOLICIT" }, 5207b6ab19dSGarrett Wollman { IS_SOL_OUT, 0, "SEND_SOLICIT" }, 5217b6ab19dSGarrett Wollman { IS_NO_ADV_OUT, IS_BCAST_RDISC, "NO_RDISC_ADV" }, 5227b6ab19dSGarrett Wollman { IS_ADV_OUT, 0, "RDISC_ADV" }, 5237b6ab19dSGarrett Wollman { IS_BCAST_RDISC, 0, "BCAST_RDISC" }, 524d5b718b3SGarrett Wollman { IS_PM_RDISC, 0, "" }, 5257b6ab19dSGarrett Wollman { 0, 0, "%#x"} 5267b6ab19dSGarrett Wollman }; 5277b6ab19dSGarrett Wollman 5287b6ab19dSGarrett Wollman static struct bits rs_bits[] = { 5297b6ab19dSGarrett Wollman { RS_IF, 0, "IF" }, 5307b6ab19dSGarrett Wollman { RS_NET_INT, RS_NET_SYN, "NET_INT" }, 5317b6ab19dSGarrett Wollman { RS_NET_SYN, 0, "NET_SYN" }, 5327b6ab19dSGarrett Wollman { RS_SUBNET, 0, "" }, 5337b6ab19dSGarrett Wollman { RS_LOCAL, 0, "LOCAL" }, 5347b6ab19dSGarrett Wollman { RS_MHOME, 0, "MHOME" }, 5357b6ab19dSGarrett Wollman { RS_STATIC, 0, "STATIC" }, 5367b6ab19dSGarrett Wollman { RS_RDISC, 0, "RDISC" }, 5377b6ab19dSGarrett Wollman { 0, 0, "%#x"} 5387b6ab19dSGarrett Wollman }; 5397b6ab19dSGarrett Wollman 5407b6ab19dSGarrett Wollman 5417b6ab19dSGarrett Wollman static void 5422c7a9781SMark Murray trace_bits(const struct bits *tbl, 5437b6ab19dSGarrett Wollman u_int field, 5447b6ab19dSGarrett Wollman int force) 5457b6ab19dSGarrett Wollman { 5462c7a9781SMark Murray u_int b; 5477b6ab19dSGarrett Wollman char c; 5487b6ab19dSGarrett Wollman 5497b6ab19dSGarrett Wollman if (force) { 5507b6ab19dSGarrett Wollman (void)putc('<', ftrace); 5517b6ab19dSGarrett Wollman c = 0; 5527b6ab19dSGarrett Wollman } else { 5537b6ab19dSGarrett Wollman c = '<'; 5547b6ab19dSGarrett Wollman } 5557b6ab19dSGarrett Wollman 5567b6ab19dSGarrett Wollman while (field != 0 5577b6ab19dSGarrett Wollman && (b = tbl->bits_mask) != 0) { 5587b6ab19dSGarrett Wollman if ((b & field) == b) { 5597b6ab19dSGarrett Wollman if (tbl->bits_name[0] != '\0') { 5607b6ab19dSGarrett Wollman if (c) 5617b6ab19dSGarrett Wollman (void)putc(c, ftrace); 5627b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%s", tbl->bits_name); 5637b6ab19dSGarrett Wollman c = '|'; 5647b6ab19dSGarrett Wollman } 5657b6ab19dSGarrett Wollman if (0 == (field &= ~(b | tbl->bits_clear))) 5667b6ab19dSGarrett Wollman break; 5677b6ab19dSGarrett Wollman } 5687b6ab19dSGarrett Wollman tbl++; 5697b6ab19dSGarrett Wollman } 5707b6ab19dSGarrett Wollman if (field != 0 && tbl->bits_name != 0) { 5717b6ab19dSGarrett Wollman if (c) 5727b6ab19dSGarrett Wollman (void)putc(c, ftrace); 5737b6ab19dSGarrett Wollman (void)fprintf(ftrace, tbl->bits_name, field); 5747b6ab19dSGarrett Wollman c = '|'; 5757b6ab19dSGarrett Wollman } 5767b6ab19dSGarrett Wollman 5777b6ab19dSGarrett Wollman if (c != '<' || force) 5787b6ab19dSGarrett Wollman (void)fputs("> ", ftrace); 5797b6ab19dSGarrett Wollman } 5807b6ab19dSGarrett Wollman 5817b6ab19dSGarrett Wollman 5822c7a9781SMark Murray char * 5832c7a9781SMark Murray rtname(naddr dst, 5847b6ab19dSGarrett Wollman naddr mask, 5852c7a9781SMark Murray naddr gate) 5867b6ab19dSGarrett Wollman { 5877b6ab19dSGarrett Wollman static char buf[3*4+3+1+2+3 /* "xxx.xxx.xxx.xxx/xx-->" */ 5887b6ab19dSGarrett Wollman +3*4+3+1]; /* "xxx.xxx.xxx.xxx" */ 5897b6ab19dSGarrett Wollman int i; 5907b6ab19dSGarrett Wollman 5917b6ab19dSGarrett Wollman i = sprintf(buf, "%-16s-->", addrname(dst, mask, 0)); 5922c7a9781SMark Murray (void)sprintf(&buf[i], "%-*s", 15+20-MAX(20,i), naddr_ntoa(gate)); 5937b6ab19dSGarrett Wollman return buf; 5947b6ab19dSGarrett Wollman } 5957b6ab19dSGarrett Wollman 5967b6ab19dSGarrett Wollman 59771965874SGarrett Wollman static void 59871965874SGarrett Wollman print_rts(struct rt_spare *rts, 59971965874SGarrett Wollman int force_metric, /* -1=suppress, 0=default */ 60071965874SGarrett Wollman int force_ifp, /* -1=suppress, 0=default */ 60171965874SGarrett Wollman int force_router, /* -1=suppress, 0=default, 1=display */ 60271965874SGarrett Wollman int force_tag, /* -1=suppress, 0=default, 1=display */ 60371965874SGarrett Wollman int force_time) /* 0=suppress, 1=display */ 60471965874SGarrett Wollman { 6052c7a9781SMark Murray int i; 6062c7a9781SMark Murray 6072c7a9781SMark Murray 60871965874SGarrett Wollman if (force_metric >= 0) 60971965874SGarrett Wollman (void)fprintf(ftrace, "metric=%-2d ", rts->rts_metric); 61071965874SGarrett Wollman if (force_ifp >= 0) 61171965874SGarrett Wollman (void)fprintf(ftrace, "%s ", (rts->rts_ifp == 0 ? 61271965874SGarrett Wollman "if?" : rts->rts_ifp->int_name)); 61371965874SGarrett Wollman if (force_router > 0 61471965874SGarrett Wollman || (force_router == 0 && rts->rts_router != rts->rts_gate)) 61571965874SGarrett Wollman (void)fprintf(ftrace, "router=%s ", 61671965874SGarrett Wollman naddr_ntoa(rts->rts_router)); 61771965874SGarrett Wollman if (force_time > 0) 61871965874SGarrett Wollman (void)fprintf(ftrace, "%s ", ts(rts->rts_time)); 61971965874SGarrett Wollman if (force_tag > 0 62071965874SGarrett Wollman || (force_tag == 0 && rts->rts_tag != 0)) 6212c7a9781SMark Murray (void)fprintf(ftrace, "tag=%#x ", ntohs(rts->rts_tag)); 6222c7a9781SMark Murray if (rts->rts_de_ag != 0) { 6232c7a9781SMark Murray for (i = 1; (u_int)(1 << i) <= rts->rts_de_ag; i++) 6242c7a9781SMark Murray continue; 6252c7a9781SMark Murray (void)fprintf(ftrace, "de_ag=%d ", i); 6262c7a9781SMark Murray } 6272c7a9781SMark Murray 62871965874SGarrett Wollman } 62971965874SGarrett Wollman 63071965874SGarrett Wollman 6317b6ab19dSGarrett Wollman void 6322c7a9781SMark Murray trace_if(const char *act, 6337b6ab19dSGarrett Wollman struct interface *ifp) 6347b6ab19dSGarrett Wollman { 6357b6ab19dSGarrett Wollman if (!TRACEACTIONS || ftrace == 0) 6367b6ab19dSGarrett Wollman return; 6377b6ab19dSGarrett Wollman 6387b6ab19dSGarrett Wollman lastlog(); 639d5b718b3SGarrett Wollman (void)fprintf(ftrace, "%-3s interface %-4s ", act, ifp->int_name); 6407b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%-15s-->%-15s ", 6417b6ab19dSGarrett Wollman naddr_ntoa(ifp->int_addr), 642d5b718b3SGarrett Wollman addrname(((ifp->int_if_flags & IFF_POINTOPOINT) 6437b6ab19dSGarrett Wollman ? ifp->int_dstaddr 644d5b718b3SGarrett Wollman : htonl(ifp->int_net)), 6457b6ab19dSGarrett Wollman ifp->int_mask, 1)); 6467b6ab19dSGarrett Wollman if (ifp->int_metric != 0) 6477b6ab19dSGarrett Wollman (void)fprintf(ftrace, "metric=%d ", ifp->int_metric); 648caa79e36SBruce M Simpson if (ifp->int_adj_inmetric != 0) 649caa79e36SBruce M Simpson (void)fprintf(ftrace, "adj_inmetric=%u ", 650caa79e36SBruce M Simpson ifp->int_adj_inmetric); 651caa79e36SBruce M Simpson if (ifp->int_adj_outmetric != 0) 652caa79e36SBruce M Simpson (void)fprintf(ftrace, "adj_outmetric=%u ", 653caa79e36SBruce M Simpson ifp->int_adj_outmetric); 654d5b718b3SGarrett Wollman if (!IS_RIP_OUT_OFF(ifp->int_state) 655d5b718b3SGarrett Wollman && ifp->int_d_metric != 0) 656caa79e36SBruce M Simpson (void)fprintf(ftrace, "fake_default=%u ", ifp->int_d_metric); 6577b6ab19dSGarrett Wollman trace_bits(if_bits, ifp->int_if_flags, 0); 6587b6ab19dSGarrett Wollman trace_bits(is_bits, ifp->int_state, 0); 6597b6ab19dSGarrett Wollman (void)fputc('\n',ftrace); 6607b6ab19dSGarrett Wollman } 6617b6ab19dSGarrett Wollman 6627b6ab19dSGarrett Wollman 6637b6ab19dSGarrett Wollman void 6647b6ab19dSGarrett Wollman trace_upslot(struct rt_entry *rt, 6657b6ab19dSGarrett Wollman struct rt_spare *rts, 6662c7a9781SMark Murray struct rt_spare *new) 6677b6ab19dSGarrett Wollman { 6687b6ab19dSGarrett Wollman if (!TRACEACTIONS || ftrace == 0) 6697b6ab19dSGarrett Wollman return; 67071965874SGarrett Wollman 6712c7a9781SMark Murray if (rts->rts_gate == new->rts_gate 6722c7a9781SMark Murray && rts->rts_router == new->rts_router 6732c7a9781SMark Murray && rts->rts_metric == new->rts_metric 6742c7a9781SMark Murray && rts->rts_tag == new->rts_tag 6752c7a9781SMark Murray && rts->rts_de_ag == new->rts_de_ag) 6767b6ab19dSGarrett Wollman return; 6777b6ab19dSGarrett Wollman 6787b6ab19dSGarrett Wollman lastlog(); 6792c7a9781SMark Murray if (new->rts_gate == 0) { 6802c7a9781SMark Murray (void)fprintf(ftrace, "Del #%d %-35s ", 6812c7a9781SMark Murray (int)(rts - rt->rt_spares), 6822c7a9781SMark Murray rtname(rt->rt_dst, rt->rt_mask, rts->rts_gate)); 6832c7a9781SMark Murray print_rts(rts, 0,0,0,0, 6842c7a9781SMark Murray (rts != rt->rt_spares 6852c7a9781SMark Murray || AGE_RT(rt->rt_state,new->rts_ifp))); 6862c7a9781SMark Murray 6872c7a9781SMark Murray } else if (rts->rts_gate != RIP_DEFAULT) { 6887b6ab19dSGarrett Wollman (void)fprintf(ftrace, "Chg #%d %-35s ", 6892c7a9781SMark Murray (int)(rts - rt->rt_spares), 6902c7a9781SMark Murray rtname(rt->rt_dst, rt->rt_mask, rts->rts_gate)); 69171965874SGarrett Wollman print_rts(rts, 0,0, 6922c7a9781SMark Murray rts->rts_gate != new->rts_gate, 6932c7a9781SMark Murray rts->rts_tag != new->rts_tag, 69471965874SGarrett Wollman rts != rt->rt_spares || AGE_RT(rt->rt_state, 69571965874SGarrett Wollman rt->rt_ifp)); 6967b6ab19dSGarrett Wollman 69771965874SGarrett Wollman (void)fprintf(ftrace, "\n %19s%-16s ", "", 6982c7a9781SMark Murray (new->rts_gate != rts->rts_gate 6992c7a9781SMark Murray ? naddr_ntoa(new->rts_gate) : "")); 7002c7a9781SMark Murray print_rts(new, 7012c7a9781SMark Murray -(new->rts_metric == rts->rts_metric), 7022c7a9781SMark Murray -(new->rts_ifp == rts->rts_ifp), 70371965874SGarrett Wollman 0, 7042c7a9781SMark Murray rts->rts_tag != new->rts_tag, 7052c7a9781SMark Murray (new->rts_time != rts->rts_time 7062c7a9781SMark Murray && (rts != rt->rt_spares 7072c7a9781SMark Murray || AGE_RT(rt->rt_state, new->rts_ifp)))); 7087b6ab19dSGarrett Wollman 7097b6ab19dSGarrett Wollman } else { 7107b6ab19dSGarrett Wollman (void)fprintf(ftrace, "Add #%d %-35s ", 7112c7a9781SMark Murray (int)(rts - rt->rt_spares), 7122c7a9781SMark Murray rtname(rt->rt_dst, rt->rt_mask, new->rts_gate)); 7132c7a9781SMark Murray print_rts(new, 0,0,0,0, 7142c7a9781SMark Murray (rts != rt->rt_spares 7152c7a9781SMark Murray || AGE_RT(rt->rt_state,new->rts_ifp))); 7167b6ab19dSGarrett Wollman } 71771965874SGarrett Wollman (void)fputc('\n',ftrace); 7187b6ab19dSGarrett Wollman } 7197b6ab19dSGarrett Wollman 7207b6ab19dSGarrett Wollman 7212c7a9781SMark Murray /* miscellaneous message checked by the caller 7227b6ab19dSGarrett Wollman */ 7237b6ab19dSGarrett Wollman void 7242c7a9781SMark Murray trace_misc(const char *p, ...) 7257b6ab19dSGarrett Wollman { 7267b6ab19dSGarrett Wollman va_list args; 7277b6ab19dSGarrett Wollman 7282c7a9781SMark Murray if (ftrace == 0) 7297b6ab19dSGarrett Wollman return; 7307b6ab19dSGarrett Wollman 7317b6ab19dSGarrett Wollman lastlog(); 7327b6ab19dSGarrett Wollman va_start(args, p); 7337b6ab19dSGarrett Wollman vfprintf(ftrace, p, args); 734caa79e36SBruce M Simpson va_end(args); 7352c7a9781SMark Murray (void)fputc('\n',ftrace); 7367b6ab19dSGarrett Wollman } 7377b6ab19dSGarrett Wollman 7387b6ab19dSGarrett Wollman 7397b6ab19dSGarrett Wollman /* display a message if tracing actions 7407b6ab19dSGarrett Wollman */ 7417b6ab19dSGarrett Wollman void 7422c7a9781SMark Murray trace_act(const char *p, ...) 7437b6ab19dSGarrett Wollman { 7447b6ab19dSGarrett Wollman va_list args; 7457b6ab19dSGarrett Wollman 7467b6ab19dSGarrett Wollman if (!TRACEACTIONS || ftrace == 0) 7477b6ab19dSGarrett Wollman return; 7487b6ab19dSGarrett Wollman 7497b6ab19dSGarrett Wollman lastlog(); 7507b6ab19dSGarrett Wollman va_start(args, p); 7517b6ab19dSGarrett Wollman vfprintf(ftrace, p, args); 752caa79e36SBruce M Simpson va_end(args); 753d5b718b3SGarrett Wollman (void)fputc('\n',ftrace); 7547b6ab19dSGarrett Wollman } 7557b6ab19dSGarrett Wollman 7567b6ab19dSGarrett Wollman 7577b6ab19dSGarrett Wollman /* display a message if tracing packets 7587b6ab19dSGarrett Wollman */ 7597b6ab19dSGarrett Wollman void 7602c7a9781SMark Murray trace_pkt(const char *p, ...) 7617b6ab19dSGarrett Wollman { 7627b6ab19dSGarrett Wollman va_list args; 7637b6ab19dSGarrett Wollman 7647b6ab19dSGarrett Wollman if (!TRACEPACKETS || ftrace == 0) 7657b6ab19dSGarrett Wollman return; 7667b6ab19dSGarrett Wollman 7677b6ab19dSGarrett Wollman lastlog(); 7687b6ab19dSGarrett Wollman va_start(args, p); 7697b6ab19dSGarrett Wollman vfprintf(ftrace, p, args); 770caa79e36SBruce M Simpson va_end(args); 771d5b718b3SGarrett Wollman (void)fputc('\n',ftrace); 7727b6ab19dSGarrett Wollman } 7737b6ab19dSGarrett Wollman 7747b6ab19dSGarrett Wollman 7757b6ab19dSGarrett Wollman void 7767b6ab19dSGarrett Wollman trace_change(struct rt_entry *rt, 7777b6ab19dSGarrett Wollman u_int state, 7782c7a9781SMark Murray struct rt_spare *new, 7792c7a9781SMark Murray const char *label) 7807b6ab19dSGarrett Wollman { 7817b6ab19dSGarrett Wollman if (ftrace == 0) 7827b6ab19dSGarrett Wollman return; 7837b6ab19dSGarrett Wollman 7842c7a9781SMark Murray if (rt->rt_metric == new->rts_metric 7852c7a9781SMark Murray && rt->rt_gate == new->rts_gate 7862c7a9781SMark Murray && rt->rt_router == new->rts_router 7877b6ab19dSGarrett Wollman && rt->rt_state == state 7882c7a9781SMark Murray && rt->rt_tag == new->rts_tag 7892c7a9781SMark Murray && rt->rt_de_ag == new->rts_de_ag) 7907b6ab19dSGarrett Wollman return; 7917b6ab19dSGarrett Wollman 7927b6ab19dSGarrett Wollman lastlog(); 79371965874SGarrett Wollman (void)fprintf(ftrace, "%s %-35s ", 7947b6ab19dSGarrett Wollman label, 7952c7a9781SMark Murray rtname(rt->rt_dst, rt->rt_mask, rt->rt_gate)); 79671965874SGarrett Wollman print_rts(rt->rt_spares, 79771965874SGarrett Wollman 0,0,0,0, AGE_RT(rt->rt_state, rt->rt_ifp)); 7987b6ab19dSGarrett Wollman trace_bits(rs_bits, rt->rt_state, rt->rt_state != state); 7997b6ab19dSGarrett Wollman 80071965874SGarrett Wollman (void)fprintf(ftrace, "\n%*s %19s%-16s ", 8012c7a9781SMark Murray (int)strlen(label), "", "", 8022c7a9781SMark Murray (rt->rt_gate != new->rts_gate 8032c7a9781SMark Murray ? naddr_ntoa(new->rts_gate) : "")); 8042c7a9781SMark Murray print_rts(new, 8052c7a9781SMark Murray -(new->rts_metric == rt->rt_metric), 8062c7a9781SMark Murray -(new->rts_ifp == rt->rt_ifp), 80771965874SGarrett Wollman 0, 8082c7a9781SMark Murray rt->rt_tag != new->rts_tag, 8092c7a9781SMark Murray (rt->rt_time != new->rts_time 8102c7a9781SMark Murray && AGE_RT(rt->rt_state,new->rts_ifp))); 8117b6ab19dSGarrett Wollman if (rt->rt_state != state) 8127b6ab19dSGarrett Wollman trace_bits(rs_bits, state, 1); 81371965874SGarrett Wollman (void)fputc('\n',ftrace); 8147b6ab19dSGarrett Wollman } 8157b6ab19dSGarrett Wollman 8167b6ab19dSGarrett Wollman 8177b6ab19dSGarrett Wollman void 8182c7a9781SMark Murray trace_add_del(const char * action, struct rt_entry *rt) 8197b6ab19dSGarrett Wollman { 8207b6ab19dSGarrett Wollman if (ftrace == 0) 8217b6ab19dSGarrett Wollman return; 8227b6ab19dSGarrett Wollman 8237b6ab19dSGarrett Wollman lastlog(); 82471965874SGarrett Wollman (void)fprintf(ftrace, "%s %-35s ", 8257b6ab19dSGarrett Wollman action, 8262c7a9781SMark Murray rtname(rt->rt_dst, rt->rt_mask, rt->rt_gate)); 82771965874SGarrett Wollman print_rts(rt->rt_spares, 0,0,0,0,AGE_RT(rt->rt_state,rt->rt_ifp)); 82871965874SGarrett Wollman trace_bits(rs_bits, rt->rt_state, 0); 82971965874SGarrett Wollman (void)fputc('\n',ftrace); 8307b6ab19dSGarrett Wollman } 8317b6ab19dSGarrett Wollman 8327b6ab19dSGarrett Wollman 8337b6ab19dSGarrett Wollman /* ARGSUSED */ 8347b6ab19dSGarrett Wollman static int 8357b6ab19dSGarrett Wollman walk_trace(struct radix_node *rn, 8362c7a9781SMark Murray struct walkarg *w UNUSED) 8377b6ab19dSGarrett Wollman { 8387b6ab19dSGarrett Wollman #define RT ((struct rt_entry *)rn) 8397b6ab19dSGarrett Wollman struct rt_spare *rts; 8402c7a9781SMark Murray int i; 8417b6ab19dSGarrett Wollman 8422c7a9781SMark Murray (void)fprintf(ftrace, " %-35s ", 8432c7a9781SMark Murray rtname(RT->rt_dst, RT->rt_mask, RT->rt_gate)); 8442c7a9781SMark Murray print_rts(&RT->rt_spares[0], 0,0,0,0, AGE_RT(RT->rt_state, RT->rt_ifp)); 8457b6ab19dSGarrett Wollman trace_bits(rs_bits, RT->rt_state, 0); 84671965874SGarrett Wollman if (RT->rt_poison_time >= now_garbage 84771965874SGarrett Wollman && RT->rt_poison_metric < RT->rt_metric) 84871965874SGarrett Wollman (void)fprintf(ftrace, "pm=%d@%s", 8492c7a9781SMark Murray RT->rt_poison_metric, ts(RT->rt_poison_time)); 8507b6ab19dSGarrett Wollman 8517b6ab19dSGarrett Wollman rts = &RT->rt_spares[1]; 8527b6ab19dSGarrett Wollman for (i = 1; i < NUM_SPARES; i++, rts++) { 85371965874SGarrett Wollman if (rts->rts_gate != RIP_DEFAULT) { 85471965874SGarrett Wollman (void)fprintf(ftrace,"\n #%d%15s%-16s ", 85571965874SGarrett Wollman i, "", naddr_ntoa(rts->rts_gate)); 85671965874SGarrett Wollman print_rts(rts, 0,0,0,0,1); 8577b6ab19dSGarrett Wollman } 8587b6ab19dSGarrett Wollman } 8597b6ab19dSGarrett Wollman (void)fputc('\n',ftrace); 8607b6ab19dSGarrett Wollman 8617b6ab19dSGarrett Wollman return 0; 8627b6ab19dSGarrett Wollman } 8637b6ab19dSGarrett Wollman 8647b6ab19dSGarrett Wollman 8657b6ab19dSGarrett Wollman static void 8667b6ab19dSGarrett Wollman trace_dump(void) 8677b6ab19dSGarrett Wollman { 868d5b718b3SGarrett Wollman struct interface *ifp; 869d5b718b3SGarrett Wollman 8707b6ab19dSGarrett Wollman if (ftrace == 0) 8717b6ab19dSGarrett Wollman return; 8727b6ab19dSGarrett Wollman lastlog(); 8737b6ab19dSGarrett Wollman 87471965874SGarrett Wollman (void)fputs("current daemon state:\n", ftrace); 875d5b718b3SGarrett Wollman for (ifp = ifnet; ifp != 0; ifp = ifp->int_next) 876d5b718b3SGarrett Wollman trace_if("", ifp); 8777b6ab19dSGarrett Wollman (void)rn_walktree(rhead, walk_trace, 0); 8787b6ab19dSGarrett Wollman } 8797b6ab19dSGarrett Wollman 8807b6ab19dSGarrett Wollman 8817b6ab19dSGarrett Wollman void 8822c7a9781SMark Murray trace_rip(const char *dir1, const char *dir2, 8837b6ab19dSGarrett Wollman struct sockaddr_in *who, 8847b6ab19dSGarrett Wollman struct interface *ifp, 8857b6ab19dSGarrett Wollman struct rip *msg, 8867b6ab19dSGarrett Wollman int size) /* total size of message */ 8877b6ab19dSGarrett Wollman { 8887b6ab19dSGarrett Wollman struct netinfo *n, *lim; 8892c7a9781SMark Murray # define NA ((struct netauth*)n) 890d5b718b3SGarrett Wollman int i, seen_route; 8917b6ab19dSGarrett Wollman 8927b6ab19dSGarrett Wollman if (!TRACEPACKETS || ftrace == 0) 8937b6ab19dSGarrett Wollman return; 8947b6ab19dSGarrett Wollman 8957b6ab19dSGarrett Wollman lastlog(); 8967b6ab19dSGarrett Wollman if (msg->rip_cmd >= RIPCMD_MAX 8977b6ab19dSGarrett Wollman || msg->rip_vers == 0) { 8987b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%s bad RIPv%d cmd=%d %s" 8997b6ab19dSGarrett Wollman " %s.%d size=%d\n", 9007b6ab19dSGarrett Wollman dir1, msg->rip_vers, msg->rip_cmd, dir2, 9017b6ab19dSGarrett Wollman naddr_ntoa(who->sin_addr.s_addr), 9027b6ab19dSGarrett Wollman ntohs(who->sin_port), 9037b6ab19dSGarrett Wollman size); 9047b6ab19dSGarrett Wollman return; 9057b6ab19dSGarrett Wollman } 9067b6ab19dSGarrett Wollman 9077b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%s RIPv%d %s %s %s.%d%s%s\n", 9087b6ab19dSGarrett Wollman dir1, msg->rip_vers, ripcmds[msg->rip_cmd], dir2, 9097b6ab19dSGarrett Wollman naddr_ntoa(who->sin_addr.s_addr), ntohs(who->sin_port), 9107b6ab19dSGarrett Wollman ifp ? " via " : "", ifp ? ifp->int_name : ""); 9117b6ab19dSGarrett Wollman if (!TRACECONTENTS) 9127b6ab19dSGarrett Wollman return; 9137b6ab19dSGarrett Wollman 914d5b718b3SGarrett Wollman seen_route = 0; 9157b6ab19dSGarrett Wollman switch (msg->rip_cmd) { 9167b6ab19dSGarrett Wollman case RIPCMD_REQUEST: 9177b6ab19dSGarrett Wollman case RIPCMD_RESPONSE: 9187b6ab19dSGarrett Wollman n = msg->rip_nets; 9197b6ab19dSGarrett Wollman lim = (struct netinfo *)((char*)msg + size); 9207b6ab19dSGarrett Wollman for (; n < lim; n++) { 921d5b718b3SGarrett Wollman if (!seen_route 922d5b718b3SGarrett Wollman && n->n_family == RIP_AF_UNSPEC 9237b6ab19dSGarrett Wollman && ntohl(n->n_metric) == HOPCNT_INFINITY 924d5b718b3SGarrett Wollman && msg->rip_cmd == RIPCMD_REQUEST 925d5b718b3SGarrett Wollman && (n+1 == lim 926d5b718b3SGarrett Wollman || (n+2 == lim 927d5b718b3SGarrett Wollman && (n+1)->n_family == RIP_AF_AUTH))) { 9287b6ab19dSGarrett Wollman (void)fputs("\tQUERY ", ftrace); 9297b6ab19dSGarrett Wollman if (n->n_dst != 0) 9307b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%s ", 9317b6ab19dSGarrett Wollman naddr_ntoa(n->n_dst)); 9327b6ab19dSGarrett Wollman if (n->n_mask != 0) 9337b6ab19dSGarrett Wollman (void)fprintf(ftrace, "mask=%#x ", 9347b6ab19dSGarrett Wollman (u_int)ntohl(n->n_mask)); 9357b6ab19dSGarrett Wollman if (n->n_nhop != 0) 9367b6ab19dSGarrett Wollman (void)fprintf(ftrace, "nhop=%s ", 9377b6ab19dSGarrett Wollman naddr_ntoa(n->n_nhop)); 9387b6ab19dSGarrett Wollman if (n->n_tag != 0) 9397b6ab19dSGarrett Wollman (void)fprintf(ftrace, "tag=%#x ", 9407b6ab19dSGarrett Wollman ntohs(n->n_tag)); 9417b6ab19dSGarrett Wollman (void)fputc('\n',ftrace); 9427b6ab19dSGarrett Wollman continue; 9437b6ab19dSGarrett Wollman } 9447b6ab19dSGarrett Wollman 9457b6ab19dSGarrett Wollman if (n->n_family == RIP_AF_AUTH) { 946d5b718b3SGarrett Wollman if (NA->a_type == RIP_AUTH_PW 947d5b718b3SGarrett Wollman && n == msg->rip_nets) { 948d5b718b3SGarrett Wollman (void)fprintf(ftrace, "\tPassword" 949d5b718b3SGarrett Wollman " Authentication:" 950d5b718b3SGarrett Wollman " \"%s\"\n", 951d5b718b3SGarrett Wollman qstring(NA->au.au_pw, 952d5b718b3SGarrett Wollman RIP_AUTH_PW_LEN)); 953d5b718b3SGarrett Wollman continue; 954d5b718b3SGarrett Wollman } 955d5b718b3SGarrett Wollman 956d5b718b3SGarrett Wollman if (NA->a_type == RIP_AUTH_MD5 957d5b718b3SGarrett Wollman && n == msg->rip_nets) { 9587b6ab19dSGarrett Wollman (void)fprintf(ftrace, 9592c7a9781SMark Murray "\tMD5 Auth" 9602c7a9781SMark Murray " pkt_len=%d KeyID=%u" 9612c7a9781SMark Murray " auth_len=%d" 9622c7a9781SMark Murray " seqno=%#x" 963d5b718b3SGarrett Wollman " rsvd=%#x,%#x\n", 9642c7a9781SMark Murray ntohs(NA->au.a_md5.md5_pkt_len), 965d5b718b3SGarrett Wollman NA->au.a_md5.md5_keyid, 9662c7a9781SMark Murray NA->au.a_md5.md5_auth_len, 9672c7a9781SMark Murray (int)ntohl(NA->au.a_md5.md5_seqno), 9682c7a9781SMark Murray (int)ntohs(NA->au.a_md5.rsvd[0]), 9692c7a9781SMark Murray (int)ntohs(NA->au.a_md5.rsvd[1])); 970d5b718b3SGarrett Wollman continue; 971d5b718b3SGarrett Wollman } 972d5b718b3SGarrett Wollman (void)fprintf(ftrace, 9732c7a9781SMark Murray "\tAuthentication type %d: ", 974d5b718b3SGarrett Wollman ntohs(NA->a_type)); 9757b6ab19dSGarrett Wollman for (i = 0; 9762c7a9781SMark Murray i < (int)sizeof(NA->au.au_pw); 9777b6ab19dSGarrett Wollman i++) 9787b6ab19dSGarrett Wollman (void)fprintf(ftrace, "%02x ", 979d5b718b3SGarrett Wollman NA->au.au_pw[i]); 9807b6ab19dSGarrett Wollman (void)fputc('\n',ftrace); 9817b6ab19dSGarrett Wollman continue; 9827b6ab19dSGarrett Wollman } 9837b6ab19dSGarrett Wollman 984d5b718b3SGarrett Wollman seen_route = 1; 9857b6ab19dSGarrett Wollman if (n->n_family != RIP_AF_INET) { 9867b6ab19dSGarrett Wollman (void)fprintf(ftrace, 9877b6ab19dSGarrett Wollman "\t(af %d) %-18s mask=%#x ", 9887b6ab19dSGarrett Wollman ntohs(n->n_family), 9897b6ab19dSGarrett Wollman naddr_ntoa(n->n_dst), 9907b6ab19dSGarrett Wollman (u_int)ntohl(n->n_mask)); 9917b6ab19dSGarrett Wollman } else if (msg->rip_vers == RIPv1) { 9927b6ab19dSGarrett Wollman (void)fprintf(ftrace, "\t%-18s ", 9937b6ab19dSGarrett Wollman addrname(n->n_dst, 9947b6ab19dSGarrett Wollman ntohl(n->n_mask), 9957b6ab19dSGarrett Wollman n->n_mask==0 ? 2 : 1)); 9967b6ab19dSGarrett Wollman } else { 9977b6ab19dSGarrett Wollman (void)fprintf(ftrace, "\t%-18s ", 9987b6ab19dSGarrett Wollman addrname(n->n_dst, 9997b6ab19dSGarrett Wollman ntohl(n->n_mask), 10007b6ab19dSGarrett Wollman n->n_mask==0 ? 2 : 0)); 10017b6ab19dSGarrett Wollman } 10027b6ab19dSGarrett Wollman (void)fprintf(ftrace, "metric=%-2d ", 10037b6ab19dSGarrett Wollman (u_int)ntohl(n->n_metric)); 10047b6ab19dSGarrett Wollman if (n->n_nhop != 0) 10057b6ab19dSGarrett Wollman (void)fprintf(ftrace, " nhop=%s ", 10067b6ab19dSGarrett Wollman naddr_ntoa(n->n_nhop)); 10077b6ab19dSGarrett Wollman if (n->n_tag != 0) 10087b6ab19dSGarrett Wollman (void)fprintf(ftrace, "tag=%#x", 10097b6ab19dSGarrett Wollman ntohs(n->n_tag)); 10107b6ab19dSGarrett Wollman (void)fputc('\n',ftrace); 10117b6ab19dSGarrett Wollman } 10127b6ab19dSGarrett Wollman if (size != (char *)n - (char *)msg) 10137b6ab19dSGarrett Wollman (void)fprintf(ftrace, "truncated record, len %d\n", 10147b6ab19dSGarrett Wollman size); 10157b6ab19dSGarrett Wollman break; 10167b6ab19dSGarrett Wollman 10177b6ab19dSGarrett Wollman case RIPCMD_TRACEON: 101871965874SGarrett Wollman fprintf(ftrace, "\tfile=\"%.*s\"\n", size-4, 101971965874SGarrett Wollman msg->rip_tracefile); 10207b6ab19dSGarrett Wollman break; 10217b6ab19dSGarrett Wollman 10227b6ab19dSGarrett Wollman case RIPCMD_TRACEOFF: 10237b6ab19dSGarrett Wollman break; 10247b6ab19dSGarrett Wollman } 10257b6ab19dSGarrett Wollman } 1026