17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5e11c3f44Smeem  * Common Development and Distribution License (the "License").
6e11c3f44Smeem  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
21*7f0c041dSRenee Danson Sommerfeld 
227c478bd9Sstevel@tonic-gate /*
23*7f0c041dSRenee Danson Sommerfeld  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <stdio.h>
277c478bd9Sstevel@tonic-gate #include <ctype.h>
287c478bd9Sstevel@tonic-gate #include <string.h>
297c478bd9Sstevel@tonic-gate #include <strings.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <sys/types.h>
327c478bd9Sstevel@tonic-gate #include <sys/socket.h>
337c478bd9Sstevel@tonic-gate #include <inet/common.h>
347c478bd9Sstevel@tonic-gate #include <net/if.h>
357c478bd9Sstevel@tonic-gate #include <netinet/in.h>
367c478bd9Sstevel@tonic-gate #include <sys/sockio.h>
377c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
387c478bd9Sstevel@tonic-gate #include <unistd.h>
397c478bd9Sstevel@tonic-gate #include <errno.h>
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #define	IPIF_SEPARATOR_CHAR	":"
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate /*
447c478bd9Sstevel@tonic-gate  * Given an interface name, this function retrives the associated
457c478bd9Sstevel@tonic-gate  * index value. Returns index value if successful, zero otherwise.
467c478bd9Sstevel@tonic-gate  * The length of the supplied interface name must be at most
477c478bd9Sstevel@tonic-gate  * IF_NAMESIZE-1 bytes
487c478bd9Sstevel@tonic-gate  */
497c478bd9Sstevel@tonic-gate uint32_t
if_nametoindex(const char * ifname)507c478bd9Sstevel@tonic-gate if_nametoindex(const char *ifname)
517c478bd9Sstevel@tonic-gate {
527c478bd9Sstevel@tonic-gate 	int		s;
537c478bd9Sstevel@tonic-gate 	struct lifreq	lifr;
547c478bd9Sstevel@tonic-gate 	int		save_err;
557c478bd9Sstevel@tonic-gate 	size_t		size;
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate 	/* Make sure the given name is not NULL */
597c478bd9Sstevel@tonic-gate 	if ((ifname == NULL)||(*ifname == '\0')) {
607c478bd9Sstevel@tonic-gate 		errno = ENXIO;
617c478bd9Sstevel@tonic-gate 		return (0);
627c478bd9Sstevel@tonic-gate 	}
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 	/*
657c478bd9Sstevel@tonic-gate 	 * Fill up the interface name in the ioctl
667c478bd9Sstevel@tonic-gate 	 * request message. Make sure that the length of
677c478bd9Sstevel@tonic-gate 	 * the given interface name <= (IF_NAMESIZE-1)
687c478bd9Sstevel@tonic-gate 	 */
697c478bd9Sstevel@tonic-gate 	size = strlen(ifname);
707c478bd9Sstevel@tonic-gate 	if (size > (IF_NAMESIZE - 1)) {
717c478bd9Sstevel@tonic-gate 		errno = EINVAL;
727c478bd9Sstevel@tonic-gate 		return (0);
737c478bd9Sstevel@tonic-gate 	}
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	strncpy(lifr.lifr_name, ifname, size +1);
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	/* Check the v4 interfaces first */
787c478bd9Sstevel@tonic-gate 	s = socket(AF_INET, SOCK_DGRAM, 0);
797c478bd9Sstevel@tonic-gate 	if (s >= 0) {
807c478bd9Sstevel@tonic-gate 		if (ioctl(s, SIOCGLIFINDEX, (caddr_t)&lifr) >= 0) {
817c478bd9Sstevel@tonic-gate 			(void) close(s);
827c478bd9Sstevel@tonic-gate 			return (lifr.lifr_index);
837c478bd9Sstevel@tonic-gate 		}
847c478bd9Sstevel@tonic-gate 		(void) close(s);
857c478bd9Sstevel@tonic-gate 	}
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	/* Check the v6 interface list */
887c478bd9Sstevel@tonic-gate 	s = socket(AF_INET6, SOCK_DGRAM, 0);
897c478bd9Sstevel@tonic-gate 	if (s < 0)
907c478bd9Sstevel@tonic-gate 		return (0);
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	if (ioctl(s, SIOCGLIFINDEX, (caddr_t)&lifr) < 0)
937c478bd9Sstevel@tonic-gate 		lifr.lifr_index = 0;
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 	save_err = errno;
967c478bd9Sstevel@tonic-gate 	(void) close(s);
977c478bd9Sstevel@tonic-gate 	errno = save_err;
987c478bd9Sstevel@tonic-gate 	return (lifr.lifr_index);
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate  * Given an index, this function returns the associated interface
1037c478bd9Sstevel@tonic-gate  * name in the supplied buffer ifname.
1047c478bd9Sstevel@tonic-gate  * Returns physical interface name if successful, NULL otherwise.
1057c478bd9Sstevel@tonic-gate  * The interface name returned will be at most IF_NAMESIZE-1 bytes.
1067c478bd9Sstevel@tonic-gate  */
1077c478bd9Sstevel@tonic-gate char *
if_indextoname(uint32_t ifindex,char * ifname)1087c478bd9Sstevel@tonic-gate if_indextoname(uint32_t ifindex, char *ifname)
1097c478bd9Sstevel@tonic-gate {
1107c478bd9Sstevel@tonic-gate 	int		n;
1117c478bd9Sstevel@tonic-gate 	int		s;
1127c478bd9Sstevel@tonic-gate 	char		*buf;
1137c478bd9Sstevel@tonic-gate 	uint32_t	index;
1147c478bd9Sstevel@tonic-gate 	struct lifnum	lifn;
1157c478bd9Sstevel@tonic-gate 	struct lifconf	lifc;
1167c478bd9Sstevel@tonic-gate 	struct lifreq	*lifrp;
1177c478bd9Sstevel@tonic-gate 	int		numifs;
1187c478bd9Sstevel@tonic-gate 	size_t		bufsize;
1197c478bd9Sstevel@tonic-gate 	boolean_t 	found;
120e11c3f44Smeem 	uint_t		flags;
121e11c3f44Smeem 
122e11c3f44Smeem 	flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES | LIFC_UNDER_IPMP;
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 	/* A interface index of 0 is invalid */
1257c478bd9Sstevel@tonic-gate 	if (ifindex == 0) {
1267c478bd9Sstevel@tonic-gate 		errno = ENXIO;
1277c478bd9Sstevel@tonic-gate 		return (NULL);
1287c478bd9Sstevel@tonic-gate 	}
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate 	s = socket(AF_INET6, SOCK_DGRAM, 0);
1317c478bd9Sstevel@tonic-gate 	if (s < 0) {
1327c478bd9Sstevel@tonic-gate 		s = socket(AF_INET, SOCK_DGRAM, 0);
1337c478bd9Sstevel@tonic-gate 		if (s < 0) {
1347c478bd9Sstevel@tonic-gate 			return (NULL);
1357c478bd9Sstevel@tonic-gate 		}
1367c478bd9Sstevel@tonic-gate 	}
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate 	/* Prepare to send a SIOCGLIFNUM request message */
1397c478bd9Sstevel@tonic-gate 	lifn.lifn_family = AF_UNSPEC;
140e11c3f44Smeem 	lifn.lifn_flags = flags;
1417c478bd9Sstevel@tonic-gate 	if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0) {
1427c478bd9Sstevel@tonic-gate 		int save_err = errno;
1437c478bd9Sstevel@tonic-gate 		(void) close(s);
1447c478bd9Sstevel@tonic-gate 		errno = save_err;
1457c478bd9Sstevel@tonic-gate 		return (NULL);
1467c478bd9Sstevel@tonic-gate 	}
147e11c3f44Smeem 
148e11c3f44Smeem 	/*
149e11c3f44Smeem 	 * NOTE: "+ 10" sleaze mitigates new IP interfaces showing up between
150e11c3f44Smeem 	 * the SIOCGLIFNUM and the SIOCGLIFCONF.
151e11c3f44Smeem 	 */
152e11c3f44Smeem 	numifs = lifn.lifn_count + 10;
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 	/*
1557c478bd9Sstevel@tonic-gate 	 * Provide enough buffer to obtain the interface
1567c478bd9Sstevel@tonic-gate 	 * list from the kernel as response to a SIOCGLIFCONF
1577c478bd9Sstevel@tonic-gate 	 * request
1587c478bd9Sstevel@tonic-gate 	 */
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 	bufsize = numifs * sizeof (struct lifreq);
1617c478bd9Sstevel@tonic-gate 	buf = malloc(bufsize);
1627c478bd9Sstevel@tonic-gate 	if (buf == NULL) {
1637c478bd9Sstevel@tonic-gate 		int save_err = errno;
1647c478bd9Sstevel@tonic-gate 		(void) close(s);
1657c478bd9Sstevel@tonic-gate 		errno = save_err;
1667c478bd9Sstevel@tonic-gate 		return (NULL);
1677c478bd9Sstevel@tonic-gate 	}
1687c478bd9Sstevel@tonic-gate 	lifc.lifc_family = AF_UNSPEC;
169e11c3f44Smeem 	lifc.lifc_flags = flags;
1707c478bd9Sstevel@tonic-gate 	lifc.lifc_len = bufsize;
1717c478bd9Sstevel@tonic-gate 	lifc.lifc_buf = buf;
1727c478bd9Sstevel@tonic-gate 	if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) {
1737c478bd9Sstevel@tonic-gate 		int save_err = errno;
1747c478bd9Sstevel@tonic-gate 		(void) close(s);
1757c478bd9Sstevel@tonic-gate 		errno = save_err;
1767c478bd9Sstevel@tonic-gate 		free(buf);
1777c478bd9Sstevel@tonic-gate 		return (NULL);
1787c478bd9Sstevel@tonic-gate 	}
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 	lifrp = lifc.lifc_req;
1817c478bd9Sstevel@tonic-gate 	found = B_FALSE;
1827c478bd9Sstevel@tonic-gate 	for (n = lifc.lifc_len / sizeof (struct lifreq); n > 0; n--, lifrp++) {
1837c478bd9Sstevel@tonic-gate 		/*
1847c478bd9Sstevel@tonic-gate 		 * Obtain the index value of each interface, and
1857c478bd9Sstevel@tonic-gate 		 * match to see if the retrived index value matches
186ffdae209SAnders Persson 		 * the given one. If so we return the corresponding
1877c478bd9Sstevel@tonic-gate 		 * device name of that interface.
1887c478bd9Sstevel@tonic-gate 		 */
1897c478bd9Sstevel@tonic-gate 		size_t	size;
1907c478bd9Sstevel@tonic-gate 
1917c478bd9Sstevel@tonic-gate 		index = if_nametoindex(lifrp->lifr_name);
1927c478bd9Sstevel@tonic-gate 		if (index == 0)
1937c478bd9Sstevel@tonic-gate 			/* Oops the interface just disappeared */
1947c478bd9Sstevel@tonic-gate 			continue;
1957c478bd9Sstevel@tonic-gate 		if (index == ifindex) {
1967c478bd9Sstevel@tonic-gate 			size = strcspn(lifrp->lifr_name,
1977c478bd9Sstevel@tonic-gate 			    (char *)IPIF_SEPARATOR_CHAR);
1987c478bd9Sstevel@tonic-gate 			lifrp->lifr_name[size] = '\0';
1997c478bd9Sstevel@tonic-gate 			found = B_TRUE;
200ffdae209SAnders Persson 			(void) strncpy(ifname, lifrp->lifr_name, size + 1);
2017c478bd9Sstevel@tonic-gate 			break;
2027c478bd9Sstevel@tonic-gate 		}
2037c478bd9Sstevel@tonic-gate 	}
2047c478bd9Sstevel@tonic-gate 	(void) close(s);
2057c478bd9Sstevel@tonic-gate 	free(buf);
2067c478bd9Sstevel@tonic-gate 	if (!found) {
2077c478bd9Sstevel@tonic-gate 		errno = ENXIO;
2087c478bd9Sstevel@tonic-gate 		return (NULL);
2097c478bd9Sstevel@tonic-gate 	}
2107c478bd9Sstevel@tonic-gate 	return (ifname);
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate /*
2147c478bd9Sstevel@tonic-gate  * This function returns all the interface names and indexes
2157c478bd9Sstevel@tonic-gate  */
2167c478bd9Sstevel@tonic-gate struct if_nameindex *
if_nameindex(void)2177c478bd9Sstevel@tonic-gate if_nameindex(void)
2187c478bd9Sstevel@tonic-gate {
2197c478bd9Sstevel@tonic-gate 	int		n;
2207c478bd9Sstevel@tonic-gate 	int		s;
2217c478bd9Sstevel@tonic-gate 	boolean_t	found;
2227c478bd9Sstevel@tonic-gate 	char		*buf;
2237c478bd9Sstevel@tonic-gate 	struct lifnum	lifn;
2247c478bd9Sstevel@tonic-gate 	struct lifconf	lifc;
2257c478bd9Sstevel@tonic-gate 	struct lifreq	*lifrp;
2267c478bd9Sstevel@tonic-gate 	int		numifs;
2277c478bd9Sstevel@tonic-gate 	int		index;
2287c478bd9Sstevel@tonic-gate 	int		i;
2297c478bd9Sstevel@tonic-gate 	int 		physinterf_num;
2307c478bd9Sstevel@tonic-gate 	size_t		bufsize;
2317c478bd9Sstevel@tonic-gate 	struct if_nameindex	 *interface_list;
2327c478bd9Sstevel@tonic-gate 	struct if_nameindex	 *interface_entry;
2337c478bd9Sstevel@tonic-gate 
2347c478bd9Sstevel@tonic-gate 	s = socket(AF_INET6, SOCK_DGRAM, 0);
2357c478bd9Sstevel@tonic-gate 	if (s < 0) {
2367c478bd9Sstevel@tonic-gate 		s = socket(AF_INET, SOCK_DGRAM, 0);
2377c478bd9Sstevel@tonic-gate 		if (s < 0)
2387c478bd9Sstevel@tonic-gate 			return (NULL);
2397c478bd9Sstevel@tonic-gate 	}
2407c478bd9Sstevel@tonic-gate 
2417c478bd9Sstevel@tonic-gate 	lifn.lifn_family = AF_UNSPEC;
2427c478bd9Sstevel@tonic-gate 	lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
2437c478bd9Sstevel@tonic-gate 	if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0)
2447c478bd9Sstevel@tonic-gate 		return (NULL);
2457c478bd9Sstevel@tonic-gate 	numifs = lifn.lifn_count;
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	bufsize = numifs * sizeof (struct lifreq);
2487c478bd9Sstevel@tonic-gate 	buf = malloc(bufsize);
2497c478bd9Sstevel@tonic-gate 	if (buf == NULL) {
2507c478bd9Sstevel@tonic-gate 		int save_err = errno;
2517c478bd9Sstevel@tonic-gate 		(void) close(s);
2527c478bd9Sstevel@tonic-gate 		errno = save_err;
2537c478bd9Sstevel@tonic-gate 		return (NULL);
2547c478bd9Sstevel@tonic-gate 	}
2557c478bd9Sstevel@tonic-gate 	lifc.lifc_family = AF_UNSPEC;
2567c478bd9Sstevel@tonic-gate 	lifc.lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
2577c478bd9Sstevel@tonic-gate 	lifc.lifc_len = bufsize;
2587c478bd9Sstevel@tonic-gate 	lifc.lifc_buf = buf;
2597c478bd9Sstevel@tonic-gate 	if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) {
2607c478bd9Sstevel@tonic-gate 		int save_err = errno;
2617c478bd9Sstevel@tonic-gate 		(void) close(s);
2627c478bd9Sstevel@tonic-gate 		errno = save_err;
2637c478bd9Sstevel@tonic-gate 		free(buf);
2647c478bd9Sstevel@tonic-gate 		return (NULL);
2657c478bd9Sstevel@tonic-gate 	}
2667c478bd9Sstevel@tonic-gate 
2677c478bd9Sstevel@tonic-gate 	lifrp = lifc.lifc_req;
2687c478bd9Sstevel@tonic-gate 	(void) close(s);
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 	/* Allocate the array of if_nameindex structure */
2717c478bd9Sstevel@tonic-gate 	interface_list = malloc((numifs + 1) * sizeof (struct if_nameindex));
2727c478bd9Sstevel@tonic-gate 	if (!interface_list) {
2737c478bd9Sstevel@tonic-gate 		int save_err = errno;
2747c478bd9Sstevel@tonic-gate 		free(buf);
2757c478bd9Sstevel@tonic-gate 		errno = save_err;
2767c478bd9Sstevel@tonic-gate 		return (NULL);
2777c478bd9Sstevel@tonic-gate 	}
2787c478bd9Sstevel@tonic-gate 	/*
2797c478bd9Sstevel@tonic-gate 	 * Make sure that terminator structure automatically
2807c478bd9Sstevel@tonic-gate 	 * happens to be all zeroes.
2817c478bd9Sstevel@tonic-gate 	 */
2827c478bd9Sstevel@tonic-gate 	bzero(interface_list, ((numifs + 1) * sizeof (struct if_nameindex)));
2837c478bd9Sstevel@tonic-gate 	interface_entry = interface_list;
2847c478bd9Sstevel@tonic-gate 	physinterf_num = 0;
2857c478bd9Sstevel@tonic-gate 	for (n = numifs; n > 0; n--, lifrp++) {
2867c478bd9Sstevel@tonic-gate 		size_t	size;
2877c478bd9Sstevel@tonic-gate 
2887c478bd9Sstevel@tonic-gate 		size = strcspn(lifrp->lifr_name, (char *)IPIF_SEPARATOR_CHAR);
2897c478bd9Sstevel@tonic-gate 		found = B_FALSE;
2907c478bd9Sstevel@tonic-gate 		/*
2917c478bd9Sstevel@tonic-gate 		 * Search the current array to see if this interface
292ffdae209SAnders Persson 		 * already exists. Only compare the physical name.
2937c478bd9Sstevel@tonic-gate 		 */
2947c478bd9Sstevel@tonic-gate 		for (i = 0; i < physinterf_num; i++) {
295ffdae209SAnders Persson 			if (strncmp(interface_entry[i].if_name,
296ffdae209SAnders Persson 			    lifrp->lifr_name, size) == 0) {
2977c478bd9Sstevel@tonic-gate 				found = B_TRUE;
2987c478bd9Sstevel@tonic-gate 				break;
2997c478bd9Sstevel@tonic-gate 			}
3007c478bd9Sstevel@tonic-gate 		}
3017c478bd9Sstevel@tonic-gate 
3027c478bd9Sstevel@tonic-gate 		/* New one. Allocate an array element and fill it */
3037c478bd9Sstevel@tonic-gate 		if (!found) {
304ffdae209SAnders Persson 			/*
305ffdae209SAnders Persson 			 * Obtain the index value for the interface
306ffdae209SAnders Persson 			 */
307ffdae209SAnders Persson 			interface_entry[physinterf_num].if_index =
308ffdae209SAnders Persson 			    if_nametoindex(lifrp->lifr_name);
309ffdae209SAnders Persson 
310ffdae209SAnders Persson 			if (interface_entry[physinterf_num].if_index == 0) {
311ffdae209SAnders Persson 				/* The interface went away. Skip this entry. */
312ffdae209SAnders Persson 				continue;
313ffdae209SAnders Persson 			}
314ffdae209SAnders Persson 
315ffdae209SAnders Persson 			/*
316ffdae209SAnders Persson 			 * Truncate the name to ensure that it represents
317ffdae209SAnders Persson 			 * a physical interface.
318ffdae209SAnders Persson 			 */
319ffdae209SAnders Persson 			lifrp->lifr_name[size] = '\0';
3207c478bd9Sstevel@tonic-gate 			if ((interface_entry[physinterf_num].if_name =
3217c478bd9Sstevel@tonic-gate 			    strdup(lifrp->lifr_name)) == NULL) {
3227c478bd9Sstevel@tonic-gate 				int save_err;
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate 				if_freenameindex(interface_list);
3257c478bd9Sstevel@tonic-gate 				save_err = errno;
3267c478bd9Sstevel@tonic-gate 				free(buf);
3277c478bd9Sstevel@tonic-gate 				errno = save_err;
3287c478bd9Sstevel@tonic-gate 				return (NULL);
3297c478bd9Sstevel@tonic-gate 			}
3307c478bd9Sstevel@tonic-gate 
331ffdae209SAnders Persson 			physinterf_num++;
3327c478bd9Sstevel@tonic-gate 		}
3337c478bd9Sstevel@tonic-gate 	}
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate 	/* Create the last one of the array */
3367c478bd9Sstevel@tonic-gate 	interface_entry[physinterf_num].if_name = NULL;
3377c478bd9Sstevel@tonic-gate 	interface_entry[physinterf_num].if_index = 0;
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 	/* Free up the excess array space */
3407c478bd9Sstevel@tonic-gate 	free(buf);
3417c478bd9Sstevel@tonic-gate 	interface_list = realloc(interface_list, ((physinterf_num + 1) *
3427c478bd9Sstevel@tonic-gate 	    sizeof (struct if_nameindex)));
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate 	return (interface_list);
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate /*
3487c478bd9Sstevel@tonic-gate  * This function frees the the array that is created while
3497c478bd9Sstevel@tonic-gate  * the if_nameindex function.
3507c478bd9Sstevel@tonic-gate  */
3517c478bd9Sstevel@tonic-gate void
if_freenameindex(struct if_nameindex * ptr)3527c478bd9Sstevel@tonic-gate if_freenameindex(struct if_nameindex *ptr)
3537c478bd9Sstevel@tonic-gate {
354*7f0c041dSRenee Danson Sommerfeld 	struct if_nameindex *p;
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
3577c478bd9Sstevel@tonic-gate 		return;
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate 	/* First free the if_name member in each array element */
360*7f0c041dSRenee Danson Sommerfeld 	for (p = ptr; p->if_name != NULL; p++)
361*7f0c041dSRenee Danson Sommerfeld 		free(p->if_name);
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 	/* Now free up the array space */
3647c478bd9Sstevel@tonic-gate 	free(ptr);
3657c478bd9Sstevel@tonic-gate }
366