122000Sdist /* 222000Sdist * Copyright (c) 1983 Regents of the University of California. 3*33489Sbostic * All rights reserved. 4*33489Sbostic * 5*33489Sbostic * Redistribution and use in source and binary forms are permitted 6*33489Sbostic * provided that this notice is preserved and that due credit is given 7*33489Sbostic * to the University of California at Berkeley. The name of the University 8*33489Sbostic * may not be used to endorse or promote products derived from this 9*33489Sbostic * software without specific prior written permission. This software 10*33489Sbostic * is provided ``as is'' without express or implied warranty. 1122000Sdist */ 1222000Sdist 139021Ssam #ifndef lint 14*33489Sbostic static char sccsid[] = "@(#)timer.c 5.5 (Berkeley) 02/16/88"; 15*33489Sbostic #endif /* not lint */ 169021Ssam 179021Ssam /* 189021Ssam * Routing Table Management Daemon 199021Ssam */ 2010245Ssam #include "defs.h" 219021Ssam 229021Ssam int timeval = -TIMER_RATE; 239021Ssam 249021Ssam /* 259021Ssam * Timer routine. Performs routing information supply 269021Ssam * duties and manages timers on routing table entries. 279021Ssam */ 289021Ssam timer() 299021Ssam { 309021Ssam register struct rthash *rh; 319021Ssam register struct rt_entry *rt; 329021Ssam struct rthash *base = hosthash; 339021Ssam int doinghost = 1, timetobroadcast; 3424278Skarels extern int externalinterfaces; 359021Ssam 369021Ssam timeval += TIMER_RATE; 379021Ssam if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0) 389021Ssam ifinit(); 399021Ssam timetobroadcast = supplier && (timeval % SUPPLY_INTERVAL) == 0; 409021Ssam again: 419021Ssam for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { 429021Ssam rt = rh->rt_forw; 439021Ssam for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { 449021Ssam /* 459021Ssam * We don't advance time on a routing entry for 4625505Skarels * a passive gateway, or any interface if we're 4725505Skarels * not acting as supplier. 489021Ssam */ 499021Ssam if (!(rt->rt_state & RTS_PASSIVE) && 5025505Skarels (supplier || !(rt->rt_state & RTS_INTERFACE))) 519021Ssam rt->rt_timer += TIMER_RATE; 529021Ssam if (rt->rt_timer >= GARBAGE_TIME) { 539021Ssam rt = rt->rt_back; 549021Ssam rtdelete(rt->rt_forw); 559021Ssam continue; 569021Ssam } 5730745Skarels if (rt->rt_timer >= EXPIRE_TIME) 5830745Skarels rtchange(rt, &rt->rt_router, HOPCNT_INFINITY); 599021Ssam if (rt->rt_state & RTS_CHANGED) { 609021Ssam rt->rt_state &= ~RTS_CHANGED; 619021Ssam /* don't send extraneous packets */ 629021Ssam if (!supplier || timetobroadcast) 639021Ssam continue; 649021Ssam msg->rip_cmd = RIPCMD_RESPONSE; 6512726Ssam msg->rip_vers = RIPVERSION; 669021Ssam msg->rip_nets[0].rip_dst = rt->rt_dst; 6712726Ssam msg->rip_nets[0].rip_dst.sa_family = 6812726Ssam htons(msg->rip_nets[0].rip_dst.sa_family); 6912726Ssam msg->rip_nets[0].rip_metric = 7030745Skarels htonl(min(rt->rt_metric + rt->rt_ifmetric, 7130745Skarels HOPCNT_INFINITY)); 729021Ssam toall(sendmsg); 739021Ssam } 749021Ssam } 759021Ssam } 769021Ssam if (doinghost) { 779021Ssam doinghost = 0; 789021Ssam base = nethash; 799021Ssam goto again; 809021Ssam } 819021Ssam if (timetobroadcast) 829021Ssam toall(supply); 839021Ssam alarm(TIMER_RATE); 849021Ssam } 8516314Skarels 8616314Skarels /* 8716314Skarels * On hangup, let everyone know we're going away. 8816314Skarels */ 8916314Skarels hup() 9016314Skarels { 9116314Skarels register struct rthash *rh; 9216314Skarels register struct rt_entry *rt; 9316314Skarels struct rthash *base = hosthash; 9416314Skarels int doinghost = 1; 9516314Skarels 9616314Skarels if (supplier) { 9716314Skarels again: 9816314Skarels for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) { 9916314Skarels rt = rh->rt_forw; 10016314Skarels for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) 10116314Skarels rt->rt_metric = HOPCNT_INFINITY; 10216314Skarels } 10316314Skarels if (doinghost) { 10416314Skarels doinghost = 0; 10516314Skarels base = nethash; 10616314Skarels goto again; 10716314Skarels } 10816314Skarels toall(supply); 10916314Skarels } 11016314Skarels exit(1); 11116314Skarels } 112