From 8e50756afa04b5aec5e9346609932ca9c23830c9 Mon Sep 17 00:00:00 2001 From: Santiago Alessandri Date: Sat, 4 Nov 2017 12:08:34 -0700 Subject: [PATCH] Add MPLS experimental field (#265) * Add experimental field to MPLS PDU See RFC-4950 https://tools.ietf.org/html/rfc4950 * Add tests for MPLS' experimental field --- include/tins/mpls.h | 24 +++++++++++++++++++----- src/mpls.cpp | 8 ++++++-- tests/src/mpls_test.cpp | 11 ++++++++++- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/include/tins/mpls.h b/include/tins/mpls.h index d13dafc..150a2dd 100644 --- a/include/tins/mpls.h +++ b/include/tins/mpls.h @@ -73,15 +73,22 @@ public: * \brief Getter for the label field. */ small_uint<20> label() const { - return (Endian::be_to_host(header_.label_high) << 4) | - ((header_.label_low_and_bottom >> 4) & 0xf); + return (Endian::be_to_host(header_.label_high) << 4) | + ((header_.label_low_exp_and_bottom >> 4) & 0xf); + } + + /** + * \brief Getter for the experimental field. + */ + small_uint<3> experimental() const { + return (header_.label_low_exp_and_bottom >> 1) & 0x7; } /** * \brief Getter for the bottom of the stack field. */ small_uint<1> bottom_of_stack() const { - return header_.label_low_and_bottom & 0x1; + return header_.label_low_exp_and_bottom & 0x1; } /** @@ -98,11 +105,18 @@ public: */ void label(small_uint<20> value); + /** + * \brief Setter for the experimental field + * + * \param value The new experimental field value + */ + void experimental(small_uint<3> value); + /** * \brief Setter for the bottom of the stack field * * Note that if this MPLS layer is somewhere between an Ethernet and IP - * layers, the bottom of the stack field will be overriden and set + * layers, the bottom of the stack field will be overriden and set * automatically. You should only set this field when constructing ICMP * extensions. * @@ -143,7 +157,7 @@ private: TINS_BEGIN_PACK struct mpls_header { uint16_t label_high; - uint8_t label_low_and_bottom; + uint8_t label_low_exp_and_bottom; uint8_t ttl; } TINS_END_PACK; diff --git a/src/mpls.cpp b/src/mpls.cpp index 58e341c..c43860f 100644 --- a/src/mpls.cpp +++ b/src/mpls.cpp @@ -76,11 +76,15 @@ void MPLS::label(small_uint<20> value) { const uint16_t label_high = Endian::host_to_be(label_value >> 4); const uint8_t label_low = (label_value << 4) & 0xf0; header_.label_high = label_high & 0xffff; - header_.label_low_and_bottom = (header_.label_low_and_bottom & 0x0f) | label_low; + header_.label_low_exp_and_bottom = (header_.label_low_exp_and_bottom & 0x0f) | label_low; +} + +void MPLS::experimental(small_uint<3> value) { + header_.label_low_exp_and_bottom = (header_.label_low_exp_and_bottom & 0xf1) | (value << 1); } void MPLS::bottom_of_stack(small_uint<1> value) { - header_.label_low_and_bottom = (header_.label_low_and_bottom & 0xfe) | value; + header_.label_low_exp_and_bottom = (header_.label_low_exp_and_bottom & 0xfe) | value; } void MPLS::ttl(uint8_t value) { diff --git a/tests/src/mpls_test.cpp b/tests/src/mpls_test.cpp index 8fd5dac..6535e3c 100644 --- a/tests/src/mpls_test.cpp +++ b/tests/src/mpls_test.cpp @@ -26,7 +26,7 @@ const uint8_t MPLSTest::eth_and_mpls[] = { }; const uint8_t MPLSTest::mpls_layer[] = { - 24, 150, 1, 1 + 24, 150, 3, 1 }; TEST_F(MPLSTest, ConstructWholePacket) { @@ -63,6 +63,7 @@ TEST_F(MPLSTest, ConstructWholePacket) { TEST_F(MPLSTest, ConstructorFromBuffer) { MPLS mpls(mpls_layer, sizeof(mpls_layer)); EXPECT_EQ(100704U, mpls.label()); + EXPECT_EQ(1, mpls.experimental()); EXPECT_EQ(1, mpls.bottom_of_stack()); EXPECT_EQ(1, mpls.ttl()); } @@ -100,9 +101,11 @@ TEST_F(MPLSTest, SetAllFields) { mpls.ttl(0xde); mpls.bottom_of_stack(1); mpls.label(0xdead8); + mpls.experimental(6); EXPECT_EQ(0xdead8U, mpls.label()); EXPECT_EQ(1, mpls.bottom_of_stack()); EXPECT_EQ(0xde, mpls.ttl()); + EXPECT_EQ(6, mpls.experimental()); } TEST_F(MPLSTest, Label) { @@ -111,6 +114,12 @@ TEST_F(MPLSTest, Label) { EXPECT_EQ(0xdead8U, mpls.label()); } +TEST_F(MPLSTest, Experimental) { + MPLS mpls; + mpls.experimental(4); + EXPECT_EQ(4, mpls.experimental()); +} + TEST_F(MPLSTest, BottomOfStack) { MPLS mpls; mpls.bottom_of_stack(1);