rtsold.c (55163) | rtsold.c (62632) |
---|---|
1/* 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. | 1/* 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. | 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. |
16 * | 16 * |
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * | 17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * |
29 * $FreeBSD: head/usr.sbin/rtsold/rtsold.c 55163 1999-12-28 02:37:14Z shin $ | 29 * $FreeBSD: head/usr.sbin/rtsold/rtsold.c 62632 2000-07-05 10:14:11Z kris $ |
30 */ 31 32#include <sys/types.h> 33#include <sys/time.h> | 30 */ 31 32#include <sys/types.h> 33#include <sys/time.h> |
34#include <sys/socket.h> |
|
34 | 35 |
36#include <net/if.h> |
|
35#include <net/if_dl.h> 36 37#include <netinet/in.h> 38#include <netinet/icmp6.h> 39 40#include <signal.h> 41#include <unistd.h> 42#include <syslog.h> --- 7 unchanged lines hidden (view full) --- 50 51struct ifinfo *iflist; 52struct timeval tm_max = {0x7fffffff, 0x7fffffff}; 53int dflag; 54static int log_upto = 999; 55static int fflag = 0; 56 57/* protocol constatns */ | 37#include <net/if_dl.h> 38 39#include <netinet/in.h> 40#include <netinet/icmp6.h> 41 42#include <signal.h> 43#include <unistd.h> 44#include <syslog.h> --- 7 unchanged lines hidden (view full) --- 52 53struct ifinfo *iflist; 54struct timeval tm_max = {0x7fffffff, 0x7fffffff}; 55int dflag; 56static int log_upto = 999; 57static int fflag = 0; 58 59/* protocol constatns */ |
58#define MAX_RTR_SOLICITATION_DELAY 1 /* second */ 59#define RTR_SOLICITATION_INTERVAL 4 /* seconds */ 60#define MAX_RTR_SOLICITATIONS 3 /* times */ | 60#define MAX_RTR_SOLICITATION_DELAY 1 /* second */ 61#define RTR_SOLICITATION_INTERVAL 4 /* seconds */ 62#define MAX_RTR_SOLICITATIONS 3 /* times */ |
61 62/* implementation dependent constants */ | 63 64/* implementation dependent constants */ |
63#define PROBE_INTERVAL 60 /* secondes XXX: should be configurable */ | 65#define PROBE_INTERVAL 60 /* secondes XXX: should be configurable */ |
64 65/* utility macros */ 66/* a < b */ | 66 67/* utility macros */ 68/* a < b */ |
67#define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\ | 69#define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\ |
68 (((a).tv_sec == (b).tv_sec) && \ 69 ((a).tv_usec < (b).tv_usec))) 70 71/* a <= b */ | 70 (((a).tv_sec == (b).tv_sec) && \ 71 ((a).tv_usec < (b).tv_usec))) 72 73/* a <= b */ |
72#define TIMEVAL_LEQ(a, b) (((a).tv_sec < (b).tv_sec) ||\ | 74#define TIMEVAL_LEQ(a, b) (((a).tv_sec < (b).tv_sec) ||\ |
73 (((a).tv_sec == (b).tv_sec) &&\ 74 ((a).tv_usec <= (b).tv_usec))) 75 76/* a == b */ | 75 (((a).tv_sec == (b).tv_sec) &&\ 76 ((a).tv_usec <= (b).tv_usec))) 77 78/* a == b */ |
77#define TIMEVAL_EQ(a, b) (((a).tv_sec==(b).tv_sec) && ((a).tv_usec==(b).tv_usec)) | 79#define TIMEVAL_EQ(a, b) (((a).tv_sec==(b).tv_sec) && ((a).tv_usec==(b).tv_usec)) |
78 79int main __P((int argc, char *argv[])); 80 81/* static variables and functions */ 82static int mobile_node = 0; 83static int do_dump; | 80 81int main __P((int argc, char *argv[])); 82 83/* static variables and functions */ 84static int mobile_node = 0; 85static int do_dump; |
84static char *dumpfilename = "/var/tmp/rtsold.dump"; /* XXX: should be configurable */ | 86static char *dumpfilename = "/var/run/rtsold.dump"; /* XXX: should be configurable */ |
85static char *pidfilename = "/var/run/rtsold.pid"; /* should be configurable */ 86 87static int ifconfig __P((char *ifname)); | 87static char *pidfilename = "/var/run/rtsold.pid"; /* should be configurable */ 88 89static int ifconfig __P((char *ifname)); |
90#if 0 91static int ifreconfig __P((char *ifname)); 92#endif |
|
88static int make_packet __P((struct ifinfo *ifinfo)); 89static struct timeval *rtsol_check_timer __P((void)); 90static void TIMEVAL_ADD __P((struct timeval *a, struct timeval *b, 91 struct timeval *result)); 92static void TIMEVAL_SUB __P((struct timeval *a, struct timeval *b, 93 struct timeval *result)); 94 | 93static int make_packet __P((struct ifinfo *ifinfo)); 94static struct timeval *rtsol_check_timer __P((void)); 95static void TIMEVAL_ADD __P((struct timeval *a, struct timeval *b, 96 struct timeval *result)); 97static void TIMEVAL_SUB __P((struct timeval *a, struct timeval *b, 98 struct timeval *result)); 99 |
95static void rtsold_set_dump_file __P(()); | 100static void rtsold_set_dump_file __P((void)); |
96static void usage __P((char *progname)); 97 98int 99main(argc, argv) 100 int argc; 101 char *argv[]; 102{ 103 int s, ch; --- 52 unchanged lines hidden (view full) --- 156 ident = argv0; 157 else 158 ident++; 159 openlog(ident, LOG_NDELAY|LOG_PID, LOG_DAEMON); 160 if (log_upto >= 0) 161 setlogmask(LOG_UPTO(log_upto)); 162 } 163 | 101static void usage __P((char *progname)); 102 103int 104main(argc, argv) 105 int argc; 106 char *argv[]; 107{ 108 int s, ch; --- 52 unchanged lines hidden (view full) --- 161 ident = argv0; 162 else 163 ident++; 164 openlog(ident, LOG_NDELAY|LOG_PID, LOG_DAEMON); 165 if (log_upto >= 0) 166 setlogmask(LOG_UPTO(log_upto)); 167 } 168 |
169#ifndef HAVE_ARC4RANDOM |
|
164 /* random value initilization */ 165 srandom((u_long)time(NULL)); | 170 /* random value initilization */ 171 srandom((u_long)time(NULL)); |
172#endif |
|
166 167 /* warn if accept_rtadv is down */ 168 if (!getinet6sysctl(IPV6CTL_ACCEPT_RTADV)) 169 warnx("kernel is configured not to accept RAs"); 170 171 /* initialization to dump internal status to a file */ 172 if (signal(SIGUSR1, (void *)rtsold_set_dump_file) < 0) 173 errx(1, "failed to set signal for dump status"); 174 | 173 174 /* warn if accept_rtadv is down */ 175 if (!getinet6sysctl(IPV6CTL_ACCEPT_RTADV)) 176 warnx("kernel is configured not to accept RAs"); 177 178 /* initialization to dump internal status to a file */ 179 if (signal(SIGUSR1, (void *)rtsold_set_dump_file) < 0) 180 errx(1, "failed to set signal for dump status"); 181 |
182 /* 183 * Open a socket for sending RS and receiving RA. 184 * This should be done before calling ifinit(), since the function 185 * uses the socket. 186 */ 187 if ((s = sockopen()) < 0) 188 errx(1, "failed to open a socket"); 189 |
|
175 /* configuration per interface */ 176 if (ifinit()) 177 errx(1, "failed to initilizatoin interfaces"); 178 while (argc--) { 179 if (ifconfig(*argv)) | 190 /* configuration per interface */ 191 if (ifinit()) 192 errx(1, "failed to initilizatoin interfaces"); 193 while (argc--) { 194 if (ifconfig(*argv)) |
180 errx(1, "failed to initilize %s", *argv); | 195 errx(1, "failed to initialize %s", *argv); |
181 argv++; 182 } 183 | 196 argv++; 197 } 198 |
184 /* open a socket for sending RS and receiving RA */ 185 if ((s = sockopen()) < 0) 186 errx(1, "failed to open a socket"); 187 | |
188 /* setup for probing default routers */ 189 if (probe_init()) 190 errx(1, "failed to setup for probing routers"); 191 192 if (!fflag) 193 daemon(0, 0); /* act as a daemon */ 194 195 /* dump the current pid */ --- 9 unchanged lines hidden (view full) --- 205 fprintf(fp, "%d\n", pid); 206 fclose(fp); 207 } 208 } 209 210 FD_ZERO(&fdset); 211 FD_SET(s, &fdset); 212 while (1) { /* main loop */ | 199 /* setup for probing default routers */ 200 if (probe_init()) 201 errx(1, "failed to setup for probing routers"); 202 203 if (!fflag) 204 daemon(0, 0); /* act as a daemon */ 205 206 /* dump the current pid */ --- 9 unchanged lines hidden (view full) --- 216 fprintf(fp, "%d\n", pid); 217 fclose(fp); 218 } 219 } 220 221 FD_ZERO(&fdset); 222 FD_SET(s, &fdset); 223 while (1) { /* main loop */ |
213 extern int errno; | |
214 int e; 215 struct fd_set select_fd = fdset; 216 217 if (do_dump) { /* SIGUSR1 */ 218 do_dump = 0; 219 rtsold_dump_file(dumpfilename); 220 } | 224 int e; 225 struct fd_set select_fd = fdset; 226 227 if (do_dump) { /* SIGUSR1 */ 228 do_dump = 0; 229 rtsold_dump_file(dumpfilename); 230 } |
221 | 231 |
222 timeout = rtsol_check_timer(); 223 224 if (once) { 225 struct ifinfo *ifi; 226 227 /* if we have no timeout, we are done (or failed) */ 228 if (timeout == NULL) 229 break; --- 34 unchanged lines hidden (view full) --- 264 if ((sdl = if_nametosdl(ifname)) == NULL) { 265 warnmsg(LOG_ERR, __FUNCTION__, 266 "failed to get link layer information for %s", ifname); 267 return(-1); 268 } 269 if (find_ifinfo(sdl->sdl_index)) { 270 warnmsg(LOG_ERR, __FUNCTION__, 271 "interface %s was already cofigured", ifname); | 232 timeout = rtsol_check_timer(); 233 234 if (once) { 235 struct ifinfo *ifi; 236 237 /* if we have no timeout, we are done (or failed) */ 238 if (timeout == NULL) 239 break; --- 34 unchanged lines hidden (view full) --- 274 if ((sdl = if_nametosdl(ifname)) == NULL) { 275 warnmsg(LOG_ERR, __FUNCTION__, 276 "failed to get link layer information for %s", ifname); 277 return(-1); 278 } 279 if (find_ifinfo(sdl->sdl_index)) { 280 warnmsg(LOG_ERR, __FUNCTION__, 281 "interface %s was already cofigured", ifname); |
282 free(sdl); |
|
272 return(-1); 273 } 274 275 if ((ifinfo = malloc(sizeof(*ifinfo))) == NULL) { 276 warnmsg(LOG_ERR, __FUNCTION__, "memory allocation failed"); | 283 return(-1); 284 } 285 286 if ((ifinfo = malloc(sizeof(*ifinfo))) == NULL) { 287 warnmsg(LOG_ERR, __FUNCTION__, "memory allocation failed"); |
288 free(sdl); |
|
277 return(-1); 278 } 279 memset(ifinfo, 0, sizeof(*ifinfo)); 280 ifinfo->sdl = sdl; 281 282 strncpy(ifinfo->ifname, ifname, sizeof(ifinfo->ifname)); 283 284 /* construct a router solicitation message */ --- 28 unchanged lines hidden (view full) --- 313 /* link into chain */ 314 if (iflist) 315 ifinfo->next = iflist; 316 iflist = ifinfo; 317 318 return(0); 319 320 bad: | 289 return(-1); 290 } 291 memset(ifinfo, 0, sizeof(*ifinfo)); 292 ifinfo->sdl = sdl; 293 294 strncpy(ifinfo->ifname, ifname, sizeof(ifinfo->ifname)); 295 296 /* construct a router solicitation message */ --- 28 unchanged lines hidden (view full) --- 325 /* link into chain */ 326 if (iflist) 327 ifinfo->next = iflist; 328 iflist = ifinfo; 329 330 return(0); 331 332 bad: |
321 free(ifinfo); | |
322 free(ifinfo->sdl); | 333 free(ifinfo->sdl); |
334 free(ifinfo); |
|
323 return(-1); 324} 325 | 335 return(-1); 336} 337 |
338#if 0 339static int 340ifreconfig(char *ifname) 341{ 342 struct ifinfo *ifi, *prev; 343 int rv; 344 345 prev = NULL; 346 for (ifi = iflist; ifi; ifi = ifi->next) { 347 if (strncmp(ifi->ifname, ifname, sizeof(ifi->ifname)) == 0) 348 break; 349 prev = ifi; 350 } 351 prev->next = ifi->next; 352 353 rv = ifconfig(ifname); 354 355 /* reclaim it after ifconfig() in case ifname is pointer inside ifi */ 356 if (ifi->rs_data) 357 free(ifi->rs_data); 358 free(ifi->sdl); 359 free(ifi); 360 361 return rv; 362} 363#endif 364 |
|
326struct ifinfo * 327find_ifinfo(int ifindex) 328{ 329 struct ifinfo *ifi; 330 331 for (ifi = iflist; ifi; ifi = ifi->next) 332 if (ifi->sdl->sdl_index == ifindex) 333 return(ifi); --- 141 unchanged lines hidden (view full) --- 475 returnval.tv_sec, returnval.tv_usec); 476 477 return(&returnval); 478} 479 480void 481rtsol_timer_update(struct ifinfo *ifinfo) 482{ | 365struct ifinfo * 366find_ifinfo(int ifindex) 367{ 368 struct ifinfo *ifi; 369 370 for (ifi = iflist; ifi; ifi = ifi->next) 371 if (ifi->sdl->sdl_index == ifindex) 372 return(ifi); --- 141 unchanged lines hidden (view full) --- 514 returnval.tv_sec, returnval.tv_usec); 515 516 return(&returnval); 517} 518 519void 520rtsol_timer_update(struct ifinfo *ifinfo) 521{ |
483#define MILLION 1000000 484#define DADRETRY 10 /* XXX: adhoc */ | 522#define MILLION 1000000 523#define DADRETRY 10 /* XXX: adhoc */ |
485 long interval; 486 struct timeval now; 487 488 bzero(&ifinfo->timer, sizeof(ifinfo->timer)); 489 490 switch (ifinfo->state) { 491 case IFS_DOWN: 492 case IFS_TENTATIVE: 493 if (++ifinfo->dadcount > DADRETRY) { 494 ifinfo->dadcount = 0; 495 ifinfo->timer.tv_sec = PROBE_INTERVAL; 496 } 497 else 498 ifinfo->timer.tv_sec = 1; 499 break; 500 case IFS_IDLE: 501 if (mobile_node) { | 524 long interval; 525 struct timeval now; 526 527 bzero(&ifinfo->timer, sizeof(ifinfo->timer)); 528 529 switch (ifinfo->state) { 530 case IFS_DOWN: 531 case IFS_TENTATIVE: 532 if (++ifinfo->dadcount > DADRETRY) { 533 ifinfo->dadcount = 0; 534 ifinfo->timer.tv_sec = PROBE_INTERVAL; 535 } 536 else 537 ifinfo->timer.tv_sec = 1; 538 break; 539 case IFS_IDLE: 540 if (mobile_node) { |
502 /* XXX should be configurable */ | 541 /* XXX should be configurable */ |
503 ifinfo->timer.tv_sec = 3; 504 } 505 else 506 ifinfo->timer = tm_max; /* stop timer(valid?) */ 507 break; 508 case IFS_DELAY: | 542 ifinfo->timer.tv_sec = 3; 543 } 544 else 545 ifinfo->timer = tm_max; /* stop timer(valid?) */ 546 break; 547 case IFS_DELAY: |
548#ifndef HAVE_ARC4RANDOM |
|
509 interval = random() % (MAX_RTR_SOLICITATION_DELAY * MILLION); | 549 interval = random() % (MAX_RTR_SOLICITATION_DELAY * MILLION); |
550#else 551 interval = arc4random() % (MAX_RTR_SOLICITATION_DELAY * MILLION); 552#endif |
|
510 ifinfo->timer.tv_sec = interval / MILLION; 511 ifinfo->timer.tv_usec = interval % MILLION; 512 break; 513 case IFS_PROBE: 514 ifinfo->timer.tv_sec = RTR_SOLICITATION_INTERVAL; 515 break; 516 default: 517 warnmsg(LOG_ERR, __FUNCTION__, --- 18 unchanged lines hidden (view full) --- 536 (int)ifinfo->timer.tv_sec, 537 (int)ifinfo->timer.tv_usec); 538 } 539 540#undef MILLION 541} 542 543/* timer related utility functions */ | 553 ifinfo->timer.tv_sec = interval / MILLION; 554 ifinfo->timer.tv_usec = interval % MILLION; 555 break; 556 case IFS_PROBE: 557 ifinfo->timer.tv_sec = RTR_SOLICITATION_INTERVAL; 558 break; 559 default: 560 warnmsg(LOG_ERR, __FUNCTION__, --- 18 unchanged lines hidden (view full) --- 579 (int)ifinfo->timer.tv_sec, 580 (int)ifinfo->timer.tv_usec); 581 } 582 583#undef MILLION 584} 585 586/* timer related utility functions */ |
544#define MILLION 1000000 | 587#define MILLION 1000000 |
545 546/* result = a + b */ 547static void 548TIMEVAL_ADD(struct timeval *a, struct timeval *b, struct timeval *result) 549{ 550 long l; 551 552 if ((l = a->tv_usec + b->tv_usec) < MILLION) { --- 70 unchanged lines hidden --- | 588 589/* result = a + b */ 590static void 591TIMEVAL_ADD(struct timeval *a, struct timeval *b, struct timeval *result) 592{ 593 long l; 594 595 if ((l = a->tv_usec + b->tv_usec) < MILLION) { --- 70 unchanged lines hidden --- |