1 /* $NetBSD: dump.c,v 1.4 2002/05/21 14:29:52 itojun Exp $ */ 2 /* $KAME: dump.c,v 1.15 2000/11/11 06:57:22 jinmei Exp $ */ 3 4 /* 5 * Copyright (C) 2000 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 #include <sys/types.h> 33 #include <sys/socket.h> 34 #include <sys/queue.h> 35 36 #include <net/if.h> 37 #if defined(__FreeBSD__) && __FreeBSD__ >= 3 38 #include <net/if_var.h> 39 #endif /* __FreeBSD__ >= 3 */ 40 #include <net/if_dl.h> 41 42 #include <netinet/in.h> 43 44 /* XXX: the following two are non-standard include files */ 45 #include <netinet6/in6_var.h> 46 #include <netinet6/nd6.h> 47 48 #include <arpa/inet.h> 49 50 #include <time.h> 51 #include <stdio.h> 52 #include <stdarg.h> 53 #include <syslog.h> 54 #include <string.h> 55 #include <errno.h> 56 57 #include "rtadvd.h" 58 #include "timer.h" 59 #include "if.h" 60 #include "dump.h" 61 62 static FILE *fp; 63 64 extern struct rainfo *ralist; 65 66 static char *ether_str __P((struct sockaddr_dl *)); 67 static void if_dump __P((void)); 68 69 #ifdef __FreeBSD__ /* XXX: see PORTABILITY */ 70 #define LONGLONG "%qu" 71 #else 72 #define LONGLONG "%llu" 73 #endif 74 75 static char * 76 ether_str(sdl) 77 struct sockaddr_dl *sdl; 78 { 79 static char ebuf[32]; 80 u_char *cp; 81 82 if (sdl->sdl_alen && sdl->sdl_alen > 5) { 83 cp = (u_char *)LLADDR(sdl); 84 sprintf(ebuf, "%x:%x:%x:%x:%x:%x", 85 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]); 86 } 87 else { 88 sprintf(ebuf, "NONE"); 89 } 90 91 return(ebuf); 92 } 93 94 static void 95 if_dump() 96 { 97 struct rainfo *rai; 98 struct prefix *pfx; 99 char prefixbuf[INET6_ADDRSTRLEN]; 100 int first; 101 struct timeval now; 102 103 gettimeofday(&now, NULL); /* XXX: unused in most cases */ 104 for (rai = ralist; rai; rai = rai->next) { 105 fprintf(fp, "%s:\n", rai->ifname); 106 107 fprintf(fp, " Status: %s\n", 108 (iflist[rai->ifindex]->ifm_flags & IFF_UP) ? "UP" : 109 "DOWN"); 110 111 /* control information */ 112 if (rai->lastsent.tv_sec) { 113 /* note that ctime() appends CR by itself */ 114 fprintf(fp, " Last RA sent: %s", 115 ctime((time_t *)&rai->lastsent.tv_sec)); 116 } 117 if (rai->timer) { 118 fprintf(fp, " Next RA will be sent: %s", 119 ctime((time_t *)&rai->timer->tm.tv_sec)); 120 } 121 else 122 fprintf(fp, " RA timer is stopped"); 123 fprintf(fp, " waits: %d, initcount: %d\n", 124 rai->waiting, rai->initcounter); 125 126 /* statistics */ 127 fprintf(fp, 128 " statistics: RA(out/in/inconsistent): " 129 LONGLONG "/" LONGLONG "/" LONGLONG ", ", 130 (unsigned long long)rai->raoutput, 131 (unsigned long long)rai->rainput, 132 (unsigned long long)rai->rainconsistent); 133 fprintf(fp, "RS(input): " LONGLONG "\n", 134 (unsigned long long)rai->rsinput); 135 136 /* interface information */ 137 if (rai->advlinkopt) 138 fprintf(fp, " Link-layer address: %s\n", 139 ether_str(rai->sdl)); 140 fprintf(fp, " MTU: %d\n", rai->phymtu); 141 142 /* Router configuration variables */ 143 fprintf(fp, 144 " DefaultLifetime: %d, MaxAdvInterval: %d, " 145 "MinAdvInterval: %d\n", 146 rai->lifetime, rai->maxinterval, rai->mininterval); 147 fprintf(fp, " Flags: %s%s%s MTU: %d\n", 148 rai->managedflg ? "M" : "", rai->otherflg ? "O" : "", 149 #ifdef MIP6 150 rai->haflg ? "H" : 151 #endif 152 "", rai->linkmtu); 153 fprintf(fp, " ReachableTime: %d, RetransTimer: %d, " 154 "CurHopLimit: %d\n", rai->reachabletime, 155 rai->retranstimer, rai->hoplimit); 156 #ifdef MIP6 157 fprintf(fp, " HAPreference: %d, HALifetime: %d\n", 158 rai->hapref, rai->hatime); 159 #endif 160 161 if (rai->clockskew) 162 fprintf(fp, " Clock skew: %ldsec\n", 163 rai->clockskew); 164 for (first = 1, pfx = rai->prefix.next; pfx != &rai->prefix; 165 pfx = pfx->next) { 166 if (first) { 167 fprintf(fp, " Prefixes:\n"); 168 first = 0; 169 } 170 fprintf(fp, " %s/%d(", 171 inet_ntop(AF_INET6, &pfx->prefix, 172 prefixbuf, sizeof(prefixbuf)), 173 pfx->prefixlen); 174 switch (pfx->origin) { 175 case PREFIX_FROM_KERNEL: 176 fprintf(fp, "KERNEL, "); 177 break; 178 case PREFIX_FROM_CONFIG: 179 fprintf(fp, "CONFIG, "); 180 break; 181 case PREFIX_FROM_DYNAMIC: 182 fprintf(fp, "DYNAMIC, "); 183 break; 184 } 185 if (pfx->validlifetime == ND6_INFINITE_LIFETIME) 186 fprintf(fp, "vltime: infinity"); 187 else 188 fprintf(fp, "vltime: %ld", 189 (long)pfx->validlifetime); 190 if (pfx->vltimeexpire != 0) 191 fprintf(fp, "(decr,expire %ld), ", (long) 192 pfx->vltimeexpire > now.tv_sec ? 193 pfx->vltimeexpire - now.tv_sec : 0); 194 else 195 fprintf(fp, ", "); 196 if (pfx->preflifetime == ND6_INFINITE_LIFETIME) 197 fprintf(fp, "pltime: infinity"); 198 else 199 fprintf(fp, "pltime: %ld", 200 (long)pfx->preflifetime); 201 if (pfx->pltimeexpire != 0) 202 fprintf(fp, "(decr,expire %ld), ", (long) 203 pfx->pltimeexpire > now.tv_sec ? 204 pfx->pltimeexpire - now.tv_sec : 0); 205 else 206 fprintf(fp, ", "); 207 fprintf(fp, "flags: %s%s%s", 208 pfx->onlinkflg ? "L" : "", 209 pfx->autoconfflg ? "A" : "", 210 #ifdef MIP6 211 pfx->routeraddr ? "R" : 212 #endif 213 ""); 214 fprintf(fp, ")\n"); 215 } 216 } 217 } 218 219 void 220 rtadvd_dump_file(dumpfile) 221 char *dumpfile; 222 { 223 if ((fp = fopen(dumpfile, "w")) == NULL) { 224 syslog(LOG_WARNING, "<%s> open a dump file(%s)", 225 __FUNCTION__, dumpfile); 226 return; 227 } 228 229 if_dump(); 230 231 fclose(fp); 232 } 233