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

Fix serialization for QinQ (#316)

* Add QinQ Frame

* Fix serialization for QinQ
This commit is contained in:
Teodoro Vargas
2018-10-09 15:02:01 -06:00
committed by Matias Fontanini
parent c26e4943c2
commit 57ac099703
6 changed files with 27 additions and 10 deletions

View File

@@ -170,6 +170,7 @@ public:
ICMPv6, ICMPv6,
SLL, SLL,
DHCPv6, DHCPv6,
DOT1AD,
DOT1Q, DOT1Q,
PPPOE, PPPOE,
STP, STP,

View File

@@ -211,6 +211,8 @@ Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag) {
return Constants::Ethernet::ARP; return Constants::Ethernet::ARP;
case PDU::DOT1Q: case PDU::DOT1Q:
return Constants::Ethernet::VLAN; return Constants::Ethernet::VLAN;
case PDU::DOT1AD:
return Constants::Ethernet::QINQ;
case PDU::PPPOE: case PDU::PPPOE:
return Constants::Ethernet::PPPOED; return Constants::Ethernet::PPPOED;
case PDU::MPLS: case PDU::MPLS:
@@ -238,6 +240,9 @@ PDU::PDUType ether_type_to_pdu_flag(Constants::Ethernet::e flag) {
return PDU::ARP; return PDU::ARP;
case Constants::Ethernet::VLAN: case Constants::Ethernet::VLAN:
return PDU::DOT1Q; return PDU::DOT1Q;
case Constants::Ethernet::QINQ:
case Constants::Ethernet::OLD_QINQ:
return PDU::DOT1AD;
case Constants::Ethernet::PPPOED: case Constants::Ethernet::PPPOED:
return PDU::PPPOE; return PDU::PPPOE;
//case PDU::RSNEAPOL //case PDU::RSNEAPOL
@@ -295,4 +300,4 @@ PDU::PDUType ip_type_to_pdu_flag(Constants::IP::e flag) {
} }
} // Internals } // Internals
} // Tins } // Tins

View File

@@ -107,15 +107,10 @@ uint32_t Dot1Q::trailer_size() const {
void Dot1Q::write_serialization(uint8_t* buffer, uint32_t total_sz) { void Dot1Q::write_serialization(uint8_t* buffer, uint32_t total_sz) {
OutputMemoryStream stream(buffer, total_sz); OutputMemoryStream stream(buffer, total_sz);
if (inner_pdu()) { if (inner_pdu()) {
Constants::Ethernet::e flag; Constants::Ethernet::e flag = Constants::Ethernet::UNKNOWN;
PDUType type = inner_pdu()->pdu_type(); PDUType type = inner_pdu()->pdu_type();
if (type == PDU::DOT1Q) { // Set the appropriate payload type flag
flag = Constants::Ethernet::QINQ; flag = Internals::pdu_flag_to_ether_type(type);
}
else {
// Set the appropriate payload type flag
flag = Internals::pdu_flag_to_ether_type(type);
}
if (flag != Constants::Ethernet::UNKNOWN) { if (flag != Constants::Ethernet::UNKNOWN) {
payload_type(static_cast<uint16_t>(flag)); payload_type(static_cast<uint16_t>(flag));
} }

View File

@@ -156,7 +156,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) { void EthernetII::write_serialization(uint8_t* buffer, uint32_t total_sz) {
OutputMemoryStream stream(buffer, total_sz); OutputMemoryStream stream(buffer, total_sz);
if (inner_pdu()) { if (inner_pdu()) {
Constants::Ethernet::e flag; Constants::Ethernet::e flag = Constants::Ethernet::UNKNOWN;
const PDUType type = inner_pdu()->pdu_type(); const PDUType type = inner_pdu()->pdu_type();
// Dirty trick to successfully tag PPPoE session/discovery packets // Dirty trick to successfully tag PPPoE session/discovery packets
if (type == PDU::PPPOE) { if (type == PDU::PPPOE) {
@@ -164,6 +164,15 @@ void EthernetII::write_serialization(uint8_t* buffer, uint32_t total_sz) {
flag = (pppoe->code() == 0) ? Constants::Ethernet::PPPOES flag = (pppoe->code() == 0) ? Constants::Ethernet::PPPOES
: Constants::Ethernet::PPPOED; : Constants::Ethernet::PPPOED;
} }
// Dirty trick: Double Dot1Q is interpreted as Dot1AD
else if (type == PDU::DOT1Q) {
if (inner_pdu()->inner_pdu()) {
const PDUType inner_type = inner_pdu()->inner_pdu()->pdu_type();
if (inner_type == PDU::DOT1Q) {
flag = Constants::Ethernet::QINQ;
}
}
}
else { else {
flag = Internals::pdu_flag_to_ether_type(type); flag = Internals::pdu_flag_to_ether_type(type);
} }

View File

@@ -81,6 +81,7 @@ string to_string(PDU::PDUType pduType) {
ENUM_TEXT(ICMPv6); ENUM_TEXT(ICMPv6);
ENUM_TEXT(SLL); ENUM_TEXT(SLL);
ENUM_TEXT(DHCPv6); ENUM_TEXT(DHCPv6);
ENUM_TEXT(DOT1AD);
ENUM_TEXT(DOT1Q); ENUM_TEXT(DOT1Q);
ENUM_TEXT(PPPOE); ENUM_TEXT(PPPOE);
ENUM_TEXT(STP); ENUM_TEXT(STP);

View File

@@ -86,6 +86,12 @@ TEST_F(Dot1QTest, QinQ) {
EthernetII pkt = EthernetII() / Dot1Q(10) / Dot1Q(42) / IP("192.168.1.2") / EthernetII pkt = EthernetII() / Dot1Q(10) / Dot1Q(42) / IP("192.168.1.2") /
TCP(23, 45) / RawPDU("asdasdasd"); TCP(23, 45) / RawPDU("asdasdasd");
PDU::serialization_type buffer = pkt.serialize(); PDU::serialization_type buffer = pkt.serialize();
// First PID of the serialized packet should be Dot1AD = 0x88a8
EXPECT_EQ(buffer[12], 0x88);
EXPECT_EQ(buffer[13], 0xa8);
// Second PID of the serialized packet chouls be Dot1Q = 0x8100
EXPECT_EQ(buffer[16], 0x81);
EXPECT_EQ(buffer[17], 0x00);
EthernetII pkt2(&buffer[0], buffer.size()); EthernetII pkt2(&buffer[0], buffer.size());
const Dot1Q& q1 = pkt2.rfind_pdu<Dot1Q>(); const Dot1Q& q1 = pkt2.rfind_pdu<Dot1Q>();
ASSERT_TRUE(q1.inner_pdu() != NULL); ASSERT_TRUE(q1.inner_pdu() != NULL);