122000Sdist /*
2*61540Sbostic * Copyright (c) 1983, 1988, 1993
3*61540Sbostic * The Regents of the University of California. All rights reserved.
433489Sbostic *
542712Sbostic * %sccs.include.redist.c%
622000Sdist */
722000Sdist
89021Ssam #ifndef lint
9*61540Sbostic static char sccsid[] = "@(#)timer.c 8.1 (Berkeley) 06/05/93";
1033489Sbostic #endif /* not lint */
119021Ssam
129021Ssam /*
139021Ssam * Routing Table Management Daemon
149021Ssam */
1510245Ssam #include "defs.h"
169021Ssam
1736831Skarels int faketime;
189021Ssam
199021Ssam /*
209021Ssam * Timer routine. Performs routing information supply
219021Ssam * duties and manages timers on routing table entries.
2236831Skarels * Management of the RTS_CHANGED bit assumes that we broadcast
2336831Skarels * each time called.
249021Ssam */
2546784Sbostic void
timer()269021Ssam timer()
279021Ssam {
289021Ssam register struct rthash *rh;
299021Ssam register struct rt_entry *rt;
309021Ssam struct rthash *base = hosthash;
3136831Skarels int doinghost = 1, timetobroadcast;
3224278Skarels extern int externalinterfaces;
339021Ssam
3436831Skarels (void) gettimeofday(&now, (struct timezone *)NULL);
3536831Skarels faketime += TIMER_RATE;
3636831Skarels if (lookforinterfaces && (faketime % CHECK_INTERVAL) == 0)
379021Ssam ifinit();
3836831Skarels timetobroadcast = supplier && (faketime % SUPPLY_INTERVAL) == 0;
399021Ssam again:
409021Ssam for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
419021Ssam rt = rh->rt_forw;
429021Ssam for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
439021Ssam /*
449021Ssam * We don't advance time on a routing entry for
4525505Skarels * a passive gateway, or any interface if we're
4625505Skarels * not acting as supplier.
479021Ssam */
489021Ssam if (!(rt->rt_state & RTS_PASSIVE) &&
4925505Skarels (supplier || !(rt->rt_state & RTS_INTERFACE)))
509021Ssam rt->rt_timer += TIMER_RATE;
519021Ssam if (rt->rt_timer >= GARBAGE_TIME) {
529021Ssam rt = rt->rt_back;
539021Ssam rtdelete(rt->rt_forw);
549021Ssam continue;
559021Ssam }
5636831Skarels if (rt->rt_timer >= EXPIRE_TIME &&
5736831Skarels rt->rt_metric < HOPCNT_INFINITY)
5830745Skarels rtchange(rt, &rt->rt_router, HOPCNT_INFINITY);
5936831Skarels rt->rt_state &= ~RTS_CHANGED;
609021Ssam }
619021Ssam }
629021Ssam if (doinghost) {
639021Ssam doinghost = 0;
649021Ssam base = nethash;
659021Ssam goto again;
669021Ssam }
6736831Skarels if (timetobroadcast) {
6836831Skarels toall(supply, 0, (struct interface *)NULL);
6936831Skarels lastbcast = now;
7036831Skarels lastfullupdate = now;
7136831Skarels needupdate = 0; /* cancel any pending dynamic update */
7236831Skarels nextbcast.tv_sec = 0;
7336831Skarels }
749021Ssam }
7516314Skarels
7616314Skarels /*
7716314Skarels * On hangup, let everyone know we're going away.
7816314Skarels */
hup()7916314Skarels hup()
8016314Skarels {
8116314Skarels register struct rthash *rh;
8216314Skarels register struct rt_entry *rt;
8316314Skarels struct rthash *base = hosthash;
8416314Skarels int doinghost = 1;
8516314Skarels
8616314Skarels if (supplier) {
8716314Skarels again:
8816314Skarels for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
8916314Skarels rt = rh->rt_forw;
9016314Skarels for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
9116314Skarels rt->rt_metric = HOPCNT_INFINITY;
9216314Skarels }
9316314Skarels if (doinghost) {
9416314Skarels doinghost = 0;
9516314Skarels base = nethash;
9616314Skarels goto again;
9716314Skarels }
9836831Skarels toall(supply, 0, (struct interface *)NULL);
9916314Skarels }
10016314Skarels exit(1);
10116314Skarels }
102