Exemple #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);
}
Exemple #2
0
void add_ptopt_localrt(struct interface *ifp)
{
    struct rt_entry *rt;
    struct sockaddr *dst;
    struct sockaddr_in net;
    int state;

    state = RTS_INTERFACE | RTS_PASSIVE;

    /* look for route to logical network */
    memset(&net, 0, sizeof (net));
    net.sin_family = AF_INET;
    net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
    dst = (struct sockaddr *)&net;
    rt = rtfind(dst);
    if (rt && rt->rt_state & RTS_INTERNAL)
        state |= RTS_SUBNET;

    dst = &ifp->int_addr;
    if ((rt = rtfind(dst))!=NULL) {
        if (rt && rt->rt_state & RTS_INTERFACE)
            return;
        rtdelete(rt);
    }
    rtadd(dst, &loopaddr, 1, state);
}
Exemple #3
0
/*------------------------------------------------------------------------
 *  hgjoin  -  handle application request to join a host group
 *------------------------------------------------------------------------
 */
int
hgjoin(unsigned ifnum, IPaddr ipa, Bool islocal)
{
	struct	hg	*phg;
	int		i;

	if (!IP_CLASSD(ipa))
		return SYSERR;
	/* restrict multicast in multi-homed host to primary interface */
	if (ifnum != NI_PRIMARY)
		return SYSERR;
	wait(HostGroup.hi_mutex);
	if (phg = hglookup(ifnum, ipa)) {
		phg->hg_refs++;
		signal(HostGroup.hi_mutex);
		return OK;	/* already in it */
	}
	signal(HostGroup.hi_mutex);
	/* add to host group and routing tables */
	if (hgadd(ifnum, ipa, islocal) == SYSERR)
		return SYSERR;
	rtadd(ipa, ip_maskall, ipa, 0, NI_LOCAL, RT_INF);
	/*
	 * advertise membership to multicast router(s); don't advertise
	 * 224.0.0.1 (all multicast hosts) membership.
	 */
	if (ipa != ig_allhosts)
		for (i=0; i < IG_NSEND; ++i) {
			igmp(IGT_HREPORT, ifnum, ipa);
			sleep10(IG_DELAY);
		}
	return OK;
}
/*------------------------------------------------------------------------
 *  setmask - set the net mask for an interface
 *------------------------------------------------------------------------
 */
int
setmask(unsigned ifn, IPaddr mask)
{
	IPaddr	defmask;

	if (nif[ifn].ni_svalid) {
		/* one set already-- fix things */

		rtdel(nif[ifn].ni_subnet, nif[ifn].ni_mask);
		rtdel(nif[ifn].ni_brc, ip_maskall);
		rtdel(nif[ifn].ni_subnet, ip_maskall);
	}
	nif[ifn].ni_mask = mask;
	nif[ifn].ni_svalid = TRUE;
	defmask = netmask(nif[ifn].ni_ip);

	nif[ifn].ni_subnet = nif[ifn].ni_ip & nif[ifn].ni_mask; 
	if (bsdbrc)
		nif[ifn].ni_brc = nif[ifn].ni_subnet;
	else
		nif[ifn].ni_brc = nif[ifn].ni_subnet |
				~nif[ifn].ni_mask;
	/* set network (not subnet) broadcast */
	nif[ifn].ni_nbrc = nif[ifn].ni_ip | ~defmask;

	/* install routes */
	/* net */
	rtadd(nif[ifn].ni_subnet, nif[ifn].ni_mask, nif[ifn].ni_ip,
		0, ifn, RT_INF);
	if (bsdbrc) {
		IPaddr	aobrc;		/* all 1's broadcast */

		aobrc = nif[ifn].ni_subnet | ~nif[ifn].ni_mask;
		rtadd(aobrc, ip_maskall, nif[ifn].ni_ip, 0,
			NI_LOCAL, RT_INF);
	} else	/* broadcast (all 1's) */
		rtadd(nif[ifn].ni_brc, ip_maskall, nif[ifn].ni_ip, 0,
			NI_LOCAL, RT_INF);
	/* broadcast (all 0's) */
	rtadd(nif[ifn].ni_subnet, ip_maskall, nif[ifn].ni_ip, 0,
		NI_LOCAL, RT_INF);
	return OK;
}
/*------------------------------------------------------------------------
 *  rarpsend  -  broadcast a RARP packet to obtain my IP address
 *------------------------------------------------------------------------
 */
