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
/*
 *  use dns to resolve the mx request
 */
static int
mxlookup(DS *ds, char *domain)
{
	int i, n, nmx;
	Ndbtuple *t, *tmx, *tpref, *tip;
	
	strcpy(domain, ds->host);
	ds->netdir = "/net";
	nmx = 0;
	if((t = dnsquery(nil, ds->host, "mx")) != nil){
		for(tmx=t; (tmx=ndbfindattr(tmx->entry, nil, "mx")) != nil && nmx<Nmx; ){
			for(tpref=tmx->line; tpref != tmx; tpref=tpref->line){
				if(strcmp(tpref->attr, "pref") == 0){
					strncpy(mx[nmx].host, tmx->val, sizeof(mx[n].host)-1);
					mx[nmx].pref = atoi(tpref->val);
					nmx++;
					break;
				}
			}	
		}
		ndbfree(t);
	}

	/*
	 * no mx record? try name itself.
	 */
	/*
	 * BUG? If domain has no dots, then we used to look up ds->host
	 * but return domain instead of ds->host in the list.  Now we return
	 * ds->host.  What will this break?
	 */
	if(nmx == 0){
		mx[0].pref = 1;
		strncpy(mx[0].host, ds->host, sizeof(mx[0].host));
		nmx++;
	}

	/*
	 * look up all ip addresses
	 */
	for(i = 0; i < nmx; i++){
		if((t = dnsquery(nil, mx[i].host, "ip")) == nil)
			goto no;
		if((tip = ndbfindattr(t, nil, "ip")) == nil){
			ndbfree(t);
			goto no;
		}
		strncpy(mx[i].ip, tip->val, sizeof(mx[i].ip)-1);
		ndbfree(t);
		continue;
	
	no:
		/* remove mx[i] and go around again */
		nmx--;
		mx[i] = mx[nmx];
		i--;
	}
	return nmx;		
}
Esempio n. 3
0
Ndbtuple*
ndblookval(Ndbtuple *entry, Ndbtuple *line, char *attr, char *to)
{
	Ndbtuple *t;

	t = ndbfindattr(entry, line, attr);
	if(t != nil){
		strncpy(to, t->val, Ndbvlen-1);
		to[Ndbvlen-1] = 0;
	}
	return t;
}
Esempio n. 4
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. 5
0
int
classify(char *ip, Ndbtuple *t)
{
	int isgov, iscountry, isbadc, isgoodc;
	char dom[256];
	char *df[128];
	Ndbtuple *nt, *x;
	int n;

	isgov = iscountry = isbadc = 0;
	isgoodc = 1;

	for(nt = t; nt != nil; nt = nt->entry){
		if(strcmp(nt->attr, "country") == 0){
			iscountry = 1;
			if(incountries(nt->val, badc)){
				if(classdebug)fprint(2, "isbadc\n");
				isbadc = 1;
				isgoodc = 0;
			} else if(!incountries(nt->val, goodc)){
				if(classdebug)fprint(2, "!isgoodc\n");
				isgoodc = 0;
			}
		}

		/* domain names can always hurt, even without forward verification */
		if(strcmp(nt->attr, "dom") == 0){
			strncpy(dom, nt->val, sizeof dom);
			dom[sizeof(dom)-1] = 0;
			n = getfields(dom, df, nelem(df), 0, ".");

			/* a bad country in a domain name is always believed */
			if(incountries(df[n-1], badc)){
				if(classdebug)fprint(2, "isbadc dom\n");
				isbadc = 1;
				isgoodc = 0;
			}

			/* a goverment in a domain name is always believed */
			if(n > 1 && indomains(df[n-2], gov))
				isgov = 1;
		}
	}
	if(iscountry == 0){
		/* did the forward lookup work? */
		for(nt = t; nt != nil; nt = nt->entry){
			if(strcmp(nt->attr, "ip") == 0 && strcmp(nt->val, ip) == 0)
				break;
		}

		/* see if the domain name ends in a country code */
		if(nt != nil && (x = ndbfindattr(t, nt, "dom")) != nil){
			strncpy(dom, x->val, sizeof dom);
			dom[sizeof(dom)-1] = 0;
			n = getfields(dom, df, nelem(df), 0, ".");
			if(incountries(df[n-1], allc))
				iscountry = 1;
		}
	}
	if(iscountry == 0)
		return Cunknown;
	if(isbadc)
		return Cbadc;
	if(!isgoodc && isgov)
		return Cbadgov;
	return C*k;
}