mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
net: ICMP protocol
Packet format and common utilities for the Internet Control Message Protocol. Issue #2732
This commit is contained in:
parent
8ba26c612a
commit
365bd347a6
95
repos/os/include/net/icmp.h
Normal file
95
repos/os/include/net/icmp.h
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* \brief Internet Control Message Protocol
|
||||
* \author Martin Stein
|
||||
* \date 2018-03-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _NET__ICMP_H_
|
||||
#define _NET__ICMP_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/endian.h>
|
||||
#include <base/exception.h>
|
||||
|
||||
namespace Genode { class Output; }
|
||||
|
||||
namespace Net { class Icmp_packet; }
|
||||
|
||||
|
||||
class Net::Icmp_packet
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::uint8_t _type;
|
||||
Genode::uint8_t _code;
|
||||
Genode::uint16_t _checksum;
|
||||
union {
|
||||
Genode::uint32_t _rest_of_header_u32[1];
|
||||
Genode::uint16_t _rest_of_header_u16[2];
|
||||
Genode::uint8_t _rest_of_header_u8[4];
|
||||
};
|
||||
Genode::uint8_t _data[0];
|
||||
|
||||
public:
|
||||
|
||||
struct Bad_data_type : Genode::Exception { };
|
||||
|
||||
enum class Type
|
||||
{
|
||||
ECHO_REPLY = 0,
|
||||
DST_UNREACHABLE = 3,
|
||||
ECHO_REQUEST = 8,
|
||||
};
|
||||
|
||||
enum class Code
|
||||
{
|
||||
DST_NET_UNREACHABLE = 0,
|
||||
ECHO_REQUEST = 0,
|
||||
ECHO_REPLY = 0,
|
||||
};
|
||||
|
||||
Genode::uint16_t calc_checksum(Genode::size_t data_sz) const;
|
||||
|
||||
|
||||
/***************
|
||||
** Accessors **
|
||||
***************/
|
||||
|
||||
Type type() const { return (Type)_type; }
|
||||
Code code() const { return (Code)_code; }
|
||||
Genode::uint16_t checksum() const { return host_to_big_endian(_checksum); }
|
||||
Genode::uint16_t query_id() const { return host_to_big_endian(_rest_of_header_u16[0]); }
|
||||
Genode::uint16_t query_seq() const { return host_to_big_endian(_rest_of_header_u16[1]); }
|
||||
Genode::uint32_t rest_of_header() const { return host_to_big_endian(_rest_of_header_u32[0]); }
|
||||
|
||||
template <typename T> T &data(Genode::size_t data_size)
|
||||
{
|
||||
if (data_size < sizeof(T)) {
|
||||
throw Bad_data_type();
|
||||
}
|
||||
return *(T *)(_data);
|
||||
}
|
||||
|
||||
void type(Type v) { _type = (Genode::uint8_t)v; }
|
||||
void code(Code v) { _code = (Genode::uint8_t)v; }
|
||||
void checksum(Genode::uint16_t v) { _checksum = host_to_big_endian(v); }
|
||||
void rest_of_header(Genode::uint32_t v) { _rest_of_header_u32[0] = host_to_big_endian(v); }
|
||||
void query_id(Genode::uint16_t v) { _rest_of_header_u16[0] = host_to_big_endian(v); }
|
||||
void query_seq(Genode::uint16_t v) { _rest_of_header_u16[1] = host_to_big_endian(v); }
|
||||
|
||||
|
||||
/*********
|
||||
** log **
|
||||
*********/
|
||||
|
||||
void print(Genode::Output &output) const;
|
||||
};
|
||||
|
||||
#endif /* _NET__ICMP_H_ */
|
@ -117,8 +117,9 @@ class Net::Ipv4_packet
|
||||
|
||||
enum class Protocol : Genode::uint8_t
|
||||
{
|
||||
TCP = 6,
|
||||
UDP = 17,
|
||||
ICMP = 1,
|
||||
TCP = 6,
|
||||
UDP = 17,
|
||||
};
|
||||
|
||||
struct Bad_data_type : Genode::Exception { };
|
||||
|
@ -1,3 +1,4 @@
|
||||
SRC_CC = ethernet.cc ipv4.cc dhcp.cc arp.cc udp.cc tcp.cc mac_address.cc
|
||||
SRC_CC += ethernet.cc ipv4.cc dhcp.cc arp.cc udp.cc tcp.cc mac_address.cc
|
||||
SRC_CC += icmp.cc
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/net
|
||||
|
54
repos/os/src/lib/net/icmp.cc
Normal file
54
repos/os/src/lib/net/icmp.cc
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* \brief Internet Control Message Protocol
|
||||
* \author Martin Stein
|
||||
* \date 2018-03-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2018 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <net/icmp.h>
|
||||
#include <base/output.h>
|
||||
|
||||
using namespace Net;
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Net::Icmp_packet::print(Output &output) const
|
||||
{
|
||||
Genode::print(output, "\033[32mICMP\033[0m ", (unsigned)type(), " ",
|
||||
(unsigned)code());
|
||||
}
|
||||
|
||||
|
||||
uint16_t Icmp_packet::calc_checksum(size_t data_sz) const
|
||||
{
|
||||
/* do not sum-up checksum itself */
|
||||
register long sum = _type + _code;
|
||||
addr_t addr = (addr_t)&_rest_of_header_u32;
|
||||
size_t count = sizeof(Icmp_packet) + data_sz - sizeof(_type) -
|
||||
sizeof(_code) - sizeof(_checksum);
|
||||
|
||||
/* sum-up rest of header and data */
|
||||
while (count > 1) {
|
||||
sum += *(uint16_t *)addr;
|
||||
addr += sizeof(uint16_t);
|
||||
count -= sizeof(uint16_t);
|
||||
}
|
||||
/* add left-over byte, if any */
|
||||
if (count) {
|
||||
sum += *(uint8_t *)addr;
|
||||
}
|
||||
/* fold 32-bit sum to 16 bits */
|
||||
while (sum >> 16) {
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
}
|
||||
/* write to header */
|
||||
uint16_t sum16 = ~sum;
|
||||
return host_to_big_endian(sum16);
|
||||
}
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <net/udp.h>
|
||||
#include <net/tcp.h>
|
||||
#include <net/icmp.h>
|
||||
#include <net/ipv4.h>
|
||||
|
||||
using namespace Genode;
|
||||
@ -32,6 +33,9 @@ void Net::Ipv4_packet::print(Genode::Output &output) const
|
||||
case Protocol::UDP:
|
||||
Genode::print(output, *reinterpret_cast<Udp_packet const *>(_data));
|
||||
break;
|
||||
case Protocol::ICMP:
|
||||
Genode::print(output, *reinterpret_cast<Icmp_packet const *>(_data));
|
||||
break;
|
||||
default: ; }
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user