Kernel/LibC: Implement basic ioctl for network addresses
This commit is contained in:
parent
c18f72ceb9
commit
e1ffbb710b
|
@ -112,6 +112,8 @@ namespace Kernel
|
||||||
BAN::ErrorOr<void> chown(uid_t, gid_t);
|
BAN::ErrorOr<void> chown(uid_t, gid_t);
|
||||||
bool has_data() const;
|
bool has_data() const;
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> ioctl(int request, void* arg);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void on_close_impl() {}
|
virtual void on_close_impl() {}
|
||||||
|
|
||||||
|
@ -138,6 +140,8 @@ namespace Kernel
|
||||||
virtual BAN::ErrorOr<void> chown_impl(uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); }
|
virtual BAN::ErrorOr<void> chown_impl(uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); }
|
||||||
virtual bool has_data_impl() const { dwarnln("nonblock not supported"); return true; }
|
virtual bool has_data_impl() const { dwarnln("nonblock not supported"); return true; }
|
||||||
|
|
||||||
|
virtual BAN::ErrorOr<long> ioctl_impl(int request, void* arg) { return BAN::Error::from_errno(ENOTSUP); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
mutable RecursivePrioritySpinLock m_lock;
|
mutable RecursivePrioritySpinLock m_lock;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ namespace Kernel
|
||||||
|
|
||||||
class NetworkInterface : public CharacterDevice
|
class NetworkInterface : public CharacterDevice
|
||||||
{
|
{
|
||||||
|
BAN_NON_COPYABLE(NetworkInterface);
|
||||||
|
BAN_NON_MOVABLE(NetworkInterface);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class Type
|
enum class Type
|
||||||
{
|
{
|
||||||
|
@ -22,7 +25,12 @@ namespace Kernel
|
||||||
virtual ~NetworkInterface() {}
|
virtual ~NetworkInterface() {}
|
||||||
|
|
||||||
virtual BAN::MACAddress get_mac_address() const = 0;
|
virtual BAN::MACAddress get_mac_address() const = 0;
|
||||||
|
|
||||||
BAN::IPv4Address get_ipv4_address() const { return m_ipv4_address; }
|
BAN::IPv4Address get_ipv4_address() const { return m_ipv4_address; }
|
||||||
|
void set_ipv4_address(BAN::IPv4Address new_address) { m_ipv4_address = new_address; }
|
||||||
|
|
||||||
|
BAN::IPv4Address get_netmask() const { return m_netmask; }
|
||||||
|
void set_netmask(BAN::IPv4Address new_netmask) { m_netmask = new_netmask; }
|
||||||
|
|
||||||
virtual bool link_up() = 0;
|
virtual bool link_up() = 0;
|
||||||
virtual int link_speed() = 0;
|
virtual int link_speed() = 0;
|
||||||
|
@ -42,6 +50,7 @@ namespace Kernel
|
||||||
char m_name[10];
|
char m_name[10];
|
||||||
|
|
||||||
BAN::IPv4Address m_ipv4_address { 0 };
|
BAN::IPv4Address m_ipv4_address { 0 };
|
||||||
|
BAN::IPv4Address m_netmask { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ namespace Kernel
|
||||||
virtual BAN::ErrorOr<ssize_t> sendto_impl(const sys_sendto_t*) override;
|
virtual BAN::ErrorOr<ssize_t> sendto_impl(const sys_sendto_t*) override;
|
||||||
virtual BAN::ErrorOr<ssize_t> recvfrom_impl(sys_recvfrom_t*) override;
|
virtual BAN::ErrorOr<ssize_t> recvfrom_impl(sys_recvfrom_t*) override;
|
||||||
|
|
||||||
|
virtual BAN::ErrorOr<long> ioctl_impl(int request, void* arg) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NetworkInterface* m_interface = nullptr;
|
NetworkInterface* m_interface = nullptr;
|
||||||
uint16_t m_port = PORT_NONE;
|
uint16_t m_port = PORT_NONE;
|
||||||
|
|
|
@ -117,6 +117,8 @@ namespace Kernel
|
||||||
BAN::ErrorOr<long> sys_sendto(const sys_sendto_t*);
|
BAN::ErrorOr<long> sys_sendto(const sys_sendto_t*);
|
||||||
BAN::ErrorOr<long> sys_recvfrom(sys_recvfrom_t*);
|
BAN::ErrorOr<long> sys_recvfrom(sys_recvfrom_t*);
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> sys_ioctl(int fildes, int request, void* arg);
|
||||||
|
|
||||||
BAN::ErrorOr<long> sys_pipe(int fildes[2]);
|
BAN::ErrorOr<long> sys_pipe(int fildes[2]);
|
||||||
BAN::ErrorOr<long> sys_dup(int fildes);
|
BAN::ErrorOr<long> sys_dup(int fildes);
|
||||||
BAN::ErrorOr<long> sys_dup2(int fildes, int fildes2);
|
BAN::ErrorOr<long> sys_dup2(int fildes, int fildes2);
|
||||||
|
|
|
@ -183,4 +183,10 @@ namespace Kernel
|
||||||
return has_data_impl();
|
return has_data_impl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> Inode::ioctl(int request, void* arg)
|
||||||
|
{
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
return ioctl_impl(request, arg);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
#include <kernel/Networking/NetworkManager.h>
|
#include <kernel/Networking/NetworkManager.h>
|
||||||
#include <kernel/Networking/NetworkSocket.h>
|
#include <kernel/Networking/NetworkSocket.h>
|
||||||
|
|
||||||
|
#include <net/if.h>
|
||||||
|
|
||||||
namespace Kernel
|
namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -123,4 +125,65 @@ namespace Kernel
|
||||||
return TRY(read_packet(BAN::ByteSpan { reinterpret_cast<uint8_t*>(arguments->buffer), arguments->length }, sender_addr));
|
return TRY(read_packet(BAN::ByteSpan { reinterpret_cast<uint8_t*>(arguments->buffer), arguments->length }, sender_addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> NetworkSocket::ioctl_impl(int request, void* arg)
|
||||||
|
{
|
||||||
|
if (!arg)
|
||||||
|
{
|
||||||
|
dprintln("No argument provided");
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
if (m_interface == nullptr)
|
||||||
|
{
|
||||||
|
dprintln("No interface bound");
|
||||||
|
return BAN::Error::from_errno(EADDRNOTAVAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* ifreq = reinterpret_cast<struct ifreq*>(arg);
|
||||||
|
|
||||||
|
switch (request)
|
||||||
|
{
|
||||||
|
case SIOCGIFADDR:
|
||||||
|
{
|
||||||
|
auto ipv4_address = m_interface->get_ipv4_address();
|
||||||
|
ifreq->ifr_ifru.ifru_addr.sa_family = AF_INET;
|
||||||
|
memcpy(ifreq->ifr_ifru.ifru_addr.sa_data, &ipv4_address, sizeof(ipv4_address));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case SIOCSIFADDR:
|
||||||
|
{
|
||||||
|
if (ifreq->ifr_ifru.ifru_addr.sa_family != AF_INET)
|
||||||
|
return BAN::Error::from_errno(EADDRNOTAVAIL);
|
||||||
|
BAN::IPv4Address ipv4_address { *reinterpret_cast<uint32_t*>(ifreq->ifr_ifru.ifru_addr.sa_data) };
|
||||||
|
m_interface->set_ipv4_address(ipv4_address);
|
||||||
|
dprintln("IPv4 address set to {}", m_interface->get_ipv4_address());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case SIOCGIFNETMASK:
|
||||||
|
{
|
||||||
|
auto netmask_address = m_interface->get_netmask();
|
||||||
|
ifreq->ifr_ifru.ifru_netmask.sa_family = AF_INET;
|
||||||
|
memcpy(ifreq->ifr_ifru.ifru_netmask.sa_data, &netmask_address, sizeof(netmask_address));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case SIOCSIFNETMASK:
|
||||||
|
{
|
||||||
|
if (ifreq->ifr_ifru.ifru_netmask.sa_family != AF_INET)
|
||||||
|
return BAN::Error::from_errno(EADDRNOTAVAIL);
|
||||||
|
BAN::IPv4Address netmask { *reinterpret_cast<uint32_t*>(ifreq->ifr_ifru.ifru_netmask.sa_data) };
|
||||||
|
m_interface->set_netmask(netmask);
|
||||||
|
dprintln("Netmask set to {}", m_interface->get_netmask());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case SIOCGIFHWADDR:
|
||||||
|
{
|
||||||
|
auto mac_address = m_interface->get_mac_address();
|
||||||
|
ifreq->ifr_ifru.ifru_hwaddr.sa_family = AF_INET;
|
||||||
|
memcpy(ifreq->ifr_ifru.ifru_hwaddr.sa_data, &mac_address, sizeof(mac_address));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return BAN::Error::from_errno(EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -952,6 +952,13 @@ namespace Kernel
|
||||||
return TRY(inode->recvfrom(arguments));
|
return TRY(inode->recvfrom(arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<long> Process::sys_ioctl(int fildes, int request, void* arg)
|
||||||
|
{
|
||||||
|
LockGuard _(m_lock);
|
||||||
|
auto inode = TRY(m_open_file_descriptors.inode_of(fildes));
|
||||||
|
return TRY(inode->ioctl(request, arg));
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_pipe(int fildes[2])
|
BAN::ErrorOr<long> Process::sys_pipe(int fildes[2])
|
||||||
{
|
{
|
||||||
LockGuard _(m_lock);
|
LockGuard _(m_lock);
|
||||||
|
|
|
@ -225,6 +225,9 @@ namespace Kernel
|
||||||
case SYS_RECVFROM:
|
case SYS_RECVFROM:
|
||||||
ret = Process::current().sys_recvfrom((sys_recvfrom_t*)arg1);
|
ret = Process::current().sys_recvfrom((sys_recvfrom_t*)arg1);
|
||||||
break;
|
break;
|
||||||
|
case SYS_IOCTL:
|
||||||
|
ret = Process::current().sys_ioctl((int)arg1, (int)arg2, (void*)arg3);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dwarnln("Unknown syscall {}", syscall);
|
dwarnln("Unknown syscall {}", syscall);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -17,6 +17,7 @@ set(LIBC_SOURCES
|
||||||
stdlib.cpp
|
stdlib.cpp
|
||||||
string.cpp
|
string.cpp
|
||||||
strings.cpp
|
strings.cpp
|
||||||
|
stropts.cpp
|
||||||
sys/banan-os.cpp
|
sys/banan-os.cpp
|
||||||
sys/mman.cpp
|
sys/mman.cpp
|
||||||
sys/socket.cpp
|
sys/socket.cpp
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#define IF_NAMESIZE 16
|
#define IF_NAMESIZE 16
|
||||||
|
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
|
@ -15,6 +17,22 @@ struct if_nameindex
|
||||||
char* if_name; /* Null-terminated name of the interface. */
|
char* if_name; /* Null-terminated name of the interface. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ifreq
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
struct sockaddr ifru_addr;
|
||||||
|
struct sockaddr ifru_netmask;
|
||||||
|
struct sockaddr ifru_hwaddr;
|
||||||
|
unsigned char __min_storage[sizeof(sockaddr) + 6];
|
||||||
|
} ifr_ifru;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SIOCGIFADDR 1 /* Get interface address */
|
||||||
|
#define SIOCSIFADDR 2 /* Set interface address */
|
||||||
|
#define SIOCGIFNETMASK 3 /* Get network mask */
|
||||||
|
#define SIOCSIFNETMASK 4 /* Set network mask */
|
||||||
|
#define SIOCGIFHWADDR 5 /* Get hardware address */
|
||||||
|
|
||||||
void if_freenameindex(struct if_nameindex* ptr);
|
void if_freenameindex(struct if_nameindex* ptr);
|
||||||
char* if_indextoname(unsigned ifindex, char* ifname);
|
char* if_indextoname(unsigned ifindex, char* ifname);
|
||||||
struct if_nameindex* if_nameindex(void);
|
struct if_nameindex* if_nameindex(void);
|
||||||
|
|
|
@ -11,8 +11,8 @@ __BEGIN_DECLS
|
||||||
#define __need_gid_t
|
#define __need_gid_t
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
typedef uint32_t t_uscalar_t;
|
typedef __UINT32_TYPE__ t_uscalar_t;
|
||||||
typedef int32_t t_scalar_t;
|
typedef __INT32_TYPE__ t_scalar_t;
|
||||||
|
|
||||||
struct bandinfo
|
struct bandinfo
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,6 +67,7 @@ __BEGIN_DECLS
|
||||||
#define SYS_BIND 66
|
#define SYS_BIND 66
|
||||||
#define SYS_SENDTO 67
|
#define SYS_SENDTO 67
|
||||||
#define SYS_RECVFROM 68
|
#define SYS_RECVFROM 68
|
||||||
|
#define SYS_IOCTL 69
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stropts.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int ioctl(int fildes, int request, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, request);
|
||||||
|
void* extra = va_arg(args, void*);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return syscall(SYS_IOCTL, fildes, request, extra);
|
||||||
|
}
|
Loading…
Reference in New Issue