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

Use 802.1ad protocol flag when seralizing stacked Dot1Q

Fixes #68
This commit is contained in:
Matias Fontanini
2016-01-09 14:30:43 -08:00
parent d84f10cf08
commit 2169b1f71f
4 changed files with 42 additions and 19 deletions

View File

@@ -75,20 +75,22 @@ struct IP {
struct Ethernet { struct Ethernet {
enum e { enum e {
UNKNOWN = 0, UNKNOWN = 0,
SPRITE = 0x0500, // Sprite SPRITE = 0x0500, // Sprite
IP = 0x0800, // IP IP = 0x0800, // IP
ARP = 0x0806, // Address resolution ARP = 0x0806, // Address resolution
MPLS = 0x8847, // MPLS MPLS = 0x8847, // MPLS
REVARP = 0x8035, // Reverse ARP REVARP = 0x8035, // Reverse ARP
AT = 0x809B, // AppleTalk protocol AT = 0x809B, // AppleTalk protocol
AARP = 0x80F3, // AppleTalk ARP AARP = 0x80F3, // AppleTalk ARP
VLAN = 0x8100, // IEEE 802.1Q VLAN tagging VLAN = 0x8100, // IEEE 802.1Q VLAN tagging
IPX = 0x8137, // IPX QINQ = 0x88a8, // IEEE 802.1ad VLAN tagging
IPV6 = 0x86dd, // IP protocol version 6 OLD_QINQ = 0x9100, // IEEE 802.1ad VLAN tagging (old, deprecated, value)
PPPOED = 0x8863, // PPPoE Discovery IPX = 0x8137, // IPX
PPPOES = 0x8864, // PPPoE Session IPV6 = 0x86dd, // IP protocol version 6
EAPOL = 0x888e, // EAPOL PPPOED = 0x8863, // PPPoE Discovery
LOOPBACK = 0x9000 // used to test interfaces PPPOES = 0x8864, // PPPoE Session
EAPOL = 0x888e, // EAPOL
LOOPBACK = 0x9000 // used to test interfaces
}; };
}; };

View File

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

View File

@@ -106,6 +106,8 @@ Tins::PDU* pdu_from_flag(Constants::Ethernet::e flag,
case Tins::Constants::Ethernet::EAPOL: case Tins::Constants::Ethernet::EAPOL:
return EAPOL::from_bytes(buffer, size); return EAPOL::from_bytes(buffer, size);
case Tins::Constants::Ethernet::VLAN: case Tins::Constants::Ethernet::VLAN:
case Tins::Constants::Ethernet::QINQ:
case Tins::Constants::Ethernet::OLD_QINQ:
return new Dot1Q(buffer, size); return new Dot1Q(buffer, size);
case Tins::Constants::Ethernet::MPLS: case Tins::Constants::Ethernet::MPLS:
return new MPLS(buffer, size); return new MPLS(buffer, size);

View File

@@ -4,6 +4,9 @@
#include <stdint.h> #include <stdint.h>
#include "dot1q.h" #include "dot1q.h"
#include "arp.h" #include "arp.h"
#include "ip.h"
#include "tcp.h"
#include "rawpdu.h"
#include "ethernetII.h" #include "ethernetII.h"
using namespace std; using namespace std;
@@ -21,7 +24,6 @@ const uint8_t Dot1QTest::expected_packet[] = {
123, 8, 6, 0, 1, 8, 0, 6, 4, 0, 2, 0, 25, 6, 234, 184, 193, 192, 168, 123, 8, 6, 0, 1, 8, 0, 6, 4, 0, 2, 0, 25, 6, 234, 184, 193, 192, 168,
123, 1, 255, 255, 255, 255, 255, 255, 192, 168, 123, 1, 0, 0, 0, 0, 123, 1, 255, 255, 255, 255, 255, 255, 192, 168, 123, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}; };
TEST_F(Dot1QTest, DefaultConstructor) { TEST_F(Dot1QTest, DefaultConstructor) {
@@ -79,3 +81,15 @@ TEST_F(Dot1QTest, Id) {
dot1.id(3543); dot1.id(3543);
EXPECT_EQ(3543, dot1.id()); EXPECT_EQ(3543, dot1.id());
} }
TEST_F(Dot1QTest, QinQ) {
EthernetII pkt = EthernetII() / Dot1Q(10) / Dot1Q(42) / IP("192.168.1.2") /
TCP(23, 45) / RawPDU("asdasdasd");
PDU::serialization_type buffer = pkt.serialize();
EthernetII pkt2(&buffer[0], buffer.size());
const Dot1Q& q1 = pkt2.rfind_pdu<Dot1Q>();
ASSERT_TRUE(q1.inner_pdu() != NULL);
const Dot1Q& q2 = q1.inner_pdu()->rfind_pdu<Dot1Q>();
EXPECT_EQ(10, q1.id());
EXPECT_EQ(42, q2.id());
}