1
0
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:
Matias Fontanini
2013-07-24 23:32:55 -03:00
8 changed files with 76 additions and 3 deletions

View File

@@ -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
/**

View File

@@ -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));
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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>());
}

View File

@@ -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();