xref: /original-bsd/sbin/routed/timer.c (revision f25de740)
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 this notice is preserved and that due credit is given
7  * to the University of California at Berkeley. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)timer.c	5.6 (Berkeley) 05/31/88";
15 #endif /* not lint */
16 
17 /*
18  * Routing Table Management Daemon
19  */
20 #include "defs.h"
21 
22 int	timeval = -TIMER_RATE;
23 
24 /*
25  * Timer routine.  Performs routing information supply
26  * duties and manages timers on routing table entries.
27  */
28 timer()
29 {
30 	register struct rthash *rh;
31 	register struct rt_entry *rt;
32 	struct rthash *base = hosthash;
33 	int doinghost = 1, timetobroadcast, changes = 0;
34 	extern int externalinterfaces;
35 	time_t now;
36 
37 	timeval += TIMER_RATE;
38 	if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0)
39 		ifinit();
40 	timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0;
41 again:
42 	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
43 		rt = rh->rt_forw;
44 		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
45 			/*
46 			 * We don't advance time on a routing entry for
47 			 * a passive gateway, or any interface if we're
48 			 * not acting as supplier.
49 			 */
50 			if (!(rt->rt_state & RTS_PASSIVE) &&
51 			    (supplier || !(rt->rt_state & RTS_INTERFACE)))
52 				rt->rt_timer += TIMER_RATE;
53 			if (rt->rt_timer >= GARBAGE_TIME) {
54 				rt = rt->rt_back;
55 				rtdelete(rt->rt_forw);
56 				continue;
57 			}
58 			if (rt->rt_timer >= EXPIRE_TIME) {
59 				if (traceactions && changes++ == 0) {
60 					(void) time(&now);
61 					curtime = ctime(&now);
62 				}
63 				rtchange(rt, &rt->rt_router, HOPCNT_INFINITY);
64 			}
65 			if (rt->rt_state & RTS_CHANGED) {
66 				rt->rt_state &= ~RTS_CHANGED;
67 				/* don't send extraneous packets */
68 				if (!supplier || timetobroadcast)
69 					continue;
70 				msg->rip_cmd = RIPCMD_RESPONSE;
71 				msg->rip_vers = RIPVERSION;
72 				msg->rip_nets[0].rip_dst = rt->rt_dst;
73 				msg->rip_nets[0].rip_dst.sa_family =
74 				   htons(msg->rip_nets[0].rip_dst.sa_family);
75 				msg->rip_nets[0].rip_metric =
76 				   htonl(min(rt->rt_metric, HOPCNT_INFINITY));
77 				toall(sendmsg);
78 			}
79 		}
80 	}
81 	if (doinghost) {
82 		doinghost = 0;
83 		base = nethash;
84 		goto again;
85 	}
86 	if (timetobroadcast)
87 		toall(supply);
88 	alarm(TIMER_RATE);
89 }
90 
91 /*
92  * On hangup, let everyone know we're going away.
93  */
94 hup()
95 {
96 	register struct rthash *rh;
97 	register struct rt_entry *rt;
98 	struct rthash *base = hosthash;
99 	int doinghost = 1;
100 
101 	if (supplier) {
102 again:
103 		for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
104 			rt = rh->rt_forw;
105 			for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
106 				rt->rt_metric = HOPCNT_INFINITY;
107 		}
108 		if (doinghost) {
109 			doinghost = 0;
110 			base = nethash;
111 			goto again;
112 		}
113 		toall(supply);
114 	}
115 	exit(1);
116 }
117