예제 #1
0
파일: cs.c 프로젝트: brho/akaros
/*
 *  lookup a telephone number
 */
static struct ndbtuple *telcolookup(struct network *np, char *host, char *serv,
                                    int nolookup)
{
	struct ndbtuple *t;
	struct ndbs s;

	werrstr("can't translate address");
	free(ndbgetvalue(db, &s, "sys", host, "telco", &t));
	if (t == 0)
		return ndbnew("telco", host);

	return reorder(t, s.t);
}
예제 #2
0
파일: ndbaux.c 프로젝트: keedon/harvey
/*
 *  parse a single tuple
 */
char*
_ndbparsetuple(char *cp, Ndbtuple **tp)
{
	char *p;
	int len;
	Ndbtuple *t;

	/* a '#' starts a comment lasting till new line */
	EATWHITE(cp);
	if(*cp == '#' || *cp == '\n')
		return 0;

	t = ndbnew(nil, nil);
	setmalloctag(t, getcallerpc());
	*tp = t;

	/* parse attribute */
	p = cp;
	while(*cp != '=' && !ISWHITE(*cp) && *cp != '\n')
		cp++;
	len = cp - p;
	if(len >= Ndbalen)
		len = Ndbalen-1;
	strncpy(t->attr, p, len);

	/* parse value */
	EATWHITE(cp);
	if(*cp == '='){
		cp++;
		if(*cp == '"'){
			p = ++cp;
			while(*cp != '\n' && *cp != '"')
				cp++;
			len = cp - p;
			if(*cp == '"')
				cp++;
		} else if(*cp == '#'){
			len = 0;
		} else {
			p = cp;
			while(!ISWHITE(*cp) && *cp != '\n')
				cp++;
			len = cp - p;
		}
		ndbsetval(t, p, len);
	}

	return cp;
}
예제 #3
0
파일: ndbgetipaddr.c 프로젝트: npe9/harvey
/* return list of ip addresses for a name */
Ndbtuple*
ndbgetipaddr(Ndb *db, char *val)
{
	char *attr, *p;
	Ndbtuple *it, *first, *last, *next;
	Ndbs s;

	/* already an IP address? */
	attr = ipattr(val);
	if(strcmp(attr, "ip") == 0){
		it = ndbnew("ip", val);
		ndbsetmalloctag(it, getcallerpc(&db));
		return it;
	}

	/* look it up */
	p = ndbgetvalue(db, &s, attr, val, "ip", &it);
	if(p == nil)
		return nil;
	free(p);

	/* remove the non-ip entries */
	first = last = nil;
	for(; it; it = next){
		next = it->entry;
		if(strcmp(it->attr, "ip") == 0){
			if(first == nil)
				first = it;
			else
				last->entry = it;
			it->entry = nil;
			it->line = first;
			last = it;
		} else {
			it->entry = nil;
			ndbfree(it);
		}
	}

	ndbsetmalloctag(first, getcallerpc(&db));
	return first;
}
예제 #4
0
static Ndbtuple*
ndbcopy(Ndb *db, Ndbtuple *from_t, Ndbs *from_s, Ndbs *to_s)
{
	Ndbtuple *first, *to_t, *last, *line;
	int newline;

	*to_s = *from_s;
	to_s->t = nil;
	to_s->db = db;

	newline = 1;
	last = nil;
	first = nil;
	line = nil;
	for(; from_t != nil; from_t = from_t->entry){
		to_t = ndbnew(from_t->attr, from_t->val);

		/* have s point to matching tuple */
		if(from_s->t == from_t)
			to_s->t = to_t;

		if(newline)
			line = to_t;
		else
			last->line = to_t;

		if(last != nil)
			last->entry = to_t;
		else {
			first = to_t;
			line = to_t;
		}
		to_t->entry = nil;
		to_t->line = line;
		last = to_t;
		newline = from_t->line != from_t->entry;
	}
	ndbsetmalloctag(first, getcallerpc(&db));
	return first;
}
예제 #5
0
파일: ndbipinfo.c 프로젝트: 00001/plan9port
/* make a filter to be used in filter */
static Ndbtuple*
mkfilter(int argc, char **argv)
{
	Ndbtuple *t, *first, *last;
	char *p;

	last = first = nil;
	while(argc-- > 0){
		t = ndbnew(0, 0);
		if(first)
			last->entry = t;
		else
			first = t;
		last = t;
		p = *argv++;
		if(*p == '@'){
			t->ptr |= Faddr;
			p++;
		}
		strncpy(t->attr, p, sizeof(t->attr)-1);
	}
	return first;
}
예제 #6
0
파일: ndbipinfo.c 프로젝트: npe9/harvey
/* make a filter to be used in filter */
static Ndbtuple*
mkfilter(int argc, char **argv)
{
	Ndbtuple *t, *first, *last;
	char *p;

	last = first = nil;
	while(argc-- > 0){
		t = ndbnew(0, 0);
		if(first)
			last->entry = t;
		else
			first = t;
		last = t;
		p = *argv++;
		if(*p == '@'){			/* @attr=val ? */
			t->ptr |= Faddr;	/* return resolved address(es) */
			p++;
		}
		strncpy(t->attr, p, sizeof(t->attr)-1);
	}
	ndbsetmalloctag(first, getcallerpc(&argc));
	return first;
}
예제 #7
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;
}
예제 #8
0
파일: cs.c 프로젝트: brho/akaros
/*
 *  lookup (and translate) an ip destination
 */
