Kernel/Net: Implement SIOCGIFINDEX and SIOCGIFNAME for sockets
These ioctls exist on Linux and can be used to implement libc functions if_indextoname and if_nametoindex (without needing to parse any JSON).
This commit is contained in:
parent
47c21cc349
commit
38dc54317c
Notes:
sideshowbarker
2024-07-17 18:23:22 +09:00
Author: https://github.com/kuzux Commit: https://github.com/SerenityOS/serenity/commit/38dc54317c Pull-request: https://github.com/SerenityOS/serenity/pull/17000 Reviewed-by: https://github.com/supercomputer7 ✅
3 changed files with 54 additions and 0 deletions
|
@ -112,6 +112,8 @@ enum IOCtlNumber {
|
||||||
SIOCSIFADDR,
|
SIOCSIFADDR,
|
||||||
SIOCGIFADDR,
|
SIOCGIFADDR,
|
||||||
SIOCGIFHWADDR,
|
SIOCGIFHWADDR,
|
||||||
|
SIOCGIFNAME,
|
||||||
|
SIOCGIFINDEX,
|
||||||
SIOCGIFNETMASK,
|
SIOCGIFNETMASK,
|
||||||
SIOCSIFNETMASK,
|
SIOCSIFNETMASK,
|
||||||
SIOCGIFBRDADDR,
|
SIOCGIFBRDADDR,
|
||||||
|
@ -174,6 +176,8 @@ enum IOCtlNumber {
|
||||||
#define SIOCGIFADDR SIOCGIFADDR
|
#define SIOCGIFADDR SIOCGIFADDR
|
||||||
#define SIOCGIFHWADDR SIOCGIFHWADDR
|
#define SIOCGIFHWADDR SIOCGIFHWADDR
|
||||||
#define SIOCGIFNETMASK SIOCGIFNETMASK
|
#define SIOCGIFNETMASK SIOCGIFNETMASK
|
||||||
|
#define SIOCGIFNAME SIOCGIFNAME
|
||||||
|
#define SIOCGIFINDEX SIOCGIFINDEX
|
||||||
#define SIOCSIFNETMASK SIOCSIFNETMASK
|
#define SIOCSIFNETMASK SIOCSIFNETMASK
|
||||||
#define SIOCGIFBRDADDR SIOCGIFBRDADDR
|
#define SIOCGIFBRDADDR SIOCGIFBRDADDR
|
||||||
#define SIOCGIFMTU SIOCGIFMTU
|
#define SIOCGIFMTU SIOCGIFMTU
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <AK/Singleton.h>
|
#include <AK/Singleton.h>
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
|
#include <AK/StringView.h>
|
||||||
#include <Kernel/API/Ioctl.h>
|
#include <Kernel/API/Ioctl.h>
|
||||||
#include <Kernel/API/POSIX/errno.h>
|
#include <Kernel/API/POSIX/errno.h>
|
||||||
#include <Kernel/Debug.h>
|
#include <Kernel/Debug.h>
|
||||||
|
@ -693,10 +694,55 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac
|
||||||
ifreq ifr;
|
ifreq ifr;
|
||||||
TRY(copy_from_user(&ifr, user_ifr));
|
TRY(copy_from_user(&ifr, user_ifr));
|
||||||
|
|
||||||
|
if (request == SIOCGIFNAME) {
|
||||||
|
// NOTE: Network devices are 1-indexed since index 0 denotes an invalid device
|
||||||
|
if (ifr.ifr_index == 0)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
size_t index = 1;
|
||||||
|
Optional<StringView> result {};
|
||||||
|
|
||||||
|
NetworkingManagement::the().for_each([&ifr, &index, &result](auto& adapter) {
|
||||||
|
if (index == ifr.ifr_index)
|
||||||
|
result = adapter.name();
|
||||||
|
++index;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.has_value()) {
|
||||||
|
auto name = result.release_value();
|
||||||
|
auto succ = name.copy_characters_to_buffer(ifr.ifr_name, IFNAMSIZ);
|
||||||
|
if (!succ) {
|
||||||
|
return EFAULT;
|
||||||
|
}
|
||||||
|
return copy_to_user(user_ifr, &ifr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
char namebuf[IFNAMSIZ + 1];
|
char namebuf[IFNAMSIZ + 1];
|
||||||
memcpy(namebuf, ifr.ifr_name, IFNAMSIZ);
|
memcpy(namebuf, ifr.ifr_name, IFNAMSIZ);
|
||||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
namebuf[sizeof(namebuf) - 1] = '\0';
|
||||||
|
|
||||||
|
if (request == SIOCGIFINDEX) {
|
||||||
|
StringView name { namebuf, strlen(namebuf) };
|
||||||
|
size_t index = 1;
|
||||||
|
Optional<size_t> result {};
|
||||||
|
|
||||||
|
NetworkingManagement::the().for_each([&name, &index, &result](auto& adapter) {
|
||||||
|
if (adapter.name() == name)
|
||||||
|
result = index;
|
||||||
|
++index;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (result.has_value()) {
|
||||||
|
ifr.ifr_index = result.release_value();
|
||||||
|
return copy_to_user(user_ifr, &ifr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
auto adapter = NetworkingManagement::the().lookup_by_name({ namebuf, strlen(namebuf) });
|
auto adapter = NetworkingManagement::the().lookup_by_name({ namebuf, strlen(namebuf) });
|
||||||
if (!adapter)
|
if (!adapter)
|
||||||
return ENODEV;
|
return ENODEV;
|
||||||
|
@ -800,6 +846,8 @@ ErrorOr<void> IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac
|
||||||
case SIOCGIFMTU:
|
case SIOCGIFMTU:
|
||||||
case SIOCGIFFLAGS:
|
case SIOCGIFFLAGS:
|
||||||
case SIOCGIFCONF:
|
case SIOCGIFCONF:
|
||||||
|
case SIOCGIFNAME:
|
||||||
|
case SIOCGIFINDEX:
|
||||||
return ioctl_interface();
|
return ioctl_interface();
|
||||||
|
|
||||||
case SIOCADDRT:
|
case SIOCADDRT:
|
||||||
|
|
|
@ -157,6 +157,8 @@ HANDLE(KEYBOARD_IOCTL_SET_CAPS_LOCK)
|
||||||
HANDLE(SIOCSIFADDR)
|
HANDLE(SIOCSIFADDR)
|
||||||
HANDLE(SIOCGIFADDR)
|
HANDLE(SIOCGIFADDR)
|
||||||
HANDLE(SIOCGIFHWADDR)
|
HANDLE(SIOCGIFHWADDR)
|
||||||
|
HANDLE(SIOCGIFNAME)
|
||||||
|
HANDLE(SIOCGIFINDEX)
|
||||||
HANDLE(SIOCGIFNETMASK)
|
HANDLE(SIOCGIFNETMASK)
|
||||||
HANDLE(SIOCSIFNETMASK)
|
HANDLE(SIOCSIFNETMASK)
|
||||||
HANDLE(SIOCGIFBRDADDR)
|
HANDLE(SIOCGIFBRDADDR)
|
||||||
|
|
Loading…
Add table
Reference in a new issue