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