/* $KAME: if_nameindex.c,v 1.8 2000/11/24 08:20:01 itojun Exp $ */12/*-3* SPDX-License-Identifier: BSD-1-Clause4*5* Copyright (c) 1997, 20006* Berkeley Software Design, Inc. All rights reserved.7*8* Redistribution and use in source and binary forms, with or without9* modification, are permitted provided that the following conditions10* are met:11* 1. Redistributions of source code must retain the above copyright12* notice, this list of conditions and the following disclaimer.13*14* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND15* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE16* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE17* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE18* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL19* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS20* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)21* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT22* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY23* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF24* SUCH DAMAGE.25*26* BSDI Id: if_nameindex.c,v 2.3 2000/04/17 22:38:05 dab Exp27*/2829#include <sys/types.h>30#include <sys/socket.h>31#include <net/if_dl.h>32#include <net/if.h>33#include <ifaddrs.h>34#include <stdlib.h>35#include <string.h>3637/*38* From RFC 2553:39*40* 4.3 Return All Interface Names and Indexes41*42* The if_nameindex structure holds the information about a single43* interface and is defined as a result of including the <net/if.h>44* header.45*46* struct if_nameindex {47* unsigned int if_index;48* char *if_name;49* };50*51* The final function returns an array of if_nameindex structures, one52* structure per interface.53*54* struct if_nameindex *if_nameindex(void);55*56* The end of the array of structures is indicated by a structure with57* an if_index of 0 and an if_name of NULL. The function returns a NULL58* pointer upon an error, and would set errno to the appropriate value.59*60* The memory used for this array of structures along with the interface61* names pointed to by the if_name members is obtained dynamically.62* This memory is freed by the next function.63*64* 4.4. Free Memory65*66* The following function frees the dynamic memory that was allocated by67* if_nameindex().68*69* #include <net/if.h>70*71* void if_freenameindex(struct if_nameindex *ptr);72*73* The argument to this function must be a pointer that was returned by74* if_nameindex().75*/7677struct if_nameindex *78if_nameindex(void)79{80struct ifaddrs *ifaddrs, *ifa;81unsigned int ni;82int nbytes;83struct if_nameindex *ifni, *ifni2;84char *cp;8586if (getifaddrs(&ifaddrs) < 0)87return(NULL);8889/*90* First, find out how many interfaces there are, and how91* much space we need for the string names.92*/93ni = 0;94nbytes = 0;95for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {96if (ifa->ifa_addr &&97ifa->ifa_addr->sa_family == AF_LINK) {98nbytes += strlen(ifa->ifa_name) + 1;99ni++;100}101}102103/*104* Next, allocate a chunk of memory, use the first part105* for the array of structures, and the last part for106* the strings.107*/108cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes);109ifni = (struct if_nameindex *)cp;110if (ifni == NULL)111goto out;112cp += (ni + 1) * sizeof(struct if_nameindex);113114/*115* Now just loop through the list of interfaces again,116* filling in the if_nameindex array and making copies117* of all the strings.118*/119ifni2 = ifni;120for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {121if (ifa->ifa_addr &&122ifa->ifa_addr->sa_family == AF_LINK) {123ifni2->if_index =124LLINDEX((struct sockaddr_dl*)ifa->ifa_addr);125ifni2->if_name = cp;126strcpy(cp, ifa->ifa_name);127ifni2++;128cp += strlen(cp) + 1;129}130}131/*132* Finally, don't forget to terminate the array.133*/134ifni2->if_index = 0;135ifni2->if_name = NULL;136out:137freeifaddrs(ifaddrs);138return(ifni);139}140141void142if_freenameindex(struct if_nameindex *ptr)143{144free(ptr);145}146147148