コード例 #1
0
ファイル: ndbipinfo.c プロジェクト: npe9/harvey
/*
 *  look through a containing subset
 */
static Ndbtuple*
subnet(Ndb *db, uint8_t *net, Ndbtuple *f, int prefix)
{
	Ndbs s;
	Ndbtuple *t, *nt, *xt;
	char netstr[128];
	uint8_t mask[IPaddrlen];
	int masklen;

	t = nil;
	sprint(netstr, "%I", net);
	nt = ndbsearch(db, &s, "ip", netstr);
	while(nt != nil){
		xt = ndbfindattr(nt, nt, "ipnet");
		if(xt){
			xt = ndbfindattr(nt, nt, "ipmask");
			if(xt)
				parseipmask(mask, xt->val);
			else
				ipmove(mask, defmask(net));
			masklen = prefixlen(mask);
			if(masklen <= prefix){
				t = ndbconcatenate(t, filter(db, nt, f));
				nt = nil;
			}
		}
		ndbfree(nt);
		nt = ndbsnext(&s, "ip", netstr);
	}
	ndbsetmalloctag(t, getcallerpc(&db));
	return t;
}
コード例 #2
0
ファイル: rip.c プロジェクト: aahud/harvey
uint8_t*
v4defmask(uint8_t *ip)
{
	uint8_t v6ip[IPaddrlen];

	v4tov6(v6ip, ip);
	ip = defmask(v6ip);
	return ip+IPv4off;
}
コード例 #3
0
ファイル: parseip.c プロジェクト: npe9/harvey
/*
 *  parse a v4 ip address/mask in cidr format
 */
char*
v4parsecidr(uint8_t *addr, uint8_t *mask, char *from)
{
	int i;
	char *p;
	uint8_t *a;

	p = v4parseip(addr, from);

	if(*p == '/'){
		/* as a number of prefix bits */
		i = strtoul(p+1, &p, 0);
		if(i > 32)
			i = 32;
		memset(mask, 0, IPv4addrlen);
		for(a = mask; i >= 8; i -= 8)
			*a++ = 0xff;
		if(i > 0)
			*a = ~((1<<(8-i))-1);
	} else 
		memcpy(mask, defmask(addr), IPv4addrlen);
	return p;
}
コード例 #4
0
ファイル: ndbipinfo.c プロジェクト: npe9/harvey
/*
 *  fill in all the requested attributes for a system.
 *  if the system's entry doesn't have all required,
 *  walk through successively more inclusive networks
 *  for inherited attributes.
 */
