diff --git a/kernel/include/arp_layer.hpp b/kernel/include/arp_layer.hpp new file mode 100644 index 00000000..26a72888 --- /dev/null +++ b/kernel/include/arp_layer.hpp @@ -0,0 +1,33 @@ +//======================================================================= +// 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 NET_ARP_LAYER_H +#define NET_ARP_LAYER_H + +#include + +#include "ethernet_layer.hpp" + +namespace network { + +namespace arp { + +struct header { + uint16_t hw_type; + uint16_t protocol_type; + uint8_t hw_len; + uint8_t protocol_len; + uint16_t operation; +} __attribute__((packed)); + +void decode(network::ethernet::packet& packet); + +} // end of arp namespace + +} // end of network namespace + +#endif diff --git a/kernel/include/ethernet_layer.hpp b/kernel/include/ethernet_layer.hpp index 59e1b637..89d1be44 100644 --- a/kernel/include/ethernet_layer.hpp +++ b/kernel/include/ethernet_layer.hpp @@ -29,8 +29,9 @@ struct packet { // Set by ethernet ether_type type; + size_t index; - packet(char* payload, size_t payload_size) : payload(payload), payload_size(payload_size) {} + packet(char* payload, size_t payload_size) : payload(payload), payload_size(payload_size), index(0) {} }; struct address { diff --git a/kernel/src/arp_layer.cpp b/kernel/src/arp_layer.cpp new file mode 100644 index 00000000..671610c9 --- /dev/null +++ b/kernel/src/arp_layer.cpp @@ -0,0 +1,46 @@ +//======================================================================= +// 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 +#include + +#include "arp_layer.hpp" +#include "logging.hpp" +#include "kernel_utils.hpp" + +namespace { + +//TODO + +} //end of anonymous namespace + +void network::arp::decode(network::ethernet::packet& packet){ + header* arp_header = reinterpret_cast(packet.payload + packet.index); + + logging::logf(logging::log_level::TRACE, "arp: Start ARP packet handling\n"); + + auto hw_type = switch_endian_16(arp_header->hw_type); + auto protocol_type = switch_endian_16(arp_header->protocol_type); + + if(hw_type != 0x1){ + logging::logf(logging::log_level::ERROR, "arp: Unhandled hardware type %h\n", size_t(hw_type)); + return; + } + + if(protocol_type != 0x800){ + logging::logf(logging::log_level::ERROR, "arp: Unhandled protocol type %h\n", size_t(protocol_type)); + return; + } + + auto hw_len = arp_header->hw_len; + auto protocol_len = arp_header->protocol_len; + auto operation = switch_endian_16(arp_header->operation); + + logging::logf(logging::log_level::TRACE, "arp: Start ARP packet handling %h\n", size_t(hw_len)); + logging::logf(logging::log_level::TRACE, "arp: Start ARP packet handling %h\n", size_t(protocol_len)); + logging::logf(logging::log_level::TRACE, "arp: Start ARP packet handling %h\n", size_t(operation)); +} diff --git a/kernel/src/ethernet_layer.cpp b/kernel/src/ethernet_layer.cpp index 0bd212b0..2962de96 100644 --- a/kernel/src/ethernet_layer.cpp +++ b/kernel/src/ethernet_layer.cpp @@ -11,6 +11,7 @@ #include "ethernet_layer.hpp" #include "logging.hpp" #include "kernel_utils.hpp" +#include "arp_layer.hpp" namespace { @@ -51,6 +52,7 @@ void network::ethernet::decode(packet& packet){ logging::logf(logging::log_level::TRACE, "ethernet: Destination MAC Address %h \n", target_mac); packet.type = decode_ether_type(ether_header); + packet.index += sizeof(header); switch(packet.type){ case ether_type::IPV4: @@ -60,7 +62,7 @@ void network::ethernet::decode(packet& packet){ logging::logf(logging::log_level::TRACE, "ethernet: IPV6 Packet (unsupported)\n"); break; case ether_type::ARP: - logging::logf(logging::log_level::TRACE, "ethernet: ARP Packet (unsupported)\n"); + network::arp::decode(packet); break; case ether_type::UNKNOWN: logging::logf(logging::log_level::TRACE, "ethernet: Unhandled Packet Type: %u\n", uint64_t(switch_endian_16(ether_header->type)));