int
rarpsend(int ifn)
{
	STATWORD		ps;
	struct	netif		*pni = &nif[ifn];
	struct	ep		*pep;
	int			i, mypid, resp;
	IPaddr			junk = 0; /* arg to mkarp; never used */

	mypid = getpid();
	for (i=0; i<ARP_MAXRETRY; ++i) {
		pep = mkarp(ifn, EPT_RARP, RA_REQUEST, junk, junk);
		if ((int)pep == SYSERR)
			break;
		disable(ps);
		rarppid = mypid;
		restore(ps);
		recvclr();
		write(pni->ni_dev, pep, EP_MINLEN);
		/* ARP_RESEND is in secs, recvtim uses 1/10's of secs	*/
		resp = recvtim(10*ARP_RESEND<<i);
		if (resp != TIMEOUT) {
			/* host route */
			rtadd(pni->ni_ip, ip_maskall, pni->ni_ip, 0,
				NI_LOCAL, RT_INF);

			/* non-subnetted route */
			rtadd(pni->ni_net, ip_maskall, pni->ni_ip, 0,
				NI_LOCAL, RT_INF);

			return OK;
		}
	}
	panic("No response to RARP");
	return SYSERR;
}
Exemple #6
0
void
addrouteforif(struct interface *ifp)
{
	struct sockaddr_ipx net;
	struct sockaddr *dst;
	struct rt_entry *rt;

	if (ifp->int_flags & IFF_POINTOPOINT) {
		int (*match)();
		struct interface *ifp2 = ifnet;
		
		dst = &ifp->int_dstaddr;

		/* Search for interfaces with the same net */
		ifp->int_sq.n = ifp->int_sq.p = &(ifp->int_sq);
		match = afswitch[dst->sa_family].af_netmatch;
		if (match)
		for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) {
			if ((ifp->int_flags & IFF_POINTOPOINT) == 0)
				continue;
			if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) {
				insque(&ifp2->int_sq,&ifp->int_sq);
				break;
			}
		}
	} else {
		bzero(&net, sizeof(net));
		net.sipx_family = AF_IPX;
		net.sipx_len = sizeof (net);
		net.sipx_addr.x_net = satoipx_addr(ifp->int_broadaddr).x_net;
		dst = (struct sockaddr *)&net;
	}
	rt = rtlookup(dst);
	if (rt)
		rtdelete(rt);
	if (tracing)
		fprintf(stderr, "Adding route to interface %s\n", ifp->int_name);
	if (ifp->int_transitions++ > 0)
		syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
	rtadd(dst, &ifp->int_addr, ifp->int_metric, 0,
		ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE));
}
Exemple #7
0
static void
addrouteforif(struct interface *ifp)
{
	struct rt_entry *rt;
	struct in6_addr *dst;

	if (ifp->int_flags & RIP6_IFF_POINTOPOINT)
		dst = &ifp->int_dstaddr;
	else
		dst = &ifp->int_addr;

	rt = rtlookup(dst, ifp->int_prefix_length);

	if (rt != NULL) {
		if (rt->rt_state & RTS_INTERFACE)
			return;
		rtdelete(rt);
	}
	rtadd(dst, &ifp->int_addr, ifp->int_prefix_length, ifp->int_metric, 0,
	    _B_TRUE, ifp);
}
Exemple #8
0
void gwkludge(void)
{
    struct sockaddr_in dst, gate;
    FILE *fp;
    char *type, *dname, *gname, *qual, buf[BUFSIZ];
    struct interface *ifp;
    int metric, n;
    struct rt_entry route;

    fp = fopen(_PATH_GATEWAYS, "r");
    if (fp == NULL)
        return;
    qual = buf;
    dname = buf + 64;
    gname = buf + ((BUFSIZ - 64) / 3);
    type = buf + (((BUFSIZ - 64) * 2) / 3);
    memset(&dst, 0, sizeof (dst));
    memset(&gate, 0, sizeof (gate));
    memset(&route, 0, sizeof(route));
    /* format: {net | host} XX gateway XX metric DD [passive | external]\n */
#define	readentry(fp) \
	fscanf((fp), "%s %s gateway %s metric %d %s\n", \
		type, dname, gname, &metric, qual)
    for (;;) {
        if ((n = readentry(fp)) == EOF)
            break;
        /*
         *	Lusertrap. Vendors should ship the line
         *
         *	CONFIGME CONFIGME gateway CONFIGME metric 1
         *
         */
        if (strcmp(type,"CONFIGME")==0)
        {
            fprintf(stderr,"Not starting gated. Please configure first.\n");
            exit(1);
        }
        if (!getnetorhostname(type, dname, &dst))
            continue;
        if (!gethostnameornumber(gname, &gate))
            continue;
        if (metric == 0)			/* XXX */
            metric = 1;
        if (strcmp(qual, "passive") == 0) {
            /*
             * Passive entries aren't placed in our tables,
             * only the kernel's, so we don't copy all of the
             * external routing information within a net.
             * Internal machines should use the default
             * route to a suitable gateway (like us).
             */
            route.rt_dst = *(struct sockaddr *) &dst;
            route.rt_router = *(struct sockaddr *) &gate;
            route.rt_flags = RTF_UP;
            if (strcmp(type, "host") == 0)
                route.rt_flags |= RTF_HOST;
            if (metric)
                route.rt_flags |= RTF_GATEWAY;
            (void) rtioctl(ADD, &route.rt_rt);
            continue;
        }
        if (strcmp(qual, "external") == 0) {
            /*
             * Entries marked external are handled
             * by other means, e.g. EGP,
             * and are placed in our tables only
             * to prevent overriding them
             * with something else.
             */
            rtadd((struct sockaddr *)&dst,
                  (struct sockaddr *)&gate, metric,
                  RTS_EXTERNAL|RTS_PASSIVE);
            continue;
        }
        /* assume no duplicate entries */
        externalinterfaces++;
        ifp = (struct interface *)malloc(sizeof (*ifp));
        memset(ifp, 0, sizeof (*ifp));
        ifp->int_flags = IFF_REMOTE;
        /* can't identify broadcast capability */
        ifp->int_net = inet_netof_subnet(dst.sin_addr);
        if (strcmp(type, "host") == 0) {
            ifp->int_flags |= IFF_POINTOPOINT;
            ifp->int_dstaddr = *((struct sockaddr *)&dst);
        }
        ifp->int_addr = *((struct sockaddr *)&gate);
        ifp->int_metric = metric;
        ifp->int_next = ifnet;
        ifnet = ifp;
        addrouteforif(ifp);
    }
    fclose(fp);
}
Exemple #9
0
/*------------------------------------------------------------------------
 *  netstart - initialize net
 *------------------------------------------------------------------------
 */
