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: releng/11.0/usr.sbin/rtsold/dump.c 254462 2013-08-17 19:23:35Z hrs $ 3255163Sshin */ 3355163Sshin 3455163Sshin#include <sys/types.h> 3562632Skris#include <sys/socket.h> 36222732Shrs#include <sys/queue.h> 3755163Sshin 3862632Skris#include <net/if.h> 3955163Sshin#include <netinet/in.h> 4055163Sshin#include <netinet/icmp6.h> 41222861Shrs#include <arpa/inet.h> 4255163Sshin 4355163Sshin#include <syslog.h> 4455163Sshin#include <time.h> 4555163Sshin#include <stdio.h> 4655163Sshin#include <string.h> 4755163Sshin#include <errno.h> 4855163Sshin 4955163Sshin#include "rtsold.h" 5055163Sshin 5155163Sshinstatic FILE *fp; 5255163Sshin 53173412Skevlostatic void dump_interface_status(void); 54204407Suqsstatic const char * const ifstatstr[] = {"IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE"}; 5555163Sshin 5655163Sshinstatic void 57124524Sumedump_interface_status(void) 5855163Sshin{ 59222732Shrs struct ifinfo *ifi; 60222861Shrs struct rainfo *rai; 61222861Shrs struct ra_opt *rao; 62253970Shrs struct timespec now; 63222861Shrs char ntopbuf[INET6_ADDRSTRLEN]; 6455163Sshin 65253970Shrs clock_gettime(CLOCK_MONOTONIC_FAST, &now); 6655163Sshin 67222732Shrs TAILQ_FOREACH(ifi, &ifinfo_head, ifi_next) { 68222732Shrs fprintf(fp, "Interface %s\n", ifi->ifname); 6955163Sshin fprintf(fp, " probe interval: "); 70222732Shrs if (ifi->probeinterval) { 71222732Shrs fprintf(fp, "%d\n", ifi->probeinterval); 72222732Shrs fprintf(fp, " probe timer: %d\n", ifi->probetimer); 73118664Sume } else { 7455163Sshin fprintf(fp, "infinity\n"); 7555163Sshin fprintf(fp, " no probe timer\n"); 7655163Sshin } 7755163Sshin fprintf(fp, " interface status: %s\n", 78222732Shrs ifi->active > 0 ? "active" : "inactive"); 79118661Sume fprintf(fp, " other config: %s\n", 80222732Shrs ifi->otherconfig ? "on" : "off"); 81222732Shrs fprintf(fp, " rtsold status: %s\n", ifstatstr[ifi->state]); 8255163Sshin fprintf(fp, " carrier detection: %s\n", 83222732Shrs ifi->mediareqok ? "available" : "unavailable"); 8455163Sshin fprintf(fp, " probes: %d, dadcount = %d\n", 85222732Shrs ifi->probes, ifi->dadcount); 86222732Shrs if (ifi->timer.tv_sec == tm_max.tv_sec && 87253970Shrs ifi->timer.tv_nsec == tm_max.tv_nsec) 8855163Sshin fprintf(fp, " no timer\n"); 8955163Sshin else { 9055163Sshin fprintf(fp, " timer: interval=%d:%d, expire=%s\n", 91222732Shrs (int)ifi->timer.tv_sec, 92253970Shrs (int)ifi->timer.tv_nsec / 1000, 93222732Shrs (ifi->expire.tv_sec < now.tv_sec) ? "expired" 94222861Shrs : sec2str(&ifi->expire)); 9555163Sshin } 96222732Shrs fprintf(fp, " number of valid RAs: %d\n", ifi->racnt); 97222861Shrs 98222861Shrs TAILQ_FOREACH(rai, &ifi->ifi_rainfo, rai_next) { 99222861Shrs fprintf(fp, " RA from %s\n", 100222861Shrs inet_ntop(AF_INET6, &rai->rai_saddr.sin6_addr, 101222861Shrs ntopbuf, sizeof(ntopbuf))); 102222861Shrs TAILQ_FOREACH(rao, &rai->rai_ra_opt, rao_next) { 103222861Shrs fprintf(fp, " option: "); 104222861Shrs switch (rao->rao_type) { 105222861Shrs case ND_OPT_RDNSS: 106222861Shrs fprintf(fp, "RDNSS: %s (expire: %s)\n", 107222861Shrs (char *)rao->rao_msg, 108222861Shrs sec2str(&rao->rao_expire)); 109222861Shrs break; 110222861Shrs case ND_OPT_DNSSL: 111222861Shrs fprintf(fp, "DNSSL: %s (expire: %s)\n", 112222861Shrs (char *)rao->rao_msg, 113222861Shrs sec2str(&rao->rao_expire)); 114222861Shrs break; 115222861Shrs default: 116222861Shrs break; 117222861Shrs } 118222861Shrs } 119222861Shrs fprintf(fp, "\n"); 120222861Shrs } 12155163Sshin } 12255163Sshin} 12355163Sshin 12455163Sshinvoid 125204407Suqsrtsold_dump_file(const char *dumpfile) 12655163Sshin{ 12755163Sshin if ((fp = fopen(dumpfile, "w")) == NULL) { 128118660Sume warnmsg(LOG_WARNING, __func__, "open a dump file(%s): %s", 129118664Sume dumpfile, strerror(errno)); 13055163Sshin return; 13155163Sshin } 13255163Sshin dump_interface_status(); 13355163Sshin fclose(fp); 13455163Sshin} 13555163Sshin 136222861Shrsconst char * 137253970Shrssec2str(const struct timespec *total) 13855163Sshin{ 13955163Sshin static char result[256]; 14055163Sshin int days, hours, mins, secs; 14155163Sshin int first = 1; 14255163Sshin char *p = result; 143118786Sume char *ep = &result[sizeof(result)]; 144118786Sume int n; 145253970Shrs struct timespec now; 146222861Shrs time_t tsec; 14755163Sshin 148253970Shrs clock_gettime(CLOCK_MONOTONIC_FAST, &now); 149222861Shrs tsec = total->tv_sec; 150253970Shrs tsec += total->tv_nsec / 1000 / 1000000; 151222861Shrs tsec -= now.tv_sec; 152253970Shrs tsec -= now.tv_nsec / 1000 / 1000000; 15355163Sshin 154222861Shrs days = tsec / 3600 / 24; 155222861Shrs hours = (tsec / 3600) % 24; 156222861Shrs mins = (tsec / 60) % 60; 157222861Shrs secs = tsec % 60; 158222861Shrs 15955163Sshin if (days) { 16055163Sshin first = 0; 161118786Sume n = snprintf(p, ep - p, "%dd", days); 162118786Sume if (n < 0 || n >= ep - p) 163118786Sume return "?"; 164118786Sume p += n; 16555163Sshin } 16655163Sshin if (!first || hours) { 16755163Sshin first = 0; 168118786Sume n = snprintf(p, ep - p, "%dh", hours); 169118786Sume if (n < 0 || n >= ep - p) 170118786Sume return "?"; 171118786Sume p += n; 17255163Sshin } 17355163Sshin if (!first || mins) { 17455163Sshin first = 0; 175118786Sume n = snprintf(p, ep - p, "%dm", mins); 176118786Sume if (n < 0 || n >= ep - p) 177118786Sume return "?"; 178118786Sume p += n; 17955163Sshin } 180118786Sume snprintf(p, ep - p, "%ds", secs); 181222732Shrs 182222732Shrs return (result); 18355163Sshin} 184