xref: /original-bsd/sbin/routed/timer.c (revision f052b07a)
1 /*
2  * Copyright (c) 1983, 1988 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)timer.c	5.7 (Berkeley) 06/18/88";
20 #endif /* not lint */
21 
22 /*
23  * Routing Table Management Daemon
24  */
25 #include "defs.h"
26 
27 int	timeval = -TIMER_RATE;
28 
29 /*
30  * Timer routine.  Performs routing information supply
31  * duties and manages timers on routing table entries.
32  */
33 timer()
34 {
35 	register struct rthash *rh;
36 	register struct rt_entry *rt;
37 	struct rthash *base = hosthash;
38 	int doinghost = 1, timetobroadcast, changes = 0;
39 	extern int externalinterfaces;
40 	time_t now;
41 
42 	timeval += TIMER_RATE;
43 	if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0)
44 		ifinit();
45 	timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0;
46 again:
47 	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
48 		rt = rh->rt_forw;
49 		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
50 			/*
51 			 * We don't advance time on a routing entry for
52 			 * a passive gateway, or any interface if we're
53 			 * not acting as supplier.
54 			 */
55 			if (!(rt->rt_state & RTS_PASSIVE) &&
56 			    (supplier || !(rt->rt_state & RTS_INTERFACE)))
57 				rt->rt_timer += TIMER_RATE;
58 			if (rt->rt_timer >= GARBAGE_TIME) {
59 				rt = rt->rt_back;
60 				rtdelete(rt->rt_forw);
61 				continue;
62 			}
63 			if (rt->rt_timer >= EXPIRE_TIME) {
64 				if (traceactions && changes++ == 0) {
65 					(void) time(&now);
66 					curtime = ctime(&now);
67 				}
68 				rtchange(rt, &rt->rt_router, HOPCNT_INFINITY);
69 			}
70 			if (rt->rt_state & RTS_CHANGED) {
71 				rt->rt_state &= ~RTS_CHANGED;
72 				/* don't send extraneous packets */
73 				if (!supplier || timetobroadcast)
74 					continue;
75 				msg->rip_cmd = RIPCMD_RESPONSE;
76 				msg->rip_vers = RIPVERSION;
77 				msg->rip_nets[0].rip_dst = rt->rt_dst;
78 				msg->rip_nets[0].rip_dst.sa_family =
79 				   htons(msg->rip_nets[0].rip_dst.sa_family);
80 				msg->rip_nets[0].rip_metric =
81 				   htonl(min(rt->rt_metric, HOPCNT_INFINITY));
82 				toall(sendmsg);
83 			}
84 		}
85 	}
86 	if (doinghost) {
87 		doinghost = 0;
88 		base = nethash;
89 		goto again;
90 	}
91 	if (timetobroadcast)
92 		toall(supply);
93 	alarm(TIMER_RATE);
94 }
95 
96 /*
97  * On hangup, let everyone know we're going away.
98  */
99 hup()
100 {
101 	register struct rthash *rh;
102 	register struct rt_entry *rt;
103 	struct rthash *base = hosthash;
104 	int doinghost = 1;
105 
106 	if (supplier) {
107 again:
108 		for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
109 			rt = rh->rt_forw;
110 			for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
111 				rt->rt_metric = HOPCNT_INFINITY;
112 		}
113 		if (doinghost) {
114 			doinghost = 0;
115 			base = nethash;
116 			goto again;
117 		}
118 		toall(supply);
119 	}
120 	exit(1);
121 }
122