1124524Sume/* $KAME: dump.c,v 1.13 2003/10/05 00:09:36 itojun Exp $ */ 266776Skris 355163Sshin/* 455163Sshin * Copyright (C) 1999 WIDE Project. 555163Sshin * All rights reserved. 662632Skris * 755163Sshin * Redistribution and use in source and binary forms, with or without 855163Sshin * modification, are permitted provided that the following conditions 955163Sshin * are met: 1055163Sshin * 1. Redistributions of source code must retain the above copyright 1155163Sshin * notice, this list of conditions and the following disclaimer. 1255163Sshin * 2. Redistributions in binary form must reproduce the above copyright 1355163Sshin * notice, this list of conditions and the following disclaimer in the 1455163Sshin * documentation and/or other materials provided with the distribution. 1555163Sshin * 3. Neither the name of the project nor the names of its contributors 1655163Sshin * may be used to endorse or promote products derived from this software 1755163Sshin * without specific prior written permission. 1862632Skris * 1955163Sshin * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2055163Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2155163Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2255163Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2355163Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2455163Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2555163Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2655163Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2755163Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2855163Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2955163Sshin * SUCH DAMAGE. 3055163Sshin * 3155163Sshin * $FreeBSD$ 3255163Sshin */ 3355163Sshin 3455163Sshin#include <sys/types.h> 3555163Sshin#include <sys/time.h> 3662632Skris#include <sys/socket.h> 37222732Shrs#include <sys/queue.h> 3855163Sshin 3962632Skris#include <net/if.h> 4055163Sshin#include <netinet/in.h> 4155163Sshin#include <netinet/icmp6.h> 42222861Shrs#include <arpa/inet.h> 4355163Sshin 4455163Sshin#include <syslog.h> 4555163Sshin#include <time.h> 4655163Sshin#include <stdio.h> 4755163Sshin#include <string.h> 4855163Sshin#include <errno.h> 4955163Sshin 5055163Sshin#include "rtsold.h" 5155163Sshin 5255163Sshinstatic FILE *fp; 5355163Sshin 5455163Sshinextern struct ifinfo *iflist; 5555163Sshin 56173412Skevlostatic void dump_interface_status(void); 57204407Suqsstatic const char * const ifstatstr[] = {"IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE"}; 5855163Sshin 5955163Sshinstatic void 60124524Sumedump_interface_status(void) 6155163Sshin{ 62222732Shrs struct ifinfo *ifi; 63222861Shrs struct rainfo *rai; 64222861Shrs struct ra_opt *rao; 6555163Sshin struct timeval now; 66222861Shrs char ntopbuf[INET6_ADDRSTRLEN]; 6755163Sshin 6855163Sshin gettimeofday(&now, NULL); 6955163Sshin 70222732Shrs TAILQ_FOREACH(ifi, &ifinfo_head, ifi_next) { 71222732Shrs fprintf(fp, "Interface %s\n", ifi->ifname); 7255163Sshin fprintf(fp, " probe interval: "); 73222732Shrs if (ifi->probeinterval) { 74222732Shrs fprintf(fp, "%d\n", ifi->probeinterval); 75222732Shrs fprintf(fp, " probe timer: %d\n", ifi->probetimer); 76118664Sume } else { 7755163Sshin fprintf(fp, "infinity\n"); 7855163Sshin fprintf(fp, " no probe timer\n"); 7955163Sshin } 8055163Sshin fprintf(fp, " interface status: %s\n", 81222732Shrs ifi->active > 0 ? "active" : "inactive"); 82118661Sume fprintf(fp, " other config: %s\n", 83222732Shrs ifi->otherconfig ? "on" : "off"); 84222732Shrs fprintf(fp, " rtsold status: %s\n", ifstatstr[ifi->state]); 8555163Sshin fprintf(fp, " carrier detection: %s\n", 86222732Shrs ifi->mediareqok ? "available" : "unavailable"); 8755163Sshin fprintf(fp, " probes: %d, dadcount = %d\n", 88222732Shrs ifi->probes, ifi->dadcount); 89222732Shrs if (ifi->timer.tv_sec == tm_max.tv_sec && 90222732Shrs ifi->timer.tv_usec == tm_max.tv_usec) 9155163Sshin fprintf(fp, " no timer\n"); 9255163Sshin else { 9355163Sshin fprintf(fp, " timer: interval=%d:%d, expire=%s\n", 94222732Shrs (int)ifi->timer.tv_sec, 95222732Shrs (int)ifi->timer.tv_usec, 96222732Shrs (ifi->expire.tv_sec < now.tv_sec) ? "expired" 97222861Shrs : sec2str(&ifi->expire)); 9855163Sshin } 99222732Shrs fprintf(fp, " number of valid RAs: %d\n", ifi->racnt); 100222861Shrs 101222861Shrs TAILQ_FOREACH(rai, &ifi->ifi_rainfo, rai_next) { 102222861Shrs fprintf(fp, " RA from %s\n", 103222861Shrs inet_ntop(AF_INET6, &rai->rai_saddr.sin6_addr, 104222861Shrs ntopbuf, sizeof(ntopbuf))); 105222861Shrs TAILQ_FOREACH(rao, &rai->rai_ra_opt, rao_next) { 106222861Shrs fprintf(fp, " option: "); 107222861Shrs switch (rao->rao_type) { 108222861Shrs case ND_OPT_RDNSS: 109222861Shrs fprintf(fp, "RDNSS: %s (expire: %s)\n", 110222861Shrs (char *)rao->rao_msg, 111222861Shrs sec2str(&rao->rao_expire)); 112222861Shrs break; 113222861Shrs case ND_OPT_DNSSL: 114222861Shrs fprintf(fp, "DNSSL: %s (expire: %s)\n", 115222861Shrs (char *)rao->rao_msg, 116222861Shrs sec2str(&rao->rao_expire)); 117222861Shrs break; 118222861Shrs default: 119222861Shrs break; 120222861Shrs } 121222861Shrs } 122222861Shrs fprintf(fp, "\n"); 123222861Shrs } 12455163Sshin } 12555163Sshin} 12655163Sshin 12755163Sshinvoid 128204407Suqsrtsold_dump_file(const char *dumpfile) 12955163Sshin{ 13055163Sshin if ((fp = fopen(dumpfile, "w")) == NULL) { 131118660Sume warnmsg(LOG_WARNING, __func__, "open a dump file(%s): %s", 132118664Sume dumpfile, strerror(errno)); 13355163Sshin return; 13455163Sshin } 13555163Sshin dump_interface_status(); 13655163Sshin fclose(fp); 13755163Sshin} 13855163Sshin 139222861Shrsconst char * 140222861Shrssec2str(const struct timeval *total) 14155163Sshin{ 14255163Sshin static char result[256]; 14355163Sshin int days, hours, mins, secs; 14455163Sshin int first = 1; 14555163Sshin char *p = result; 146118786Sume char *ep = &result[sizeof(result)]; 147118786Sume int n; 148222861Shrs struct timeval now; 149222861Shrs time_t tsec; 15055163Sshin 151222861Shrs gettimeofday(&now, NULL); 152222861Shrs tsec = total->tv_sec; 153222861Shrs tsec += total->tv_usec / 1000000; 154222861Shrs tsec -= now.tv_sec; 155222861Shrs tsec -= now.tv_usec / 1000000; 15655163Sshin 157222861Shrs days = tsec / 3600 / 24; 158222861Shrs hours = (tsec / 3600) % 24; 159222861Shrs mins = (tsec / 60) % 60; 160222861Shrs secs = tsec % 60; 161222861Shrs 16255163Sshin if (days) { 16355163Sshin first = 0; 164118786Sume n = snprintf(p, ep - p, "%dd", days); 165118786Sume if (n < 0 || n >= ep - p) 166118786Sume return "?"; 167118786Sume p += n; 16855163Sshin } 16955163Sshin if (!first || hours) { 17055163Sshin first = 0; 171118786Sume n = snprintf(p, ep - p, "%dh", hours); 172118786Sume if (n < 0 || n >= ep - p) 173118786Sume return "?"; 174118786Sume p += n; 17555163Sshin } 17655163Sshin if (!first || mins) { 17755163Sshin first = 0; 178118786Sume n = snprintf(p, ep - p, "%dm", mins); 179118786Sume if (n < 0 || n >= ep - p) 180118786Sume return "?"; 181118786Sume p += n; 18255163Sshin } 183118786Sume snprintf(p, ep - p, "%ds", secs); 184222732Shrs 185222732Shrs return (result); 18655163Sshin} 187