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.6 2005/12/05 00:56:37 swildner 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(struct sockaddr_dl *sdl) 86 { 87 static char ebuf[32]; 88 u_char *cp; 89 90 if (sdl->sdl_alen && sdl->sdl_alen > 5) { 91 cp = (u_char *)LLADDR(sdl); 92 sprintf(ebuf, "%x:%x:%x:%x:%x:%x", 93 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]); 94 } 95 else { 96 sprintf(ebuf, "NONE"); 97 } 98 99 return(ebuf); 100 } 101 102 static void 103 if_dump(void) 104 { 105 struct rainfo *rai; 106 struct prefix *pfx; 107 char prefixbuf[INET6_ADDRSTRLEN]; 108 int first; 109 struct timeval now; 110 111 gettimeofday(&now, NULL); /* XXX: unused in most cases */ 112 for (rai = ralist; rai; rai = rai->next) { 113 fprintf(fp, "%s:\n", rai->ifname); 114 115 fprintf(fp, " Status: %s\n", 116 (iflist[rai->ifindex]->ifm_flags & IFF_UP) ? "UP" : 117 "DOWN"); 118 119 /* control information */ 120 if (rai->lastsent.tv_sec) { 121 /* note that ctime() appends CR by itself */ 122 fprintf(fp, " Last RA sent: %s", 123 ctime((time_t *)&rai->lastsent.tv_sec)); 124 } 125 if (rai->timer) { 126 fprintf(fp, " Next RA will be sent: %s", 127 ctime((time_t *)&rai->timer->tm.tv_sec)); 128 } 129 else 130 fprintf(fp, " RA timer is stopped"); 131 fprintf(fp, " waits: %d, initcount: %d\n", 132 rai->waiting, rai->initcounter); 133 134 /* statistics */ 135 fprintf(fp, 136 " statistics: RA(out/in/inconsistent): " 137 LONGLONG "/" LONGLONG "/" LONGLONG ", ", 138 (unsigned long long)rai->raoutput, 139 (unsigned long long)rai->rainput, 140 (unsigned long long)rai->rainconsistent); 141 fprintf(fp, "RS(input): " LONGLONG "\n", 142 (unsigned long long)rai->rsinput); 143 144 /* interface information */ 145 if (rai->advlinkopt) 146 fprintf(fp, " Link-layer address: %s\n", 147 ether_str(rai->sdl)); 148 fprintf(fp, " MTU: %d\n", rai->phymtu); 149 150 /* Router configuration variables */ 151 fprintf(fp, 152 " DefaultLifetime: %d, MaxAdvInterval: %d, " 153 "MinAdvInterval: %d\n", 154 rai->lifetime, rai->maxinterval, rai->mininterval); 155 fprintf(fp, " Flags: %s%s%s, ", 156 rai->managedflg ? "M" : "", rai->otherflg ? "O" : "", 157 #ifdef MIP6 158 rai->haflg ? "H" : 159 #endif 160 ""); 161 fprintf(fp, "Preference: %s, ", 162 rtpref_str[(rai->rtpref >> 3) & 0xff]); 163 fprintf(fp, "MTU: %d\n", rai->linkmtu); 164 fprintf(fp, " ReachableTime: %d, RetransTimer: %d, " 165 "CurHopLimit: %d\n", rai->reachabletime, 166 rai->retranstimer, rai->hoplimit); 167 #ifdef MIP6 168 fprintf(fp, " HAPreference: %d, HALifetime: %d\n", 169 rai->hapref, rai->hatime); 170 #endif 171 172 if (rai->clockskew) 173 fprintf(fp, " Clock skew: %ldsec\n", 174 rai->clockskew); 175 for (first = 1, pfx = rai->prefix.next; pfx != &rai->prefix; 176 pfx = pfx->next) { 177 if (first) { 178 fprintf(fp, " Prefixes:\n"); 179 first = 0; 180 } 181 fprintf(fp, " %s/%d(", 182 inet_ntop(AF_INET6, &pfx->prefix, 183 prefixbuf, sizeof(prefixbuf)), 184 pfx->prefixlen); 185 switch(pfx->origin) { 186 case PREFIX_FROM_KERNEL: 187 fprintf(fp, "KERNEL, "); 188 break; 189 case PREFIX_FROM_CONFIG: 190 fprintf(fp, "CONFIG, "); 191 break; 192 case PREFIX_FROM_DYNAMIC: 193 fprintf(fp, "DYNAMIC, "); 194 break; 195 } 196 if (pfx->validlifetime == ND6_INFINITE_LIFETIME) 197 fprintf(fp, "vltime: infinity"); 198 else 199 fprintf(fp, "vltime: %ld", 200 (long)pfx->validlifetime); 201 if (pfx->vltimeexpire != 0) 202 fprintf(fp, "(decr,expire %ld), ", (long) 203 pfx->vltimeexpire > now.tv_sec ? 204 pfx->vltimeexpire - now.tv_sec : 0); 205 else 206 fprintf(fp, ", "); 207 if (pfx->preflifetime == ND6_INFINITE_LIFETIME) 208 fprintf(fp, "pltime: infinity"); 209 else 210 fprintf(fp, "pltime: %ld", 211 (long)pfx->preflifetime); 212 if (pfx->pltimeexpire != 0) 213 fprintf(fp, "(decr,expire %ld), ", (long) 214 pfx->pltimeexpire > now.tv_sec ? 215 pfx->pltimeexpire - now.tv_sec : 0); 216 else 217 fprintf(fp, ", "); 218 fprintf(fp, "flags: %s%s%s", 219 pfx->onlinkflg ? "L" : "", 220 pfx->autoconfflg ? "A" : "", 221 #ifdef MIP6 222 pfx->routeraddr ? "R" : 223 #endif 224 ""); 225 if (pfx->timer) { 226 struct timeval *rest; 227 228 rest = rtadvd_timer_rest(pfx->timer); 229 if (rest) { /* XXX: what if not? */ 230 fprintf(fp, ", expire in: %ld", 231 (long)rest->tv_sec); 232 } 233 } 234 fprintf(fp, ")\n"); 235 } 236 } 237 } 238 239 void 240 rtadvd_dump_file(char *dumpfile) 241 { 242 if ((fp = fopen(dumpfile, "w")) == NULL) { 243 syslog(LOG_WARNING, "<%s> open a dump file(%s)", 244 __func__, dumpfile); 245 return; 246 } 247 248 if_dump(); 249 250 fclose(fp); 251 } 252