static struct ndbtuple *iplookup(struct network *np, char *host, char *serv,
                                 int nolookup)
{
	char *attr, *dnsname;
	struct ndbtuple *t, *nt;
	struct ndbs s;
	char ts[Maxservice];
	char dollar[Maxhost];
	uint8_t ip[IPaddrlen];
	uint8_t net[IPaddrlen];
	uint8_t tnet[IPaddrlen];
	struct ipifc *ifc;
	struct iplifc *lifc;

	/*
	 *  start with the service since it's the most likely to fail
	 *  and costs the least
	 */
	werrstr("can't translate address");
	if (serv == 0 || ipserv(np, serv, ts, sizeof(ts)) == 0) {
		werrstr("can't translate service");
		return 0;
	}

	/* for dial strings with no host */
	if (strcmp(host, "*") == 0)
		return ndbnew("ip", "*");

	/*
	 *  hack till we go v6 :: = 0.0.0.0
	 */
	if (strcmp("::", host) == 0)
		return ndbnew("ip", "*");

	/*
	 *  '$' means the rest of the name is an attribute that we
	 *  need to search for
	 */
	if (*host == '$') {
		if (ipattrlookup(db, ipaddr, host + 1, dollar, sizeof(dollar)))
			host = dollar;
	}

	/*
	 *  turn '[ip address]' into just 'ip address'
	 */
	if (*host == '[' && host[strlen(host) - 1] == ']') {
		host++;
		host[strlen(host) - 1] = 0;
	}

	/*
	 *  just accept addresses
	 */
	attr = ipattr(host);
	if (strcmp(attr, "ip") == 0)
		return ndbnew("ip", host);

	/*
	 *  give the domain name server the first opportunity to
	 *  resolve domain names.  if that fails try the database.
	 */
	t = 0;
	werrstr("can't translate address");
	if (strcmp(attr, "dom") == 0)
		t = dnsiplookup(host, &s);
	if (t == 0)
		free(ndbgetvalue(db, &s, attr, host, "ip", &t));
	if (t == 0) {
		dnsname = ndbgetvalue(db, &s, attr, host, "dom", NULL);
		if (dnsname) {
			t = dnsiplookup(dnsname, &s);
			free(dnsname);
		}
	}
	if (t == 0)
		t = dnsiplookup(host, &s);
	if (t == 0)
		return 0;

	/*
	 *  reorder the tuple to have the matched line first and
	 *  save that in the request structure.
	 */
	t = reorder(t, s.t);

	/*
	 * reorder according to our interfaces
	 */
	spinlock_lock(&ipifclock);
	for (ifc = ipifcs; ifc != NULL; ifc = ifc->next) {
		for (lifc = ifc->lifc; lifc != NULL; lifc = lifc->next) {
			maskip(lifc->ip, lifc->mask, net);
			for (nt = t; nt; nt = nt->entry) {
				if (strcmp(nt->attr, "ip") != 0)
					continue;
				parseip(ip, nt->val);
				maskip(ip, lifc->mask, tnet);
				if (memcmp(net, tnet, IPaddrlen) == 0) {
					t = reorder(t, nt);
					spinlock_unlock(&ipifclock);
					return t;
				}
			}
		}
	}
	spinlock_unlock(&ipifclock);

	return t;
}