mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-16 16:11:42 -04:00
prepare_packet can fail
This commit is contained in:
parent
1d4b202224
commit
175bda1ad2
@ -9,6 +9,7 @@
|
|||||||
#define NET_ETHERNET_LAYER_H
|
#define NET_ETHERNET_LAYER_H
|
||||||
|
|
||||||
#include <types.hpp>
|
#include <types.hpp>
|
||||||
|
#include <expected.hpp>
|
||||||
|
|
||||||
#include "net/network.hpp"
|
#include "net/network.hpp"
|
||||||
#include "net/ethernet_packet.hpp"
|
#include "net/ethernet_packet.hpp"
|
||||||
@ -35,8 +36,8 @@ void mac64_to_mac6(uint64_t input, char* mac);
|
|||||||
|
|
||||||
void decode(network::interface_descriptor& interface, packet& packet);
|
void decode(network::interface_descriptor& interface, packet& packet);
|
||||||
|
|
||||||
packet prepare_packet(network::interface_descriptor& interface, size_t size, size_t destination, ether_type type);
|
std::expected<packet> prepare_packet(network::interface_descriptor& interface, size_t size, size_t destination, ether_type type);
|
||||||
packet prepare_packet(char* buffer, network::interface_descriptor& interface, size_t size, size_t destination, ether_type type);
|
std::expected<packet> prepare_packet(char* buffer, network::interface_descriptor& interface, size_t size, size_t destination, ether_type type);
|
||||||
void finalize_packet(network::interface_descriptor& interface, packet& p);
|
void finalize_packet(network::interface_descriptor& interface, packet& p);
|
||||||
|
|
||||||
} // end of ethernet namespace
|
} // end of ethernet namespace
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#define NET_ICMP_LAYER_H
|
#define NET_ICMP_LAYER_H
|
||||||
|
|
||||||
#include <types.hpp>
|
#include <types.hpp>
|
||||||
|
#include <expected.hpp>
|
||||||
|
|
||||||
#include "tlib/net_constants.hpp"
|
#include "tlib/net_constants.hpp"
|
||||||
|
|
||||||
@ -23,8 +24,8 @@ static_assert(sizeof(echo_request_header) == sizeof(header::rest), "Invalid size
|
|||||||
|
|
||||||
void decode(network::interface_descriptor& interface, network::ethernet::packet& packet);
|
void decode(network::interface_descriptor& interface, network::ethernet::packet& packet);
|
||||||
|
|
||||||
network::ethernet::packet prepare_packet(network::interface_descriptor& interface, network::ip::address target_ip, size_t payload_size, type t, size_t code);
|
std::expected<network::ethernet::packet> prepare_packet(network::interface_descriptor& interface, network::ip::address target_ip, size_t payload_size, type t, size_t code);
|
||||||
network::ethernet::packet prepare_packet(char* buffer, network::interface_descriptor& interface, network::ip::address target_ip, size_t payload_size, type t, size_t code);
|
std::expected<network::ethernet::packet> prepare_packet(char* buffer, network::interface_descriptor& interface, network::ip::address target_ip, size_t payload_size, type t, size_t code);
|
||||||
void finalize_packet(network::interface_descriptor& interface, network::ethernet::packet& p);
|
void finalize_packet(network::interface_descriptor& interface, network::ethernet::packet& p);
|
||||||
|
|
||||||
void ping(network::interface_descriptor& interface, network::ip::address addr);
|
void ping(network::interface_descriptor& interface, network::ip::address addr);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#define NET_IP_LAYER_H
|
#define NET_IP_LAYER_H
|
||||||
|
|
||||||
#include <types.hpp>
|
#include <types.hpp>
|
||||||
|
#include <expected.hpp>
|
||||||
|
|
||||||
#include "net/network.hpp"
|
#include "net/network.hpp"
|
||||||
#include "tlib/net_constants.hpp"
|
#include "tlib/net_constants.hpp"
|
||||||
@ -37,8 +38,8 @@ static_assert(sizeof(header) == 20, "The size of an IPv4 header must be 20 bytes
|
|||||||
|
|
||||||
void decode(network::interface_descriptor& interface, network::ethernet::packet& packet);
|
void decode(network::interface_descriptor& interface, network::ethernet::packet& packet);
|
||||||
|
|
||||||
network::ethernet::packet prepare_packet(network::interface_descriptor& interface, size_t size, address& destination, size_t protocol);
|
std::expected<network::ethernet::packet> prepare_packet(network::interface_descriptor& interface, size_t size, address& destination, size_t protocol);
|
||||||
network::ethernet::packet prepare_packet(char* buffer, network::interface_descriptor& interface, size_t size, address& destination, size_t protocol);
|
std::expected<network::ethernet::packet> prepare_packet(char* buffer, network::interface_descriptor& interface, size_t size, address& destination, size_t protocol);
|
||||||
void finalize_packet(network::interface_descriptor& interface, network::ethernet::packet& p);
|
void finalize_packet(network::interface_descriptor& interface, network::ethernet::packet& p);
|
||||||
|
|
||||||
} // end of ip namespace
|
} // end of ip namespace
|
||||||
|
@ -28,25 +28,32 @@ struct cache_entry {
|
|||||||
|
|
||||||
std::vector<cache_entry> cache;
|
std::vector<cache_entry> cache;
|
||||||
|
|
||||||
void arp_request(network::interface_descriptor& interface, network::ip::address ip){
|
bool arp_request(network::interface_descriptor& interface, network::ip::address ip){
|
||||||
// Ask the ethernet layer to craft a packet
|
// Ask the ethernet layer to craft a packet
|
||||||
auto packet = network::ethernet::prepare_packet(interface, sizeof(network::arp::header), 0xFFFFFFFFFFFF, network::ethernet::ether_type::ARP);
|
auto packet = network::ethernet::prepare_packet(interface, sizeof(network::arp::header), 0xFFFFFFFFFFFF, network::ethernet::ether_type::ARP);
|
||||||
|
|
||||||
auto* arp_request_header = reinterpret_cast<network::arp::header*>(packet.payload + packet.index);
|
if(packet){
|
||||||
|
auto* arp_request_header = reinterpret_cast<network::arp::header*>(packet->payload + packet->index);
|
||||||
|
|
||||||
arp_request_header->hw_type = switch_endian_16(0x1); // ethernet
|
arp_request_header->hw_type = switch_endian_16(0x1); // ethernet
|
||||||
arp_request_header->protocol_type = switch_endian_16(0x800); // IPV4
|
arp_request_header->protocol_type = switch_endian_16(0x800); // IPV4
|
||||||
arp_request_header->hw_len = 0x6; // MAC Address
|
arp_request_header->hw_len = 0x6; // MAC Address
|
||||||
arp_request_header->protocol_len = 0x4; // IP Address
|
arp_request_header->protocol_len = 0x4; // IP Address
|
||||||
arp_request_header->operation = switch_endian_16(0x1); //ARP Request
|
arp_request_header->operation = switch_endian_16(0x1); //ARP Request
|
||||||
|
|
||||||
network::arp::mac64_to_mac3(interface.mac_address, arp_request_header->source_hw_addr);
|
network::arp::mac64_to_mac3(interface.mac_address, arp_request_header->source_hw_addr);
|
||||||
network::arp::mac64_to_mac3(0x0, arp_request_header->target_hw_addr);
|
network::arp::mac64_to_mac3(0x0, arp_request_header->target_hw_addr);
|
||||||
|
|
||||||
network::arp::ip_to_ip2(interface.ip_address, arp_request_header->source_protocol_addr);
|
network::arp::ip_to_ip2(interface.ip_address, arp_request_header->source_protocol_addr);
|
||||||
network::arp::ip_to_ip2(ip, arp_request_header->target_protocol_addr);
|
network::arp::ip_to_ip2(ip, arp_request_header->target_protocol_addr);
|
||||||
|
|
||||||
network::ethernet::finalize_packet(interface, packet);
|
network::ethernet::finalize_packet(interface, *packet);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
//TODO Don't loose the error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} //end of anonymous namespace
|
} //end of anonymous namespace
|
||||||
@ -130,6 +137,7 @@ uint64_t network::arp::get_mac_force(network::interface_descriptor& interface, n
|
|||||||
logging::logf(logging::log_level::TRACE, "arp: IP %u.%u.%u.%u not cached, generate ARP Request\n",
|
logging::logf(logging::log_level::TRACE, "arp: IP %u.%u.%u.%u not cached, generate ARP Request\n",
|
||||||
ip(0), ip(1), ip(2), ip(3));
|
ip(0), ip(1), ip(2), ip(3));
|
||||||
|
|
||||||
|
// TODO Handle error here
|
||||||
arp_request(interface, ip);
|
arp_request(interface, ip);
|
||||||
|
|
||||||
while(!is_ip_cached(ip)){
|
while(!is_ip_cached(ip)){
|
||||||
@ -157,6 +165,7 @@ std::expected<uint64_t> network::arp::get_mac_force(network::interface_descripto
|
|||||||
logging::logf(logging::log_level::TRACE, "arp: IP %u.%u.%u.%u not cached, generate ARP Request\n",
|
logging::logf(logging::log_level::TRACE, "arp: IP %u.%u.%u.%u not cached, generate ARP Request\n",
|
||||||
ip(0), ip(1), ip(2), ip(3));
|
ip(0), ip(1), ip(2), ip(3));
|
||||||
|
|
||||||
|
// TODO Handle error here
|
||||||
arp_request(interface, ip);
|
arp_request(interface, ip);
|
||||||
|
|
||||||
auto start = timer::milliseconds();
|
auto start = timer::milliseconds();
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <vector.hpp>
|
#include <vector.hpp>
|
||||||
#include <string.hpp>
|
#include <string.hpp>
|
||||||
|
|
||||||
|
#include "tlib/errors.hpp"
|
||||||
|
|
||||||
#include "net/arp_layer.hpp"
|
#include "net/arp_layer.hpp"
|
||||||
#include "net/arp_cache.hpp"
|
#include "net/arp_cache.hpp"
|
||||||
#include "net/ip_layer.hpp"
|
#include "net/ip_layer.hpp"
|
||||||
@ -118,22 +120,27 @@ void network::arp::decode(network::interface_descriptor& interface, network::eth
|
|||||||
// Ask the ethernet layer to craft a packet
|
// Ask the ethernet layer to craft a packet
|
||||||
auto packet = network::ethernet::prepare_packet(interface, sizeof(header), source_hw, ethernet::ether_type::ARP);
|
auto packet = network::ethernet::prepare_packet(interface, sizeof(header), source_hw, ethernet::ether_type::ARP);
|
||||||
|
|
||||||
auto* arp_reply_header = reinterpret_cast<header*>(packet.payload + packet.index);
|
if(packet){
|
||||||
|
auto* arp_reply_header = reinterpret_cast<header*>(packet->payload + packet->index);
|
||||||
|
|
||||||
arp_reply_header->hw_type = switch_endian_16(0x1); // ethernet
|
arp_reply_header->hw_type = switch_endian_16(0x1); // ethernet
|
||||||
arp_reply_header->protocol_type = switch_endian_16(0x800); // IPV4
|
arp_reply_header->protocol_type = switch_endian_16(0x800); // IPV4
|
||||||
arp_reply_header->hw_len = 0x6; // MAC Address
|
arp_reply_header->hw_len = 0x6; // MAC Address
|
||||||
arp_reply_header->protocol_len = 0x4; // IP Address
|
arp_reply_header->protocol_len = 0x4; // IP Address
|
||||||
arp_reply_header->operation = switch_endian_16(0x2); //ARP Reply
|
arp_reply_header->operation = switch_endian_16(0x2); //ARP Reply
|
||||||
|
|
||||||
mac64_to_mac3(interface.mac_address, arp_reply_header->source_hw_addr);
|
mac64_to_mac3(interface.mac_address, arp_reply_header->source_hw_addr);
|
||||||
|
|
||||||
std::copy_n(arp_header->source_hw_addr, 3, arp_reply_header->target_hw_addr);
|
std::copy_n(arp_header->source_hw_addr, 3, arp_reply_header->target_hw_addr);
|
||||||
|
|
||||||
std::copy_n(arp_header->target_protocol_addr, 2, arp_reply_header->source_protocol_addr);
|
std::copy_n(arp_header->target_protocol_addr, 2, arp_reply_header->source_protocol_addr);
|
||||||
std::copy_n(arp_header->source_protocol_addr, 2, arp_reply_header->target_protocol_addr);
|
std::copy_n(arp_header->source_protocol_addr, 2, arp_reply_header->target_protocol_addr);
|
||||||
|
|
||||||
network::ethernet::finalize_packet(interface, packet);
|
network::ethernet::finalize_packet(interface, *packet);
|
||||||
|
} else {
|
||||||
|
logging::logf(logging::log_level::ERROR, "arp: Impossible to reply to ARP Request: %s\n", std::error_message(packet.error()));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if(operation == 0x2){
|
} else if(operation == 0x2){
|
||||||
logging::logf(logging::log_level::TRACE, "arp: Handle Reply\n");
|
logging::logf(logging::log_level::TRACE, "arp: Handle Reply\n");
|
||||||
|
@ -120,7 +120,7 @@ void network::ethernet::decode(network::interface_descriptor& interface, packet&
|
|||||||
logging::logf(logging::log_level::TRACE, "ethernet: Finished decoding packet\n");
|
logging::logf(logging::log_level::TRACE, "ethernet: Finished decoding packet\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
network::ethernet::packet network::ethernet::prepare_packet(network::interface_descriptor& interface, size_t size, size_t destination, ether_type type){
|
std::expected<network::ethernet::packet> network::ethernet::prepare_packet(network::interface_descriptor& interface, size_t size, size_t destination, ether_type type){
|
||||||
auto total_size = size + sizeof(header);
|
auto total_size = size + sizeof(header);
|
||||||
|
|
||||||
network::ethernet::packet p(new char[total_size], total_size);
|
network::ethernet::packet p(new char[total_size], total_size);
|
||||||
@ -130,7 +130,7 @@ network::ethernet::packet network::ethernet::prepare_packet(network::interface_d
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
network::ethernet::packet network::ethernet::prepare_packet(char* buffer, network::interface_descriptor& interface, size_t size, size_t destination, ether_type type){
|
std::expected<network::ethernet::packet> network::ethernet::prepare_packet(char* buffer, network::interface_descriptor& interface, size_t size, size_t destination, ether_type type){
|
||||||
auto total_size = size + sizeof(header);
|
auto total_size = size + sizeof(header);
|
||||||
|
|
||||||
network::ethernet::packet p(buffer, total_size);
|
network::ethernet::packet p(buffer, total_size);
|
||||||
|
@ -96,20 +96,24 @@ void network::icmp::decode(network::interface_descriptor& /*interface*/, network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
network::ethernet::packet network::icmp::prepare_packet(network::interface_descriptor& interface, network::ip::address target_ip, size_t payload_size, type t, size_t code){
|
std::expected<network::ethernet::packet> network::icmp::prepare_packet(network::interface_descriptor& interface, network::ip::address target_ip, size_t payload_size, type t, size_t code){
|
||||||
// Ask the IP layer to craft a packet
|
// Ask the IP layer to craft a packet
|
||||||
auto packet = network::ip::prepare_packet(interface, sizeof(header) + payload_size, target_ip, 0x01);
|
auto packet = network::ip::prepare_packet(interface, sizeof(header) + payload_size, target_ip, 0x01);
|
||||||
|
|
||||||
::prepare_packet(packet, t, code);
|
if(packet){
|
||||||
|
::prepare_packet(*packet, t, code);
|
||||||
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
network::ethernet::packet network::icmp::prepare_packet(char* buffer, network::interface_descriptor& interface, network::ip::address target_ip, size_t payload_size, type t, size_t code){
|
std::expected<network::ethernet::packet> network::icmp::prepare_packet(char* buffer, network::interface_descriptor& interface, network::ip::address target_ip, size_t payload_size, type t, size_t code){
|
||||||
// Ask the IP layer to craft a packet
|
// Ask the IP layer to craft a packet
|
||||||
auto packet = network::ip::prepare_packet(buffer, interface, sizeof(header) + payload_size, target_ip, 0x01);
|
auto packet = network::ip::prepare_packet(buffer, interface, sizeof(header) + payload_size, target_ip, 0x01);
|
||||||
|
|
||||||
::prepare_packet(packet, t, code);
|
if(packet){
|
||||||
|
::prepare_packet(*packet, t, code);
|
||||||
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
@ -137,13 +141,15 @@ void network::icmp::ping(network::interface_descriptor& interface, network::ip::
|
|||||||
// Ask the ICMP layer to craft a packet
|
// Ask the ICMP layer to craft a packet
|
||||||
auto packet = network::icmp::prepare_packet(interface, target_ip, 0, type::ECHO_REQUEST, 0);
|
auto packet = network::icmp::prepare_packet(interface, target_ip, 0, type::ECHO_REQUEST, 0);
|
||||||
|
|
||||||
// Set the Command header
|
if(packet){
|
||||||
|
// Set the Command header
|
||||||
|
|
||||||
auto* command_header = reinterpret_cast<echo_request_header*>(packet.payload + packet.index);
|
auto* command_header = reinterpret_cast<echo_request_header*>(packet->payload + packet->index);
|
||||||
|
|
||||||
command_header->identifier = 0x666;
|
command_header->identifier = 0x666;
|
||||||
command_header->sequence = echo_sequence++;
|
command_header->sequence = echo_sequence++;
|
||||||
|
|
||||||
// Send the packet back to ICMP
|
// Send the packet back to ICMP
|
||||||
network::icmp::finalize_packet(interface, packet);
|
network::icmp::finalize_packet(interface, *packet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,24 +110,28 @@ void network::ip::decode(network::interface_descriptor& interface, network::ethe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
network::ethernet::packet network::ip::prepare_packet(network::interface_descriptor& interface, size_t size, address& target_ip, size_t protocol){
|
std::expected<network::ethernet::packet> network::ip::prepare_packet(network::interface_descriptor& interface, size_t size, address& target_ip, size_t protocol){
|
||||||
auto target_mac = network::arp::get_mac_force(interface, target_ip);
|
auto target_mac = network::arp::get_mac_force(interface, target_ip);
|
||||||
|
|
||||||
// Ask the ethernet layer to craft a packet
|
// Ask the ethernet layer to craft a packet
|
||||||
auto packet = network::ethernet::prepare_packet(interface, size + sizeof(header), target_mac, ethernet::ether_type::IPV4);
|
auto packet = network::ethernet::prepare_packet(interface, size + sizeof(header), target_mac, ethernet::ether_type::IPV4);
|
||||||
|
|
||||||
::prepare_packet(packet, interface, size, target_ip, protocol);
|
if(packet){
|
||||||
|
::prepare_packet(*packet, interface, size, target_ip, protocol);
|
||||||
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
network::ethernet::packet network::ip::prepare_packet(char* buffer, network::interface_descriptor& interface, size_t size, address& target_ip, size_t protocol){
|
std::expected<network::ethernet::packet> network::ip::prepare_packet(char* buffer, network::interface_descriptor& interface, size_t size, address& target_ip, size_t protocol){
|
||||||
auto target_mac = network::arp::get_mac_force(interface, target_ip);
|
auto target_mac = network::arp::get_mac_force(interface, target_ip);
|
||||||
|
|
||||||
// Ask the ethernet layer to craft a packet
|
// Ask the ethernet layer to craft a packet
|
||||||
auto packet = network::ethernet::prepare_packet(buffer, interface, size + sizeof(header), target_mac, ethernet::ether_type::IPV4);
|
auto packet = network::ethernet::prepare_packet(buffer, interface, size + sizeof(header), target_mac, ethernet::ether_type::IPV4);
|
||||||
|
|
||||||
::prepare_packet(packet, interface, size, target_ip, protocol);
|
if(packet){
|
||||||
|
::prepare_packet(*packet, interface, size, target_ip, protocol);
|
||||||
|
}
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
@ -187,9 +187,14 @@ std::tuple<size_t, size_t> network::prepare_packet(size_t socket_fd, void* desc,
|
|||||||
case network::socket_protocol::ICMP:
|
case network::socket_protocol::ICMP:
|
||||||
auto descriptor = static_cast<network::icmp::packet_descriptor*>(desc);
|
auto descriptor = static_cast<network::icmp::packet_descriptor*>(desc);
|
||||||
auto packet = network::icmp::prepare_packet(buffer, interface, descriptor->target_ip, descriptor->payload_size, descriptor->type, descriptor->code);
|
auto packet = network::icmp::prepare_packet(buffer, interface, descriptor->target_ip, descriptor->payload_size, descriptor->type, descriptor->code);
|
||||||
auto fd = socket.register_packet(packet);
|
|
||||||
|
|
||||||
return {fd, packet.index};
|
if(packet){
|
||||||
|
auto fd = socket.register_packet(*packet);
|
||||||
|
|
||||||
|
return {fd, packet->index};
|
||||||
|
} else {
|
||||||
|
return {-packet.error(), 0};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {-std::ERROR_SOCKET_UNIMPLEMENTED, 0};
|
return {-std::ERROR_SOCKET_UNIMPLEMENTED, 0};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user