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