diff --git a/include/tins/pdu.h b/include/tins/pdu.h index ab006ef..bde9a1b 100644 --- a/include/tins/pdu.h +++ b/include/tins/pdu.h @@ -231,8 +231,11 @@ public: * \param rhs The PDU to be moved. */ PDU(PDU &&rhs) TINS_NOEXCEPT - : inner_pdu_(0) { + : inner_pdu_(0), parent_pdu_(0) { std::swap(inner_pdu_, rhs.inner_pdu_); + if (inner_pdu_) { + inner_pdu_->parent_pdu(this); + } } /** @@ -242,6 +245,10 @@ public: */ PDU& operator=(PDU &&rhs) TINS_NOEXCEPT { std::swap(inner_pdu_, rhs.inner_pdu_); + rhs.inner_pdu_ = 0; + if (inner_pdu_) { + inner_pdu_->parent_pdu(this); + } return* this; } #endif @@ -274,11 +281,19 @@ public: /** * \brief Getter for the inner PDU. - * \return The current inner PDU. Might be 0. + * \return The current inner PDU. Might be a null pointer. */ PDU* inner_pdu() const { return inner_pdu_; } + + /** + * Getter for the parent PDU + * \return The current parent PDU. Might be a null pointer. + */ + PDU* parent_pdu() const { + return parent_pdu_; + } /** * \brief Releases the inner PDU. @@ -314,7 +329,6 @@ public: */ void inner_pdu(const PDU& next_pdu); - /** * \brief Serializes the whole chain of PDU's, including this one. * @@ -505,7 +519,10 @@ protected: */ virtual void write_serialization(uint8_t* buffer, uint32_t total_sz, const PDU* parent) = 0; private: + void parent_pdu(PDU* parent); + PDU* inner_pdu_; + PDU* parent_pdu_; }; /** diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 63e78af..82a7ae0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -80,7 +80,6 @@ SET(PCAP_DEPENDENT_SOURCES ) IF(LIBTINS_ENABLE_PCAP) - message(STATUS "SETTING TO ${PCAP_DEPENDENT_SOURCES}") SET(SOURCES ${SOURCES} ${PCAP_DEPENDENT_SOURCES}) ENDIF() diff --git a/src/pdu.cpp b/src/pdu.cpp index f772da3..50899d9 100644 --- a/src/pdu.cpp +++ b/src/pdu.cpp @@ -49,12 +49,12 @@ PDU::metadata::metadata(uint32_t header_size, PDUType current_type, PDUType next // PDU PDU::PDU() -: inner_pdu_() { +: inner_pdu_(), parent_pdu_() { } PDU::PDU(const PDU& other) -: inner_pdu_(0) { +: inner_pdu_(), parent_pdu_() { copy_inner_pdu(other); } @@ -101,6 +101,9 @@ bool PDU::matches_response(const uint8_t* /*ptr*/, uint32_t /*total_sz*/) const void PDU::inner_pdu(PDU* next_pdu) { delete inner_pdu_; inner_pdu_ = next_pdu; + if (inner_pdu_) { + inner_pdu_->parent_pdu(this); + } } void PDU::inner_pdu(const PDU& next_pdu) { @@ -110,6 +113,9 @@ void PDU::inner_pdu(const PDU& next_pdu) { PDU* PDU::release_inner_pdu() { PDU* result = 0; swap(result, inner_pdu_); + if (result) { + result->parent_pdu(0); + } return result; } @@ -132,4 +138,8 @@ void PDU::serialize(uint8_t* buffer, uint32_t total_sz, const PDU* parent) { write_serialization(buffer, total_sz, parent); } +void PDU::parent_pdu(PDU* parent) { + parent_pdu_ = parent; +} + } // Tins diff --git a/tests/src/pdu_test.cpp b/tests/src/pdu_test.cpp index 5d6df86..209f982 100644 --- a/tests/src/pdu_test.cpp +++ b/tests/src/pdu_test.cpp @@ -17,7 +17,7 @@ public: }; TEST_F(PDUTest, FindPDU) { - IP ip = IP("192.168.0.1") / TCP(22, 52) / RawPDU("Test"); + IP ip = IP("192.168.0.1") / TCP(22, 52) / RawPDU("Test"); EXPECT_TRUE(ip.find_pdu() != NULL); EXPECT_TRUE(ip.find_pdu() != NULL); EXPECT_FALSE(ip.find_pdu() != NULL); @@ -28,6 +28,21 @@ TEST_F(PDUTest, FindPDU) { EXPECT_THROW(ip.rfind_pdu(), pdu_not_found); } +TEST_F(PDUTest, PDURelationship) { + IP packet = IP("192.168.0.1") / TCP(22, 52) / RawPDU("Test"); + IP* ip = packet.find_pdu(); + TCP* tcp = packet.find_pdu(); + RawPDU* raw = packet.find_pdu(); + + ASSERT_TRUE(ip != 0); + ASSERT_TRUE(tcp != 0); + ASSERT_TRUE(raw != 0); + + EXPECT_EQ(0, ip->parent_pdu()); + EXPECT_EQ(ip, tcp->parent_pdu()); + EXPECT_EQ(tcp, raw->parent_pdu()); +} + TEST_F(PDUTest, OperatorConcat) { std::string raw_payload = "Test"; IP ip = IP("192.168.0.1") / TCP(22, 52) / RawPDU(raw_payload);