mirror of
https://github.com/mfontanini/libtins
synced 2026-01-27 20:24:26 +01:00
Added STP root_id and bridge_id setters/getters.
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "pdu.h"
|
||||
#include "endianness.h"
|
||||
#include "hw_address.h"
|
||||
#include "small_uint.h"
|
||||
|
||||
namespace Tins {
|
||||
@@ -41,6 +42,24 @@ public:
|
||||
* This PDU's flag.
|
||||
*/
|
||||
static const PDU::PDUType pdu_flag = PDU::STP;
|
||||
|
||||
/**
|
||||
* The type used to store BPDU identifier addresses.
|
||||
*/
|
||||
typedef HWAddress<6> address_type;
|
||||
|
||||
/**
|
||||
* The type used to store the BPDU identifiers.
|
||||
*/
|
||||
struct bpdu_id_type {
|
||||
small_uint<4> priority;
|
||||
small_uint<12> ext_id;
|
||||
address_type id;
|
||||
|
||||
bpdu_id_type(small_uint<4> priority=0, small_uint<12> ext_id=0,
|
||||
const address_type& id=address_type())
|
||||
: priority(priority), ext_id(ext_id), id(id) { }
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Default constructor.
|
||||
@@ -139,6 +158,18 @@ public:
|
||||
uint16_t fwd_delay() const {
|
||||
return Endian::be_to_host(_header.fwd_delay) / 256;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Getter for the root id field.
|
||||
* \return The stored root id field value.
|
||||
*/
|
||||
bpdu_id_type root_id() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the bridge id field.
|
||||
* \return The stored bridge id field value.
|
||||
*/
|
||||
bpdu_id_type bridge_id() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
@@ -221,13 +252,26 @@ public:
|
||||
* \param new_fwd_delay The new fwd_delay field value.
|
||||
*/
|
||||
void fwd_delay(uint16_t new_fwd_delay);
|
||||
|
||||
/**
|
||||
* \brief Setter for the root id field.
|
||||
* \param new_fwd_delay The new root id field value.
|
||||
*/
|
||||
void root_id(const bpdu_id_type &id);
|
||||
|
||||
/**
|
||||
* \brief Setter for the bridge id field.
|
||||
* \param new_fwd_delay The new bridge id field value.
|
||||
*/
|
||||
void bridge_id(const bpdu_id_type &id);
|
||||
private:
|
||||
TINS_BEGIN_PACK
|
||||
struct pvt_bpdu_id {
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
// fixme
|
||||
uint16_t priority:4,
|
||||
ext_id:12;
|
||||
uint16_t ext_id:4,
|
||||
priority:4,
|
||||
ext_idL:8;
|
||||
#else
|
||||
uint16_t priority:4,
|
||||
ext_id:12;
|
||||
@@ -251,6 +295,9 @@ private:
|
||||
uint16_t fwd_delay;
|
||||
} TINS_END_PACK;
|
||||
|
||||
static bpdu_id_type convert(const pvt_bpdu_id &id);
|
||||
static pvt_bpdu_id convert(const bpdu_id_type &id);
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
stphdr _header;
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include <mstcpip.h>
|
||||
#endif
|
||||
#include <limits>
|
||||
#include <iostream> // borrame
|
||||
#include <sstream>
|
||||
#include "ipv6_address.h"
|
||||
|
||||
|
||||
40
src/stp.cpp
40
src/stp.cpp
@@ -29,6 +29,7 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <algorithm>
|
||||
#include "stp.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
@@ -87,6 +88,22 @@ void STP::fwd_delay(uint16_t new_fwd_delay) {
|
||||
_header.fwd_delay = Endian::host_to_be<uint16_t>(new_fwd_delay * 256);
|
||||
}
|
||||
|
||||
STP::bpdu_id_type STP::root_id() const {
|
||||
return convert(_header.root_id);
|
||||
}
|
||||
|
||||
STP::bpdu_id_type STP::bridge_id() const {
|
||||
return convert(_header.bridge_id);
|
||||
}
|
||||
|
||||
void STP::root_id(const bpdu_id_type &id) {
|
||||
_header.root_id = convert(id);
|
||||
}
|
||||
|
||||
void STP::bridge_id(const bpdu_id_type &id) {
|
||||
_header.bridge_id = convert(id);
|
||||
}
|
||||
|
||||
void STP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= sizeof(_header));
|
||||
@@ -97,5 +114,28 @@ void STP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
uint32_t STP::header_size() const {
|
||||
return sizeof(_header);
|
||||
}
|
||||
|
||||
STP::bpdu_id_type STP::convert(const pvt_bpdu_id &id) {
|
||||
bpdu_id_type result(id.priority, 0, id.id);
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
result.ext_id = (id.ext_id << 8) | id.ext_idL;
|
||||
#else
|
||||
result.ext_id = id.ext_id;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
STP::pvt_bpdu_id STP::convert(const bpdu_id_type &id) {
|
||||
pvt_bpdu_id result;
|
||||
result.priority = id.priority;
|
||||
std::copy(id.id.begin(), id.id.end(), result.id);
|
||||
#if TINS_IS_LITTLE_ENDIAN
|
||||
result.ext_id = (id.ext_id >> 8) & 0xf;
|
||||
result.ext_idL = id.ext_id & 0xff;
|
||||
#else
|
||||
result.ext_id = id.ext_id;
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
#include <iostream> //borrame
|
||||
#include <cstring>
|
||||
#include "utils.h"
|
||||
#ifndef WIN32
|
||||
|
||||
@@ -12,6 +12,7 @@ using namespace Tins;
|
||||
class STPTest : public testing::Test {
|
||||
public:
|
||||
static const uint8_t expected_packet[];
|
||||
static void test_equals(const STP::bpdu_id_type &lhs, const STP::bpdu_id_type &rhs);
|
||||
};
|
||||
|
||||
const uint8_t STPTest::expected_packet[] = {
|
||||
@@ -20,6 +21,12 @@ const uint8_t STPTest::expected_packet[] = {
|
||||
0
|
||||
};
|
||||
|
||||
void STPTest::test_equals(const STP::bpdu_id_type &lhs, const STP::bpdu_id_type &rhs) {
|
||||
EXPECT_EQ(lhs.priority, rhs.priority);
|
||||
EXPECT_EQ(lhs.ext_id, rhs.ext_id);
|
||||
EXPECT_EQ(lhs.id, rhs.id);
|
||||
}
|
||||
|
||||
TEST_F(STPTest, DefaultConstructor) {
|
||||
STP pdu;
|
||||
EXPECT_EQ(0, pdu.proto_id());
|
||||
@@ -36,12 +43,15 @@ TEST_F(STPTest, DefaultConstructor) {
|
||||
|
||||
TEST_F(STPTest, ConstructorFromBuffer) {
|
||||
STP pdu(expected_packet, sizeof(expected_packet));
|
||||
STP::bpdu_id_type bpdu(0x8, 0, "00:90:4c:08:17:b5");
|
||||
EXPECT_EQ(0x9283, pdu.proto_id());
|
||||
EXPECT_EQ(0x8a, pdu.proto_version());
|
||||
EXPECT_EQ(0x92, pdu.bpdu_type());
|
||||
EXPECT_EQ(0x92, pdu.bpdu_flags());
|
||||
test_equals(bpdu, pdu.root_id());
|
||||
// root identifier(32768. 0, 00:90:4c:08:17:b5
|
||||
EXPECT_EQ(0x928378, pdu.root_path_cost());
|
||||
test_equals(bpdu, pdu.bridge_id());
|
||||
// bridge identifier(32768. 0, 00:90:4c:08:17:b5
|
||||
EXPECT_EQ(0x8001, pdu.port_id());
|
||||
EXPECT_EQ(15, pdu.msg_age());
|
||||
@@ -50,6 +60,17 @@ TEST_F(STPTest, ConstructorFromBuffer) {
|
||||
EXPECT_EQ(0, pdu.fwd_delay());
|
||||
}
|
||||
|
||||
TEST_F(STPTest, BPDUId) {
|
||||
const uint8_t expected_packet[] = {
|
||||
0, 0, 0, 0, 0, 128, 100, 0, 28, 14, 135, 120, 0, 0, 0, 0, 4, 128,
|
||||
100, 0, 28, 14, 135, 133, 0, 128, 4, 1, 0, 20, 0, 2, 0, 15, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
STP pdu(expected_packet, sizeof(expected_packet));
|
||||
STP::bpdu_id_type bpdu(0x8, 100, "00:1c:0e:87:78:00");
|
||||
test_equals(bpdu, pdu.root_id());
|
||||
}
|
||||
|
||||
TEST_F(STPTest, ChainedPDUs) {
|
||||
const uint8_t input[] = {
|
||||
1, 128, 194, 0, 0, 0, 0, 144, 76, 8, 23, 181, 0, 38, 66, 66, 3,
|
||||
@@ -140,3 +161,17 @@ TEST_F(STPTest, HelloTime) {
|
||||
pdu.hello_time(15);
|
||||
EXPECT_EQ(15, pdu.hello_time());
|
||||
}
|
||||
|
||||
TEST_F(STPTest, RootID) {
|
||||
STP pdu;
|
||||
STP::bpdu_id_type bpdu(0x8, 100, "00:1c:0e:87:78:00");
|
||||
pdu.root_id(bpdu);
|
||||
test_equals(bpdu, pdu.root_id());
|
||||
}
|
||||
|
||||
TEST_F(STPTest, BridgeID) {
|
||||
STP pdu;
|
||||
STP::bpdu_id_type bpdu(0x8, 100, "00:1c:0e:87:78:00");
|
||||
pdu.bridge_id(bpdu);
|
||||
test_equals(bpdu, pdu.bridge_id());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user