mirror of
https://github.com/mfontanini/libtins
synced 2026-01-28 12:44:25 +01:00
HWAddress class is working. EthernetII now uses this classes instead of raw uint8_t*
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "pdu.h"
|
||||
#include "utils.h"
|
||||
#include "hwaddress.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -35,6 +36,8 @@ namespace Tins {
|
||||
*/
|
||||
class EthernetII : public PDU {
|
||||
public:
|
||||
typedef HWAddress<6> address_type;
|
||||
|
||||
/**
|
||||
* \brief This PDU's flag.
|
||||
*/
|
||||
@@ -61,7 +64,11 @@ namespace Tins {
|
||||
* \param src_hw_addr uint8_t array of 6 bytes containing the source's MAC(optional).
|
||||
* \param child PDU* with the PDU contained by the ethernet PDU (optional).
|
||||
*/
|
||||
EthernetII(const std::string& iface, const uint8_t* dst_hw_addr = 0, const uint8_t* src_hw_addr = 0, PDU* child = 0) throw (std::runtime_error);
|
||||
//EthernetII(const std::string& iface, const uint8_t* dst_hw_addr = 0, const uint8_t* src_hw_addr = 0, PDU* child = 0);
|
||||
EthernetII(const std::string& iface,
|
||||
const address_type &dst_hw_addr = address_type(),
|
||||
const address_type &src_hw_addr = address_type(),
|
||||
PDU* child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating an ethernet PDU
|
||||
@@ -74,7 +81,10 @@ namespace Tins {
|
||||
* \param src_hw_addr uint8_t array of 6 bytes containing the source's MAC(optional).
|
||||
* \param child PDU* with the PDU contained by the ethernet PDU (optional).
|
||||
*/
|
||||
EthernetII(uint32_t iface_index, const uint8_t* dst_hw_addr = 0, const uint8_t* src_hw_addr = 0, PDU* child = 0);
|
||||
EthernetII(uint32_t iface_index,
|
||||
const address_type &dst_hw_addr = address_type(),
|
||||
const address_type &src_hw_addr = address_type(),
|
||||
PDU* child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an EthernetII object from a buffer and adds all identifiable
|
||||
@@ -90,14 +100,14 @@ namespace Tins {
|
||||
*
|
||||
* \return Returns the destination's mac address as a constant uint8_t pointer.
|
||||
*/
|
||||
const uint8_t* dst_addr() const { return _eth.dst_mac; }
|
||||
address_type dst_addr() const { return _eth.dst_mac; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the source's mac address.
|
||||
*
|
||||
* \return Returns the source's mac address as a constant uint8_t pointer.
|
||||
*/
|
||||
const uint8_t* src_addr() const { return _eth.src_mac; }
|
||||
address_type src_addr() const { return _eth.src_mac; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the interface.
|
||||
@@ -119,14 +129,14 @@ namespace Tins {
|
||||
*
|
||||
* \param new_dst_mac uint8_t array of 6 bytes containing the new destination's MAC.
|
||||
*/
|
||||
void dst_addr(const uint8_t* new_dst_mac);
|
||||
void dst_addr(const address_type &new_dst_mac);
|
||||
|
||||
/**
|
||||
* \brief Setter for the source's MAC.
|
||||
*
|
||||
* \param new_src_mac uint8_t array of 6 bytes containing the new source's MAC.
|
||||
*/
|
||||
void src_addr(const uint8_t* new_src_mac);
|
||||
void src_addr(const address_type &new_src_mac);
|
||||
|
||||
/**
|
||||
* \brief Setter for the interface.
|
||||
|
||||
@@ -24,26 +24,37 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdexcept>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <tins/utils.h> //borrame
|
||||
#include <sstream>
|
||||
|
||||
namespace Tins {
|
||||
template<size_t n>
|
||||
template<size_t n, typename Storage = uint8_t>
|
||||
class HWAddress {
|
||||
public:
|
||||
typedef uint8_t element_type;
|
||||
typedef element_type* iterator;
|
||||
typedef const element_type* const_iterator;
|
||||
typedef Storage storage_type;
|
||||
typedef storage_type* iterator;
|
||||
typedef const storage_type* const_iterator;
|
||||
static const size_t address_size = n;
|
||||
|
||||
HWAddress() {
|
||||
std::fill(buffer, buffer + address_size, element_type());
|
||||
std::fill(buffer, buffer + address_size, storage_type());
|
||||
}
|
||||
|
||||
HWAddress(const storage_type* ptr) {
|
||||
std::copy(ptr, ptr + address_size, buffer);
|
||||
}
|
||||
|
||||
HWAddress(const std::string &address) {
|
||||
convert(address, buffer);
|
||||
}
|
||||
|
||||
HWAddress& operator=(const std::string &address) {
|
||||
convert(address, buffer);
|
||||
}
|
||||
|
||||
iterator begin() {
|
||||
return buffer;
|
||||
}
|
||||
@@ -60,6 +71,14 @@ public:
|
||||
return buffer + address_size;
|
||||
}
|
||||
|
||||
bool operator==(const HWAddress &rhs) const {
|
||||
return std::equal(begin(), end(), rhs.begin());
|
||||
}
|
||||
|
||||
bool operator!=(const HWAddress &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, const HWAddress &addr) {
|
||||
std::transform(
|
||||
addr.buffer,
|
||||
@@ -73,7 +92,7 @@ private:
|
||||
template<typename OutputIterator>
|
||||
static void convert(const std::string &hw_addr, OutputIterator output);
|
||||
|
||||
static std::string to_string(element_type element) {
|
||||
static std::string to_string(storage_type element) {
|
||||
std::ostringstream oss;
|
||||
oss << std::hex;
|
||||
if(element < 0x10)
|
||||
@@ -82,17 +101,19 @@ private:
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
element_type buffer[n];
|
||||
storage_type buffer[n];
|
||||
};
|
||||
|
||||
template<size_t n>
|
||||
template<size_t n, typename Storage>
|
||||
template<typename OutputIterator>
|
||||
void HWAddress<n>::convert(const std::string &hw_addr, OutputIterator output) {
|
||||
void HWAddress<n, Storage>::convert(const std::string &hw_addr,
|
||||
OutputIterator output)
|
||||
{
|
||||
unsigned i(0);
|
||||
element_type tmp;
|
||||
storage_type tmp;
|
||||
while(i < hw_addr.size()) {
|
||||
const unsigned end = i+2;
|
||||
tmp = element_type();
|
||||
tmp = storage_type();
|
||||
while(i < end) {
|
||||
if(hw_addr[i] >= 'a' && hw_addr[i] <= 'f')
|
||||
tmp = (tmp << 4) | (hw_addr[i] - 'a' + 10);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#ifndef WIN32
|
||||
#include <net/ethernet.h>
|
||||
#include <netpacket/packet.h>
|
||||
@@ -35,28 +36,34 @@
|
||||
const uint8_t* Tins::EthernetII::BROADCAST = (const uint8_t*)"\xff\xff\xff\xff\xff\xff";
|
||||
const uint32_t Tins::EthernetII::ADDR_SIZE;
|
||||
|
||||
Tins::EthernetII::EthernetII(const std::string& iface, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) throw (std::runtime_error) : PDU(ETHERTYPE_IP, child) {
|
||||
Tins::EthernetII::EthernetII(const std::string& iface,
|
||||
const address_type &dst_hw_addr, const address_type &src_hw_addr,
|
||||
PDU* child)
|
||||
: PDU(ETHERTYPE_IP, child)
|
||||
{
|
||||
memset(&_eth, 0, sizeof(ethhdr));
|
||||
if(dst_hw_addr)
|
||||
this->dst_addr(dst_hw_addr);
|
||||
if(src_hw_addr)
|
||||
this->src_addr(src_hw_addr);
|
||||
dst_addr(dst_hw_addr);
|
||||
src_addr(src_hw_addr);
|
||||
this->iface(iface);
|
||||
this->_eth.payload_type = 0;
|
||||
_eth.payload_type = 0;
|
||||
|
||||
}
|
||||
|
||||
Tins::EthernetII::EthernetII(uint32_t iface_index, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) : PDU(ETHERTYPE_IP, child) {
|
||||
Tins::EthernetII::EthernetII(uint32_t iface_index,
|
||||
const address_type &dst_hw_addr, const address_type &src_hw_addr,
|
||||
PDU* child)
|
||||
: PDU(ETHERTYPE_IP, child)
|
||||
{
|
||||
memset(&_eth, 0, sizeof(ethhdr));
|
||||
if(dst_hw_addr)
|
||||
this->dst_addr(dst_hw_addr);
|
||||
if(src_hw_addr)
|
||||
this->src_addr(src_hw_addr);
|
||||
this->iface(iface_index);
|
||||
this->_eth.payload_type = 0;
|
||||
dst_addr(dst_hw_addr);
|
||||
src_addr(src_hw_addr);
|
||||
iface(iface_index);
|
||||
_eth.payload_type = 0;
|
||||
}
|
||||
|
||||
Tins::EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz) : PDU(ETHERTYPE_IP) {
|
||||
Tins::EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz)
|
||||
: PDU(ETHERTYPE_IP)
|
||||
{
|
||||
if(total_sz < sizeof(ethhdr))
|
||||
throw std::runtime_error("Not enough size for an ethernetII header in the buffer.");
|
||||
memcpy(&_eth, buffer, sizeof(ethhdr));
|
||||
@@ -77,12 +84,12 @@ Tins::EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz) : PDU(ETH
|
||||
}
|
||||
}
|
||||
|
||||
void Tins::EthernetII::dst_addr(const uint8_t* new_dst_mac) {
|
||||
memcpy(_eth.dst_mac, new_dst_mac, sizeof(_eth.dst_mac));
|
||||
void Tins::EthernetII::dst_addr(const address_type &new_dst_mac) {
|
||||
std::copy(new_dst_mac.begin(), new_dst_mac.end(), _eth.dst_mac);
|
||||
}
|
||||
|
||||
void Tins::EthernetII::src_addr(const uint8_t* new_src_mac) {
|
||||
memcpy(_eth.src_mac, new_src_mac, sizeof(_eth.src_mac));
|
||||
void Tins::EthernetII::src_addr(const address_type &new_src_mac) {
|
||||
std::copy(new_src_mac.begin(), new_src_mac.end(), _eth.src_mac);
|
||||
}
|
||||
|
||||
void Tins::EthernetII::iface(uint32_t new_iface_index) {
|
||||
|
||||
@@ -5,12 +5,14 @@
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
typedef EthernetII::address_type address_type;
|
||||
|
||||
class EthernetIITest : public ::testing::Test {
|
||||
public:
|
||||
static const uint8_t expected_packet[];
|
||||
static const uint8_t s_addr[];
|
||||
static const uint8_t d_addr[];
|
||||
static const uint8_t empty_addr[6];
|
||||
static address_type s_addr;
|
||||
static address_type d_addr;
|
||||
static address_type empty_addr;
|
||||
static const uint16_t p_type;
|
||||
static const uint32_t iface;
|
||||
|
||||
@@ -24,23 +26,19 @@ const uint8_t EthernetIITest::expected_packet[] = {
|
||||
'\xd0', '\xab'
|
||||
};
|
||||
|
||||
const uint8_t EthernetIITest::s_addr[] = {
|
||||
'\x8a', '\x8b', '\x8c', '\x8d', '\x8e', '\x8f'
|
||||
};
|
||||
address_type EthernetIITest::s_addr("8a:8b:8c:8d:8e:8f");
|
||||
|
||||
const uint8_t EthernetIITest::d_addr[] = {
|
||||
'\xaa', '\xbb', '\xcc', '\xdd', '\xee', '\xff'
|
||||
};
|
||||
address_type EthernetIITest::d_addr("aa:bb:cc:dd:ee:ff");
|
||||
|
||||
const uint8_t EthernetIITest::empty_addr[6] = {0};
|
||||
address_type EthernetIITest::empty_addr;
|
||||
|
||||
const uint16_t EthernetIITest::p_type = 0xd0ab;
|
||||
|
||||
const uint32_t EthernetIITest::iface = 0x12345678;
|
||||
|
||||
void EthernetIITest::test_equals(const EthernetII ð1, const EthernetII ð2) {
|
||||
EXPECT_TRUE(std::equal(eth1.dst_addr(), eth1.dst_addr() + EthernetII::ADDR_SIZE, eth2.dst_addr()));
|
||||
EXPECT_TRUE(std::equal(eth1.src_addr(), eth1.src_addr() + EthernetII::ADDR_SIZE, eth2.src_addr()));
|
||||
EXPECT_EQ(eth1.dst_addr(), eth2.dst_addr());
|
||||
EXPECT_EQ(eth1.src_addr(), eth2.src_addr());
|
||||
EXPECT_EQ(eth1.payload_type(), eth2.payload_type());
|
||||
EXPECT_EQ(eth1.iface(), eth2.iface());
|
||||
EXPECT_EQ((bool)eth1.inner_pdu(), (bool)eth2.inner_pdu());
|
||||
@@ -49,8 +47,8 @@ void EthernetIITest::test_equals(const EthernetII ð1, const EthernetII ð2)
|
||||
TEST_F(EthernetIITest, DefaultConstructor) {
|
||||
EthernetII eth(0);
|
||||
EXPECT_EQ(eth.iface(), 0);
|
||||
EXPECT_TRUE(memcmp(eth.dst_addr(), empty_addr, 6) == 0);
|
||||
EXPECT_TRUE(memcmp(eth.src_addr(), empty_addr, 6) == 0);
|
||||
EXPECT_EQ(eth.dst_addr(), empty_addr);
|
||||
EXPECT_EQ(eth.src_addr(), empty_addr);
|
||||
EXPECT_EQ(eth.payload_type(), 0);
|
||||
EXPECT_FALSE(eth.inner_pdu());
|
||||
EXPECT_EQ(eth.pdu_type(), PDU::ETHERNET_II);
|
||||
@@ -84,13 +82,13 @@ TEST_F(EthernetIITest, NestedCopy) {
|
||||
TEST_F(EthernetIITest, SourceAddress) {
|
||||
EthernetII eth(0);
|
||||
eth.src_addr(s_addr);
|
||||
ASSERT_TRUE(memcmp(eth.src_addr(), s_addr, 6) == 0);
|
||||
ASSERT_EQ(eth.src_addr(), s_addr);
|
||||
}
|
||||
|
||||
TEST_F(EthernetIITest, DestinationAddress) {
|
||||
EthernetII eth(0);
|
||||
eth.dst_addr(d_addr);
|
||||
ASSERT_TRUE(memcmp(eth.dst_addr(), d_addr, 6) == 0);
|
||||
ASSERT_EQ(eth.dst_addr(), d_addr);
|
||||
}
|
||||
|
||||
TEST_F(EthernetIITest, PayloadType) {
|
||||
@@ -110,8 +108,8 @@ TEST_F(EthernetIITest, Interface) {
|
||||
TEST_F(EthernetIITest, CompleteConstructor) {
|
||||
EthernetII* eth2 = new EthernetII(0);
|
||||
EthernetII eth(iface, d_addr, s_addr, eth2);
|
||||
EXPECT_TRUE(memcmp(eth.dst_addr(), d_addr, 6) == 0);
|
||||
EXPECT_TRUE(memcmp(eth.src_addr(), s_addr, 6) == 0);
|
||||
EXPECT_EQ(eth.dst_addr(), d_addr);
|
||||
EXPECT_EQ(eth.src_addr(), s_addr);
|
||||
EXPECT_TRUE(eth.inner_pdu() == eth2);
|
||||
EXPECT_EQ(eth.payload_type(), 0);
|
||||
EXPECT_EQ(eth.iface(), iface);
|
||||
@@ -130,8 +128,8 @@ TEST_F(EthernetIITest, Serialize) {
|
||||
|
||||
TEST_F(EthernetIITest, ConstructorFromBuffer) {
|
||||
EthernetII eth(expected_packet, sizeof(expected_packet));
|
||||
EXPECT_TRUE(memcmp(eth.src_addr(), s_addr, sizeof(s_addr)) == 0);
|
||||
EXPECT_TRUE(memcmp(eth.dst_addr(), d_addr, sizeof(d_addr)) == 0);
|
||||
EXPECT_EQ(eth.src_addr(), s_addr);
|
||||
EXPECT_EQ(eth.dst_addr(), d_addr);
|
||||
EXPECT_EQ(eth.payload_type(), p_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,11 @@ TEST_F(HWAddressTest, DefaultConstructor) {
|
||||
EXPECT_TRUE(std::equal(addr.begin(), addr.end(), empty_addr));
|
||||
}
|
||||
|
||||
TEST_F(HWAddressTest, ConstructorFromBytes) {
|
||||
HWAddress<6> addr(byte_address);
|
||||
EXPECT_TRUE(std::equal(addr.begin(), addr.end(), byte_address));
|
||||
}
|
||||
|
||||
TEST_F(HWAddressTest, ConstructorFromAddress) {
|
||||
HWAddress<6> addr(address);
|
||||
EXPECT_TRUE(std::equal(addr.begin(), addr.end(), byte_address));
|
||||
|
||||
Reference in New Issue
Block a user