Esempio n. 1
0
/*
 *  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;
}
Esempio n. 2
0
File: cs.c Progetto: brho/akaros
/*
 *  generic query lookup.  The query is of one of the following
 *  forms:
 *
 *  attr1=val1 attr2=val2 attr3=val3 ...
 *
 *  returns the matching tuple
 *
 *  ipinfo attr=val attr1 attr2 attr3 ...
 *
 *  is like ipinfo and returns the attr{1-n}
 *  associated with the ip address.
 */
static char *genquery(struct mfile *mf, char *query)
{
	int i, n;
	char *p;
	char *attr[Maxattr];
	char *val[Maxattr];
	struct ndbtuple *t;
	struct ndbs s;

	n = getfields(query, attr, COUNT_OF(attr), 1, " ");
	if (n == 0)
		return "bad query";

	if (strcmp(attr[0], "ipinfo") == 0)
		return ipinfoquery(mf, attr, n);

	/* parse pairs */
	for (i = 0; i < n; i++) {
		p = strchr(attr[i], '=');
		if (p == 0)
			return "bad query";
		*p++ = 0;
		val[i] = p;
	}

	/* give dns a chance */
	if ((strcmp(attr[0], "dom") == 0 || strcmp(attr[0], "ip") == 0)
	    && val[0]) {
		t = dnsiplookup(val[0], &s);
		if (t) {
			if (qmatch(t, attr, val, n)) {
				qreply(mf, t);
				ndbfree(t);
				return 0;
			}
			ndbfree(t);
		}
	}

	/* first pair is always the key.  It can't be a '*' */
	t = ndbsearch(db, &s, attr[0], val[0]);

	/* search is the and of all the pairs */
	while (t) {
		if (qmatch(t, attr, val, n)) {
			qreply(mf, t);
			ndbfree(t);
			return 0;
		}

		ndbfree(t);
		t = ndbsnext(&s, attr[0], val[0]);
	}

	return "no match";
}
Esempio n. 3
0
File: query.c Progetto: aahud/harvey
void
search(Ndb *db, char *attr, char *val, char *rattr)
{
	char *p;
	Ndbs s;
	Ndbtuple *t, *nt;

	/* first entry with a matching rattr */
	if(rattr && !all){
		p = ndbgetvalue(db, &s, attr, val, rattr, &t);
		if (multiple)
			prmatch(t, rattr);
		else if(p)
			Bprint(&bout, "%s\n", p);
		ndbfree(t);
		free(p);
		return;
	}

	/* all entries with matching rattrs */
	if(rattr) {
		for(t = ndbsearch(db, &s, attr, val); t != nil;
		    t = ndbsnext(&s, attr, val)){
			prmatch(t, rattr);
			ndbfree(t);
		}
		return;
	}

	/* all entries */
	for(t = ndbsearch(db, &s, attr, val); t; t = ndbsnext(&s, attr, val)){
		for(nt = t; nt; nt = nt->entry)
			Bprint(&bout, "%s=%s ", nt->attr, nt->val);
		Bprint(&bout, "\n");
		ndbfree(t);
	}
}
Esempio n. 4
0
/*
 *  search for a tuple that has the given 'attr=val' and also 'rattr=x'.
 *  copy 'x' into 'buf' and return the whole tuple.
 *
 *  return 0 if not found.
 */
char*
ndbgetvalue(struct ndb *db, struct ndbs *s, char *attr, char *val, char *rattr,
	    struct ndbtuple **pp)
{
	struct ndbtuple *t, *nt;
	char *rv;
	struct ndbs temps;

	if(s == NULL)
		s = &temps;
	if(pp)
		*pp = NULL;
	t = ndbsearch(db, s, attr, val);
	while(t){
		/* first look on same line (closer binding) */
		nt = s->t;
		for(;;){
			if(strcmp(rattr, nt->attr) == 0){
				rv = strdup(nt->val);
				if(pp != NULL)
					*pp = t;
				else
					ndbfree(t);
				return rv;
			}
			nt = nt->line;
			if(nt == s->t)
				break;
		}
		/* search whole tuple */
		for(nt = t; nt; nt = nt->entry){
			if(strcmp(rattr, nt->attr) == 0){
				rv = strdup(nt->val);
				if(pp != NULL)
					*pp = t;
				else
					ndbfree(t);
				return rv;
			}
		}
		ndbfree(t);
		t = ndbsnext(s, attr, val);
	}
	return NULL;
}
Esempio n. 5
0
/*
 *  return the ip addresses for a type of server for system ip
 */
