]> git.cameronkatri.com Git - apple_cmds.git/blob - network_cmds/rtadvd.tproj/dump.c
download.sh: Properly update
[apple_cmds.git] / network_cmds / rtadvd.tproj / dump.c
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 <string.h>
79 #include <errno.h>
80
81 #include "rtadvd.h"
82 #include "timer.h"
83 #include "if.h"
84 #include "dump.h"
85
86 static FILE *fp;
87
88 extern struct rainfo *ralist;
89
90 static char *ether_str(struct sockaddr_dl *);
91 static void if_dump(void);
92
93 static char *rtpref_str[] = {
94 "medium", /* 00 */
95 "high", /* 01 */
96 "rsv", /* 10 */
97 "low" /* 11 */
98 };
99
100 static char *
101 ether_str(sdl)
102 struct sockaddr_dl *sdl;
103 {
104 static char hbuf[32];
105 u_char *cp;
106
107 if (sdl->sdl_alen && sdl->sdl_alen > 5) {
108 cp = (u_char *)LLADDR(sdl);
109 snprintf(hbuf, sizeof(hbuf), "%x:%x:%x:%x:%x:%x",
110 cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
111 } else
112 snprintf(hbuf, sizeof(hbuf), "NONE");
113
114 return(hbuf);
115 }
116
117 static void
118 if_dump()
119 {
120 struct rainfo *rai;
121 struct prefix *pfx;
122 #ifdef ROUTEINFO
123 struct rtinfo *rti;
124 #endif
125 char prefixbuf[INET6_ADDRSTRLEN];
126 int first;
127 struct timeval now;
128
129 gettimeofday(&now, NULL); /* XXX: unused in most cases */
130 for (rai = ralist; rai; rai = rai->next) {
131 fprintf(fp, "%s:\n", rai->ifname);
132 struct if_msghdr *ifm = get_interface_entry(rai->ifindex);
133 if (ifm == NULL) {
134 debuglog("Skippingg RA entry for interface %s"
135 "as we couldn't find interface entry for it.", rai->ifname);
136 continue;
137 }
138 fprintf(fp, " Status: %s\n",
139 (ifm->ifm_flags & IFF_UP) ? "UP" :
140 "DOWN");
141
142 /* control information */
143 if (rai->lastsent.tv_sec) {
144 /* note that ctime() appends CR by itself */
145 fprintf(fp, " Last RA sent: %s",
146 ctime((time_t *)&rai->lastsent.tv_sec));
147 }
148 if (rai->timer) {
149 fprintf(fp, " Next RA will be sent: %s",
150 ctime((time_t *)&rai->timer->tm.tv_sec));
151 }
152 else
153 fprintf(fp, " RA timer is stopped");
154 fprintf(fp, " waits: %d, initcount: %d\n",
155 rai->waiting, rai->initcounter);
156
157 /* statistics */
158 fprintf(fp, " statistics: RA(out/in/inconsistent): "
159 "%llu/%llu/%llu, ",
160 (unsigned long long)rai->raoutput,
161 (unsigned long long)rai->rainput,
162 (unsigned long long)rai->rainconsistent);
163 fprintf(fp, "RS(input): %llu\n",
164 (unsigned long long)rai->rsinput);
165
166 /* interface information */
167 if (rai->advlinkopt)
168 fprintf(fp, " Link-layer address: %s\n",
169 ether_str(rai->sdl));
170 fprintf(fp, " MTU: %d\n", rai->phymtu);
171
172 /* Router configuration variables */
173 fprintf(fp, " DefaultLifetime: %d, MaxAdvInterval: %d, "
174 "MinAdvInterval: %d\n", rai->lifetime, rai->maxinterval,
175 rai->mininterval);
176 fprintf(fp, " Flags: %s%s%s, ",
177 rai->managedflg ? "M" : "", rai->otherflg ? "O" : "", "");
178 fprintf(fp, "Preference: %s, ",
179 rtpref_str[(rai->rtpref >> 3) & 0xff]);
180 fprintf(fp, "MTU: %d\n", rai->linkmtu);
181 fprintf(fp, " ReachableTime: %d, RetransTimer: %d, "
182 "CurHopLimit: %d\n", rai->reachabletime,
183 rai->retranstimer, rai->hoplimit);
184 if (rai->clockskew)
185 fprintf(fp, " Clock skew: %ldsec\n",
186 rai->clockskew);
187 for (first = 1, pfx = rai->prefix.next; pfx != &rai->prefix;
188 pfx = pfx->next) {
189 if (first) {
190 fprintf(fp, " Prefixes:\n");
191 first = 0;
192 }
193 fprintf(fp, " %s/%d(",
194 inet_ntop(AF_INET6, &pfx->prefix, prefixbuf,
195 sizeof(prefixbuf)), pfx->prefixlen);
196 switch (pfx->origin) {
197 case PREFIX_FROM_KERNEL:
198 fprintf(fp, "KERNEL, ");
199 break;
200 case PREFIX_FROM_CONFIG:
201 fprintf(fp, "CONFIG, ");
202 break;
203 case PREFIX_FROM_DYNAMIC:
204 fprintf(fp, "DYNAMIC, ");
205 break;
206 }
207 if (pfx->validlifetime == ND6_INFINITE_LIFETIME)
208 fprintf(fp, "vltime: infinity");
209 else
210 fprintf(fp, "vltime: %ld",
211 (long)pfx->validlifetime);
212 if (pfx->vltimeexpire != 0)
213 fprintf(fp, "(decr,expire %ld), ", (long)
214 pfx->vltimeexpire > now.tv_sec ?
215 pfx->vltimeexpire - now.tv_sec : 0);
216 else
217 fprintf(fp, ", ");
218 if (pfx->preflifetime == ND6_INFINITE_LIFETIME)
219 fprintf(fp, "pltime: infinity");
220 else
221 fprintf(fp, "pltime: %ld",
222 (long)pfx->preflifetime);
223 if (pfx->pltimeexpire != 0)
224 fprintf(fp, "(decr,expire %ld), ", (long)
225 pfx->pltimeexpire > now.tv_sec ?
226 pfx->pltimeexpire - now.tv_sec : 0);
227 else
228 fprintf(fp, ", ");
229 fprintf(fp, "flags: %s%s%s",
230 pfx->onlinkflg ? "L" : "",
231 pfx->autoconfflg ? "A" : "",
232 "");
233 if (pfx->timer) {
234 struct timeval *rest;
235
236 rest = rtadvd_timer_rest(pfx->timer);
237 if (rest) { /* XXX: what if not? */
238 fprintf(fp, ", expire in: %ld",
239 (long)rest->tv_sec);
240 }
241 }
242 fprintf(fp, ")\n");
243 }
244 #ifdef ROUTEINFO
245 for (first = 1, rti = rai->route.next; rti != &rai->route;
246 rti = rti->next) {
247 if (first) {
248 fprintf(fp, " Route Information:\n");
249 first = 0;
250 }
251 fprintf(fp, " %s/%d (",
252 inet_ntop(AF_INET6, &rti->prefix,
253 prefixbuf, sizeof(prefixbuf)),
254 rti->prefixlen);
255 fprintf(fp, "preference: %s, ",
256 rtpref_str[0xff & (rti->rtpref >> 3)]);
257 if (rti->ltime == ND6_INFINITE_LIFETIME)
258 fprintf(fp, "lifetime: infinity");
259 else
260 fprintf(fp, "lifetime: %ld", (long)rti->ltime);
261 fprintf(fp, ")\n");
262 }
263 #endif
264 }
265 }
266
267 void
268 rtadvd_dump_file(dumpfile)
269 char *dumpfile;
270 {
271 debuglog("<%s> dump current status to %s", __func__,
272 dumpfile);
273
274 if ((fp = fopen(dumpfile, "w")) == NULL) {
275 errorlog("<%s> open a dump file(%s)",
276 __func__, dumpfile);
277 return;
278 }
279
280 if_dump();
281
282 fclose(fp);
283 }