Deleted Added
full compact
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 ---