Ndbtuple*
ndbipinfo(Ndb *db, char *attr, char *val, char **alist, int n)
{
	Ndbtuple *t, *nt, *f;
	Ndbs s;
	char *ipstr;
	uint8_t net[IPaddrlen], ip[IPaddrlen];
	int prefix, smallestprefix, force;
	int64_t r;

	/* just in case */
	fmtinstall('I', eipfmt);
	fmtinstall('M', eipfmt);

	/* get needed attributes */
	f = mkfilter(n, alist);

	/*
	 *  first look for a matching entry with an ip address
	 */
	t = nil;
	ipstr = ndbgetvalue(db, &s, attr, val, "ip", &nt);
	if(ipstr == nil){
		/* none found, make one up */
		if(strcmp(attr, "ip") != 0) {
			ndbfree(f);
			return nil;	
		}
		t = ndbnew("ip", val);
		t->line = t;
		t->entry = nil;
		r = parseip(net, val);
		if(r == -1)
			ndbfree(t);
	} else {
		/* found one */
		while(nt != nil){
			nt = ndbreorder(nt, s.t);
			t = ndbconcatenate(t, nt);
			nt = ndbsnext(&s, attr, val);
		}
		r = parseip(net, ipstr);
		free(ipstr);
	}
	if(r < 0){
		ndbfree(f);
		return nil;
	}
	ipmove(ip, net);
	t = filter(db, t, f);

	/*
	 *  now go through subnets to fill in any missing attributes
	 */
	if(isv4(net)){
		prefix = 127;
		smallestprefix = 100;
		force = 0;
	} else {
		/* in v6, the last 8 bytes have no structure (we hope) */
		prefix = 64;
		smallestprefix = 2;
		memset(net+8, 0, 8);
		force = 1;
	}

	/*
	 *  to find a containing network, keep turning off
	 *  the lower bit and look for a network with
	 *  that address and a shorter mask.  tedius but
	 *  complete, we may need to find a trick to speed this up.
	 */
	for(; prefix >= smallestprefix; prefix--){
		if(filtercomplete(f))
			break;
		if(!force && (net[prefix/8] & (1<<(7-(prefix%8)))) == 0)
			continue;
		force = 0;
		net[prefix/8] &= ~(1<<(7-(prefix%8)));
		t = ndbconcatenate(t, subnet(db, net, f, prefix));
	}

	/*
	 *  if there's an unfulfilled ipmask, make one up
	 */
	nt = ndbfindattr(f, f, "ipmask");
	if(nt && !(nt->ptr & Fignore)){
		char x[64];

		snprint(x, sizeof(x), "%M", defmask(ip));
		t = ndbconcatenate(t, ndbnew("ipmask", x));
	}

	ndbfree(f);
	ndbsetmalloctag(t, getcallerpc(&db));
	return t;
}
コード例 #5
0
ファイル: ipifc.c プロジェクト: qioixiy/harvey
/*
 *  add an address to an interface.
 */
