diff --git a/kernel/include/net/ethernet_packet.hpp b/kernel/include/net/ethernet_packet.hpp index b421c6c7..e0ea16e7 100644 --- a/kernel/include/net/ethernet_packet.hpp +++ b/kernel/include/net/ethernet_packet.hpp @@ -35,6 +35,7 @@ struct packet { bool user; uint64_t tags; // This allows for 4 tags (4 layer) + uint64_t interface; ///< Id of the interface packet() : fd(0), user(false), tags(0) {} packet(char* payload, size_t payload_size) : payload(payload), payload_size(payload_size), index(0), fd(0), user(false), tags(0) {} diff --git a/kernel/src/net/ethernet_layer.cpp b/kernel/src/net/ethernet_layer.cpp index d1b6361c..eaeb4221 100644 --- a/kernel/src/net/ethernet_layer.cpp +++ b/kernel/src/net/ethernet_layer.cpp @@ -51,6 +51,7 @@ uint16_t type_to_code(network::ethernet::ether_type type){ void prepare_packet(network::ethernet::packet& p, network::interface_descriptor& interface, size_t destination, network::ethernet::ether_type type){ p.type = type; p.index = sizeof(network::ethernet::header); + p.interface = interface.id; auto source_mac = interface.mac_address; diff --git a/kernel/src/net/network.cpp b/kernel/src/net/network.cpp index fe97672f..017b421c 100644 --- a/kernel/src/net/network.cpp +++ b/kernel/src/net/network.cpp @@ -26,6 +26,7 @@ #include "net/icmp_layer.hpp" namespace { + std::vector interfaces; void rx_thread(void* data){ @@ -65,6 +66,26 @@ void tx_thread(void* data){ } } +network::interface_descriptor& select_interface(network::ip::address address){ + if(address == network::ip::make_address(127, 0, 0, 1)){ + for(auto& interface : interfaces){ + if(interface.enabled && interface.driver == "loopback"){ + return interface; + } + } + } + + // Otherwise return the first enabled interface + + for(auto& interface : interfaces){ + if(interface.enabled){ + return interface; + } + } + + thor_unreachable("network: Should never happen"); +} + } //end of anonymous namespace void network::init(){ @@ -194,17 +215,16 @@ std::tuple network::prepare_packet(socket_fd_t socket_fd, void* return {-std::ERROR_SOCKET_INVALID_FD, 0}; } - // TODO A socket should be bound to an interface somehow if(!network::number_of_interfaces()){ return {-std::ERROR_SOCKET_NO_INTERFACE, 0}; } - auto& interface = network::interface(0); auto& socket = scheduler::get_socket(socket_fd); switch(socket.protocol){ case network::socket_protocol::ICMP: auto descriptor = static_cast(desc); + auto& interface = select_interface(descriptor->target_ip); auto packet = network::icmp::prepare_packet(buffer, interface, descriptor->target_ip, descriptor->payload_size, descriptor->type, descriptor->code); if(packet){ @@ -224,7 +244,6 @@ std::expected network::finalize_packet(socket_fd_t socket_fd, size_t packe return std::make_unexpected(std::ERROR_SOCKET_INVALID_FD); } - auto& interface = network::interface(0); auto& socket = scheduler::get_socket(socket_fd); if(!socket.has_packet(packet_fd)){ @@ -232,6 +251,7 @@ std::expected network::finalize_packet(socket_fd_t socket_fd, size_t packe } auto& packet = socket.get_packet(packet_fd); + auto& interface = network::interface(packet.interface); switch(socket.protocol){ case network::socket_protocol::ICMP: