1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1983, 1988, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $FreeBSD: stable/12/sbin/routed/main.c 327276 2017-12-28 05:34:24Z imp $
32 */
33
34 #include "defs.h"
35 #include "pathnames.h"
36 #ifdef sgi
37 #include "math.h"
38 #endif
39 #include <signal.h>
40 #include <fcntl.h>
41 #include <sys/file.h>
42
43 __COPYRIGHT("@(#) Copyright (c) 1983, 1988, 1993 "
44 "The Regents of the University of California."
45 " All rights reserved.");
46 #ifdef __NetBSD__
47 __RCSID("$NetBSD$");
48 #include <util.h>
49 #elif defined(__FreeBSD__)
50 __RCSID("$FreeBSD: stable/12/sbin/routed/main.c 327276 2017-12-28 05:34:24Z imp $");
51 #else
52 __RCSID("$Revision: 2.31 $");
53 #ident "$Revision: 2.31 $"
54 #endif
55
56 pid_t mypid;
57
58 naddr myaddr; /* system address */
59 static char myname[MAXHOSTNAMELEN+1];
60
61 static int verbose;
62
63 int supplier; /* supply or broadcast updates */
64 int supplier_set;
65 static int ipforwarding = 1; /* kernel forwarding on */
66
67 static int default_gateway; /* 1=advertise default */
68 static int background = 1;
69 int ridhosts; /* 1=reduce host routes */
70 int mhome; /* 1=want multi-homed host route */
71 int advertise_mhome; /* 1=must continue advertising it */
72 int auth_ok = 1; /* 1=ignore auth if we do not care */
73 int insecure; /* Reply to special queries or not */
74
75 struct timeval epoch; /* when started */
76 struct timeval clk;
77 static struct timeval prev_clk;
78 static int usec_fudge;
79 struct timeval now; /* current idea of time */
80 time_t now_stale;
81 time_t now_expire;
82 time_t now_garbage;
83
84 static struct timeval next_bcast; /* next general broadcast */
85 struct timeval no_flash = { /* inhibit flash update */
86 EPOCH+SUPPLY_INTERVAL, 0
87 };
88
89 static struct timeval flush_kern_timer;
90
91 static fd_set fdbits;
92 static int sock_max;
93 int rip_sock = -1; /* RIP socket */
94 const struct interface *rip_sock_mcast; /* current multicast interface */
95 int rt_sock; /* routing socket */
96 int rt_sock_seqno;
97
98
99 static int get_rip_sock(naddr, int);
100 static void timevalsub(struct timeval *, struct timeval *, struct timeval *);
101 static void sigalrm(int s UNUSED);
102 static void sigterm(int sig);
103
104 int
main(int argc,char * argv[])105 main(int argc,
106 char *argv[])
107 {
108 int n, mib[4], off;
109 size_t len;
110 char *p, *q;
111 const char *cp;
112 struct timeval wtime, t2;
113 time_t dt;
114 fd_set ibits;
115 naddr p_net, p_mask;
116 struct interface *ifp;
117 struct parm parm;
118 char *tracename = 0;
119
120
121 /* Some shells are badly broken and send SIGHUP to backgrounded
122 * processes.
123 */
124 signal(SIGHUP, SIG_IGN);
125
126 openlog("routed", LOG_PID, LOG_DAEMON);
127 ftrace = stdout;
128
129 gettimeofday(&clk, 0);
130 prev_clk = clk;
131 epoch = clk;
132 epoch.tv_sec -= EPOCH;
133 now.tv_sec = EPOCH;
134 now_stale = EPOCH - STALE_TIME;
135 now_expire = EPOCH - EXPIRE_TIME;
136 now_garbage = EPOCH - GARBAGE_TIME;
137 wtime.tv_sec = 0;
138
139 (void)gethostname(myname, sizeof(myname)-1);
140 (void)gethost(myname, &myaddr);
141
142 while ((n = getopt(argc, argv, "isqdghmAtvT:F:P:")) != -1) {
143 switch (n) {
144 case 'i':
145 insecure++;
146 break;
147 case 's':
148 supplier = 1;
149 supplier_set = 1;
150 break;
151
152 case 'q':
153 supplier = 0;
154 supplier_set = 1;
155 break;
156
157 case 'd':
158 background = 0;
159 break;
160
161 case 'g':
162 memset(&parm, 0, sizeof(parm));
163 parm.parm_d_metric = 1;
164 cp = check_parms(&parm);
165 if (cp != 0)
166 msglog("bad -g: %s", cp);
167 else
168 default_gateway = 1;
169 break;
170
171 case 'h': /* suppress extra host routes */
172 ridhosts = 1;
173 break;
174
175 case 'm': /* advertise host route */
176 mhome = 1; /* on multi-homed hosts */
177 break;
178
179 case 'A':
180 /* Ignore authentication if we do not care.
181 * Crazy as it is, that is what RFC 1723 requires.
182 */
183 auth_ok = 0;
184 break;
185
186 case 't':
187 new_tracelevel++;
188 break;
189
190 case 'T':
191 tracename = optarg;
192 break;
193
194 case 'F': /* minimal routes for SLIP */
195 n = FAKE_METRIC;
196 p = strchr(optarg,',');
197 if (p && *p != '\0') {
198 n = (int)strtoul(p+1, &q, 0);
199 if (*q == '\0'
200 && n <= HOPCNT_INFINITY-1
201 && n >= 1)
202 *p = '\0';
203 }
204 if (!getnet(optarg, &p_net, &p_mask)) {
205 msglog("bad network; \"-F %s\"",
206 optarg);
207 break;
208 }
209 memset(&parm, 0, sizeof(parm));
210 parm.parm_net = p_net;
211 parm.parm_mask = p_mask;
212 parm.parm_d_metric = n;
213 cp = check_parms(&parm);
214 if (cp != 0)
215 msglog("bad -F: %s", cp);
216 break;
217
218 case 'P':
219 /* handle arbitrary parameters.
220 */
221 q = strdup(optarg);
222 cp = parse_parms(q, 0);
223 if (cp != 0)
224 msglog("%s in \"-P %s\"", cp, optarg);
225 free(q);
226 break;
227
228 case 'v':
229 /* display version */
230 verbose++;
231 msglog("version 2.31");
232 break;
233
234 default:
235 goto usage;
236 }
237 }
238 argc -= optind;
239 argv += optind;
240
241 if (tracename == 0 && argc >= 1) {
242 tracename = *argv++;
243 argc--;
244 }
245 if (tracename != 0 && tracename[0] == '\0')
246 goto usage;
247 if (argc != 0) {
248 usage:
249 logbad(0, "usage: routed [-sqdghmAtv] [-T tracefile]"
250 " [-F net[,metric]] [-P parms]");
251 }
252 if (geteuid() != 0) {
253 if (verbose)
254 exit(0);
255 logbad(0, "requires UID 0");
256 }
257
258 mib[0] = CTL_NET;
259 mib[1] = PF_INET;
260 mib[2] = IPPROTO_IP;
261 mib[3] = IPCTL_FORWARDING;
262 len = sizeof(ipforwarding);
263 if (sysctl(mib, 4, &ipforwarding, &len, 0, 0) < 0)
264 LOGERR("sysctl(IPCTL_FORWARDING)");
265
266 if (!ipforwarding) {
267 if (supplier)
268 msglog("-s incompatible with ipforwarding=0");
269 if (default_gateway) {
270 msglog("-g incompatible with ipforwarding=0");
271 default_gateway = 0;
272 }
273 supplier = 0;
274 supplier_set = 1;
275 }
276 if (default_gateway) {
277 if (supplier_set && !supplier) {
278 msglog("-g and -q incompatible");
279 } else {
280 supplier = 1;
281 supplier_set = 1;
282 }
283 }
284
285
286 signal(SIGALRM, sigalrm);
287 if (!background)
288 signal(SIGHUP, sigterm); /* SIGHUP fatal during debugging */
289 signal(SIGTERM, sigterm);
290 signal(SIGINT, sigterm);
291 signal(SIGUSR1, sigtrace_on);
292 signal(SIGUSR2, sigtrace_off);
293
294 /* get into the background */
295 #ifdef sgi
296 if (0 > _daemonize(background ? 0 : (_DF_NOCHDIR|_DF_NOFORK),
297 STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO))
298 BADERR(0, "_daemonize()");
299 #else
300 if (background && daemon(0, 1) < 0)
301 BADERR(0,"daemon()");
302 #endif
303
304 #if defined(__NetBSD__)
305 pidfile(0);
306 #endif
307 mypid = getpid();
308
309 /* prepare socket connected to the kernel.
310 */
311 rt_sock = socket(AF_ROUTE, SOCK_RAW, 0);
312 if (rt_sock < 0)
313 BADERR(1,"rt_sock = socket()");
314 if (fcntl(rt_sock, F_SETFL, O_NONBLOCK) == -1)
315 logbad(1, "fcntl(rt_sock) O_NONBLOCK: %s", strerror(errno));
316 off = 0;
317 if (setsockopt(rt_sock, SOL_SOCKET,SO_USELOOPBACK,
318 &off,sizeof(off)) < 0)
319 LOGERR("setsockopt(SO_USELOOPBACK,0)");
320
321 fix_select();
322
323
324 if (tracename != 0) {
325 strncpy(inittracename, tracename, sizeof(inittracename)-1);
326 set_tracefile(inittracename, "%s", -1);
327 } else {
328 tracelevel_msg("%s", -1); /* turn on tracing to stdio */
329 }
330
331 bufinit();
332
333 /* initialize radix tree */
334 rtinit();
335
336 /* Pick a random part of the second for our output to minimize
337 * collisions.
338 *
339 * Start broadcasting after hearing from other routers, and
340 * at a random time so a bunch of systems do not get synchronized
341 * after a power failure.
342 */
343 intvl_random(&next_bcast, EPOCH+MIN_WAITTIME, EPOCH+SUPPLY_INTERVAL);
344 age_timer.tv_usec = next_bcast.tv_usec;
345 age_timer.tv_sec = EPOCH+MIN_WAITTIME;
346 rdisc_timer = next_bcast;
347 ifinit_timer.tv_usec = next_bcast.tv_usec;
348
349 /* Collect an initial view of the world by checking the interface
350 * configuration and the kludge file.
351 */
352 gwkludge();
353 ifinit();
354
355 /* Ask for routes */
356 rip_query();
357 rdisc_sol();
358
359 /* Now turn off stdio if not tracing */
360 if (new_tracelevel == 0)
361 trace_close(background);
362
363 /* Loop forever, listening and broadcasting.
364 */
365 for (;;) {
366 prev_clk = clk;
367 gettimeofday(&clk, 0);
368 if (prev_clk.tv_sec == clk.tv_sec
369 && prev_clk.tv_usec == clk.tv_usec+usec_fudge) {
370 /* Much of `routed` depends on time always advancing.
371 * On systems that do not guarantee that gettimeofday()
372 * produces unique timestamps even if called within
373 * a single tick, use trickery like that in classic
374 * BSD kernels.
375 */
376 clk.tv_usec += ++usec_fudge;
377
378 } else {
379 usec_fudge = 0;
380
381 timevalsub(&t2, &clk, &prev_clk);
382 if (t2.tv_sec < 0
383 || t2.tv_sec > wtime.tv_sec + 5) {
384 /* Deal with time changes before other
385 * housekeeping to keep everything straight.
386 */
387 dt = t2.tv_sec;
388 if (dt > 0)
389 dt -= wtime.tv_sec;
390 trace_act("time changed by %d sec", (int)dt);
391 epoch.tv_sec += dt;
392 }
393 }
394 timevalsub(&now, &clk, &epoch);
395 now_stale = now.tv_sec - STALE_TIME;
396 now_expire = now.tv_sec - EXPIRE_TIME;
397 now_garbage = now.tv_sec - GARBAGE_TIME;
398
399 /* deal with signals that should affect tracing */
400 set_tracelevel();
401
402 if (stopint != 0) {
403 rip_bcast(0);
404 rdisc_adv();
405 trace_off("exiting with signal %d", stopint);
406 exit(stopint | 128);
407 }
408
409 /* look for new or dead interfaces */
410 timevalsub(&wtime, &ifinit_timer, &now);
411 if (wtime.tv_sec <= 0) {
412 wtime.tv_sec = 0;
413 ifinit();
414 rip_query();
415 continue;
416 }
417
418 /* Check the kernel table occasionally for mysteriously
419 * evaporated routes
420 */
421 timevalsub(&t2, &flush_kern_timer, &now);
422 if (t2.tv_sec <= 0) {
423 flush_kern();
424 flush_kern_timer.tv_sec = (now.tv_sec
425 + CHECK_QUIET_INTERVAL);
426 continue;
427 }
428 if (timercmp(&t2, &wtime, <))
429 wtime = t2;
430
431 /* If it is time, then broadcast our routes.
432 */
433 if (supplier || advertise_mhome) {
434 timevalsub(&t2, &next_bcast, &now);
435 if (t2.tv_sec <= 0) {
436 /* Synchronize the aging and broadcast
437 * timers to minimize awakenings
438 */
439 age(0);
440
441 rip_bcast(0);
442
443 /* It is desirable to send routing updates
444 * regularly. So schedule the next update
445 * 30 seconds after the previous one was
446 * scheduled, instead of 30 seconds after
447 * the previous update was finished.
448 * Even if we just started after discovering
449 * a 2nd interface or were otherwise delayed,
450 * pick a 30-second anniversary of the
451 * original broadcast time.
452 */
453 n = 1 + (0-t2.tv_sec)/SUPPLY_INTERVAL;
454 next_bcast.tv_sec += n*SUPPLY_INTERVAL;
455
456 continue;
457 }
458
459 if (timercmp(&t2, &wtime, <))
460 wtime = t2;
461 }
462
463 /* If we need a flash update, either do it now or
464 * set the delay to end when it is time.
465 *
466 * If we are within MIN_WAITTIME seconds of a full update,
467 * do not bother.
468 */
469 if (need_flash
470 && supplier
471 && no_flash.tv_sec+MIN_WAITTIME < next_bcast.tv_sec) {
472 /* accurate to the millisecond */
473 if (!timercmp(&no_flash, &now, >))
474 rip_bcast(1);
475 timevalsub(&t2, &no_flash, &now);
476 if (timercmp(&t2, &wtime, <))
477 wtime = t2;
478 }
479
480 /* trigger the main aging timer.
481 */
482 timevalsub(&t2, &age_timer, &now);
483 if (t2.tv_sec <= 0) {
484 age(0);
485 continue;
486 }
487 if (timercmp(&t2, &wtime, <))
488 wtime = t2;
489
490 /* update the kernel routing table
491 */
492 timevalsub(&t2, &need_kern, &now);
493 if (t2.tv_sec <= 0) {
494 age(0);
495 continue;
496 }
497 if (timercmp(&t2, &wtime, <))
498 wtime = t2;
499
500 /* take care of router discovery,
501 * but do it in the correct the millisecond
502 */
503 if (!timercmp(&rdisc_timer, &now, >)) {
504 rdisc_age(0);
505 continue;
506 }
507 timevalsub(&t2, &rdisc_timer, &now);
508 if (timercmp(&t2, &wtime, <))
509 wtime = t2;
510
511
512 /* wait for input or a timer to expire.
513 */
514 trace_flush();
515 ibits = fdbits;
516 n = select(sock_max, &ibits, 0, 0, &wtime);
517 if (n <= 0) {
518 if (n < 0 && errno != EINTR && errno != EAGAIN)
519 BADERR(1,"select");
520 continue;
521 }
522
523 if (FD_ISSET(rt_sock, &ibits)) {
524 read_rt();
525 n--;
526 }
527 if (rdisc_sock >= 0 && FD_ISSET(rdisc_sock, &ibits)) {
528 read_d();
529 n--;
530 }
531 if (rip_sock >= 0 && FD_ISSET(rip_sock, &ibits)) {
532 read_rip(rip_sock, 0);
533 n--;
534 }
535
536 LIST_FOREACH(ifp, &ifnet, int_list) {
537 if (n <= 0)
538 break;
539 if (ifp->int_rip_sock >= 0
540 && FD_ISSET(ifp->int_rip_sock, &ibits)) {
541 read_rip(ifp->int_rip_sock, ifp);
542 n--;
543 }
544 }
545 }
546 }
547
548
549 /* ARGSUSED */
550 static void
sigalrm(int s UNUSED)551 sigalrm(int s UNUSED)
552 {
553 /* Historically, SIGALRM would cause the daemon to check for
554 * new and broken interfaces.
555 */
556 ifinit_timer.tv_sec = now.tv_sec;
557 trace_act("SIGALRM");
558 }
559
560
561 /* watch for fatal signals */
562 static void
sigterm(int sig)563 sigterm(int sig)
564 {
565 stopint = sig;
566 (void)signal(sig, SIG_DFL); /* catch it only once */
567 }
568
569
570 void
fix_select(void)571 fix_select(void)
572 {
573 struct interface *ifp;
574
575
576 FD_ZERO(&fdbits);
577 sock_max = 0;
578
579 FD_SET(rt_sock, &fdbits);
580 if (sock_max <= rt_sock)
581 sock_max = rt_sock+1;
582 if (rip_sock >= 0) {
583 FD_SET(rip_sock, &fdbits);
584 if (sock_max <= rip_sock)
585 sock_max = rip_sock+1;
586 }
587 LIST_FOREACH(ifp, &ifnet, int_list) {
588 if (ifp->int_rip_sock >= 0) {
589 FD_SET(ifp->int_rip_sock, &fdbits);
590 if (sock_max <= ifp->int_rip_sock)
591 sock_max = ifp->int_rip_sock+1;
592 }
593 }
594 if (rdisc_sock >= 0) {
595 FD_SET(rdisc_sock, &fdbits);
596 if (sock_max <= rdisc_sock)
597 sock_max = rdisc_sock+1;
598 }
599 }
600
601
602 void
fix_sock(int sock,const char * name)603 fix_sock(int sock,
604 const char *name)
605 {
606 int on;
607 #define MIN_SOCKBUF (4*1024)
608 static int rbuf;
609
610 if (fcntl(sock, F_SETFL, O_NONBLOCK) == -1)
611 logbad(1, "fcntl(%s) O_NONBLOCK: %s",
612 name, strerror(errno));
613 on = 1;
614 if (setsockopt(sock, SOL_SOCKET,SO_BROADCAST, &on,sizeof(on)) < 0)
615 msglog("setsockopt(%s,SO_BROADCAST): %s",
616 name, strerror(errno));
617 #ifdef USE_PASSIFNAME
618 on = 1;
619 if (setsockopt(sock, SOL_SOCKET, SO_PASSIFNAME, &on,sizeof(on)) < 0)
620 msglog("setsockopt(%s,SO_PASSIFNAME): %s",
621 name, strerror(errno));
622 #endif
623
624 if (rbuf >= MIN_SOCKBUF) {
625 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
626 &rbuf, sizeof(rbuf)) < 0)
627 msglog("setsockopt(%s,SO_RCVBUF=%d): %s",
628 name, rbuf, strerror(errno));
629 } else {
630 for (rbuf = 60*1024; ; rbuf -= 4096) {
631 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
632 &rbuf, sizeof(rbuf)) == 0) {
633 trace_act("RCVBUF=%d", rbuf);
634 break;
635 }
636 if (rbuf < MIN_SOCKBUF) {
637 msglog("setsockopt(%s,SO_RCVBUF = %d): %s",
638 name, rbuf, strerror(errno));
639 break;
640 }
641 }
642 }
643 }
644
645
646 /* get a rip socket
647 */
648 static int /* <0 or file descriptor */
get_rip_sock(naddr addr,int serious)649 get_rip_sock(naddr addr,
650 int serious) /* 1=failure to bind is serious */
651 {
652 struct sockaddr_in rsin;
653 unsigned char ttl;
654 int s;
655
656
657 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
658 BADERR(1,"rip_sock = socket()");
659
660 memset(&rsin, 0, sizeof(rsin));
661 #ifdef _HAVE_SIN_LEN
662 rsin.sin_len = sizeof(rsin);
663 #endif
664 rsin.sin_family = AF_INET;
665 rsin.sin_port = htons(RIP_PORT);
666 rsin.sin_addr.s_addr = addr;
667 if (bind(s, (struct sockaddr *)&rsin, sizeof(rsin)) < 0) {
668 if (serious)
669 BADERR(errno != EADDRINUSE, "bind(rip_sock)");
670 close(s);
671 return -1;
672 }
673 fix_sock(s,"rip_sock");
674
675 ttl = 1;
676 if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL,
677 &ttl, sizeof(ttl)) < 0)
678 DBGERR(1,"rip_sock setsockopt(IP_MULTICAST_TTL)");
679
680 return s;
681 }
682
683
684 /* turn off main RIP socket */
685 void
rip_off(void)686 rip_off(void)
687 {
688 struct interface *ifp;
689 naddr addr;
690
691
692 if (rip_sock >= 0 && !mhome) {
693 trace_act("turn off RIP");
694
695 (void)close(rip_sock);
696 rip_sock = -1;
697
698 /* get non-broadcast sockets to listen to queries.
699 */
700 LIST_FOREACH(ifp, &ifnet, int_list) {
701 if (ifp->int_state & IS_REMOTE)
702 continue;
703 if (ifp->int_rip_sock < 0) {
704 addr = ((ifp->int_if_flags & IFF_POINTOPOINT)
705 ? ifp->int_dstaddr
706 : ifp->int_addr);
707 ifp->int_rip_sock = get_rip_sock(addr, 0);
708 }
709 }
710
711 fix_select();
712
713 age(0);
714 }
715 }
716
717
718 /* turn on RIP multicast input via an interface
719 */
720 static void
rip_mcast_on(struct interface * ifp)721 rip_mcast_on(struct interface *ifp)
722 {
723 struct group_req gr;
724 struct sockaddr_in *sin;
725
726 if (!IS_RIP_IN_OFF(ifp->int_state)
727 && (ifp->int_if_flags & IFF_MULTICAST)
728 && !(ifp->int_state & IS_ALIAS)) {
729 memset(&gr, 0, sizeof(gr));
730 gr.gr_interface = ifp->int_index;
731 sin = (struct sockaddr_in *)&gr.gr_group;
732 sin->sin_family = AF_INET;
733 #ifdef _HAVE_SIN_LEN
734 sin->sin_len = sizeof(struct sockaddr_in);
735 #endif
736 sin->sin_addr.s_addr = htonl(INADDR_RIP_GROUP);
737 if (setsockopt(rip_sock, IPPROTO_IP, MCAST_JOIN_GROUP,
738 &gr, sizeof(gr)) < 0)
739 LOGERR("setsockopt(MCAST_JOIN_GROUP RIP)");
740 }
741 }
742
743
744 /* Prepare socket used for RIP.
745 */
746 void
rip_on(struct interface * ifp)747 rip_on(struct interface *ifp)
748 {
749 /* If the main RIP socket is already alive, only start receiving
750 * multicasts for this interface.
751 */
752 if (rip_sock >= 0) {
753 if (ifp != NULL)
754 rip_mcast_on(ifp);
755 return;
756 }
757
758 /* If the main RIP socket is off and it makes sense to turn it on,
759 * then turn it on for all of the interfaces.
760 * It makes sense if either router discovery is off, or if
761 * router discover is on and at most one interface is doing RIP.
762 */
763 if (rip_interfaces > 0 && (!rdisc_ok || rip_interfaces > 1)) {
764 trace_act("turn on RIP");
765
766 /* Close all of the query sockets so that we can open
767 * the main socket. SO_REUSEPORT is not a solution,
768 * since that would let two daemons bind to the broadcast
769 * socket.
770 */
771 LIST_FOREACH(ifp, &ifnet, int_list) {
772 if (ifp->int_rip_sock >= 0) {
773 (void)close(ifp->int_rip_sock);
774 ifp->int_rip_sock = -1;
775 }
776 }
777
778 rip_sock = get_rip_sock(INADDR_ANY, 1);
779 rip_sock_mcast = NULL;
780
781 /* Do not advertise anything until we have heard something
782 */
783 if (next_bcast.tv_sec < now.tv_sec+MIN_WAITTIME)
784 next_bcast.tv_sec = now.tv_sec+MIN_WAITTIME;
785
786 LIST_FOREACH(ifp, &ifnet, int_list) {
787 ifp->int_query_time = NEVER;
788 rip_mcast_on(ifp);
789 }
790 ifinit_timer.tv_sec = now.tv_sec;
791
792 } else if (ifp != NULL
793 && !(ifp->int_state & IS_REMOTE)
794 && ifp->int_rip_sock < 0) {
795 /* RIP is off, so ensure there are sockets on which
796 * to listen for queries.
797 */
798 ifp->int_rip_sock = get_rip_sock(ifp->int_addr, 0);
799 }
800
801 fix_select();
802 }
803
804
805 /* die if malloc(3) fails
806 */
807 void *
rtmalloc(size_t size,const char * msg)808 rtmalloc(size_t size,
809 const char *msg)
810 {
811 void *p = malloc(size);
812 if (p == NULL)
813 logbad(1,"malloc(%lu) failed in %s", (u_long)size, msg);
814 return p;
815 }
816
817
818 /* get a random instant in an interval
819 */
820 void
intvl_random(struct timeval * tp,u_long lo,u_long hi)821 intvl_random(struct timeval *tp, /* put value here */
822 u_long lo, /* value is after this second */
823 u_long hi) /* and before this */
824 {
825 tp->tv_sec = (time_t)(hi == lo
826 ? lo
827 : (lo + arc4random_uniform(1 + hi - lo)));
828 tp->tv_usec = arc4random_uniform(1000000);
829 }
830
831
832 void
timevaladd(struct timeval * t1,struct timeval * t2)833 timevaladd(struct timeval *t1,
834 struct timeval *t2)
835 {
836
837 t1->tv_sec += t2->tv_sec;
838 if ((t1->tv_usec += t2->tv_usec) >= 1000000) {
839 t1->tv_sec++;
840 t1->tv_usec -= 1000000;
841 }
842 }
843
844
845 /* t1 = t2 - t3
846 */
847 static void
timevalsub(struct timeval * t1,struct timeval * t2,struct timeval * t3)848 timevalsub(struct timeval *t1,
849 struct timeval *t2,
850 struct timeval *t3)
851 {
852 t1->tv_sec = t2->tv_sec - t3->tv_sec;
853 if ((t1->tv_usec = t2->tv_usec - t3->tv_usec) < 0) {
854 t1->tv_sec--;
855 t1->tv_usec += 1000000;
856 }
857 }
858
859
860 /* put a message into the system log
861 */
862 void
msglog(const char * p,...)863 msglog(const char *p, ...)
864 {
865 va_list args;
866
867 trace_flush();
868
869 va_start(args, p);
870 vsyslog(LOG_ERR, p, args);
871 va_end(args);
872 if (ftrace != NULL) {
873 if (ftrace == stdout)
874 (void)fputs("routed: ", ftrace);
875 va_start(args, p);
876 (void)vfprintf(ftrace, p, args);
877 va_end(args);
878 (void)fputc('\n', ftrace);
879 }
880 }
881
882
883 /* Put a message about a bad system into the system log if
884 * we have not complained about it recently.
885 *
886 * It is desirable to complain about all bad systems, but not too often.
887 * In the worst case, it is not practical to keep track of all bad systems.
888 * For example, there can be many systems with the wrong password.
889 */
890 void
msglim(struct msg_limit * lim,naddr addr,const char * p,...)891 msglim(struct msg_limit *lim, naddr addr, const char *p, ...)
892 {
893 va_list args;
894 int i;
895 struct msg_sub *ms1, *ms;
896 const char *p1;
897
898 /* look for the oldest slot in the table
899 * or the slot for the bad router.
900 */
901 ms = ms1 = lim->subs;
902 for (i = MSG_SUBJECT_N; ; i--, ms1++) {
903 if (i == 0) {
904 /* Reuse a slot at most once every 10 minutes.
905 */
906 if (lim->reuse > now.tv_sec) {
907 ms = NULL;
908 } else {
909 ms = ms1;
910 lim->reuse = now.tv_sec + 10*60;
911 }
912 break;
913 }
914 if (ms->addr == addr) {
915 /* Repeat a complaint about a given system at
916 * most once an hour.
917 */
918 if (ms->until > now.tv_sec)
919 ms = NULL;
920 break;
921 }
922 if (ms->until < ms1->until)
923 ms = ms1;
924 }
925 if (ms != NULL) {
926 ms->addr = addr;
927 ms->until = now.tv_sec + 60*60; /* 60 minutes */
928
929 trace_flush();
930 for (p1 = p; *p1 == ' '; p1++)
931 continue;
932 va_start(args, p);
933 vsyslog(LOG_ERR, p1, args);
934 va_end(args);
935 }
936
937 /* always display the message if tracing */
938 if (ftrace != NULL) {
939 va_start(args, p);
940 (void)vfprintf(ftrace, p, args);
941 va_end(args);
942 (void)fputc('\n', ftrace);
943 }
944 }
945
946
947 void
logbad(int dump,const char * p,...)948 logbad(int dump, const char *p, ...)
949 {
950 va_list args;
951
952 trace_flush();
953
954 va_start(args, p);
955 vsyslog(LOG_ERR, p, args);
956 va_end(args);
957 (void)fputs("routed: ", stderr);
958 va_start(args, p);
959 (void)vfprintf(stderr, p, args);
960 va_end(args);
961 (void)fputs("; giving up\n",stderr);
962 (void)fflush(stderr);
963
964 if (dump)
965 abort();
966 exit(1);
967 }
968