mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Add ICMP extensions to ICMP PDU
The length field is still not being set
This commit is contained in:
@@ -353,10 +353,21 @@ namespace Tins {
|
|||||||
* \brief Returns the header size.
|
* \brief Returns the header size.
|
||||||
*
|
*
|
||||||
* This metod overrides PDU::header_size. This size includes the
|
* This metod overrides PDU::header_size. This size includes the
|
||||||
* payload and options size. \sa PDU::header_size
|
* payload and options size.
|
||||||
|
*
|
||||||
|
* \sa PDU::header_size
|
||||||
*/
|
*/
|
||||||
uint32_t header_size() const;
|
uint32_t header_size() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Returns the trailer size.
|
||||||
|
*
|
||||||
|
* This metod overrides PDU::trailer_size. This size will hold the extensions size
|
||||||
|
*
|
||||||
|
* \sa PDU::header_size
|
||||||
|
*/
|
||||||
|
uint32_t trailer_size() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Check wether ptr points to a valid response for this PDU.
|
* \brief Check wether ptr points to a valid response for this PDU.
|
||||||
*
|
*
|
||||||
@@ -366,7 +377,24 @@ namespace Tins {
|
|||||||
*/
|
*/
|
||||||
bool matches_response(const uint8_t *ptr, uint32_t total_sz) const;
|
bool matches_response(const uint8_t *ptr, uint32_t total_sz) const;
|
||||||
|
|
||||||
const ICMPExtensionsStructure& extensions() { return extensions_; }
|
/**
|
||||||
|
* \brief Getter for the extensions field.
|
||||||
|
*
|
||||||
|
* \return The extensions field
|
||||||
|
*/
|
||||||
|
const ICMPExtensionsStructure& extensions() const { return extensions_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Getter for the extensions field.
|
||||||
|
*
|
||||||
|
* \return The extensions field
|
||||||
|
*/
|
||||||
|
ICMPExtensionsStructure& extensions() { return extensions_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Indicates whether this object contains ICMP extensions
|
||||||
|
*/
|
||||||
|
bool has_extensions() const { return !extensions_.extensions().empty(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Getter for the PDU's type.
|
* \brief Getter for the PDU's type.
|
||||||
|
|||||||
@@ -189,6 +189,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
const extensions_type& extensions() const { return extensions_; }
|
const extensions_type& extensions() const { return extensions_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Adds an extension to this structure
|
||||||
|
*
|
||||||
|
* \param extension The extension to be added;
|
||||||
|
*/
|
||||||
|
void add_extension(const ICMPExtension& extension);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Gets the size of this ICMP extensions structure
|
* \brief Gets the size of this ICMP extensions structure
|
||||||
*
|
*
|
||||||
|
|||||||
26
src/icmp.cpp
26
src/icmp.cpp
@@ -140,9 +140,21 @@ uint32_t ICMP::header_size() const {
|
|||||||
extra = sizeof(uint32_t) * 3;
|
extra = sizeof(uint32_t) * 3;
|
||||||
else if(type() == ADDRESS_MASK_REQUEST || type() == ADDRESS_MASK_REPLY)
|
else if(type() == ADDRESS_MASK_REQUEST || type() == ADDRESS_MASK_REPLY)
|
||||||
extra = sizeof(uint32_t);
|
extra = sizeof(uint32_t);
|
||||||
|
|
||||||
return sizeof(icmphdr) + extra;
|
return sizeof(icmphdr) + extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ICMP::trailer_size() const {
|
||||||
|
uint32_t output = 0;
|
||||||
|
if (has_extensions()) {
|
||||||
|
output += extensions_.size();
|
||||||
|
if (inner_pdu()) {
|
||||||
|
output += 128 - std::min(inner_pdu()->size(), 128U);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
void ICMP::set_echo_request(uint16_t id, uint16_t seq) {
|
void ICMP::set_echo_request(uint16_t id, uint16_t seq) {
|
||||||
type(ECHO_REQUEST);
|
type(ECHO_REQUEST);
|
||||||
this->id(id);
|
this->id(id);
|
||||||
@@ -216,6 +228,20 @@ void ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *)
|
|||||||
uint32_t_buffer = address_mask();
|
uint32_t_buffer = address_mask();
|
||||||
memcpy(buffer + sizeof(icmphdr), &uint32_t_buffer, sizeof(uint32_t));
|
memcpy(buffer + sizeof(icmphdr), &uint32_t_buffer, sizeof(uint32_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_extensions()) {
|
||||||
|
uint8_t* extensions_ptr = buffer + sizeof(icmphdr);
|
||||||
|
if (inner_pdu()) {
|
||||||
|
uint32_t inner_pdu_size = inner_pdu()->size();
|
||||||
|
if (inner_pdu_size < 128) {
|
||||||
|
memset(buffer + sizeof(icmphdr) + inner_pdu_size, 0, 128 - inner_pdu_size);
|
||||||
|
inner_pdu_size = 128;
|
||||||
|
}
|
||||||
|
extensions_ptr += inner_pdu_size;
|
||||||
|
}
|
||||||
|
extensions_.serialize(extensions_ptr, total_sz - (extensions_ptr - buffer));
|
||||||
|
}
|
||||||
|
|
||||||
// checksum calc
|
// checksum calc
|
||||||
_icmp.check = 0;
|
_icmp.check = 0;
|
||||||
memcpy(buffer, &_icmp, sizeof(icmphdr));
|
memcpy(buffer, &_icmp, sizeof(icmphdr));
|
||||||
|
|||||||
@@ -76,8 +76,8 @@ ICMPExtension::serialization_type ICMPExtension::serialize() const {
|
|||||||
const uint32_t ICMPExtensionsStructure::BASE_HEADER_SIZE = sizeof(uint16_t) * 2;
|
const uint32_t ICMPExtensionsStructure::BASE_HEADER_SIZE = sizeof(uint16_t) * 2;
|
||||||
|
|
||||||
ICMPExtensionsStructure::ICMPExtensionsStructure()
|
ICMPExtensionsStructure::ICMPExtensionsStructure()
|
||||||
: version_and_reserved_(0x2000), checksum_(0) {
|
: version_and_reserved_(), checksum_(0) {
|
||||||
|
version(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ICMPExtensionsStructure::ICMPExtensionsStructure(const uint8_t* buffer, uint32_t total_sz) {
|
ICMPExtensionsStructure::ICMPExtensionsStructure(const uint8_t* buffer, uint32_t total_sz) {
|
||||||
@@ -135,6 +135,10 @@ uint32_t ICMPExtensionsStructure::size() const {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ICMPExtensionsStructure::add_extension(const ICMPExtension& extension) {
|
||||||
|
extensions_.push_back(extension);
|
||||||
|
}
|
||||||
|
|
||||||
void ICMPExtensionsStructure::serialize(uint8_t* buffer, uint32_t buffer_size) {
|
void ICMPExtensionsStructure::serialize(uint8_t* buffer, uint32_t buffer_size) {
|
||||||
const uint32_t structure_size = size();
|
const uint32_t structure_size = size();
|
||||||
if (buffer_size < structure_size) {
|
if (buffer_size < structure_size) {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ using namespace Tins;
|
|||||||
class ICMPTest : public testing::Test {
|
class ICMPTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
static const uint8_t expected_packets[][8];
|
static const uint8_t expected_packets[][8];
|
||||||
static const uint8_t ts_request[], ts_reply[];
|
static const uint8_t ts_request[], ts_reply[], packet_with_extensions[];
|
||||||
static const uint32_t expected_packet_count;
|
static const uint32_t expected_packet_count;
|
||||||
|
|
||||||
void test_equals(const ICMP &icmp1, const ICMP &icmp2);
|
void test_equals(const ICMP &icmp1, const ICMP &icmp2);
|
||||||
@@ -35,6 +35,16 @@ const uint8_t ICMPTest::ts_reply[] = {
|
|||||||
14, 0, 172, 45, 0, 0, 0, 0, 0, 0, 0, 0, 4, 144, 30, 89, 4, 144, 30, 89, 0, 0, 0, 0, 0, 0
|
14, 0, 172, 45, 0, 0, 0, 0, 0, 0, 0, 0, 4, 144, 30, 89, 4, 144, 30, 89, 0, 0, 0, 0, 0, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const uint8_t ICMPTest::packet_with_extensions[] = {
|
||||||
|
11, 0, 205, 4, 0, 0, 0, 0, 69, 0, 0, 40, 165, 76, 0, 0, 1, 17, 247, 111, 12, 4, 4, 4, 12,
|
||||||
|
1, 1, 1, 165, 75, 130, 155, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 197, 95, 0,
|
||||||
|
8, 1, 1, 24, 150, 1, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TEST_F(ICMPTest, DefaultConstructor) {
|
TEST_F(ICMPTest, DefaultConstructor) {
|
||||||
ICMP icmp;
|
ICMP icmp;
|
||||||
@@ -289,10 +299,9 @@ TEST_F(ICMPTest, ConstructorFromBuffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ICMPTest, ExtensionsParsingWithoutALengthField) {
|
TEST_F(ICMPTest, ExtensionsParsingWithoutALengthField) {
|
||||||
const uint8_t packet[] = { 11, 0, 205, 4, 0, 0, 0, 0, 69, 0, 0, 40, 165, 76, 0, 0, 1, 17, 247, 111, 12, 4, 4, 4, 12, 1, 1, 1, 165, 75, 130, 155, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 197, 95, 0, 8, 1, 1, 24, 150, 1, 1 };
|
|
||||||
const uint8_t encapsulated[] = { 69, 0, 0, 40, 165, 76, 0, 0, 1, 17, 247, 111, 12, 4, 4, 4, 12, 1, 1, 1, 165, 75, 130, 155, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
const uint8_t encapsulated[] = { 69, 0, 0, 40, 165, 76, 0, 0, 1, 17, 247, 111, 12, 4, 4, 4, 12, 1, 1, 1, 165, 75, 130, 155, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
const uint8_t ext[] = { 0, 8, 1, 1, 24, 150, 1, 1 };
|
const uint8_t ext[] = { 0, 8, 1, 1, 24, 150, 1, 1 };
|
||||||
ICMP icmp(packet, sizeof(packet));
|
ICMP icmp(packet_with_extensions, sizeof(packet_with_extensions));
|
||||||
ICMPExtensionsStructure extensions = icmp.extensions();
|
ICMPExtensionsStructure extensions = icmp.extensions();
|
||||||
ASSERT_EQ(1, extensions.extensions().size());
|
ASSERT_EQ(1, extensions.extensions().size());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
@@ -305,4 +314,11 @@ TEST_F(ICMPTest, ExtensionsParsingWithoutALengthField) {
|
|||||||
RawPDU::payload_type(encapsulated, encapsulated + sizeof(encapsulated)),
|
RawPDU::payload_type(encapsulated, encapsulated + sizeof(encapsulated)),
|
||||||
raw->payload()
|
raw->payload()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
PDU::serialization_type buffer = icmp.serialize();
|
||||||
|
EXPECT_EQ(sizeof(packet_with_extensions), buffer.size());
|
||||||
|
EXPECT_EQ(
|
||||||
|
buffer,
|
||||||
|
PDU::serialization_type(packet_with_extensions, packet_with_extensions + sizeof(packet_with_extensions))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user