From 9f70247a4a2ddec336f2aabd21ce1a6f0714311b Mon Sep 17 00:00:00 2001 From: Baptiste Wicht Date: Thu, 25 Aug 2016 19:19:13 +0200 Subject: [PATCH] Add socket_open and socket_close system calls --- kernel/include/net/network.hpp | 14 ++++++++++++++ kernel/src/net/network.cpp | 25 ++++++++++++++++++++++++- kernel/src/system_calls.cpp | 22 ++++++++++++++++++++++ tlib/include/tlib/errors.hpp | 9 +++++++++ tlib/include/tlib/net.hpp | 18 ++++++++++++++++++ tlib/include/tlib/net_constants.hpp | 8 +++++--- tlib/src/net.cpp | 29 +++++++++++++++++++++++++++++ 7 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 tlib/include/tlib/net.hpp create mode 100644 tlib/src/net.cpp diff --git a/kernel/include/net/network.hpp b/kernel/include/net/network.hpp index 17254f11..36363d8a 100644 --- a/kernel/include/net/network.hpp +++ b/kernel/include/net/network.hpp @@ -56,6 +56,20 @@ size_t number_of_interfaces(); interface_descriptor& interface(size_t index); +/*! + * \brief Open a new socket + * \param domain The socket domain + * \param type The socket type + * \param protocol The socket protocol + * \return The file descriptor on success, a negative error code otherwise + */ +int64_t open(network::socket_domain domain, network::socket_type type, network::socket_protocol protocol); + +/*! + * \brief Close the given socket file descriptor + */ +void close(size_t fd); + } // end of network namespace #endif diff --git a/kernel/src/net/network.cpp b/kernel/src/net/network.cpp index b5960c18..a1aa6f84 100644 --- a/kernel/src/net/network.cpp +++ b/kernel/src/net/network.cpp @@ -20,8 +20,9 @@ #include "fs/sysfs.hpp" -namespace { +#include "tlib/errors.hpp" +namespace { std::vector interfaces; void rx_thread(void* data){ @@ -139,3 +140,25 @@ size_t network::number_of_interfaces(){ network::interface_descriptor& network::interface(size_t index){ return interfaces[index]; } + +int64_t network::open(network::socket_domain domain, network::socket_type type, network::socket_protocol protocol){ + if(domain != socket_domain::AF_INET){ + return -std::ERROR_SOCKET_INVALID_DOMAIN; + } + + if(type != socket_type::RAW){ + return -std::ERROR_SOCKET_INVALID_TYPE; + } + + if(protocol != socket_protocol::ICMP){ + return -std::ERROR_SOCKET_INVALID_PROTOCOL; + } + + return scheduler::register_new_socket(domain, type, protocol); +} + +void network::close(size_t fd){ + if(scheduler::has_socket(fd)){ + scheduler::release_socket(fd); + } +} diff --git a/kernel/src/system_calls.cpp b/kernel/src/system_calls.cpp index 5e4062df..235e7646 100644 --- a/kernel/src/system_calls.cpp +++ b/kernel/src/system_calls.cpp @@ -341,6 +341,20 @@ void sc_alpha(interrupt::syscall_regs*){ } } +void sc_socket_open(interrupt::syscall_regs* regs){ + auto domain = static_cast(regs->rbx); + auto type = static_cast(regs->rcx); + auto protocol = static_cast(regs->rdx); + + regs->rax = network::open(domain, type, protocol); +} + +void sc_socket_close(interrupt::syscall_regs* regs){ + auto fd = regs->rbx; + + network::close(fd); +} + } //End of anonymous namespace void system_call_entry(interrupt::syscall_regs* regs){ @@ -552,6 +566,14 @@ void system_call_entry(interrupt::syscall_regs* regs){ sc_ioctl(regs); break; + case 0x3000: + sc_socket_open(regs); + break; + + case 0x3001: + sc_socket_close(regs); + break; + case 0x6666: sc_alpha(regs); break; diff --git a/tlib/include/tlib/errors.hpp b/tlib/include/tlib/errors.hpp index 92450cb6..6a767a8f 100644 --- a/tlib/include/tlib/errors.hpp +++ b/tlib/include/tlib/errors.hpp @@ -32,6 +32,9 @@ constexpr const size_t ERROR_INVALID_COUNT = 16; constexpr const size_t ERROR_INVALID_REQUEST = 17; constexpr const size_t ERROR_INVALID_DEVICE = 18; constexpr const size_t ERROR_ALREADY_MOUNTED = 19; +constexpr const size_t ERROR_SOCKET_INVALID_DOMAIN = 20; +constexpr const size_t ERROR_SOCKET_INVALID_TYPE = 21; +constexpr const size_t ERROR_SOCKET_INVALID_PROTOCOL = 22; inline const char* error_message(size_t error){ switch(error){ @@ -73,6 +76,12 @@ inline const char* error_message(size_t error){ return "The device is not valid for this request"; case ERROR_ALREADY_MOUNTED: return "Something is already mounted"; + case ERROR_SOCKET_INVALID_DOMAIN: + return "The socket domain is invalid"; + case ERROR_SOCKET_INVALID_TYPE: + return "The socket type is invalid"; + case ERROR_SOCKET_INVALID_PROTOCOL: + return "The socket protocol is invalid"; default: return "Unknonwn error"; } diff --git a/tlib/include/tlib/net.hpp b/tlib/include/tlib/net.hpp new file mode 100644 index 00000000..47788dbb --- /dev/null +++ b/tlib/include/tlib/net.hpp @@ -0,0 +1,18 @@ +//======================================================================= +// Copyright Baptiste Wicht 2013-2016. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#ifndef TLIB_NET_H +#define TLIB_NET_H + +#include + +#include "net_constants.hpp" + +std::expected socket_open(network::socket_domain domain, network::socket_type type, network::socket_protocol protocol); +void socket_close(size_t fd); + +#endif diff --git a/tlib/include/tlib/net_constants.hpp b/tlib/include/tlib/net_constants.hpp index 815fe629..c642d70c 100644 --- a/tlib/include/tlib/net_constants.hpp +++ b/tlib/include/tlib/net_constants.hpp @@ -8,17 +8,19 @@ #ifndef TLIB_NET_CONSTANTS_H #define TLIB_NET_CONSTANTS_H +#include + namespace network { -enum class socket_domain { +enum class socket_domain : size_t { AF_INET }; -enum class socket_type { +enum class socket_type : size_t { RAW }; -enum class socket_protocol { +enum class socket_protocol : size_t { ICMP }; diff --git a/tlib/src/net.cpp b/tlib/src/net.cpp new file mode 100644 index 00000000..5f6e5c40 --- /dev/null +++ b/tlib/src/net.cpp @@ -0,0 +1,29 @@ +//======================================================================= +// Copyright Baptiste Wicht 2013-2016. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +//======================================================================= + +#include "tlib/net.hpp" + +std::expected socket_open(network::socket_domain domain, network::socket_type type, network::socket_protocol protocol){ + int64_t fd; + asm volatile("mov rax, 0x3000; mov rbx, %[type]; mov rcx, %[type]; mov rdx, %[protocol]; int 50; mov %[fd], rax" + : [fd] "=m" (fd) + : [domain] "g" (static_cast(domain)), [type] "g" (static_cast(type)), [protocol] "g" (static_cast(protocol)) + : "rax", "rbx", "rcx", "rdx"); + + if(fd < 0){ + return std::make_expected_from_error(-fd); + } else { + return std::make_expected(fd); + } +} + +void socket_close(size_t fd){ + asm volatile("mov rax, 0x3001; mov rbx, %[fd]; int 50;" + : /* No outputs */ + : [fd] "g" (fd) + : "rax", "rbx"); +}