Basic IP decoding

This commit is contained in:
Baptiste Wicht 2016-07-10 17:27:12 +02:00
parent ab8c9534f6
commit c736a9838b
3 changed files with 78 additions and 1 deletions

View File

@ -10,6 +10,8 @@
#include <types.hpp>
#include "network.hpp"
namespace network {
namespace ip {
@ -19,6 +21,9 @@ namespace ip {
struct address {
uint32_t raw_address = 0;
address(){}
address(uint32_t raw) : raw_address(raw) {}
uint8_t operator()(size_t index) const {
return (raw_address >> ((3 - index) * 8)) & 0xFF;
}
@ -41,6 +46,23 @@ inline address make_address(uint8_t a, uint8_t b, uint8_t c, uint8_t d){
return addr;
}
struct header {
uint8_t version_ihl;
uint8_t dscp_ecn;
uint16_t total_len;
uint16_t identification;
uint16_t flags_offset;
uint8_t ttl;
uint8_t protocol;
uint16_t header_checksum;
uint32_t source_ip;
uint32_t target_ip;
} __attribute__((packed));
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);
} // end of ip namespace
} // end of network namespace

View File

@ -12,6 +12,7 @@
#include "logging.hpp"
#include "kernel_utils.hpp"
#include "arp_layer.hpp"
#include "ip_layer.hpp"
namespace {
@ -70,7 +71,7 @@ void network::ethernet::decode(network::interface_descriptor& interface, packet&
switch(packet.type){
case ether_type::IPV4:
logging::logf(logging::log_level::TRACE, "ethernet: IPV4 Packet (unsupported)\n");
network::ip::decode(interface, packet);
break;
case ether_type::IPV6:
logging::logf(logging::log_level::TRACE, "ethernet: IPV6 Packet (unsupported)\n");

54
kernel/src/ip_layer.cpp Normal file
View File

@ -0,0 +1,54 @@
//=======================================================================
// 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 <vector.hpp>
#include <string.hpp>
#include "ip_layer.hpp"
#include "logging.hpp"
#include "kernel_utils.hpp"
void network::ip::decode(network::interface_descriptor& interface, network::ethernet::packet& packet){
header* arp_header = reinterpret_cast<header*>(packet.payload + packet.index);
logging::logf(logging::log_level::TRACE, "ip: Start IPv4 packet handling\n");
auto version = arp_header->version_ihl >> 4;
if(version != 4){
logging::logf(logging::log_level::ERROR, "ip: IPv6 Packet received instead of IPv4\n");
return;
}
auto ihl = arp_header->version_ihl & 0xF;
auto length = switch_endian_16(arp_header->total_len);
auto data_length = length - ihl * 4;
logging::logf(logging::log_level::TRACE, "ip: Data Length: %u\n", size_t(data_length));
logging::logf(logging::log_level::TRACE, "ip: Time To Live: %u\n", size_t(arp_header->ttl));
network::ip::address source(switch_endian_32(arp_header->source_ip));
network::ip::address target(switch_endian_32(arp_header->target_ip));
logging::logf(logging::log_level::TRACE, "ip: Source Protocol Address %u.%u.%u.%u \n",
uint64_t(source(0)), uint64_t(source(1)), uint64_t(source(2)), uint64_t(source(3)));
logging::logf(logging::log_level::TRACE, "ip: Target Protocol Address %u.%u.%u.%u \n",
uint64_t(target(0)), uint64_t(target(1)), uint64_t(target(2)), uint64_t(target(3)));
auto protocol = arp_header->protocol;
if(protocol == 0x01){
logging::logf(logging::log_level::DEBUG, "ip: ICMP packet detected\n");
} else if(protocol == 0x06){
logging::logf(logging::log_level::ERROR, "ip: TCP packet detected (unsupported)\n");
} else if(protocol == 0x11){
logging::logf(logging::log_level::ERROR, "ip: UDP packet detected (unsupported)\n");
} else {
logging::logf(logging::log_level::ERROR, "ip: Packet of unknown protocol detected (%h)\n", size_t(protocol));
}
}