Skip to content

siocgifname_eth & siocgifindex calls / if_nametoindex, if_indextoname, if_nameindex & if_freenameindex functions #76

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions include/bits/in.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
#define IP_MULTICAST_LOOP 11 /* i_char; set/get IP multicast loopback */
#define IP_ADD_MEMBERSHIP 12 /* ip_mreq; add an IP group membership */
#define IP_DROP_MEMBERSHIP 13 /* ip_mreq; drop an IP group membership */

#define MCAST_JOIN_GROUP 19 /* MCAST_JOIN_GROUP is protocol independent */
#define MCAST_LEAVE_GROUP 22

#if 0 /* not yet supported or defined */
#define IP_UNBLOCK_SOURCE 14 /* ip_mreq_source: unblock data from source */
#define IP_BLOCK_SOURCE 15 /* ip_mreq_source: block data from source */
Expand Down Expand Up @@ -124,14 +128,6 @@ struct ip_opts
char ip_opts[40]; /* Actually variable in size. */
};

/* Like `struct ip_mreq' but including interface specification by index. */
struct ip_mreqn
{
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_address; /* local IP address of interface */
int imr_ifindex; /* Interface index */
};

/* Structure used for IP_PKTINFO. */
struct in_pktinfo
{
Expand Down
17 changes: 17 additions & 0 deletions include/bits/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ struct sockaddr
char sa_data[14]; /* Address data. */
};


#if 0
/* Structure large enough to hold any socket address (with the historical
exception of AF_UNIX). We reserve 128 bytes. */
#define __ss_aligntype unsigned long int
Expand All @@ -186,7 +188,22 @@ struct sockaddr_storage
__ss_aligntype __ss_align; /* Force desired alignment. */
char __ss_padding[_SS_PADSIZE];
};
#endif

/*
* Desired design of maximum size and alignment.
*/
#define _SS_MAXSIZE 128
#define _SS_ALIGNSIZE sizeof(unsigned short)

#define _SS_PAD1SIZE ((2 * _SS_ALIGNSIZE - sizeof (sa_family_t)) % _SS_ALIGNSIZE)
#define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (sa_family_t) + _SS_PAD1SIZE + _SS_ALIGNSIZE))

struct sockaddr_storage {
sa_family_t ss_family;
char __ss_pad1[_SS_PAD1SIZE];
unsigned long __ss_align[_SS_PAD2SIZE / sizeof(unsigned long) + 1];
};

/* Bits in the FLAGS argument to `send', `recv', et al. */
enum
Expand Down
15 changes: 15 additions & 0 deletions include/net/if.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ struct ifreq {
struct sockaddr ifru_broadaddr;
struct sockaddr ifru_netmask;
short ifru_flags;
short ifru_ifindex;
long ifru_metric;
long ifru_mtu;
struct ifstat ifru_stats;
Expand All @@ -156,6 +157,7 @@ struct ifreq {
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
#define ifr_netmask ifr_ifru.ifru_netmask /* netmask */
#define ifr_flags ifr_ifru.ifru_flags /* flags */
#define ifr_ifindex ifr_ifru.ifru_ifindex /* ifindex */
#define ifr_metric ifr_ifru.ifru_metric /* metric */
#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
#define ifr_stats ifr_ifru.ifru_stats /* statistics */
Expand Down Expand Up @@ -216,6 +218,19 @@ 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

#endif /* _NET_IF_H */
9 changes: 9 additions & 0 deletions include/netinet/in.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,15 @@ struct ip_mreq_source
/* IP address of source. */
struct in_addr imr_sourceaddr;
};

/* Like `struct ip_mreq' but including interface specification by index. */
struct ip_mreqn
{
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_address; /* local IP address of interface */
int imr_ifindex; /* Interface index */
};

#endif

#if !__USE_KERNEL_IPV6_DEFS
Expand Down
13 changes: 13 additions & 0 deletions include/sockios.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,22 @@
#define SIOCADDRT (('S' << 8) | 30) /* add routing table entry */
#define SIOCDELRT (('S' << 8) | 31) /* delete routing table entry */

/* network devices calls */
#define SIOCGIFNAME_ETH (('S' << 8) | 32) /* return the name of the interface */
#define SIOCGIFINDEX (('S' << 8) | 33) /* retrieve the interface index */

/* ARP cache control calls */
#define SIOCDARP (('S' << 8) | 40) /* delete ARP table entry */
#define SIOCGARP (('S' << 8) | 41) /* get ARP table entry */
#define SIOCSARP (('S' << 8) | 42) /* set ARP table entry */

#ifdef __USE_GNU

#ifdef SIOCGIFNAME
#undef SIOCGIFNAME
#define SIOCGIFNAME SIOCGIFNAME_ETH
#endif

#endif

#endif /* _SOCKIOS_H */
4 changes: 4 additions & 0 deletions socket/SRCFILES
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ 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 \
inet_makeaddr.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)
30 changes: 30 additions & 0 deletions socket/if_indextoname.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <net/if.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

__typeof__(if_indextoname) __if_indextoname;

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;
}
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);
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)
30 changes: 30 additions & 0 deletions socket/if_nametoindex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <net/if.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

__typeof__(if_nametoindex) __if_nametoindex;

unsigned short
__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);
return 0;
}

weak_alias (__if_nametoindex, if_nametoindex)