1 /* $NetBSD: dump.c,v 1.12 2015/06/05 14:09:20 roy Exp $ */
2 /* $KAME: dump.c,v 1.34 2004/06/14 05:35:59 itojun Exp $ */
5 * Copyright (C) 2000 WIDE Project.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/types.h>
33 #include <sys/socket.h>
34 #include <sys/queue.h>
37 #include <net/if_dl.h>
39 #include <net/if_var.h>
42 #include <netinet/in.h>
44 /* XXX: the following two are non-standard include files */
45 #include <netinet6/in6_var.h>
46 #include <netinet6/nd6.h>
48 #include <arpa/inet.h>
65 static char *ether_str(struct sockaddr_dl
*);
66 static void if_dump(void);
68 static const char *rtpref_str
[] = {
76 ether_str(struct sockaddr_dl
*sdl
)
78 static char hbuf
[NI_MAXHOST
];
81 if (getnameinfo((struct sockaddr
*)sdl
, sdl
->sdl_len
,
82 hbuf
, sizeof(hbuf
), NULL
, 0, NI_NUMERICHOST
) != 0)
83 snprintf(hbuf
, sizeof(hbuf
), "<invalid>");
85 snprintf(hbuf
, sizeof(hbuf
), "NONE");
97 struct rdnss_addr
*rdnsa
;
99 struct dnssl_domain
*dnsd
;
101 char prefixbuf
[INET6_ADDRSTRLEN
];
104 clock_gettime(CLOCK_MONOTONIC
, &now
); /* XXX: unused in most cases */
105 TAILQ_FOREACH(rai
, &ralist
, next
) {
106 fprintf(fp
, "%s:\n", rai
->ifname
);
108 fprintf(fp
, " Status: %s\n",
109 (rai
->ifflags
& IFF_UP
) ? "UP" : "DOWN");
111 /* control information */
112 if (rai
->lastsent
.tv_sec
) {
113 /* note that ctime() appends CR by itself */
114 fprintf(fp
, " Last RA sent: %s",
115 ctime((time_t *)&rai
->lastsent
.tv_sec
));
118 fprintf(fp
, " Next RA will be sent: %s",
119 ctime((time_t *)&rai
->timer
->tm
.tv_sec
));
122 fprintf(fp
, " RA timer is stopped");
123 fprintf(fp
, " waits: %d, initcount: %d\n",
124 rai
->waiting
, rai
->initcounter
);
127 fprintf(fp
, " statistics: RA(out/in/inconsistent): "
129 (unsigned long long)rai
->raoutput
,
130 (unsigned long long)rai
->rainput
,
131 (unsigned long long)rai
->rainconsistent
);
132 fprintf(fp
, "RS(input): %llu\n",
133 (unsigned long long)rai
->rsinput
);
135 /* interface information */
137 fprintf(fp
, " Link-layer address: %s\n",
138 ether_str(rai
->sdl
));
139 fprintf(fp
, " MTU: %d\n", rai
->phymtu
);
141 /* Router configuration variables */
142 fprintf(fp
, " DefaultLifetime: %d, MaxAdvInterval: %d, "
143 "MinAdvInterval: %d\n", rai
->lifetime
, rai
->maxinterval
,
145 fprintf(fp
, " Flags: %s%s%s, ",
146 rai
->managedflg
? "M" : "", rai
->otherflg
? "O" : "",
148 fprintf(fp
, "Preference: %s, ",
149 rtpref_str
[(rai
->rtpref
>> 3) & 0xff]);
150 fprintf(fp
, "MTU: %d\n", rai
->linkmtu
);
151 fprintf(fp
, " ReachableTime: %d, RetransTimer: %d, "
152 "CurHopLimit: %d\n", rai
->reachabletime
,
153 rai
->retranstimer
, rai
->hoplimit
);
155 fprintf(fp
, " Clock skew: %dsec\n",
157 TAILQ_FOREACH(pfx
, &rai
->prefix
, next
) {
158 if (pfx
== TAILQ_FIRST(&rai
->prefix
))
159 fprintf(fp
, " Prefixes:\n");
160 fprintf(fp
, " %s/%d(",
161 inet_ntop(AF_INET6
, &pfx
->prefix
, prefixbuf
,
162 sizeof(prefixbuf
)), pfx
->prefixlen
);
163 switch (pfx
->origin
) {
164 case PREFIX_FROM_KERNEL
:
165 fprintf(fp
, "KERNEL, ");
167 case PREFIX_FROM_CONFIG
:
168 fprintf(fp
, "CONFIG, ");
170 case PREFIX_FROM_DYNAMIC
:
171 fprintf(fp
, "DYNAMIC, ");
174 if (pfx
->validlifetime
== ND6_INFINITE_LIFETIME
)
175 fprintf(fp
, "vltime: infinity");
177 fprintf(fp
, "vltime: %ld",
178 (long)pfx
->validlifetime
);
179 if (pfx
->vltimeexpire
!= 0)
180 fprintf(fp
, "(decr,expire %lld), ", (long long)
181 (pfx
->vltimeexpire
> now
.tv_sec
?
182 pfx
->vltimeexpire
- now
.tv_sec
: 0));
185 if (pfx
->preflifetime
== ND6_INFINITE_LIFETIME
)
186 fprintf(fp
, "pltime: infinity");
188 fprintf(fp
, "pltime: %ld",
189 (long)pfx
->preflifetime
);
190 if (pfx
->pltimeexpire
!= 0)
191 fprintf(fp
, "(decr,expire %lld), ", (long long)
192 (pfx
->pltimeexpire
> now
.tv_sec
?
193 pfx
->pltimeexpire
- now
.tv_sec
: 0));
196 fprintf(fp
, "flags: %s%s%s",
197 pfx
->onlinkflg
? "L" : "",
198 pfx
->autoconfflg
? "A" : "",
201 struct timespec
*rest
;
203 rest
= rtadvd_timer_rest(pfx
->timer
);
204 if (rest
) { /* XXX: what if not? */
205 fprintf(fp
, ", expire in: %ld",
212 TAILQ_FOREACH(rti
, &rai
->route
, next
) {
213 if (rti
== TAILQ_FIRST(&rai
->route
))
214 fprintf(fp
, " Route Information:\n");
215 fprintf(fp
, " %s/%d (",
216 inet_ntop(AF_INET6
, &rti
->prefix
,
217 prefixbuf
, sizeof(prefixbuf
)),
219 fprintf(fp
, "preference: %s, ",
220 rtpref_str
[0xff & (rti
->rtpref
>> 3)]);
221 if (rti
->ltime
== ND6_INFINITE_LIFETIME
)
222 fprintf(fp
, "lifetime: infinity");
224 fprintf(fp
, "lifetime: %ld", (long)rti
->ltime
);
228 TAILQ_FOREACH(rdns
, &rai
->rdnss
, next
) {
229 fprintf(fp
, " Recursive DNS Servers:\n");
230 if (rdns
->lifetime
== ND6_INFINITE_LIFETIME
)
231 fprintf(fp
, " lifetime: infinity\n");
233 fprintf(fp
, " lifetime: %ld\n",
234 (long)rdns
->lifetime
);
235 TAILQ_FOREACH(rdnsa
, &rdns
->list
, next
)
237 inet_ntop(AF_INET6
, &rdnsa
->addr
,
238 prefixbuf
, sizeof(prefixbuf
)));
241 TAILQ_FOREACH(dnsl
, &rai
->dnssl
, next
) {
242 fprintf(fp
, " DNS Search List:\n");
243 if (dnsl
->lifetime
== ND6_INFINITE_LIFETIME
)
244 fprintf(fp
, " lifetime: infinity\n");
246 fprintf(fp
, " lifetime: %ld\n",
247 (long)dnsl
->lifetime
);
248 TAILQ_FOREACH(dnsd
, &dnsl
->list
, next
) {
250 for (p
= dnsd
->domain
, len
= *p
++;
254 if (p
!= dnsd
->domain
)
266 rtadvd_dump_file(const char *dumpfile
)
268 syslog(LOG_DEBUG
, "<%s> dump current status to %s", __func__
,
271 if ((fp
= fopen(dumpfile
, "w")) == NULL
) {
272 syslog(LOG_WARNING
, "<%s> open a dump file(%s): %m",