1 /* 2 * Copyright (c) 1985 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This file includes significant work done at Cornell University by 6 * Bill Nesheim. That work included by permission. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)timer.c 5.6 (Berkeley) 06/01/90"; 13 #endif /* not lint */ 14 15 /* 16 * Routing Table Management Daemon 17 */ 18 #include "defs.h" 19 20 int timeval = -TIMER_RATE; 21 22 /* 23 * Timer routine. Performs routing information supply 24 * duties and manages timers on routing table entries. 25 */ 26 timer() 27 { 28 register struct rthash *rh; 29 register struct rt_entry *rt; 30 struct rthash *base = hosthash; 31 int doinghost = 1, timetobroadcast; 32 33 timeval += TIMER_RATE; 34 if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0) 35 ifinit(); 36 timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0; 37 again: 38 for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { 39 rt = rh->rt_forw; 40 for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { 41 /* 42 * We don't advance time on a routing entry for 43 * a passive gateway or that for our only interface. 44 * The latter is excused because we don't act as 45 * a routing information supplier and hence would 46 * time it out. This is fair as if it's down 47 * we're cut off from the world anyway and it's 48 * not likely we'll grow any new hardware in 49 * the mean time. 50 */ 51 if (!(rt->rt_state & RTS_PASSIVE) && 52 (supplier || !(rt->rt_state & RTS_INTERFACE))) 53 rt->rt_timer += TIMER_RATE; 54 if (rt->rt_timer >= EXPIRE_TIME) 55 rt->rt_metric = HOPCNT_INFINITY; 56 if (rt->rt_timer >= GARBAGE_TIME) { 57 rt = rt->rt_back; 58 /* Perhaps we should send a REQUEST for this route? */ 59 rtdelete(rt->rt_forw); 60 continue; 61 } 62 if (rt->rt_state & RTS_CHANGED) { 63 rt->rt_state &= ~RTS_CHANGED; 64 /* don't send extraneous packets */ 65 if (!supplier || timetobroadcast) 66 continue; 67 msg->rip_cmd = htons(RIPCMD_RESPONSE); 68 msg->rip_nets[0].rip_dst = 69 (satons_addr(rt->rt_dst)).x_net; 70 msg->rip_nets[0].rip_metric = 71 htons(min(rt->rt_metric+1, HOPCNT_INFINITY)); 72 toall(sendmsg); 73 } 74 } 75 } 76 if (doinghost) { 77 doinghost = 0; 78 base = nethash; 79 goto again; 80 } 81 if (timetobroadcast) 82 toall(supply); 83 alarm(TIMER_RATE); 84 } 85 86 /* 87 * On hangup, let everyone know we're going away. 88 */ 89 hup() 90 { 91 register struct rthash *rh; 92 register struct rt_entry *rt; 93 struct rthash *base = hosthash; 94 int doinghost = 1; 95 96 if (supplier) { 97 again: 98 for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { 99 rt = rh->rt_forw; 100 for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) 101 rt->rt_metric = HOPCNT_INFINITY; 102 } 103 if (doinghost) { 104 doinghost = 0; 105 base = nethash; 106 goto again; 107 } 108 toall(supply); 109 } 110 exit(1); 111 } 112