2011-12-22 15:19:25 +00:00
|
|
|
/*
|
|
|
|
* \brief Ethernet protocol
|
|
|
|
* \author Stefan Kalkowski
|
|
|
|
* \date 2010-08-19
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 12:23:52 +00:00
|
|
|
* Copyright (C) 2010-2017 Genode Labs GmbH
|
2011-12-22 15:19:25 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 12:23:52 +00:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _NET__ETHERNET_H_
|
|
|
|
#define _NET__ETHERNET_H_
|
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <base/exception.h>
|
|
|
|
#include <util/string.h>
|
|
|
|
|
|
|
|
#include <util/endian.h>
|
2016-08-15 10:50:33 +00:00
|
|
|
#include <net/mac_address.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2016-08-25 15:40:45 +00:00
|
|
|
namespace Net
|
|
|
|
{
|
|
|
|
class Ethernet_frame;
|
|
|
|
|
|
|
|
template <Genode::size_t DATA_SIZE>
|
|
|
|
class Ethernet_frame_sized;
|
|
|
|
}
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Data layout of this class conforms to the Ethernet II frame
|
|
|
|
* (IEEE 802.3).
|
|
|
|
*
|
|
|
|
* Ethernet-frame-header-format:
|
|
|
|
*
|
|
|
|
* ----------------------------------------------------------
|
|
|
|
* | destination mac address | source mac address | ethertype |
|
|
|
|
* | 6 bytes | 6 bytes | 2 bytes |
|
|
|
|
* ----------------------------------------------------------
|
|
|
|
*/
|
|
|
|
class Net::Ethernet_frame
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
enum Size {
|
|
|
|
ADDR_LEN = 6, /* MAC address length in bytes */
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static const Mac_address BROADCAST; /* broadcast address */
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
2017-09-14 13:10:32 +00:00
|
|
|
Genode::uint8_t _dst[ADDR_LEN]; /* destination mac address */
|
|
|
|
Genode::uint8_t _src[ADDR_LEN]; /* source mac address */
|
|
|
|
Genode::uint16_t _type; /* encapsulated protocol */
|
|
|
|
unsigned _data[0]; /* encapsulated data */
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
class No_ethernet_frame : Genode::Exception {};
|
|
|
|
|
2016-08-25 15:40:45 +00:00
|
|
|
enum { MIN_SIZE = 64 };
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Id representing encapsulated protocol.
|
|
|
|
*/
|
2017-09-13 11:10:39 +00:00
|
|
|
enum class Type : Genode::uint16_t {
|
|
|
|
IPV4 = 0x0800,
|
|
|
|
ARP = 0x0806,
|
2015-03-04 20:12:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/*****************
|
|
|
|
** Constructor **
|
|
|
|
*****************/
|
|
|
|
|
|
|
|
Ethernet_frame(Genode::size_t size) {
|
|
|
|
/* at least, frame header needs to fit in */
|
|
|
|
if (size < sizeof(Ethernet_frame))
|
|
|
|
throw No_ethernet_frame();
|
|
|
|
}
|
|
|
|
|
2017-10-06 11:00:05 +00:00
|
|
|
/**
|
|
|
|
* Constructor for composing a new Ethernet frame
|
|
|
|
*/
|
|
|
|
Ethernet_frame() { }
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
|
2017-09-14 13:10:32 +00:00
|
|
|
/***************
|
|
|
|
** Accessors **
|
|
|
|
***************/
|
2015-03-04 20:12:14 +00:00
|
|
|
|
2017-09-14 13:10:32 +00:00
|
|
|
Mac_address dst() const { return Mac_address((void *)_dst); }
|
|
|
|
Mac_address src() const { return Mac_address((void *)_src); }
|
|
|
|
Type type() const { return (Type)host_to_big_endian(_type); }
|
|
|
|
template <typename T> T const *data() const { return (T const *)(_data); }
|
|
|
|
template <typename T> T *data() { return (T *)(_data); }
|
2015-03-04 20:12:14 +00:00
|
|
|
|
2017-09-14 13:10:32 +00:00
|
|
|
void dst(Mac_address v) { v.copy(&_dst); }
|
|
|
|
void src(Mac_address v) { v.copy(&_src); }
|
|
|
|
void type(Type type) { _type = host_to_big_endian((Genode::uint16_t)type); }
|
2015-03-04 20:12:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
/***************
|
|
|
|
** Operators **
|
|
|
|
***************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Placement new operator.
|
|
|
|
*/
|
2016-09-15 12:40:37 +00:00
|
|
|
void * operator new(__SIZE_TYPE__ size, void* addr) { return addr; }
|
2015-03-04 20:12:14 +00:00
|
|
|
|
2016-11-02 00:00:59 +00:00
|
|
|
|
|
|
|
/*********
|
|
|
|
** log **
|
|
|
|
*********/
|
|
|
|
|
|
|
|
void print(Genode::Output &output) const;
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
} __attribute__((packed));
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2016-08-25 15:40:45 +00:00
|
|
|
|
|
|
|
template <Genode::size_t DATA_SIZE>
|
|
|
|
class Net::Ethernet_frame_sized : public Ethernet_frame
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
|
|
|
enum {
|
|
|
|
HS = sizeof(Ethernet_frame),
|
|
|
|
DS = DATA_SIZE + HS >= MIN_SIZE ? DATA_SIZE : MIN_SIZE - HS,
|
|
|
|
};
|
|
|
|
|
|
|
|
Genode::uint8_t _data[DS];
|
|
|
|
Genode::uint32_t _checksum;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
Ethernet_frame_sized(Mac_address dst_in, Mac_address src_in,
|
2017-09-13 11:10:39 +00:00
|
|
|
Type type_in)
|
2016-08-25 15:40:45 +00:00
|
|
|
:
|
|
|
|
Ethernet_frame(sizeof(Ethernet_frame))
|
|
|
|
{
|
|
|
|
dst(dst_in);
|
|
|
|
src(src_in);
|
|
|
|
type(type_in);
|
|
|
|
}
|
|
|
|
|
|
|
|
} __attribute__((packed));
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
#endif /* _NET__ETHERNET_H_ */
|