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