Skip to content

Commit

Permalink
Implement if_nameindex & if_freenameindex
Browse files Browse the repository at this point in the history
  • Loading branch information
MedourMehdi committed Sep 3, 2024
1 parent f3e1f12 commit 566329f
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 14 deletions.
9 changes: 9 additions & 0 deletions include/net/if.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,18 @@ struct sockaddr_hw {
unsigned char shw_addr[8]; /* address */
};

struct if_nameindex {
short if_index; /* 1, 2, ... */
char* if_name; /* null terminated name: "le0", ... */
};

/* Convert an interface name to an index, and vice versa. */
extern unsigned short if_nametoindex (const char *__ifname) __THROW;
extern char *if_indextoname (unsigned short __ifindex, char __ifname[IF_NAMESIZE]) __THROW;
/* Return a list of all interfaces and their indices. */
extern struct if_nameindex *if_nameindex (void) __THROW;
/* Free the data returned from if_nameindex. */
extern void if_freenameindex (struct if_nameindex *__ptr) __THROW;

__END_DECLS

Expand Down
2 changes: 2 additions & 0 deletions socket/SRCFILES
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ SRCFILES = \
hstrerror.c \
hton.c \
ident_sock.c \
if_freenameindex.c \
if_indextoname.c \
if_nameindex.c \
if_nametoindex.c \
inet_addr.c \
inet_lnaof.c \
Expand Down
12 changes: 12 additions & 0 deletions socket/if_freenameindex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include <net/if.h>
#include <stdlib.h>

__typeof__(if_freenameindex) __if_freenameindex;

void
__if_freenameindex(struct if_nameindex *idx)
{
free(idx);
}

weak_alias (__if_freenameindex, if_freenameindex)
17 changes: 9 additions & 8 deletions socket/if_indextoname.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,24 @@

__typeof__(if_indextoname) __if_indextoname;

char *
char*
__if_indextoname(unsigned short index, char name[IF_NAMESIZE])
{
struct ifreq ifr;
int fd, r;

if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
__set_errno (ENXIO);
return NULL;
}
__set_errno (ENXIO);
return NULL;
}
ifr.ifr_ifindex = index;
r = ioctl(fd, SIOCGIFNAME_ETH, &ifr);
close(fd);
if(!r){
return strncpy(name, ifr.ifr_name, IF_NAMESIZE);
}
__set_errno (ENXIO);
if(!r){
return strncpy(name, ifr.ifr_name, IF_NAMESIZE);
}
__set_errno (ENXIO);
return NULL;
}

weak_alias (__if_indextoname, if_indextoname)
149 changes: 149 additions & 0 deletions socket/if_nameindex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/* $KAME: if_nameindex.c,v 1.8 2000/11/24 08:20:01 itojun Exp $ */

/*-
* SPDX-License-Identifier: BSD-1-Clause
*
* Copyright (c) 1997, 2000
* Berkeley Software Design, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* BSDI Id: if_nameindex.c,v 2.3 2000/04/17 22:38:05 dab Exp
*/

#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
/*
* From RFC 2553:
*
* 4.3 Return All Interface Names and Indexes
*
* The if_nameindex structure holds the information about a single
* interface and is defined as a result of including the <net/if.h>
* header.
*
* struct if_nameindex {
* unsigned int if_index;
* char *if_name;
* };
*
* The final function returns an array of if_nameindex structures, one
* structure per interface.
*
* struct if_nameindex *if_nameindex(void);
*
* The end of the array of structures is indicated by a structure with
* an if_index of 0 and an if_name of NULL. The function returns a NULL
* pointer upon an error, and would set errno to the appropriate value.
*
* The memory used for this array of structures along with the interface
* names pointed to by the if_name members is obtained dynamically.
* This memory is freed by the next function.
*
* 4.4. Free Memory
*
* The following function frees the dynamic memory that was allocated by
* if_nameindex().
*
* #include <net/if.h>
*
* void if_freenameindex(struct if_nameindex *ptr);
*
* The argument to this function must be a pointer that was returned by
* if_nameindex().
*/

__typeof__(if_nameindex) __if_nameindex;

struct if_nameindex*
__if_nameindex (void)
{
struct ifaddrs *ifaddrs, *ifa;
unsigned int ni;
int nbytes;
struct if_nameindex *ifni, *ifni2;
char *cp;

if (getifaddrs(&ifaddrs) < 0){
__set_errno (ENOBUFS);
return(NULL);
}
/*
* First, find out how many interfaces there are, and how
* much space we need for the string names.
*/
ni = 0;
nbytes = 0;

for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) {
nbytes += strlen(ifa->ifa_name) + 1;
ni++;
}
}

/*
* Next, allocate a chunk of memory, use the first part
* for the array of structures, and the last part for
* the strings.
*/
cp = malloc((ni + 1) * sizeof(struct if_nameindex) + nbytes);

ifni = (struct if_nameindex *)cp;
if (ifni == NULL){
__set_errno (ENOBUFS);
goto out;
}
cp += (ni + 1) * sizeof(struct if_nameindex);
/*
* Now just loop through the list of interfaces again,
* filling in the if_nameindex array and making copies
* of all the strings.
*/
ifni2 = ifni;
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
if (ifa->ifa_addr &&
ifa->ifa_addr->sa_family == AF_INET) {

ifni2->if_index = if_nametoindex(ifa->ifa_name);

ifni2->if_name = cp;
strcpy(cp, ifa->ifa_name);
ifni2++;
cp += strlen(cp) + 1;
}
}

/*
* Finally, don't forget to terminate the array.
*/
ifni2->if_index = 0;
ifni2->if_name = NULL;
out:
freeifaddrs(ifaddrs);
return(ifni);
}

weak_alias (__if_nameindex, if_nameindex)
13 changes: 7 additions & 6 deletions socket/if_nametoindex.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,23 @@
__typeof__(if_nametoindex) __if_nametoindex;

unsigned short
if_nametoindex(const char *name)
__if_nametoindex(const char *name)
{
struct ifreq ifr;
int fd, r;

if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
__set_errno (ENODEV);
return 0;
}
}
strlcpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
r = ioctl(fd, SIOCGIFINDEX, &ifr);
close(fd);
if(!r){
return ifr.ifr_ifindex;
}
__set_errno (ENODEV);
if(!r){
return ifr.ifr_ifindex;
}
__set_errno (ENODEV);
return 0;
}

weak_alias (__if_nametoindex, if_nametoindex)

0 comments on commit 566329f

Please sign in to comment.