int     i, j, fd = -1, extra, len = 0; struct if_nameindex *nameindex = NULL; struct ifconf ifconf; char    lastname[IFNAMSIZ], *c, *inbuf; struct if_nameindex *n; struct sockaddr *sa; void   *p;
struct ifaddrs *ifaddrs, *ifa; unsigned int ni; size_t nbytes; struct if_nameindex *ifni, *ifni2; char *cp;
if_nameindex(void){	int     i, j, fd = -1, extra, len = 0;	struct if_nameindex *nameindex = NULL;	struct ifconf ifconf;	char    lastname[IFNAMSIZ], *c, *inbuf;	struct if_nameindex *n;	struct sockaddr *sa;	void   *p;	ifconf.ifc_buf = NULL;	if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)		goto ret;	/*	 * Try ifc_len == 0 hack first, to get the actual length.	 * If that fails, revert to a loop which grows the ifc_buf	 * until it is sufficiently large.	 */	extra = sizeof(struct ifreq);	while (1) {		ifconf.ifc_len = len;		if (ioctl(fd, SIOCGIFCONF, (void *) &ifconf) == -1 &&		    ifconf.ifc_buf)			goto ret;		if (ifconf.ifc_buf &&		    ifconf.ifc_len + extra < len)			break;		if (ifconf.ifc_buf) {			if (len == 0)				len = 4096;			ifconf.ifc_len = len *= 2;		} else {			len = ifconf.ifc_len;			extra = 0;		}		inbuf = realloc(ifconf.ifc_buf, ifconf.ifc_len);		if (inbuf == NULL)			goto ret;		ifconf.ifc_buf = inbuf;	}	i = sizeof(struct if_nameindex);	j = 0;	p = ifconf.ifc_buf;	len = ifconf.ifc_len;	lastname[0] = 0;	lastname[sizeof(lastname)-1] = 0;	while (len > 0) {		if (len < (IFNAMSIZ + sizeof(struct sockaddr)))			goto ret;		if (strncmp(lastname, p, IFNAMSIZ)) {			strlcpy(lastname, p, sizeof(lastname));			i += sizeof(struct if_nameindex);			j += strlen(lastname) + 1;		}		len -= IFNAMSIZ;		p += IFNAMSIZ;		sa = p;		if (sa->sa_len < sizeof(struct sockaddr))			sa->sa_len = sizeof(struct sockaddr);		if (len < sa->sa_len)			goto ret;		len -= sa->sa_len;		p += sa->sa_len;	}	nameindex = malloc(i + j);	if (nameindex == NULL) {		errno = ENOMEM;		goto ret;	}	memset(nameindex, 0, i + j);	n = nameindex;	p = ifconf.ifc_buf;	c = (void *) nameindex + i;	i = 0;	len = ifconf.ifc_len;	lastname[0] = 0;	while (len > 0) {		if (len < IFNAMSIZ + sizeof(struct sockaddr))			goto ret;		if (strncmp(lastname, p, IFNAMSIZ)) {			if (i) {				if (!n->if_index)					n->if_index = i;				n++;			}			i++;			memcpy(lastname, p, sizeof(lastname));			strlcpy(c, lastname, sizeof(lastname));			n->if_name = c;			c += strlen(c) + 1;		}		len -= IFNAMSIZ;		p += IFNAMSIZ;		sa = p;		if (len < sa->sa_len)			goto ret;		if (sa->sa_family == AF_LINK) {			struct sockaddr_dl *sd = (struct sockaddr_dl *)sa;			n->if_index = sd->sdl_index;		}		len -= sa->sa_len;		p += sa->sa_len;	}	if (n->if_index == 0)		n->if_index = i;ret:	if (fd != -1)		close(fd);	if (ifconf.ifc_buf)		free(ifconf.ifc_buf);	return (nameindex);}