Deleted Added
sdiff udiff text old ( 55163 ) new ( 62632 )
full compact
1/*
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
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.
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 *
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>
34#include <sys/socket.h>
35
36#include <net/if.h>
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 */
60#define MAX_RTR_SOLICITATION_DELAY 1 /* second */
61#define RTR_SOLICITATION_INTERVAL 4 /* seconds */
62#define MAX_RTR_SOLICITATIONS 3 /* times */
63
64/* implementation dependent constants */
65#define PROBE_INTERVAL 60 /* secondes XXX: should be configurable */
66
67/* utility macros */
68/* a < b */
69#define TIMEVAL_LT(a, b) (((a).tv_sec < (b).tv_sec) ||\
70 (((a).tv_sec == (b).tv_sec) && \
71 ((a).tv_usec < (b).tv_usec)))
72
73/* a <= b */
74#define TIMEVAL_LEQ(a, b) (((a).tv_sec < (b).tv_sec) ||\
75 (((a).tv_sec == (b).tv_sec) &&\
76 ((a).tv_usec <= (b).tv_usec)))
77
78/* a == b */
79#define TIMEVAL_EQ(a, b) (((a).tv_sec==(b).tv_sec) && ((a).tv_usec==(b).tv_usec))
80
81int main __P((int argc, char *argv[]));
82
83/* static variables and functions */
84static int mobile_node = 0;
85static int do_dump;
86static char *dumpfilename = "/var/run/rtsold.dump"; /* XXX: should be configurable */
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
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
100static void rtsold_set_dump_file __P((void));
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
170 /* random value initilization */
171 srandom((u_long)time(NULL));
172#endif
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
190 /* configuration per interface */
191 if (ifinit())
192 errx(1, "failed to initilizatoin interfaces");
193 while (argc--) {
194 if (ifconfig(*argv))
195 errx(1, "failed to initialize %s", *argv);
196 argv++;
197 }
198
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 */
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 }
231
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);
283 return(-1);
284 }
285
286 if ((ifinfo = malloc(sizeof(*ifinfo))) == NULL) {
287 warnmsg(LOG_ERR, __FUNCTION__, "memory allocation failed");
288 free(sdl);
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:
333 free(ifinfo->sdl);
334 free(ifinfo);
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
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{
522#define MILLION 1000000
523#define DADRETRY 10 /* XXX: adhoc */
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) {
541 /* XXX should be configurable */
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
549 interval = random() % (MAX_RTR_SOLICITATION_DELAY * MILLION);
550#else
551 interval = arc4random() % (MAX_RTR_SOLICITATION_DELAY * MILLION);
552#endif
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 */
587#define MILLION 1000000
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 ---