forked from Bananymous/banan-os
				
			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