1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 02:35:57 +01:00

Fix IPv6 extension headers parsing/serialization

This commit is contained in:
Matias Fontanini
2016-01-01 14:39:09 -08:00
parent d7e0d17154
commit 2c16aaaecd
2 changed files with 30 additions and 4 deletions

View File

@@ -68,10 +68,10 @@ IPv6::IPv6(const uint8_t *buffer, uint32_t total_sz)
const uint8_t ext_type = stream.read<uint8_t>();
// every ext header is at least 8 bytes long
// minus one, from the next_header field.
const uint32_t ext_size = static_cast<uint32_t>(stream.read<uint8_t>()) + 8;
const uint32_t ext_size = (static_cast<uint32_t>(stream.read<uint8_t>()) + 1) * 8;
const uint32_t payload_size = ext_size - sizeof(uint8_t) * 2;
// -1 -> next header identifier
if(!stream.can_read(ext_size)) {
if (!stream.can_read(ext_size)) {
throw malformed_packet();
}
// minus one, from the size field
@@ -245,7 +245,7 @@ void IPv6::set_last_next_header(uint8_t value) {
}
void IPv6::write_header(const ext_header &header, OutputMemoryStream& stream) {
const uint8_t length = (header.length_field() > 8) ? (header.length_field() - 8) : 0;
const uint8_t length = header.length_field() / 8;
stream.write(header.option());
stream.write(length);
stream.write(header.data_ptr(), header.data_size());

View File

@@ -23,7 +23,8 @@ using namespace Tins;
class IPv6Test : public testing::Test {
public:
static const uint8_t expected_packet1[], expected_packet2[];
static const uint8_t expected_packet1[], expected_packet2[],
hop_by_hop_options[];
void test_equals(IPv6 &ip1, IPv6 &ip2);
};
@@ -42,6 +43,18 @@ const uint8_t IPv6Test::expected_packet2[] = {
0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 152, 6, 225
};
const uint8_t IPv6Test::hop_by_hop_options[] = {
0, 1, 1, 0, 0, 2, 0, 1, 1, 0, 0, 1, 134, 221, 96, 0, 0, 0, 0, 180, 0, 255, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 58, 1,
0, 0, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 143, 0, 27, 180, 0, 0, 0, 1, 1, 2, 0, 8, 255,
2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 2, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 0, 0, 9,
222, 173, 190, 239, 190, 173, 254, 237
};
void IPv6Test::test_equals(IPv6 &ip1, IPv6 &ip2) {
EXPECT_EQ(ip1.version(), ip2.version());
EXPECT_EQ(ip1.traffic_class(), ip2.traffic_class());
@@ -123,6 +136,19 @@ TEST_F(IPv6Test, ConstructorFromBuffer2) {
EXPECT_EQ(header->data_size(), 6U);
}
TEST_F(IPv6Test, ConstructorFromBuffer_MLD2_Packet) {
EthernetII eth(hop_by_hop_options, sizeof(hop_by_hop_options));
PDU::serialization_type buffer = eth.serialize();
EXPECT_EQ(
PDU::serialization_type(
hop_by_hop_options,
hop_by_hop_options + sizeof(hop_by_hop_options)
),
buffer
);
}
TEST_F(IPv6Test, Serialize) {
IPv6 ip1(expected_packet1, sizeof(expected_packet1));
IPv6::serialization_type buffer = ip1.serialize();