From bba08c0b3e8c67e047d2c1f4eeb6d7148c6695b4 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 7 Apr 2024 21:44:07 -0300 Subject: [PATCH] socket: SIOCADDRT ioctl --- kernel-src/fs/sockfs.c | 52 +++++++++++++++++++++++++++++++-- kernel-src/include/kernel/abi.h | 21 ++++++++++++- kernel-src/include/kernel/net.h | 1 + 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/kernel-src/fs/sockfs.c b/kernel-src/fs/sockfs.c index a6189db0..6317b689 100644 --- a/kernel-src/fs/sockfs.c +++ b/kernel-src/fs/sockfs.c @@ -65,6 +65,7 @@ int sockfs_setattr(vnode_t *node, vattr_t *attr, cred_t *cred) { int sockfs_ioctl(vnode_t *node, unsigned long request, void *arg, int *result) { switch (request) { case SIOCGIFHWADDR: + { ifreq_t *ifreq = arg; netdev_t *netdev = netdev_getdev(ifreq->name); if (netdev) { @@ -73,9 +74,56 @@ int sockfs_ioctl(vnode_t *node, unsigned long request, void *arg, int *result) { } else { return ENODEV; } - default: - return EINVAL; + break; + } + case SIOCADDRT: + { + abirtentry_t abirtentry; + memcpy(&abirtentry, arg, sizeof(abirtentry_t)); + + abisockaddr_t abiaddr; + abisockaddr_t abigateway; + abisockaddr_t abimask; + memcpy(&abiaddr, (void *)&abirtentry.rt_dst, sizeof(abisockaddr_t)); + memcpy(&abigateway, (void *)&abirtentry.rt_gateway, sizeof(abisockaddr_t)); + memcpy(&abimask, (void *)&abirtentry.rt_genmask, sizeof(abisockaddr_t)); + + sockaddr_t addr; + sockaddr_t gateway; + sockaddr_t mask; + + int e = sock_convertaddress(&addr, &abiaddr); + if (e) + return e; + + e = sock_convertaddress(&gateway, &abigateway); + if (e) + return e; + + e = sock_convertaddress(&mask, &abimask); + if (e) + return e; + + char *dev = alloc(strlen(abirtentry.rt_dev) + 1); + if (dev == NULL) + return ENOMEM; + strcpy(dev, abirtentry.rt_dev); + + netdev_t *netdev = netdev_getdev(dev); + if (netdev == NULL) { + free(dev); + return ENOMEM; + } + + e = ipv4_addroute(netdev, addr.ipv4addr.addr, gateway.ipv4addr.addr, mask.ipv4addr.addr, abirtentry.rt_metric); + + free(dev); + return e; + default: + return EINVAL; + } } + return 0; } int sockfs_inactive(vnode_t *node) { diff --git a/kernel-src/include/kernel/abi.h b/kernel-src/include/kernel/abi.h index 26da378f..0d48f781 100644 --- a/kernel-src/include/kernel/abi.h +++ b/kernel-src/include/kernel/abi.h @@ -94,7 +94,7 @@ typedef struct { typedef struct { unsigned short type; - char addr[]; + char addr[14]; } abisockaddr_t; typedef struct { @@ -129,6 +129,7 @@ typedef struct { #define IFNAMSIZ 16 #define SIOCGIFHWADDR 0x8927 +#define SIOCADDRT 0x890b typedef struct { char name[IFNAMSIZ]; @@ -137,4 +138,22 @@ typedef struct { }; } ifreq_t; +typedef struct { + unsigned long int rt_pad1; + abisockaddr_t rt_dst; + abisockaddr_t rt_gateway; + abisockaddr_t rt_genmask; + unsigned short int rt_flags; + short int rt_pad2; + unsigned long int rt_pad3; + unsigned char rt_tos; + unsigned char rt_class; + short int rt_pad4[3]; + short int rt_metric; + char *rt_dev; + unsigned long int rt_mtu; + unsigned long int rt_window; + unsigned short int rt_irtt; +} abirtentry_t; + #endif diff --git a/kernel-src/include/kernel/net.h b/kernel-src/include/kernel/net.h index 35d57a53..0ba534d8 100644 --- a/kernel-src/include/kernel/net.h +++ b/kernel-src/include/kernel/net.h @@ -82,6 +82,7 @@ int arp_lookup(netdev_t *netdev, uint32_t ip, mac_t *mac); int udp_sendpacket(void *buffer, size_t packetsize, uint32_t ip, uint16_t srcport, uint16_t dstport, netdev_t *broadcastdev); int ipv4_sendpacket(void *buffer, size_t packetsize, uint32_t ip, int proto, netdev_t *broadcastdev); void ipv4_process(netdev_t *netdev, void *nextbuff); +int ipv4_addroute(netdev_t *netdev, uint32_t addr, uint32_t gateway, uint32_t mask, int weight); int netdev_register(netdev_t *netdev, char *name); netdev_t *netdev_getdev(char *name);