/* 
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */
#include <stdlib.h>

#include <stdio.h>
#include <parlib/parlib.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <iplib/iplib.h>
#include <ndblib/ndb.h>

enum
{
	Ffound=	1<<0,
	Fignore=1<<1,
	Faddr=	1<<2,
};

static struct ndbtuple*	filter(struct ndb *db, struct ndbtuple *t,
				      struct ndbtuple *f);
static struct ndbtuple*	mkfilter(int argc, char **argv);
static int		filtercomplete(struct ndbtuple *f);
static struct ndbtuple*	toipaddr(struct ndb *db, struct ndbtuple *t);
static int		prefixlen(uint8_t *ip);
static struct ndbtuple*	subnet(struct ndb *db, uint8_t *net,
				      struct ndbtuple *f, int prefix);

/* make a filter to be used in filter */
static struct ndbtuple*
mkfilter(int argc, char **argv)
{
	struct ndbtuple *t, *first, *last;
	char *p;

	last = first = NULL;
	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;
}

/* return true if every pair of filter has been used */
static int
filtercomplete(struct ndbtuple *f)
{
	for(; f; f = f->entry)
		if((f->ptr & Fignore) == 0)
			return 0;
	return 1;
}

/* set the attribute of all entries in a tuple */
static struct ndbtuple*
setattr(struct ndbtuple *t, char *attr)
{
	struct ndbtuple *nt;

	for(nt = t; nt; nt = nt->entry)
		strcpy(nt->attr, attr);
	return t;
}

/*
 *  return only the attr/value pairs in t maching the filter, f.
 *  others are freed.  line structure is preserved.
 */
static struct ndbtuple*
filter(struct ndb *db, struct ndbtuple *t, struct ndbtuple *f)
{
	struct ndbtuple *nt, *nf, *next;

	/* filter out what we don't want */
	for(nt = t; nt; nt = next){
		next = nt->entry;

		/* look through filter */
		for(nf = f; nf != NULL; nf = nf->entry){
			if (!(nf->ptr&Fignore) && strcmp(nt->attr, nf->attr) ==
			   0)
				break;
		}
		if(nf == NULL){
			/* remove nt from t */
			t = ndbdiscard(t, nt);
		} else {
			if (nf->ptr & Faddr)
				t = ndbsubstitute(t, nt,
						  setattr(ndbgetipaddr(db,
								       nt->val),
							  nt->attr));
			nf->ptr |= Ffound;
		}
	}

	/* remember filter etnries that matched */
	for(nf = f; nf != NULL; nf = nf->entry)
		if(nf->ptr & Ffound)
			nf->ptr = (nf->ptr & ~Ffound) | Fignore;

	ndbsetmalloctag(t, getcallerpc(&db));
	return t;
}

static int
prefixlen(uint8_t *ip)
{
	int y, i;

	for(y = IPaddrlen-1; y >= 0; y--)
		for(i = 8; i > 0; i--)
			if(ip[y] & (1<<(8-i)))
				return y*8 + i;
	return 0;
}

/*
 *  look through a containing subset
 */
static struct ndbtuple*
subnet(struct ndb *db, uint8_t *net, struct ndbtuple *f, int prefix)
{
	struct ndbs s;
	struct ndbtuple *t, *nt, *xt;
	char netstr[128];
	uint8_t mask[IPaddrlen];
	int masklen;

	t = NULL;
	sprintf(netstr, "%I", net);
	nt = ndbsearch(db, &s, "ip", netstr);
	while(nt != NULL){
		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 = NULL;
			}
		}
		ndbfree(nt);
		nt = ndbsnext(&s, "ip", netstr);
	}
	ndbsetmalloctag(t, getcallerpc(&db));
	return t;
}

/*
 *  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.
 */
struct ndbtuple*
ndbipinfo(struct ndb *db, char *attr, char *val, char **alist, int n)
{
	struct ndbtuple *t, *nt, *f;
	struct ndbs s;
	char *ipstr;
	uint8_t net[IPaddrlen], ip[IPaddrlen];
	int prefix, smallestprefix, force;
	int64_t r;

#if 0
	/* just in case */
	fmtinstall('I', eipfmt);
	fmtinstall('M', eipfmt);
#endif

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

	/*
	 *  first look for a matching entry with an ip address
	 */
	t = NULL;
	ipstr = ndbgetvalue(db, &s, attr, val, "ip", &nt);
	if(ipstr == NULL){
		/* none found, make one up */
		if(strcmp(attr, "ip") != 0) {
			ndbfree(f);
			return NULL;	
		}
		t = ndbnew("ip", val);
		t->line = t;
		t->entry = NULL;
		r = parseip(net, val);
		if(r == -1)
			ndbfree(t);
	} else {
		/* found one */
		while(nt != NULL){
			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 NULL;
	}
	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];

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

	ndbfree(f);
	ndbsetmalloctag(t, getcallerpc(&db));
	return t;
}
