mirror of
https://github.com/mfontanini/libtins
synced 2026-01-28 04:34:27 +01:00
Merge branch 'master' of ssh://git.code.sf.net/p/libtins/code
This commit is contained in:
@@ -136,6 +136,14 @@ namespace Tins {
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Returns the ethernet II frame's padding.
|
||||
*
|
||||
* \return An uint32_t with the padding size.
|
||||
* \sa PDU::trailer_size()
|
||||
*/
|
||||
uint32_t trailer_size() const;
|
||||
|
||||
// Windows does not support sending L2 PDUs.
|
||||
#ifndef WIN32
|
||||
/**
|
||||
|
||||
@@ -63,6 +63,7 @@ ARP::ARP(const uint8_t *buffer, uint32_t total_sz)
|
||||
throw malformed_packet();
|
||||
memcpy(&_arp, buffer, sizeof(arphdr));
|
||||
total_sz -= sizeof(arphdr);
|
||||
//TODO: Check whether this should be removed or not.
|
||||
if(total_sz)
|
||||
inner_pdu(new RawPDU(buffer + sizeof(arphdr), total_sz));
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ EAPOL *EAPOL::from_bytes(const uint8_t *buffer, uint32_t total_sz) {
|
||||
if(total_sz < sizeof(eapolhdr))
|
||||
throw malformed_packet();
|
||||
const eapolhdr *ptr = (const eapolhdr*)buffer;
|
||||
total_sz = std::min(total_sz, (uint32_t)ptr->length);
|
||||
switch(ptr->type) {
|
||||
case RC4:
|
||||
return new Tins::RC4EAPOL(buffer, total_sz);
|
||||
|
||||
@@ -82,6 +82,7 @@ EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EthernetII::dst_addr(const address_type &new_dst_addr) {
|
||||
@@ -97,9 +98,19 @@ void EthernetII::payload_type(uint16_t new_payload_type) {
|
||||
}
|
||||
|
||||
uint32_t EthernetII::header_size() const {
|
||||
|
||||
return sizeof(ethhdr);
|
||||
}
|
||||
|
||||
uint32_t EthernetII::trailer_size() const {
|
||||
int32_t padding = 60 - sizeof(ethhdr); // EthernetII min size is 60, padding is sometimes needed
|
||||
if (inner_pdu()) {
|
||||
padding -= inner_pdu()->size();
|
||||
padding = std::max(0, padding);
|
||||
}
|
||||
return padding;
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
void EthernetII::send(PacketSender &sender, const NetworkInterface &iface) {
|
||||
if(!iface)
|
||||
@@ -140,7 +151,7 @@ bool EthernetII::matches_response(const uint8_t *ptr, uint32_t total_sz) const {
|
||||
|
||||
void EthernetII::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
#ifdef TINS_DEBUG
|
||||
assert(total_sz >= header_size());
|
||||
assert(total_sz >= header_size() + trailer_size());
|
||||
#endif
|
||||
|
||||
/* Inner type defaults to IP */
|
||||
@@ -151,6 +162,14 @@ void EthernetII::write_serialization(uint8_t *buffer, uint32_t total_sz, const P
|
||||
payload_type(static_cast<uint16_t>(flag));
|
||||
}
|
||||
memcpy(buffer, &_eth, sizeof(ethhdr));
|
||||
uint32_t trailer = trailer_size();
|
||||
if (trailer) {
|
||||
uint32_t trailer_offset = header_size();
|
||||
if (inner_pdu())
|
||||
trailer_offset += inner_pdu()->size();
|
||||
memset(buffer + trailer_offset, 0, trailer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
|
||||
@@ -115,6 +115,9 @@ IP::IP(const uint8_t *buffer, uint32_t total_sz)
|
||||
uint8_t padding = _options_size % 4;
|
||||
_padded_options_size = padding ? (_options_size - padding + 4) : _options_size;
|
||||
// check this line PLX
|
||||
total_sz = std::min(total_sz, (uint32_t)tot_len());
|
||||
if (total_sz < head_len() * sizeof(uint32_t))
|
||||
throw malformed_packet();
|
||||
total_sz -= head_len() * sizeof(uint32_t);
|
||||
if (total_sz) {
|
||||
switch(_ip.protocol) {
|
||||
|
||||
@@ -51,6 +51,7 @@ PPPoE::PPPoE(const uint8_t *buffer, uint32_t total_sz)
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
total_sz = std::min(total_sz, (uint32_t)payload_length());
|
||||
const uint8_t *end = buffer + total_sz;
|
||||
while(buffer < end) {
|
||||
if(buffer + sizeof(uint32_t) * 2 > end)
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "macros.h"
|
||||
#include "ipv6.h"
|
||||
#include "ip.h"
|
||||
#include "tcp.h"
|
||||
#include "rawpdu.h"
|
||||
|
||||
using namespace Tins;
|
||||
|
||||
@@ -12,7 +14,7 @@ typedef EthernetII::address_type address_type;
|
||||
|
||||
class EthernetIITest : public ::testing::Test {
|
||||
public:
|
||||
static const uint8_t expected_packet[], ip_packet[], ipv6_packet[];
|
||||
static const uint8_t expected_packet[], ip_packet[], ipv6_packet[], smallip_packet[];
|
||||
static address_type src_addr;
|
||||
static address_type dst_addr;
|
||||
static address_type empty_addr;
|
||||
@@ -22,7 +24,10 @@ public:
|
||||
};
|
||||
|
||||
const uint8_t EthernetIITest::expected_packet[] = {
|
||||
170, 187, 204, 221, 238, 255, 138, 139, 140, 141, 142, 143, 208, 171
|
||||
170, 187, 204, 221, 238, 255, 138, 139, 140, 141, 142, 143, 208, 171,
|
||||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
|
||||
00, 00, 00, 00, 00, 00, 00, 00, 00, 00
|
||||
},
|
||||
EthernetIITest::ip_packet[] = {
|
||||
255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 8, 0, 69, 0, 0, 20,
|
||||
@@ -32,6 +37,12 @@ EthernetIITest::ipv6_packet[] = {
|
||||
255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 134, 221, 96, 0, 0,
|
||||
0, 0, 0, 59, 64, 0, 0, 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, 1
|
||||
},
|
||||
EthernetIITest::smallip_packet[] = {
|
||||
64, 97, 134, 43, 174, 3, 0, 36, 1, 254, 210, 68, 8, 0, 69, 0, 0, 40,
|
||||
53, 163, 64, 0, 127, 6, 44, 53, 192, 168, 1, 120, 173, 194, 42, 21,
|
||||
163, 42, 1, 187, 162, 113, 212, 162, 132, 15, 66, 219, 80, 16, 16,
|
||||
194, 34, 54, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
address_type EthernetIITest::src_addr("8a:8b:8c:8d:8e:8f");
|
||||
@@ -113,6 +124,14 @@ TEST_F(EthernetIITest, Serialize) {
|
||||
EXPECT_TRUE(std::equal(serialized.begin(), serialized.end(), expected_packet));
|
||||
}
|
||||
|
||||
TEST_F(EthernetIITest, SerializeSmallEthernetWithPadding) {
|
||||
EthernetII eth(smallip_packet, sizeof(smallip_packet));
|
||||
ASSERT_TRUE(eth.inner_pdu());
|
||||
PDU::serialization_type serialized = eth.serialize();
|
||||
EXPECT_EQ(serialized.size(), sizeof(smallip_packet));
|
||||
EXPECT_TRUE(std::equal(serialized.begin(), serialized.end(), smallip_packet));
|
||||
}
|
||||
|
||||
TEST_F(EthernetIITest, ConstructorFromBuffer) {
|
||||
EthernetII eth(expected_packet, sizeof(expected_packet));
|
||||
EXPECT_EQ(eth.src_addr(), src_addr);
|
||||
@@ -132,3 +151,10 @@ TEST_F(EthernetIITest, ConstructorFromIPv6Buffer) {
|
||||
EXPECT_EQ(eth.find_pdu<IPv6>(), eth.inner_pdu());
|
||||
}
|
||||
|
||||
TEST_F(EthernetIITest, EliminateEthernetPadding) {
|
||||
EthernetII eth(smallip_packet, sizeof(smallip_packet));
|
||||
ASSERT_TRUE(eth.inner_pdu());
|
||||
ASSERT_TRUE(eth.find_pdu<IP>());
|
||||
ASSERT_TRUE(eth.find_pdu<TCP>());
|
||||
ASSERT_FALSE(eth.find_pdu<RawPDU>());
|
||||
}
|
||||
|
||||
@@ -46,6 +46,20 @@ TEST_F(PPPoETest, StackedOnEthernet) {
|
||||
ASSERT_TRUE(eth2.find_pdu<PPPoE>());
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, StackedOnEthernetSerializationWithTags) {
|
||||
PPPoE pdu(expected_packet, sizeof(expected_packet));
|
||||
EthernetII eth = EthernetII() / pdu;
|
||||
PDU::serialization_type buffer = eth.serialize();
|
||||
EthernetII eth2(&buffer[0], buffer.size());
|
||||
PPPoE* unserialized = eth2.find_pdu<PPPoE>();
|
||||
ASSERT_TRUE(unserialized);
|
||||
EXPECT_EQ(
|
||||
PPPoE::serialization_type(expected_packet, expected_packet + sizeof(expected_packet)),
|
||||
unserialized->serialize()
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
TEST_F(PPPoETest, Serialize) {
|
||||
PPPoE pdu(expected_packet, sizeof(expected_packet));
|
||||
PPPoE::serialization_type buffer = pdu.serialize();
|
||||
|
||||
Reference in New Issue
Block a user