#include <u.h>
/* #include <everything_but_the_kitchen_sink.h> */
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/sysctl.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <libc.h>
#include <ip.h>

static void
sockaddr2ip(uchar *ip, struct sockaddr *sa)
{
	struct sockaddr_in *sin;
	
	sin = (struct sockaddr_in*)sa;
	memmove(ip, v4prefix, IPaddrlen);
	memmove(ip+IPv4off, &sin->sin_addr, 4);
}

Ipifc*
readipifc(char *net, Ipifc *ifc, int index)
{
	char *p, *ep, *q, *bp;
	int i, mib[6];
	size_t n;
	Ipifc *list, **last;
	Iplifc *lifc, **lastlifc;
	struct if_msghdr *mh, *nmh;
	struct ifa_msghdr *ah;
	struct sockaddr *sa;
	struct sockaddr_dl *sdl;
	uchar ip[IPaddrlen];

	USED(net);

	free(ifc);
	ifc = nil;
	list = nil;
	last = &list;

	/*
	 * Does not handle IPv6 yet.
	 */

	mib[0] = CTL_NET;
	mib[1] = PF_ROUTE;
	mib[2] = 0;
	mib[3] = 0;
	mib[4] = NET_RT_IFLIST;
	mib[5] = 0;
	
	n = 0;
	if(sysctl(mib, 6, nil, &n, nil, 0) < 0)
		return nil;
	bp = mallocz(n, 1);
	if(bp == nil)
		return nil;
	if(sysctl(mib, 6, bp, &n, nil, 0) < 0){
		free(bp);
		return nil;
	}

	p = bp;
	ep = p+n;
	while(p < ep){
		mh = (struct if_msghdr*)p;
		p += mh->ifm_msglen;
		if(mh->ifm_type != RTM_IFINFO)
			continue;
		ifc = mallocz(sizeof *ifc, 1);
		if(ifc == nil)
			break;
		*last = ifc;
		last = &ifc->next;
		sdl = (struct sockaddr_dl*)(mh+1);
		n = sdl->sdl_nlen;
		if(n >= sizeof ifc->dev)
			n = sizeof ifc->dev - 1;
		memmove(ifc->dev, sdl->sdl_data, n);
		ifc->dev[n] = 0;
		ifc->rp.linkmtu = mh->ifm_data.ifi_mtu;
		lastlifc = &ifc->lifc;

		if(sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == 6)
			memmove(ifc->ether, LLADDR(sdl), 6);

		while(p < ep){
			ah = (struct ifa_msghdr*)p;
			nmh = (struct if_msghdr*)p;
			if(nmh->ifm_type != RTM_NEWADDR)
				break;
			p += nmh->ifm_msglen;
			lifc = nil;
			for(i=0, q=(char*)(ah+1); i<RTAX_MAX && q<p; i++){
				if(!(ah->ifam_addrs & (1<<i)))
					continue;
				sa = (struct sockaddr*)q;
				q += (sa->sa_len+sizeof(long)-1) & ~(sizeof(long)-1);
				if(sa->sa_family != AF_INET)
					continue;
				if(lifc == nil){
					lifc = mallocz(sizeof *lifc, 1);
					if(lifc == nil)
						continue;
					*lastlifc = lifc;
					lastlifc = &lifc->next;
				}	
				sockaddr2ip(ip, sa);
				switch(i){
				case RTAX_IFA:
					ipmove(lifc->ip, ip);
					break;
				case RTAX_NETMASK:
					memset(ip, 0xFF, IPv4off);
					ipmove(lifc->mask, ip);
					break;
				case RTAX_BRD:
					if(mh->ifm_flags & IFF_POINTOPOINT)
						/* ipmove(lifc->remote, ip) */ ;
					if(mh->ifm_flags & IFF_BROADCAST)
						/* ipmove(lifc->bcast, ip) */ ;
					break;
				case RTAX_GATEWAY:
					break;
				case RTAX_DST:
					break;
				}
			}
			if(lifc)
				maskip(lifc->ip, lifc->mask, lifc->net);
		}
	}
	free(bp);
	return list;
}