int
lookupserver(char *attr, uchar ipaddrs[2][IPaddrlen], Ipinfo *iip)
{
	Ndbtuple *t, *nt;
	Ndbs s;
	char ip[32];
	char name[Ndbvlen];
	char name1[Ndbvlen];
	int i;

	name[0] = name1[0] = 0;

	snprint(ip, sizeof(ip), "%I", iip->ipaddr);
	t = ndbsearch(db, &s, "ip", ip);
	while(t){
		for(nt = t; nt; nt = nt->entry){
			if(strcmp(attr, nt->attr) == 0){
				if(*name == 0)
					strcpy(name, nt->val);
				else {
					strcpy(name1, nt->val);
					break;
				}
			}
		}
		if(name[0])
			break;
		t = ndbsnext(&s, "ip", ip);
	}

	if(name[0] == 0)
		recursesubnet(db, iip->ipaddr, classmask[CLASS(iip->ipaddr)], attr, name, name1);

	i = 0;
	if(name[0] && getipaddr(db, name, *ipaddrs, iip) == 1){
		ipaddrs++;
		i++;
	}
	if(name1[0] && getipaddr(db, name1, *ipaddrs, iip) == 1)
		i++;
	return i;
}
Esempio n. 6
0
int
dbctlr(char* name, Vga* vga)
{
	Ndb *db;
	Ndbs s;
	Ndbtuple *tuple;
	Ndbtuple *pcituple;

	db = dbopen(name);

	/*
	 * Search vgadb for a matching BIOS string or PCI id.
	 * If we have both, the BIOS string wins.
	 */
	pcituple = nil;
	for(tuple = ndbsearch(db, &s, "ctlr", ""); tuple; tuple = ndbsnext(&s, "ctlr", "")){
		if(!pcituple && dbpci(vga, tuple))
			pcituple = tuple;
		if(dbbios(vga, tuple)){
			save(vga, tuple);
			if(pcituple && pcituple != tuple)
				ndbfree(pcituple);
			ndbfree(tuple);
			ndbclose(db);
			return 1;
		}
		if(tuple != pcituple)
			ndbfree(tuple);
	}

	if(pcituple){
		save(vga, pcituple);
		ndbfree(pcituple);
	}
	ndbclose(db);
	if(pcituple)
		return 1;
	return 0;
}
Esempio n. 7
0
/*
 *  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;
}
Esempio n. 8
0
/*
 *  find out everything we can about a system from what has been
 *  specified.
 */