int
netstart(int userpid)
{
	char str[128];
	char *str1 = "sleeping 30 secs to get routes...";
	char *str2 = "\ndone.\n";
	unsigned long	now;
	int		i;

	if (clkruns == FALSE)
		panic("net: no clock");

	/* initialize ports */

	for (i=0 ; i<UPPS ; i++)
		upqs[i].up_valid = FALSE;
	udpmutex = screate(1);

	arpinit();
	ipfinit();	/* init the IP frag queue */

	/* these need a command to set/clear them. FIX ME!!! */
	gateway = 1;
	IpForwarding = 1;	/* == 2 if not a gateway */
	IfNumber = Net.nif - 1;

	/* bsdbrc = 1; */ /* uncomment to use 0's broadcast */

	if (gateway) {
		IPaddr	gw;
		initgate();
		gw = dot2ip(DEFRTR);
		rtadd(RT_DEFAULT, RT_DEFAULT, gw, RTM_INF-1, 1, RT_INF);
	} else
		inithost();
	rtadd(RT_LOOPBACK, ip_maskall, RT_LOOPBACK, 0, NI_LOCAL, RT_INF);

	for (i=0; i<Net.nif; ++i) {
		nif[i].ni_ipinq = newq(NI_INQSZ, QF_NOWAIT);
		nif[i].ni_hwtype = AR_HARDWARE;		/* for ARP */
		/* no OTHER's for now */
		if (i < 2)
			nif[i].ni_state = NIS_UP;
	}

	/*
	 * wait()'s synchronize to insure initialization is done
	 * before proceeding.
	 */

	resume(create(slowtimer, STSTK, STPRI, STNAM, STARGC));
	wait(Net.sema);
	resume(create(ipproc, IPSTK, IPPRI, IPNAM, IPARGC));
	wait(Net.sema);
	resume(create(tcptimer, TMSTK, TMPRI, TMNAM, TMARGC));
	wait(Net.sema);
	resume(create(tcpinp, TCPISTK, TCPIPRI, TCPINAM, TCPIARGC));
	wait(Net.sema);
	resume(create(tcpout, TCPOSTK, TCPOPRI, TCPONAM, TCPOARGC));
	wait(Net.sema);


	if (!gateway) {
		write(CONSOLE, str1, strlen(str1));
		sleep(30);
		write(CONSOLE, str2, strlen(str2));
	}

	/* get addrs & names */
	for (i=0; i<Net.nif; ++i) {
		IPaddr junk;
		char junk2[64];

		if (i == NI_LOCAL)
			continue;
		if (nif[i].ni_state != NIS_UP)
			continue;
		junk = getiaddr(i);
		sprintf(str,
		"if%d IP %s ha %02x:%02x:%02x:%02x:%02x:%02x ",
			i,
			ip2dot(junk2, nif[i].ni_ip),
			nif[i].ni_hwa.ha_addr[0]&0xff,
			nif[i].ni_hwa.ha_addr[1]&0xff,
			nif[i].ni_hwa.ha_addr[2]&0xff,
			nif[i].ni_hwa.ha_addr[3]&0xff,
			nif[i].ni_hwa.ha_addr[4]&0xff,
			nif[i].ni_hwa.ha_addr[5]&0xff);
		write(CONSOLE, str, strlen(str));
		sprintf(str, "br %02x:%02x:%02x:%02x:%02x:%02x\n",
			nif[i].ni_hwb.ha_addr[0]&0xff,
			nif[i].ni_hwb.ha_addr[1]&0xff,
			nif[i].ni_hwb.ha_addr[2]&0xff,
			nif[i].ni_hwb.ha_addr[3]&0xff,
			nif[i].ni_hwb.ha_addr[4]&0xff,
			nif[i].ni_hwb.ha_addr[5]&0xff);
		write(CONSOLE, str, strlen(str));

		icmp(ICT_MASKRQ, 0, nif[i].ni_brc, 0, 0);
		recvtim(30);	/* wait for an answer */
		getiname(i, junk2);
	}
	getutim(&now);

#ifdef	MULTICAST
	hginit();
#endif	/* MULTICAST */
#ifdef RIP
	resume(create(rip, RIPISTK, RIPPRI, RIPNAM, RIPARGC));
#endif	/* RIP */
#ifdef	OSPF
	resume(create(ospf, OSPFSTK, OSPFPRI, OSPFNAM, 0));
#endif /* OSPF */
#ifdef	SNMP
	resume(create(snmpd, SNMPSTK, SNMPPRI, SNMPDNAM, 0));
#endif	/* SNMP */

	rwho();
	resume(create(FINGERD, FNGDSTK, FNGDPRI, FNGDNAM, FNGDARGC));
	resume(create(ECHOD, ECHOSTK, ECHOPRI, ECHODNAM, 0));
	resume(create(udpecho, 1000, 50, "udpecho", 0));

	resume(userpid);
}