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