From 8313d357499b3ac473120252143037e6e633bf60 Mon Sep 17 00:00:00 2001 From: brapru Date: Sat, 24 Jul 2021 20:04:11 -0400 Subject: [PATCH] Kernel: Support ioctl SIOCSARP and SIOCDARP Creates ioctl calls necessary to set/delete an entry from the ARP table --- Kernel/Net/IPv4Socket.cpp | 30 +++++++++++++++++++++ Kernel/UnixTypes.h | 8 ++++++ Userland/Libraries/LibC/net/route.h | 8 ++++++ Userland/Libraries/LibC/sys/ioctl_numbers.h | 4 +++ 4 files changed, 50 insertions(+) diff --git a/Kernel/Net/IPv4Socket.cpp b/Kernel/Net/IPv4Socket.cpp index 011efabdea..aded09dc5a 100644 --- a/Kernel/Net/IPv4Socket.cpp +++ b/Kernel/Net/IPv4Socket.cpp @@ -604,6 +604,32 @@ int IPv4Socket::ioctl(FileDescription&, unsigned request, FlatPtr arg) return -EINVAL; }; + auto ioctl_arp = [request, arg]() { + arpreq arp_req; + if (!copy_from_user(&arp_req, (arpreq*)arg)) + return -EFAULT; + + switch (request) { + case SIOCSARP: + if (!Process::current()->is_superuser()) + return -EPERM; + if (arp_req.arp_pa.sa_family != AF_INET) + return -EAFNOSUPPORT; + update_arp_table(IPv4Address(((sockaddr_in&)arp_req.arp_pa).sin_addr.s_addr), *(MACAddress*)&arp_req.arp_ha.sa_data[0], UpdateArp::Set); + return 0; + + case SIOCDARP: + if (!Process::current()->is_superuser()) + return -EPERM; + if (arp_req.arp_pa.sa_family != AF_INET) + return -EAFNOSUPPORT; + update_arp_table(IPv4Address(((sockaddr_in&)arp_req.arp_pa).sin_addr.s_addr), *(MACAddress*)&arp_req.arp_ha.sa_data[0], UpdateArp::Delete); + return 0; + } + + return -EINVAL; + }; + auto ioctl_interface = [request, arg]() { ifreq* user_ifr = (ifreq*)arg; ifreq ifr; @@ -730,6 +756,10 @@ int IPv4Socket::ioctl(FileDescription&, unsigned request, FlatPtr arg) case SIOCADDRT: case SIOCDELRT: return ioctl_route(); + + case SIOCSARP: + case SIOCDARP: + return ioctl_arp(); } return -EINVAL; diff --git a/Kernel/UnixTypes.h b/Kernel/UnixTypes.h index 53ba25595c..88a69f5070 100644 --- a/Kernel/UnixTypes.h +++ b/Kernel/UnixTypes.h @@ -691,6 +691,14 @@ struct rtentry { #define AT_FDCWD -100 #define AT_SYMLINK_NOFOLLOW 0x100 +struct arpreq { + struct sockaddr arp_pa; /* protocol address */ + struct sockaddr arp_ha; /* hardware address */ + struct sockaddr arp_netmask; /* netmask of protocol address */ + int arp_flags; /* flags */ + char arp_dev[16]; +}; + #define PURGE_ALL_VOLATILE 0x1 #define PURGE_ALL_CLEAN_INODE 0x2 diff --git a/Userland/Libraries/LibC/net/route.h b/Userland/Libraries/LibC/net/route.h index 27cf9596c6..aa82d81c92 100644 --- a/Userland/Libraries/LibC/net/route.h +++ b/Userland/Libraries/LibC/net/route.h @@ -18,3 +18,11 @@ struct rtentry { #define RTF_UP 0x1 /* do not delete the route */ #define RTF_GATEWAY 0x2 /* the route is a gateway and not an end host */ + +struct arpreq { + struct sockaddr arp_pa; /* protocol address */ + struct sockaddr arp_ha; /* hardware address */ + struct sockaddr arp_netmask; /* netmask of protocol address */ + int arp_flags; /* flags */ + char arp_dev[16]; +}; diff --git a/Userland/Libraries/LibC/sys/ioctl_numbers.h b/Userland/Libraries/LibC/sys/ioctl_numbers.h index 234a5decd2..0e24317ac9 100644 --- a/Userland/Libraries/LibC/sys/ioctl_numbers.h +++ b/Userland/Libraries/LibC/sys/ioctl_numbers.h @@ -79,6 +79,8 @@ enum IOCtlNumber { SIOCGIFCONF, SIOCADDRT, SIOCDELRT, + SIOCSARP, + SIOCDARP, FIBMAP, FIONBIO, }; @@ -117,5 +119,7 @@ enum IOCtlNumber { #define SIOCGIFCONF SIOCGIFCONF #define SIOCADDRT SIOCADDRT #define SIOCDELRT SIOCDELRT +#define SIOCSARP SIOCSARP +#define SIOCDARP SIOCDARP #define FIBMAP FIBMAP #define FIONBIO FIONBIO