int
ipinfo(Ndb *db, char *etherin, char *ipin, char *name, Ipinfo *iip)
{
	Ndbtuple *t;
	Ndbs s;
	char ether[Ndbvlen];
	char ip[Ndbvlen];
	char fsname[Ndbvlen];
	char gwname[Ndbvlen];
	char auname[Ndbvlen];

	memset(iip, 0, sizeof(Ipinfo));
	fsname[0] = 0;
	gwname[0] = 0;
	auname[0] = 0;

	/*
	 *  look for a matching entry
	 */
	t = 0;
	if(etherin)
		t = ndbgetval(db, &s, "ether", etherin, "ip", ip);
	if(t == 0 && ipin)
		t = ndbsearch(db, &s, "ip", ipin);
	if(t == 0 && name)
		t = ndbgetval(db, &s, ipattr(name), name, "ip", ip);
	if(t){
		/*
		 *  copy in addresses and name
		 */
		if(lookval(t, s.t, "ip", ip))
			parseip(iip->ipaddr, ip);
		if(lookval(t, s.t, "ether", ether))
			parseether(iip->etheraddr, ether);
		lookval(t, s.t, "dom", iip->domain);

		/*
		 *  Look for bootfile, fs, and gateway.
		 *  If necessary, search through all entries for
		 *  this ip address.
		 */
		while(t){
			if(iip->bootf[0] == 0)
				lookval(t, s.t, "bootf", iip->bootf);
			if(fsname[0] == 0)
				lookval(t, s.t, "fs", fsname);
			if(gwname[0] == 0)
				lookval(t, s.t, "ipgw", gwname);
			if(auname[0] == 0)
				lookval(t, s.t, "auth", auname);
			ndbfree(t);
			if(iip->bootf[0] && fsname[0] && gwname[0] && auname[0])
				break;
			t = ndbsnext(&s, "ether", ether);
		}
	} else if(ipin) {
		/*
		 *  copy in addresses (all we know)
		 */
		parseip(iip->ipaddr, ipin);
		if(etherin)
			parseether(iip->etheraddr, etherin);
	} else
		return -1;

	/*
	 *  Look up the client's network and find a subnet mask for it.
	 *  Fill in from the subnet (or net) entry anything we can't figure
	 *  out from the client record.
	 */
	recursesubnet(db, classmask[CLASS(iip->ipaddr)], iip, fsname, gwname, auname);

	/* lookup fs's and gw's ip addresses */
	
	if(fsname[0])
		lookupip(db, fsname, iip->fsip, iip);
	if(gwname[0])
		lookupip(db, gwname, iip->gwip, iip);
	if(auname[0])
		lookupip(db, auname, iip->auip, iip);
	return 0;
}
Esempio n. 9
0
Mode*
dbmode(char* name, char* type, char* size)
{
	Ndb *db;
	Ndbs s;
	Ndbtuple *t, *tuple;
	Mode *mode;
	char attr[Namelen+1];
	ulong videobw;

	db = dbopen(name);
	mode = alloc(sizeof(Mode));
	strcpy(attr, type);

	videobw = 0;
	/*
	 * Look for the attr=size entry.
	 */
	if(dbmonitor(db, mode, attr, size)){
		strcpy(mode->type, type);
		strcpy(mode->size, size);
		ndbclose(db);
		return mode;
	}

	if(mode->videobw && videobw == 0)	/* we at least found that; save it away */
		videobw = mode->videobw;

	/*
	 * Not found. Look for an attr="" entry and then
	 * for an alias=attr within.
	 */
buggery:
	for(tuple = ndbsearch(db, &s, attr, ""); tuple; tuple = ndbsnext(&s, attr, "")){
		for(t = tuple->entry; t; t = t->entry){
			if(strcmp(t->attr, "alias"))
				continue;
			strcpy(attr, t->val);
			if(dbmonitor(db, mode, attr, size)){
				strcpy(mode->type, type);
				strcpy(mode->size, size);
				ndbfree(tuple);
				ndbclose(db);
				if(videobw)
					mode->videobw = videobw;
				return mode;
			}

			/*
			 * Found an alias but no match for size,
			 * restart looking for attr="" with the
			 * new attr.
			 */
			ndbfree(tuple);
			goto buggery;
		}
		ndbfree(tuple);
	}

	free(mode);
	ndbclose(db);
	return 0;
}
Esempio n. 10
0
/*
 *  lookup info about a client in the database.  Find an address on the
 *  same net as riip.
 */
int
lookup(Bootp *bp, Info *iip, Info *riip)
{
	Ndbtuple *t, *nt;
	Ndbs s;
	char *hwattr;
	char *hwval, hwbuf[33];
	uchar ciaddr[IPaddrlen];

	if(opendb() == nil){
		warning(1, "can't open db");
		return -1;
	}

	memset(iip, 0, sizeof(*iip));

	/* client knows its address? */
	v4tov6(ciaddr, bp->ciaddr);
	if(validip(ciaddr)){
		if(lookupip(ciaddr, iip, 0) < 0) {
			if (debug)
				warning(0, "don't know %I", ciaddr);
			return -1;	/* don't know anything about it */
		}
		if(!samenet(riip->ipaddr, iip)){
			warning(0, "%I not on %I", ciaddr, riip->ipnet);
			return -1;
		}

		/*
		 *  see if this is a masquerade, i.e., if the ether
		 *  address doesn't match what we expected it to be.
		 */
		if(memcmp(iip->etheraddr, zeroes, 6) != 0)
		if(memcmp(bp->chaddr, iip->etheraddr, 6) != 0)
			warning(0, "ciaddr %I rcvd from %E instead of %E",
				ciaddr, bp->chaddr, iip->etheraddr);

		return 0;
	}

	if(bp->hlen > Maxhwlen)
		return -1;
	switch(bp->htype){
	case 1:
		hwattr = "ether";
		hwval = hwbuf;
		snprint(hwbuf, sizeof(hwbuf), "%E", bp->chaddr);
		break;
	default:
		syslog(0, blog, "not ethernet %E, htype %d, hlen %d",
			bp->chaddr, bp->htype, bp->hlen);
		return -1;
	}

	/*
	 *  use hardware address to find an ip address on
	 *  same net as riip
	 */
	t = ndbsearch(db, &s, hwattr, hwval);
	while(t){
		for(nt = t; nt; nt = nt->entry){
			if(strcmp(nt->attr, "ip") != 0)
				continue;
			parseip(ciaddr, nt->val);
			if(lookupip(ciaddr, iip, 0) < 0)
				continue;
			if(samenet(riip->ipaddr, iip)){
				ndbfree(t);
				return 0;
			}
		}
		ndbfree(t);
		t = ndbsnext(&s, hwattr, hwval);
	}
	return -1;
}