示例#1
0
void addrouteforif(struct interface *ifp)
{
    struct sockaddr_in net;
    struct sockaddr *dst;
    int state;
    struct rt_entry *rt;

    if (ifp->int_flags & IFF_POINTOPOINT)
        dst = &ifp->int_dstaddr;
    else {
        memset(&net, 0, sizeof (net));
        net.sin_family = AF_INET;
        net.sin_addr = inet_makeaddr(ifp->int_subnet, INADDR_ANY);
        dst = (struct sockaddr *)&net;
    }
    rt = rtfind(dst);
    if (rt &&
            (rt->rt_state & (RTS_INTERFACE | RTS_INTERNAL)) == RTS_INTERFACE)
        return;
    if (rt)
        rtdelete(rt);
    /*
     * If interface on subnetted network,
     * install route to network as well.
     * This is meant for external viewers.
     */
    if ((ifp->int_flags & (IFF_SUBNET|IFF_POINTOPOINT)) == IFF_SUBNET) {
        struct in_addr subnet;

        subnet = net.sin_addr;
        net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
        rt = rtfind(dst);
        if (rt == 0)
            rtadd(dst, &ifp->int_addr, ifp->int_metric,
                  ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) |
                   RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET));
        else if ((rt->rt_state & (RTS_INTERNAL|RTS_SUBNET)) ==
                 (RTS_INTERNAL|RTS_SUBNET) &&
                 ifp->int_metric < rt->rt_metric)
            rtchange(rt, &rt->rt_router, ifp->int_metric);
        net.sin_addr = subnet;
    }
    if (ifp->int_transitions++ > 0)
        syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
    state = ifp->int_flags &
            (IFF_INTERFACE | IFF_PASSIVE | IFF_REMOTE | IFF_SUBNET);
    if (ifp->int_flags & IFF_POINTOPOINT &&
            (ntohl(((struct sockaddr_in *)&ifp->int_dstaddr)->sin_addr.s_addr) &
             ifp->int_netmask) != ifp->int_net)
        state &= ~RTS_SUBNET;
    if (ifp->int_flags & IFF_LOOPBACK)
        state |= RTS_EXTERNAL;
    rtadd(dst, &ifp->int_addr, ifp->int_metric, state);
    if (ifp->int_flags & IFF_POINTOPOINT && foundloopback)
        add_ptopt_localrt(ifp);
}
示例#2
0
void timer(int signum)
{
	register struct rthash *rh;
	register struct rt_entry *rt;
	struct rthash *base = hosthash;
	int doinghost = 1, timetobroadcast;

	(void)signum;

	(void) gettimeofday(&now, (struct timezone *)NULL);
	faketime += TIMER_RATE;
	if (lookforinterfaces && (faketime % CHECK_INTERVAL) == 0)
		ifinit();
	timetobroadcast = supplier && (faketime % SUPPLY_INTERVAL) == 0;
again:
	for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
		rt = rh->rt_forw;
		for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
			/*
			 * We don't advance time on a routing entry for
			 * a passive gateway, or any interface if we're
			 * not acting as supplier.
			 */
			if (!(rt->rt_state & RTS_PASSIVE) &&
			    (supplier || !(rt->rt_state & RTS_INTERFACE)))
				rt->rt_timer += TIMER_RATE;
			if (rt->rt_timer >= GARBAGE_TIME) {
				rt = rt->rt_back;
				rtdelete(rt->rt_forw);
				continue;
			}
			if (rt->rt_timer >= EXPIRE_TIME &&
			    rt->rt_metric < HOPCNT_INFINITY)
				rtchange(rt, &rt->rt_router, HOPCNT_INFINITY);
			rt->rt_state &= ~RTS_CHANGED;
		}
	}
	if (doinghost) {
		doinghost = 0;
		base = nethash;
		goto again;
	}
	if (timetobroadcast) {
		toall(supply, 0, (struct interface *)NULL);
		lastbcast = now;
		lastfullupdate = now;
		needupdate = 0;		/* cancel any pending dynamic update */
		nextbcast.tv_sec = 0;
	}
#ifdef EMBED
	signal(signum, timer);
#endif
}