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