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