#include <stdlib.h>
#include <stdio.h>
#include <parlib.h>
#include <unistd.h>
#include <signal.h>
#include <nixip.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>

#define NFIELD 200
#define nelem(x) (sizeof(x)/sizeof(x[0]))
static struct ipifc**
_readoldipifc(char *buf, struct ipifc **l, int index)
{
	char *f[NFIELD];
	int i, n;
	struct ipifc *ifc;
	struct iplifc *lifc, **ll;

	/* allocate new interface */
	*l = ifc = calloc(sizeof(struct ipifc), 1);
	if(ifc == NULL)
		return l;
	l = &ifc->next;
	ifc->index = index;

	n = tokenize(buf, f, NFIELD);
	if(n < 2)
		return l;

	strncpy(ifc->dev, f[0], sizeof ifc->dev);
	ifc->dev[sizeof(ifc->dev) - 1] = 0;
	ifc->mtu = strtoul(f[1], NULL, 10);

	ll = &ifc->lifc;
	for(i = 2; n-i >= 7; i += 7){
		/* allocate new local address */
		*ll = lifc = calloc(sizeof(struct iplifc), 1);
		ll = &lifc->next;

		parseip(lifc->ip, f[i]);
		parseipmask(lifc->mask, f[i+1]);
		parseip(lifc->net, f[i+2]);
		ifc->pktin = strtoul(f[i+3], NULL, 10);
		ifc->pktout = strtoul(f[i+4], NULL, 10);
		ifc->errin = strtoul(f[i+5], NULL, 10);
		ifc->errout = strtoul(f[i+6], NULL, 10);
	}
	return l;
}

static char*
findfield(char *name, char **f, int n)
{
	int i;

	for(i = 0; i < n-1; i++)
		if(strcmp(f[i], name) == 0)
			return f[i+1];
	return "";
}

static struct ipifc**
_readipifc(char *file, struct ipifc **l, int index)
{
	int i, n, fd, lines;
	char buf[4*1024];
	char *line[32];
	char *f[64];
	struct ipifc *ifc, **l0;
	struct iplifc *lifc, **ll;

	/* read the file */
	fd = open(file, O_RDONLY);
	if(fd < 0)
		return l;
	n = 0;
	while((i = read(fd, buf+n, sizeof(buf)-1-n)) > 0 && n < sizeof(buf) - 1)
		n += i;
	buf[n] = 0;
	close(fd);

	if(strncmp(buf, "device", 6) != 0)
		return _readoldipifc(buf, l, index);
	/* ignore ifcs with no associated device */
	if(strncmp(buf+6, "  ", 2) == 0)
		return l;
	/* allocate new interface */
	*l = ifc = calloc(sizeof(struct ipifc), 1);
	if(ifc == NULL)
		return l;
	l0 = l;
	l = &ifc->next;
	ifc->index = index;

	lines = getfields(buf, line, nelem(line), 1, "\n");

	/* pick off device specific info(first line) */
	n = tokenize(line[0], f, nelem(f));
	if(n%2 != 0)
		goto lose;
	strncpy(ifc->dev, findfield("device", f, n), sizeof(ifc->dev));
	ifc->dev[sizeof(ifc->dev)-1] = 0;
	if(ifc->dev[0] == 0){
lose:
		free(ifc);
		*l0 = NULL;
		return l;
	}
	ifc->mtu = strtoul(findfield("maxtu", f, n), NULL, 10);
	ifc->sendra6 = atoi(findfield("sendra", f, n));
	ifc->recvra6 = atoi(findfield("recvra", f, n));
	ifc->rp.mflag = atoi(findfield("mflag", f, n));
	ifc->rp.oflag = atoi(findfield("oflag", f, n));
	ifc->rp.maxraint = atoi(findfield("maxraint", f, n));
	ifc->rp.minraint = atoi(findfield("minraint", f, n));
	ifc->rp.linkmtu = atoi(findfield("linkmtu", f, n));
	ifc->rp.reachtime = atoi(findfield("reachtime", f, n));
	ifc->rp.rxmitra = atoi(findfield("rxmitra", f, n));
	ifc->rp.ttl = atoi(findfield("ttl", f, n));
	ifc->rp.routerlt = atoi(findfield("routerlt", f, n));
	ifc->pktin = strtoul(findfield("pktin", f, n), NULL, 10);
	ifc->pktout = strtoul(findfield("pktout", f, n), NULL, 10);
	ifc->errin = strtoul(findfield("errin", f, n), NULL, 10);
	ifc->errout = strtoul(findfield("errout", f, n), NULL, 10);

	/* now read the addresses */
	ll = &ifc->lifc;
	for(i = 1; i < lines; i++){
		n = tokenize(line[i], f, nelem(f));
		if(n < 5)
			break;

		/* allocate new local address */
		*ll = lifc = calloc(sizeof(struct iplifc), 1);
		ll = &lifc->next;

		parseip(lifc->ip, f[0]);
		parseipmask(lifc->mask, f[1]);
		parseip(lifc->net, f[2]);

		lifc->validlt = strtoul(f[3], NULL, 10);
		lifc->preflt = strtoul(f[4], NULL, 10);
	}

	return l;
}

static void
_freeifc(struct ipifc *ifc)
{
	struct ipifc *next;
	struct iplifc *lnext, *lifc;

	if(ifc == NULL)
		return;
	for(; ifc; ifc = next){
		next = ifc->next;
		for(lifc = ifc->lifc; lifc; lifc = lnext){
			lnext = lifc->next;
			free(lifc);
		}
		free(ifc);
	}
}

struct ipifc*
readipifc(char *net, struct ipifc *ifc, int index)
{
	int fd, i, n;
	struct dir *dir;
	char directory[128];
	char buf[128];
	struct ipifc **l;

	_freeifc(ifc);

	l = &ifc;
	ifc = NULL;

	if(net == 0)
		net = "/net";
	snprintf(directory, sizeof(directory), "%s/ipifc", net);

	if(index >= 0){
		snprintf(buf, sizeof(buf), "%s/%d/status", directory, index);
		_readipifc(buf, l, index);
	} else {
		DIR *d;
		struct dirent *de;
		d = opendir(directory);
		if(! d)
			return NULL;
		
		while (de = readdir(d)){
			if(strcmp(de->d_name, "clone") == 0)
				continue;
			if(strcmp(de->d_name, "stats") == 0)
				continue;
			snprintf(buf, sizeof(buf), "%s/%s/status", directory, de->d_name);
			l = _readipifc(buf, l, atoi(de->d_name));
		}
		closedir(d);
	}
	
	return ifc;
}
