diff --git a/Kernel/API/Ioctl.h b/Kernel/API/Ioctl.h index 354944b135..3f8b89e322 100644 --- a/Kernel/API/Ioctl.h +++ b/Kernel/API/Ioctl.h @@ -112,6 +112,8 @@ enum IOCtlNumber { SIOCSIFADDR, SIOCGIFADDR, SIOCGIFHWADDR, + SIOCGIFNAME, + SIOCGIFINDEX, SIOCGIFNETMASK, SIOCSIFNETMASK, SIOCGIFBRDADDR, @@ -174,6 +176,8 @@ enum IOCtlNumber { #define SIOCGIFADDR SIOCGIFADDR #define SIOCGIFHWADDR SIOCGIFHWADDR #define SIOCGIFNETMASK SIOCGIFNETMASK +#define SIOCGIFNAME SIOCGIFNAME +#define SIOCGIFINDEX SIOCGIFINDEX #define SIOCSIFNETMASK SIOCSIFNETMASK #define SIOCGIFBRDADDR SIOCGIFBRDADDR #define SIOCGIFMTU SIOCGIFMTU diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 39318f75ff..67ab93c33d 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -693,10 +694,55 @@ ErrorOr IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac ifreq 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 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]; memcpy(namebuf, ifr.ifr_name, IFNAMSIZ); namebuf[sizeof(namebuf) - 1] = '\0'; + if (request == SIOCGIFINDEX) { + StringView name { namebuf, strlen(namebuf) }; + size_t index = 1; + Optional 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) }); if (!adapter) return ENODEV; @@ -800,6 +846,8 @@ ErrorOr IPv4Socket::ioctl(OpenFileDescription&, unsigned request, Userspac case SIOCGIFMTU: case SIOCGIFFLAGS: case SIOCGIFCONF: + case SIOCGIFNAME: + case SIOCGIFINDEX: return ioctl_interface(); case SIOCADDRT: diff --git a/Userland/Utilities/strace.cpp b/Userland/Utilities/strace.cpp index a51e903599..4e7e615617 100644 --- a/Userland/Utilities/strace.cpp +++ b/Userland/Utilities/strace.cpp @@ -157,6 +157,8 @@ HANDLE(KEYBOARD_IOCTL_SET_CAPS_LOCK) HANDLE(SIOCSIFADDR) HANDLE(SIOCGIFADDR) HANDLE(SIOCGIFHWADDR) +HANDLE(SIOCGIFNAME) +HANDLE(SIOCGIFINDEX) HANDLE(SIOCGIFNETMASK) HANDLE(SIOCSIFNETMASK) HANDLE(SIOCGIFBRDADDR)