Add socket_open and socket_close system calls

This commit is contained in:
Baptiste Wicht 2016-08-25 19:19:13 +02:00
parent 4626c6128d
commit 9f70247a4a
7 changed files with 121 additions and 4 deletions

View File

@ -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

View File

@ -20,8 +20,9 @@
#include "fs/sysfs.hpp"
namespace {
#include "tlib/errors.hpp"
namespace {
std::vector<network::interface_descriptor> 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);
}
}

View File

@ -341,6 +341,20 @@ void sc_alpha(interrupt::syscall_regs*){
}
}
void sc_socket_open(interrupt::syscall_regs* regs){
auto domain = static_cast<network::socket_domain>(regs->rbx);
auto type = static_cast<network::socket_type>(regs->rcx);
auto protocol = static_cast<network::socket_protocol>(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;

View File

@ -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";
}

18
tlib/include/tlib/net.hpp Normal file
View File

@ -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 <expected.hpp>
#include "net_constants.hpp"
std::expected<size_t> socket_open(network::socket_domain domain, network::socket_type type, network::socket_protocol protocol);
void socket_close(size_t fd);
#endif

View File

@ -8,17 +8,19 @@
#ifndef TLIB_NET_CONSTANTS_H
#define TLIB_NET_CONSTANTS_H
#include <types.hpp>
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
};

29
tlib/src/net.cpp Normal file
View File

@ -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<size_t> 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<size_t>(domain)), [type] "g" (static_cast<size_t>(type)), [protocol] "g" (static_cast<size_t>(protocol))
: "rax", "rbx", "rcx", "rdx");
if(fd < 0){
return std::make_expected_from_error<size_t, size_t>(-fd);
} else {
return std::make_expected<size_t>(fd);
}
}
void socket_close(size_t fd){
asm volatile("mov rax, 0x3001; mov rbx, %[fd]; int 50;"
: /* No outputs */
: [fd] "g" (fd)
: "rax", "rbx");
}