[libc] Implement if_nametoindex and if_indextoname (#206082)
This patch implements if_nametoindex and if_indextoname for Linux. Both functions work by creating a temporary AF_UNIX socket and issuing ioctl calls (SIOCGIFINDEX and SIOCGIFNAME, respectively). The main implementation details: - for if_nametoindex, I check that the interface name fits within IF_NAMESIZE before issuing the ioctl - for if_indextoname, if the kernel returns ENODEV for an unknown index, I map it to ENXIO to comply with POSIX requirements - added the definition of struct ifreq to support these operations. Similar to the other net structure definitions, I'm using an anonymous union to avoid #defining members. Assisted by Gemini.
This commit is contained in:
parent
b4c4fd9ee3
commit
12c36c7abb
27 changed files with 585 additions and 0 deletions
|
|
@ -1033,6 +1033,10 @@ if(LLVM_LIBC_FULL_BUILD)
|
|||
libc.src.arpa.inet.ntohl
|
||||
libc.src.arpa.inet.ntohs
|
||||
|
||||
# net/if.h entrypoints
|
||||
libc.src.net.if_indextoname
|
||||
libc.src.net.if_nametoindex
|
||||
|
||||
# netinet/in.h entrypoints
|
||||
libc.src.netinet.in6addr_any
|
||||
libc.src.netinet.in6addr_loopback
|
||||
|
|
|
|||
|
|
@ -1167,6 +1167,10 @@ if(LLVM_LIBC_FULL_BUILD)
|
|||
libc.src.arpa.inet.ntohl
|
||||
libc.src.arpa.inet.ntohs
|
||||
|
||||
# net/if.h entrypoints
|
||||
libc.src.net.if_indextoname
|
||||
libc.src.net.if_nametoindex
|
||||
|
||||
# netinet/in.h entrypoints
|
||||
libc.src.netinet.in6addr_any
|
||||
libc.src.netinet.in6addr_loopback
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ set(TARGET_LIBC_ENTRYPOINTS
|
|||
libc.src.fcntl.open
|
||||
libc.src.fcntl.openat
|
||||
|
||||
# net/if.h entrypoints
|
||||
libc.src.net.if_indextoname
|
||||
libc.src.net.if_nametoindex
|
||||
|
||||
# netinet/in.h entrypoints
|
||||
libc.src.netinet.in6addr_any
|
||||
libc.src.netinet.in6addr_loopback
|
||||
|
|
|
|||
|
|
@ -86,6 +86,15 @@ add_proxy_header_library(
|
|||
libc.include.llvm-libc-macros.inet_address_macros
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
net_if_macros
|
||||
HDRS
|
||||
net_if_macros.h
|
||||
FULL_BUILD_DEPENDS
|
||||
libc.include.net_if
|
||||
libc.include.llvm-libc-macros.net_if_macros
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
netinet_in_macros
|
||||
HDRS
|
||||
|
|
|
|||
27
libc/hdr/net_if_macros.h
Normal file
27
libc/hdr/net_if_macros.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Definition of macros from net/if.h.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_HDR_NET_IF_MACROS_H
|
||||
#define LLVM_LIBC_HDR_NET_IF_MACROS_H
|
||||
|
||||
#ifdef LIBC_FULL_BUILD
|
||||
|
||||
#include "include/llvm-libc-macros/net-if-macros.h"
|
||||
|
||||
#else // Overlay mode
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#endif // LIBC_FULL_BUILD
|
||||
|
||||
#endif // LLVM_LIBC_HDR_NET_IF_MACROS_H
|
||||
|
|
@ -538,6 +538,15 @@ add_proxy_header_library(
|
|||
libc.include.arpa_inet
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
struct_ifreq
|
||||
HDRS
|
||||
struct_ifreq.h
|
||||
FULL_BUILD_DEPENDS
|
||||
libc.include.llvm-libc-types.struct_ifreq
|
||||
libc.include.net_if
|
||||
)
|
||||
|
||||
add_proxy_header_library(
|
||||
struct_sockaddr
|
||||
HDRS
|
||||
|
|
|
|||
26
libc/hdr/types/struct_ifreq.h
Normal file
26
libc/hdr/types/struct_ifreq.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Proxy for struct ifreq.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_IFREQ_H
|
||||
#define LLVM_LIBC_HDR_TYPES_STRUCT_IFREQ_H
|
||||
|
||||
#ifdef LIBC_FULL_BUILD
|
||||
|
||||
#include "include/llvm-libc-types/struct_ifreq.h"
|
||||
|
||||
#else
|
||||
|
||||
#include <net/if.h>
|
||||
|
||||
#endif // LIBC_FULL_BUILD
|
||||
|
||||
#endif // LLVM_LIBC_HDR_TYPES_STRUCT_IFREQ_H
|
||||
|
|
@ -896,6 +896,18 @@ add_header_macro(
|
|||
.llvm-libc-types.siginfo_t
|
||||
)
|
||||
|
||||
file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/net)
|
||||
|
||||
add_header_macro(
|
||||
net_if
|
||||
../libc/include/net/if.yaml
|
||||
net/if.h
|
||||
DEPENDS
|
||||
.llvm_libc_common_h
|
||||
.llvm-libc-macros.net_if_macros
|
||||
.llvm-libc-types.struct_ifreq
|
||||
)
|
||||
|
||||
# TODO: This should be conditional on POSIX networking being included.
|
||||
file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/netinet)
|
||||
|
||||
|
|
|
|||
|
|
@ -314,6 +314,12 @@ add_macro_header(
|
|||
sys-socket-macros.h
|
||||
)
|
||||
|
||||
add_macro_header(
|
||||
net_if_macros
|
||||
HDR
|
||||
net-if-macros.h
|
||||
)
|
||||
|
||||
add_macro_header(
|
||||
sys_time_macros
|
||||
HDR
|
||||
|
|
|
|||
|
|
@ -64,6 +64,12 @@ add_header(
|
|||
sys-socket-macros.h
|
||||
)
|
||||
|
||||
add_header(
|
||||
net_if_macros
|
||||
HDR
|
||||
net-if-macros.h
|
||||
)
|
||||
|
||||
add_header(
|
||||
sys_wait_macros
|
||||
HDR
|
||||
|
|
|
|||
19
libc/include/llvm-libc-macros/linux/net-if-macros.h
Normal file
19
libc/include/llvm-libc-macros/linux/net-if-macros.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Macros defined in net/if.h header file.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_MACROS_LINUX_NET_IF_MACROS_H
|
||||
#define LLVM_LIBC_MACROS_LINUX_NET_IF_MACROS_H
|
||||
|
||||
#define IF_NAMESIZE 16
|
||||
|
||||
#endif // LLVM_LIBC_MACROS_LINUX_NET_IF_MACROS_H
|
||||
21
libc/include/llvm-libc-macros/net-if-macros.h
Normal file
21
libc/include/llvm-libc-macros/net-if-macros.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Macros defined in net/if.h header file.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_MACROS_NET_IF_MACROS_H
|
||||
#define LLVM_LIBC_MACROS_NET_IF_MACROS_H
|
||||
|
||||
#ifdef __linux__
|
||||
#include "linux/net-if-macros.h"
|
||||
#endif
|
||||
|
||||
#endif // LLVM_LIBC_MACROS_NET_IF_MACROS_H
|
||||
|
|
@ -226,6 +226,7 @@ add_header(
|
|||
)
|
||||
add_header(struct_sockaddr_storage HDR struct_sockaddr_storage.h DEPENDS .sa_family_t)
|
||||
add_header(struct_sockaddr_un HDR struct_sockaddr_un.h DEPENDS .sa_family_t)
|
||||
add_header(struct_ifreq HDR struct_ifreq.h DEPENDS libc.include.llvm-libc-macros.net_if_macros .struct_sockaddr)
|
||||
add_header(struct_iovec HDR struct_iovec.h DEPENDS .size_t)
|
||||
add_header(struct_linger HDR struct_linger.h)
|
||||
add_header(struct_cmsghdr HDR struct_cmsghdr.h DEPENDS .size_t)
|
||||
|
|
|
|||
40
libc/include/llvm-libc-types/struct_ifreq.h
Normal file
40
libc/include/llvm-libc-types/struct_ifreq.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Definition of struct ifreq.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_TYPES_STRUCT_IFREQ_H
|
||||
#define LLVM_LIBC_TYPES_STRUCT_IFREQ_H
|
||||
|
||||
#include "../llvm-libc-macros/net-if-macros.h"
|
||||
#include "struct_sockaddr.h"
|
||||
|
||||
struct ifreq {
|
||||
char ifr_name[IF_NAMESIZE];
|
||||
__extension__ union {
|
||||
struct sockaddr ifr_hwaddr;
|
||||
struct sockaddr ifr_addr;
|
||||
struct sockaddr ifr_dstaddr;
|
||||
struct sockaddr ifr_broadaddr;
|
||||
struct sockaddr ifr_netmask;
|
||||
short int ifr_flags;
|
||||
int ifr_metric;
|
||||
int ifr_mtu;
|
||||
int ifr_ifindex;
|
||||
int ifr_bandwidth;
|
||||
int ifr_qlen;
|
||||
char ifr_newname[IF_NAMESIZE];
|
||||
char ifr_slave[IF_NAMESIZE];
|
||||
char *ifr_data;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // LLVM_LIBC_TYPES_STRUCT_IFREQ_H
|
||||
24
libc/include/net/if.yaml
Normal file
24
libc/include/net/if.yaml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
header: net/if.h
|
||||
standards:
|
||||
- posix
|
||||
macros:
|
||||
- macro_name: IF_NAMESIZE
|
||||
macro_header: net-if-macros.h
|
||||
types:
|
||||
- type_name: struct_ifreq
|
||||
enums: []
|
||||
objects: []
|
||||
functions:
|
||||
- name: if_indextoname
|
||||
standards:
|
||||
- posix
|
||||
return_type: char *
|
||||
arguments:
|
||||
- type: unsigned int
|
||||
- type: char *
|
||||
- name: if_nametoindex
|
||||
standards:
|
||||
- posix
|
||||
return_type: unsigned int
|
||||
arguments:
|
||||
- type: const char *
|
||||
|
|
@ -10,6 +10,7 @@ add_subdirectory(inttypes)
|
|||
add_subdirectory(libgen)
|
||||
add_subdirectory(link)
|
||||
add_subdirectory(math)
|
||||
add_subdirectory(net)
|
||||
add_subdirectory(netinet)
|
||||
add_subdirectory(stdbit)
|
||||
add_subdirectory(stdfix)
|
||||
|
|
|
|||
17
libc/src/net/CMakeLists.txt
Normal file
17
libc/src/net/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
|
||||
endif()
|
||||
|
||||
add_entrypoint_object(
|
||||
if_indextoname
|
||||
ALIAS
|
||||
DEPENDS
|
||||
.${LIBC_TARGET_OS}.if_indextoname
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
if_nametoindex
|
||||
ALIAS
|
||||
DEPENDS
|
||||
.${LIBC_TARGET_OS}.if_nametoindex
|
||||
)
|
||||
25
libc/src/net/if_indextoname.h
Normal file
25
libc/src/net/if_indextoname.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Implementation header for if_indextoname.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_NET_IF_INDEXTONAME_H
|
||||
#define LLVM_LIBC_SRC_NET_IF_INDEXTONAME_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
char *if_indextoname(unsigned int ifindex, char *ifname);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_NET_IF_INDEXTONAME_H
|
||||
25
libc/src/net/if_nametoindex.h
Normal file
25
libc/src/net/if_nametoindex.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Implementation header for if_nametoindex.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIBC_SRC_NET_IF_NAMETOINDEX_H
|
||||
#define LLVM_LIBC_SRC_NET_IF_NAMETOINDEX_H
|
||||
|
||||
#include "src/__support/macros/config.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
unsigned int if_nametoindex(const char *ifname);
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
||||
#endif // LLVM_LIBC_SRC_NET_IF_NAMETOINDEX_H
|
||||
44
libc/src/net/linux/CMakeLists.txt
Normal file
44
libc/src/net/linux/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
add_entrypoint_object(
|
||||
if_indextoname
|
||||
SRCS
|
||||
if_indextoname.cpp
|
||||
HDRS
|
||||
../if_indextoname.h
|
||||
DEPENDS
|
||||
libc.hdr.net_if_macros
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.sys_ioctl_macros
|
||||
libc.hdr.sys_socket_macros
|
||||
libc.hdr.types.struct_ifreq
|
||||
libc.src.__support.CPP.string_view
|
||||
libc.src.__support.common
|
||||
libc.src.__support.macros.null_check
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.socket
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.close
|
||||
libc.src.errno.errno
|
||||
libc.src.string.memory_utils.inline_memcpy
|
||||
libc.src.string.string_utils
|
||||
)
|
||||
|
||||
add_entrypoint_object(
|
||||
if_nametoindex
|
||||
SRCS
|
||||
if_nametoindex.cpp
|
||||
HDRS
|
||||
../if_nametoindex.h
|
||||
DEPENDS
|
||||
libc.hdr.net_if_macros
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.sys_ioctl_macros
|
||||
libc.hdr.sys_socket_macros
|
||||
libc.hdr.types.struct_ifreq
|
||||
libc.src.__support.CPP.string_view
|
||||
libc.src.__support.common
|
||||
libc.src.__support.macros.null_check
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.socket
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.ioctl
|
||||
libc.src.__support.OSUtil.linux.syscall_wrappers.close
|
||||
libc.src.errno.errno
|
||||
libc.src.string.memory_utils.inline_memcpy
|
||||
)
|
||||
71
libc/src/net/linux/if_indextoname.cpp
Normal file
71
libc/src/net/linux/if_indextoname.cpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Linux implementation of if_indextoname.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/net/if_indextoname.h"
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/net_if_macros.h"
|
||||
#include "hdr/sys_ioctl_macros.h"
|
||||
#include "hdr/sys_socket_macros.h"
|
||||
#include "hdr/types/struct_ifreq.h"
|
||||
#include "src/__support/CPP/string_view.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/close.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/ioctl.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/socket.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/null_check.h"
|
||||
#include "src/string/memory_utils/inline_memcpy.h"
|
||||
#include "src/string/string_utils.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(char *, if_indextoname,
|
||||
(unsigned int ifindex, char *ifname)) {
|
||||
LIBC_CRASH_ON_NULLPTR(ifname);
|
||||
|
||||
ErrorOr<int> fd =
|
||||
linux_syscalls::socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||
if (!fd.has_value()) {
|
||||
libc_errno = fd.error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct ifreq ifr;
|
||||
ifr.ifr_ifindex = static_cast<int>(ifindex);
|
||||
|
||||
ErrorOr<int> ioctl_res = linux_syscalls::ioctl(*fd, SIOCGIFNAME, &ifr);
|
||||
|
||||
if (ErrorOr<int> res = linux_syscalls::close(*fd); !res.has_value()) {
|
||||
libc_errno = res.error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ioctl_res.has_value()) {
|
||||
// Map kernel ENODEV to POSIX-mandated ENXIO.
|
||||
libc_errno = (ioctl_res.error() == ENODEV) ? ENXIO : ioctl_res.error();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cpp::string_view k_name(
|
||||
ifr.ifr_name, internal::strnlen(ifr.ifr_name, sizeof(ifr.ifr_name)));
|
||||
inline_memcpy(ifname, k_name.data(), k_name.size());
|
||||
// Linux kernel does allow network devices exactly IF_NAMESIZE long (it leaves
|
||||
// room for the terminating \0). But if that happens, let's not overrun the
|
||||
// user provided buffer.
|
||||
if (k_name.size() < IF_NAMESIZE)
|
||||
ifname[k_name.size()] = '\0';
|
||||
|
||||
return ifname;
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
65
libc/src/net/linux/if_nametoindex.cpp
Normal file
65
libc/src/net/linux/if_nametoindex.cpp
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Linux implementation of if_nametoindex.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "src/net/if_nametoindex.h"
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/net_if_macros.h"
|
||||
#include "hdr/sys_ioctl_macros.h"
|
||||
#include "hdr/sys_socket_macros.h"
|
||||
#include "hdr/types/struct_ifreq.h"
|
||||
#include "src/__support/CPP/string_view.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/close.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/ioctl.h"
|
||||
#include "src/__support/OSUtil/linux/syscall_wrappers/socket.h"
|
||||
#include "src/__support/common.h"
|
||||
#include "src/__support/libc_errno.h"
|
||||
#include "src/__support/macros/null_check.h"
|
||||
#include "src/string/memory_utils/inline_memcpy.h"
|
||||
|
||||
namespace LIBC_NAMESPACE_DECL {
|
||||
|
||||
LLVM_LIBC_FUNCTION(unsigned int, if_nametoindex, (const char *ifname)) {
|
||||
LIBC_CRASH_ON_NULLPTR(ifname);
|
||||
|
||||
cpp::string_view name(ifname);
|
||||
if (name.empty() || name.size() >= IF_NAMESIZE) {
|
||||
libc_errno = ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ErrorOr<int> fd =
|
||||
linux_syscalls::socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||
if (!fd.has_value()) {
|
||||
libc_errno = fd.error();
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ifreq ifr;
|
||||
inline_memcpy(ifr.ifr_name, name.data(), name.size() + 1);
|
||||
|
||||
ErrorOr<int> ioctl_res = linux_syscalls::ioctl(*fd, SIOCGIFINDEX, &ifr);
|
||||
|
||||
if (ErrorOr<int> res = linux_syscalls::close(*fd); !res.has_value()) {
|
||||
libc_errno = res.error();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ioctl_res.has_value()) {
|
||||
libc_errno = ioctl_res.error();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return static_cast<unsigned int>(ifr.ifr_ifindex);
|
||||
}
|
||||
|
||||
} // namespace LIBC_NAMESPACE_DECL
|
||||
|
|
@ -66,6 +66,7 @@ add_subdirectory(fenv)
|
|||
add_subdirectory(libgen)
|
||||
add_subdirectory(link)
|
||||
add_subdirectory(math)
|
||||
add_subdirectory(net)
|
||||
add_subdirectory(netinet)
|
||||
add_subdirectory(search)
|
||||
add_subdirectory(setjmp)
|
||||
|
|
|
|||
4
libc/test/src/net/CMakeLists.txt
Normal file
4
libc/test/src/net/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
|
||||
add_subdirectory(${LIBC_TARGET_OS})
|
||||
endif()
|
||||
|
||||
27
libc/test/src/net/linux/CMakeLists.txt
Normal file
27
libc/test/src/net/linux/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
add_custom_target(libc_net_unittests)
|
||||
|
||||
add_libc_unittest(
|
||||
if_indextoname_test
|
||||
SUITE
|
||||
libc_net_unittests
|
||||
SRCS
|
||||
if_indextoname_test.cpp
|
||||
DEPENDS
|
||||
libc.hdr.errno_macros
|
||||
libc.hdr.net_if_macros
|
||||
libc.src.net.if_indextoname
|
||||
libc.src.net.if_nametoindex
|
||||
libc.test.UnitTest.ErrnoCheckingTest
|
||||
)
|
||||
|
||||
add_libc_unittest(
|
||||
if_nametoindex_test
|
||||
SUITE
|
||||
libc_net_unittests
|
||||
SRCS
|
||||
if_nametoindex_test.cpp
|
||||
DEPENDS
|
||||
libc.hdr.errno_macros
|
||||
libc.src.net.if_nametoindex
|
||||
libc.test.UnitTest.ErrnoCheckingTest
|
||||
)
|
||||
51
libc/test/src/net/linux/if_indextoname_test.cpp
Normal file
51
libc/test/src/net/linux/if_indextoname_test.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Unittests for if_indextoname.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "hdr/net_if_macros.h"
|
||||
#include "src/net/if_indextoname.h"
|
||||
#include "src/net/if_nametoindex.h"
|
||||
#include "test/UnitTest/ErrnoCheckingTest.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
||||
using LlvmLibcIfIndexToNameTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
|
||||
|
||||
TEST_F(LlvmLibcIfIndexToNameTest, Loopback) {
|
||||
unsigned int lo_idx = LIBC_NAMESPACE::if_nametoindex("lo");
|
||||
ASSERT_GT(lo_idx, 0u);
|
||||
|
||||
char buf[IF_NAMESIZE];
|
||||
char *res = LIBC_NAMESPACE::if_indextoname(lo_idx, buf);
|
||||
ASSERT_EQ(res, buf);
|
||||
ASSERT_STREQ(buf, "lo");
|
||||
ASSERT_ERRNO_SUCCESS();
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcIfIndexToNameTest, InvalidIndex) {
|
||||
char buf[IF_NAMESIZE];
|
||||
char *res = LIBC_NAMESPACE::if_indextoname(-1u, buf);
|
||||
ASSERT_EQ(res, static_cast<char *>(nullptr));
|
||||
ASSERT_ERRNO_EQ(ENXIO);
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcIfIndexToNameTest, ZeroIndex) {
|
||||
char buf[IF_NAMESIZE];
|
||||
char *res = LIBC_NAMESPACE::if_indextoname(0u, buf);
|
||||
ASSERT_EQ(res, static_cast<char *>(nullptr));
|
||||
ASSERT_ERRNO_EQ(ENXIO);
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcIfIndexToNameTest, NullPtrDeath) {
|
||||
ASSERT_DEATH([]() { LIBC_NAMESPACE::if_indextoname(1u, nullptr); },
|
||||
WITH_SIGNAL(-1));
|
||||
}
|
||||
42
libc/test/src/net/linux/if_nametoindex_test.cpp
Normal file
42
libc/test/src/net/linux/if_nametoindex_test.cpp
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// Unittests for if_nametoindex.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "hdr/errno_macros.h"
|
||||
#include "src/net/if_nametoindex.h"
|
||||
#include "test/UnitTest/ErrnoCheckingTest.h"
|
||||
#include "test/UnitTest/Test.h"
|
||||
|
||||
using LlvmLibcIfNameToIndexTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
|
||||
|
||||
TEST_F(LlvmLibcIfNameToIndexTest, Loopback) {
|
||||
unsigned int idx = LIBC_NAMESPACE::if_nametoindex("lo");
|
||||
ASSERT_GT(idx, 0u);
|
||||
ASSERT_ERRNO_SUCCESS();
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcIfNameToIndexTest, InvalidName) {
|
||||
unsigned int idx = LIBC_NAMESPACE::if_nametoindex("nonexistent_if");
|
||||
ASSERT_EQ(idx, 0u);
|
||||
ASSERT_ERRNO_EQ(ENODEV);
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcIfNameToIndexTest, EmptyName) {
|
||||
unsigned int idx = LIBC_NAMESPACE::if_nametoindex("");
|
||||
ASSERT_EQ(idx, 0u);
|
||||
ASSERT_ERRNO_EQ(ENODEV);
|
||||
}
|
||||
|
||||
TEST_F(LlvmLibcIfNameToIndexTest, NullPtrDeath) {
|
||||
ASSERT_DEATH([]() { LIBC_NAMESPACE::if_nametoindex(nullptr); },
|
||||
WITH_SIGNAL(-1));
|
||||
}
|
||||
Loading…
Reference in a new issue