char*
ipifcadd(Ipifc *ifc, char **argv, int argc, int tentative, Iplifc *lifcp)
{
	int i, type, mtu, sendnbrdisc = 0;
	uint8_t ip[IPaddrlen], mask[IPaddrlen], rem[IPaddrlen];
	uint8_t bcast[IPaddrlen], net[IPaddrlen];
	Iplifc *lifc, **l;
	Fs *f;

	if(ifc->medium == nil)
		return "ipifc not yet bound to device";

	f = ifc->conv->p->f;

	type = Rifc;
	memset(ip, 0, IPaddrlen);
	memset(mask, 0, IPaddrlen);
	memset(rem, 0, IPaddrlen);
	switch(argc){
	case 6:
		if(strcmp(argv[5], "proxy") == 0)
			type |= Rproxy;
		/* fall through */
	case 5:
		mtu = strtoul(argv[4], 0, 0);
		if(mtu >= ifc->medium->mintu && mtu <= ifc->medium->maxtu)
			ifc->maxtu = mtu;
		/* fall through */
	case 4:
		if (parseip(ip, argv[1]) == -1 || parseip(rem, argv[3]) == -1)
			return Ebadip;
		parseipmask(mask, argv[2]);
		maskip(rem, mask, net);
		break;
	case 3:
		if (parseip(ip, argv[1]) == -1)
			return Ebadip;
		parseipmask(mask, argv[2]);
		maskip(ip, mask, rem);
		maskip(rem, mask, net);
		break;
	case 2:
		if (parseip(ip, argv[1]) == -1)
			return Ebadip;
		memmove(mask, defmask(ip), IPaddrlen);
		maskip(ip, mask, rem);
		maskip(rem, mask, net);
		break;
	default:
		return Ebadarg;
	}
	if(isv4(ip))
		tentative = 0;
	wlock(ifc);

	/* ignore if this is already a local address for this ifc */
	for(lifc = ifc->lifc; lifc; lifc = lifc->next) {
		if(ipcmp(lifc->local, ip) == 0) {
			if(lifc->tentative != tentative)
				lifc->tentative = tentative;
			if(lifcp) {
				lifc->onlink = lifcp->onlink;
				lifc->autoflag = lifcp->autoflag;
				lifc->validlt = lifcp->validlt;
				lifc->preflt = lifcp->preflt;
				lifc->origint = lifcp->origint;
			}
			goto out;
		}
	}

	/* add the address to the list of logical ifc's for this ifc */
	lifc = smalloc(sizeof(Iplifc));
	ipmove(lifc->local, ip);
	ipmove(lifc->mask, mask);
	ipmove(lifc->remote, rem);
	ipmove(lifc->net, net);
	lifc->tentative = tentative;
	if(lifcp) {
		lifc->onlink = lifcp->onlink;
		lifc->autoflag = lifcp->autoflag;
		lifc->validlt = lifcp->validlt;
		lifc->preflt = lifcp->preflt;
		lifc->origint = lifcp->origint;
	} else {		/* default values */
		lifc->onlink = lifc->autoflag = 1;
		lifc->validlt = lifc->preflt = ~0L;
		lifc->origint = NOW / 1000;
	}
	lifc->next = nil;

	for(l = &ifc->lifc; *l; l = &(*l)->next)
		;
	*l = lifc;

	/* check for point-to-point interface */
	if(ipcmp(ip, v6loopback)) /* skip v6 loopback, it's a special address */
	if(ipcmp(mask, IPallbits) == 0)
		type |= Rptpt;

	/* add local routes */
	if(isv4(ip))
		v4addroute(f, tifc, rem+IPv4off, mask+IPv4off, rem+IPv4off, type);
	else
		v6addroute(f, tifc, rem, mask, rem, type);

	addselfcache(f, ifc, lifc, ip, Runi);

	if((type & (Rproxy|Rptpt)) == (Rproxy|Rptpt)){
		ipifcregisterproxy(f, ifc, rem);
		goto out;
	}

	if(isv4(ip) || ipcmp(ip, IPnoaddr) == 0) {
		/* add subnet directed broadcast address to the self cache */
		for(i = 0; i < IPaddrlen; i++)
			bcast[i] = (ip[i] & mask[i]) | ~mask[i];
		addselfcache(f, ifc, lifc, bcast, Rbcast);

		/* add subnet directed network address to the self cache */
		for(i = 0; i < IPaddrlen; i++)
			bcast[i] = (ip[i] & mask[i]) & mask[i];
		addselfcache(f, ifc, lifc, bcast, Rbcast);

		/* add network directed broadcast address to the self cache */
		memmove(mask, defmask(ip), IPaddrlen);
		for(i = 0; i < IPaddrlen; i++)
			bcast[i] = (ip[i] & mask[i]) | ~mask[i];
		addselfcache(f, ifc, lifc, bcast, Rbcast);

		/* add network directed network address to the self cache */
		memmove(mask, defmask(ip), IPaddrlen);
		for(i = 0; i < IPaddrlen; i++)
			bcast[i] = (ip[i] & mask[i]) & mask[i];
		addselfcache(f, ifc, lifc, bcast, Rbcast);

		addselfcache(f, ifc, lifc, IPv4bcast, Rbcast);
	}
	else {
		if(ipcmp(ip, v6loopback) == 0) {
			/* add node-local mcast address */
			addselfcache(f, ifc, lifc, v6allnodesN, Rmulti);

			/* add route for all node multicast */
			v6addroute(f, tifc, v6allnodesN, v6allnodesNmask,
				v6allnodesN, Rmulti);
		}

		/* add all nodes multicast address */
		addselfcache(f, ifc, lifc, v6allnodesL, Rmulti);

		/* add route for all nodes multicast */
		v6addroute(f, tifc, v6allnodesL, v6allnodesLmask, v6allnodesL,
			Rmulti);

		/* add solicited-node multicast address */
		ipv62smcast(bcast, ip);
		addselfcache(f, ifc, lifc, bcast, Rmulti);

		sendnbrdisc = 1;
	}

	/* register the address on this network for address resolution */
	if(isv4(ip) && ifc->medium->areg != nil)
		(*ifc->medium->areg)(ifc, ip);

out:
	wunlock(ifc);
	if(tentative && sendnbrdisc)
		icmpns(f, 0, SRC_UNSPEC, ip, TARG_MULTI, ifc->mac);
	return nil;
}