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

Added Dot1Q class.

This commit is contained in:
Matias Fontanini
2013-03-17 23:27:34 -03:00
parent b5f9f5095e
commit f5ecaa3faa
9 changed files with 430 additions and 9 deletions

View File

@@ -19,6 +19,7 @@ libtins_la_SOURCES=src/arp.cpp \
src/dns.cpp \
src/dns_record.cpp \
src/dot11.cpp \
src/dot1q.cpp \
src/eapol.cpp \
src/ethernetII.cpp \
src/icmp.cpp \
@@ -49,6 +50,7 @@ libtins_includedir = $(includedir)/tins
libtins_include_HEADERS = include/internals.h \
include/dhcpv6.h \
include/dot11.h \
include/dot1q.h \
include/small_uint.h \
include/ip.h \
include/dns_record.h \

View File

@@ -57,7 +57,8 @@ subdir = .
DIST_COMMON = README $(am__configure_deps) $(libtins_include_HEADERS) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/libtins.pc.in $(top_srcdir)/configure AUTHORS THANKS \
config.guess config.sub depcomp install-sh ltmain.sh missing
TODO config.guess config.sub depcomp install-sh ltmain.sh \
missing
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -101,13 +102,14 @@ libtins_la_LIBADD =
am__dirstamp = $(am__leading_dot)dirstamp
am_libtins_la_OBJECTS = src/arp.lo src/bootp.lo src/crypto.lo \
src/dhcp.lo src/dhcpv6.lo src/dns.lo src/dns_record.lo \
src/dot11.lo src/eapol.lo src/ethernetII.lo src/icmp.lo \
src/icmpv6.lo src/ieee802_3.lo src/internals.lo src/ip.lo \
src/ip_address.lo src/ipv6.lo src/ipv6_address.lo src/llc.lo \
src/loopback.lo src/network_interface.lo src/packet_sender.lo \
src/packet_writer.lo src/pdu.lo src/radiotap.lo src/rawpdu.lo \
src/rsn_information.lo src/sll.lo src/snap.lo src/sniffer.lo \
src/tcp.lo src/tcp_stream.lo src/udp.lo src/utils.lo
src/dot11.lo src/dot1q.lo src/eapol.lo src/ethernetII.lo \
src/icmp.lo src/icmpv6.lo src/ieee802_3.lo src/internals.lo \
src/ip.lo src/ip_address.lo src/ipv6.lo src/ipv6_address.lo \
src/llc.lo src/loopback.lo src/network_interface.lo \
src/packet_sender.lo src/packet_writer.lo src/pdu.lo \
src/radiotap.lo src/rawpdu.lo src/rsn_information.lo \
src/sll.lo src/snap.lo src/sniffer.lo src/tcp.lo \
src/tcp_stream.lo src/udp.lo src/utils.lo
libtins_la_OBJECTS = $(am_libtins_la_OBJECTS)
libtins_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
@@ -289,6 +291,7 @@ libtins_la_SOURCES = src/arp.cpp \
src/dns.cpp \
src/dns_record.cpp \
src/dot11.cpp \
src/dot1q.cpp \
src/eapol.cpp \
src/ethernetII.cpp \
src/icmp.cpp \
@@ -319,6 +322,7 @@ libtins_includedir = $(includedir)/tins
libtins_include_HEADERS = include/internals.h \
include/dhcpv6.h \
include/dot11.h \
include/dot1q.h \
include/small_uint.h \
include/ip.h \
include/dns_record.h \
@@ -448,6 +452,7 @@ src/dhcpv6.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dns.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dns_record.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dot11.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/dot1q.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/eapol.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ethernetII.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/icmp.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
@@ -499,6 +504,8 @@ mostlyclean-compile:
-rm -f src/dns_record.lo
-rm -f src/dot11.$(OBJEXT)
-rm -f src/dot11.lo
-rm -f src/dot1q.$(OBJEXT)
-rm -f src/dot1q.lo
-rm -f src/eapol.$(OBJEXT)
-rm -f src/eapol.lo
-rm -f src/ethernetII.$(OBJEXT)
@@ -563,6 +570,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dns.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dns_record.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dot11.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/dot1q.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/eapol.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ethernetII.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/icmp.Plo@am__quote@

166
include/dot1q.h Normal file
View File

@@ -0,0 +1,166 @@
/*
* Copyright (c) 2012, Nasel
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef TINS_DOT1Q_H
#define TINS_DOT1Q_H
#include "pdu.h"
#include "endianness.h"
#include "small_uint.h"
namespace Tins {
class Dot1Q : public PDU {
public:
/**
* This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::DOT1Q;
/**
* Default constructor
*/
Dot1Q();
/**
* \brief Constructor which creates an Dot1Q object from a buffer and
* adds all identifiable PDUs found in the buffer as children of this
* one.
*
* \param buffer The buffer from which this PDU will be constructed.
* \param total_sz The total size of the buffer.
*/
Dot1Q(const uint8_t *buffer, uint32_t total_sz);
// Getters
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_size. \sa PDU::header_size
*/
uint32_t header_size() const;
/**
* \brief Returns the frame's trailer size.
* \return The trailer's size.
*/
uint32_t trailer_size() const;
/**
* \brief Getter for the priority field.
* \return The stored priority field value.
*/
small_uint<3> priority() const {
return _header.priority;
}
/**
* \brief Getter for the cfi field.
* \return The stored cfi field value.
*/
small_uint<1> cfi() const {
return _header.cfi;
}
/**
* \brief Getter for the id field.
* \return The stored id field value.
*/
small_uint<12> id() const {
return _header.idL | (_header.idH << 8);
}
/**
* \brief Getter for the payload type field.
* \return The stored type field value.
*/
uint16_t payload_type() const {
return Endian::be_to_host(_header.type);
}
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \sa PDU::clone
*/
Dot1Q *clone() const {
return new Dot1Q(*this);
}
// Setters
/**
* \brief Setter for the priority field.
* \param new_priority The new priority field value.
*/
void priority(small_uint<3> new_priority);
/**
* \brief Setter for the cfi field.
* \param new_cfi The new cfi field value.
*/
void cfi(small_uint<1> new_cfi);
/**
* \brief Setter for the id field.
* \param new_id The new id field value.
*/
void id(small_uint<12> new_id);
/**
* \brief Setter for the payload type field.
* \param new_type The new type field value.
*/
void payload_type(uint16_t new_type);
private:
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
struct dot1q_hdr {
#if TINS_IS_BIG_ENDIAN
uint16_t priority:3,
cfi:1
id:12;
uint16_t type;
#else
uint16_t idH:4,
cfi:1,
priority:3,
idL:8;
uint16_t type;
#endif
};
dot1q_hdr _header;
};
}
#endif // TINS_DOT1Q_H

View File

@@ -105,7 +105,8 @@ namespace Tins {
IPv6,
ICMPv6,
SLL,
DHCPv6
DHCPv6,
DOT1Q
};
/** \brief PDU constructor

107
src/dot1q.cpp Normal file
View File

@@ -0,0 +1,107 @@
/*
* Copyright (c) 2012, Nasel
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <stdexcept>
#include <cstring>
#include <cassert>
#include "dot1q.h"
#include "internals.h"
namespace Tins {
Dot1Q::Dot1Q()
: _header()
{
}
Dot1Q::Dot1Q(const uint8_t *buffer, uint32_t total_sz) {
if(total_sz < sizeof(_header))
throw std::runtime_error("Not enough size for a Dot1Q header");
std::memcpy(&_header, buffer, sizeof(_header));
buffer += sizeof(_header);
total_sz -= sizeof(_header);
if(total_sz) {
inner_pdu(
Internals::pdu_from_flag(
(Constants::Ethernet::e)payload_type(),
buffer,
total_sz
)
);
}
}
void Dot1Q::priority(small_uint<3> new_priority) {
_header.priority = new_priority;
}
void Dot1Q::cfi(small_uint<1> new_cfi) {
_header.cfi = new_cfi;
}
void Dot1Q::id(small_uint<12> new_id) {
uint16_t value = new_id;
_header.idL = new_id & 0xff;
_header.idH = new_id >> 8;
}
void Dot1Q::payload_type(uint16_t new_type) {
_header.type = Endian::host_to_be(new_type);
}
uint32_t Dot1Q::header_size() const {
return sizeof(_header);
}
uint32_t Dot1Q::trailer_size() const {
uint32_t total_size = sizeof(_header);
if(inner_pdu())
total_size += inner_pdu()->size();
return (total_size > 50) ? 0 : (50 - total_size);
}
void Dot1Q::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
uint32_t trailer = trailer_size();
#ifdef TINS_DEBUG
assert(total_sz >= sizeof(_header) + trailer);
#endif
if ((payload_type() == 0) && inner_pdu()) {
Constants::Ethernet::e flag = Internals::pdu_flag_to_ether_type(
inner_pdu()->pdu_type()
);
payload_type(static_cast<uint16_t>(flag));
}
std::memcpy(buffer, &_header, sizeof(_header));
buffer += sizeof(_header) + inner_pdu()->size();
std::fill(buffer, buffer + trailer, 0);
}
}

View File

@@ -33,6 +33,7 @@
#include "arp.h"
#include "eapol.h"
#include "rawpdu.h"
#include "dot1q.h"
using std::string;
@@ -73,6 +74,8 @@ Tins::PDU *pdu_from_flag(Constants::Ethernet::e flag, const uint8_t *buffer,
return new Tins::ARP(buffer, size);
case Tins::Constants::Ethernet::EAPOL:
return Tins::EAPOL::from_bytes(buffer, size);
case Tins::Constants::Ethernet::VLAN:
return new Tins::Dot1Q(buffer, size);
default:
return rawpdu_on_no_match ? new RawPDU(buffer, size) : 0;
};

View File

@@ -1,3 +1,32 @@
/*
* Copyright (c) 2012, Nasel
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <cstring>
#include <cassert>
#ifndef WIN32

View File

@@ -192,6 +192,23 @@
../include/packet_sender.h:
../include/snap.h:
../src/dot1q.o: ../src/dot1q.cpp ../include/dot1q.h ../include/pdu.h \
../include/endianness.h ../include/macros.h ../include/small_uint.h \
../include/internals.h ../include/constants.h
../include/dot1q.h:
../include/pdu.h:
../include/endianness.h:
../include/macros.h:
../include/small_uint.h:
../include/internals.h:
../include/constants.h:
../src/eapol.o: ../src/eapol.cpp ../include/eapol.h ../include/pdu.h \
../include/macros.h ../include/small_uint.h ../include/endianness.h \
../include/dot11.h ../include/hw_address.h ../include/pdu_option.h \
@@ -1563,6 +1580,18 @@ src/dot11/rts.o: src/dot11/rts.cpp ../include/dot11.h ../include/macros.h \
include/tests/dot11.h:
include/tests/dot11.h:
src/dot1q.o: src/dot1q.cpp ../include/dot1q.h ../include/pdu.h \
../include/endianness.h ../include/macros.h ../include/small_uint.h
../include/dot1q.h:
../include/pdu.h:
../include/endianness.h:
../include/macros.h:
../include/small_uint.h:
src/ethernetII.o: src/ethernetII.cpp ../include/ethernetII.h \
../include/macros.h ../include/pdu.h ../include/endianness.h \
../include/hw_address.h ../include/network_interface.h \

76
tests/src/dot1q.cpp Normal file
View File

@@ -0,0 +1,76 @@
#include <gtest/gtest.h>
#include <cstring>
#include <string>
#include <stdint.h>
#include "dot1q.h"
#include "arp.h"
#include "ethernetII.h"
using namespace std;
using namespace Tins;
class Dot1QTest : public testing::Test {
public:
static const uint8_t expected_packet[];
void test_equals(const Dot1Q &pdu1, const Dot1Q &pdu2);
};
const uint8_t Dot1QTest::expected_packet[] = {
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\x00', '\x19', '\x06',
'\xea', '\xb8', '\xc1', '\x81', '\x00', '\xb0', '{', '\x08', '\x06',
'\x00', '\x01', '\x08', '\x00', '\x06', '\x04', '\x00', '\x02', '\x00',
'\x19', '\x06', '\xea', '\xb8', '\xc1', '\xc0', '\xa8', '{', '\x01',
'\xff', '\xff', '\xff', '\xff', '\xff', '\xff', '\xc0', '\xa8', '{',
'\x01', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00',
'\x00'
};
TEST_F(Dot1QTest, DefaultConstructor) {
Dot1Q dot1;
EXPECT_EQ(0, dot1.payload_type());
EXPECT_EQ(0, dot1.priority());
EXPECT_EQ(0, dot1.cfi());
EXPECT_EQ(0, dot1.id());
}
TEST_F(Dot1QTest, ConstructorFromBuffer) {
EthernetII eth(expected_packet, sizeof(expected_packet));
const Dot1Q *dot1 = eth.find_pdu<Dot1Q>();
ASSERT_TRUE(dot1);
EXPECT_EQ(0x806, dot1->payload_type());
EXPECT_EQ(5, dot1->priority());
EXPECT_EQ(1, dot1->cfi());
EXPECT_EQ(123, dot1->id());
const ARP *arp = dot1->find_pdu<ARP>();
ASSERT_TRUE(arp);
// just to check it the offset's OK
EXPECT_EQ(ARP::hwaddress_type("00:19:06:ea:b8:c1"), arp->sender_hw_addr());
}
TEST_F(Dot1QTest, PayloadType) {
Dot1Q dot1;
dot1.payload_type(0x9283);
EXPECT_EQ(0x9283, dot1.payload_type());
}
TEST_F(Dot1QTest, Priority) {
Dot1Q dot1;
dot1.priority(5);
EXPECT_EQ(5, dot1.priority());
}
TEST_F(Dot1QTest, CFI) {
Dot1Q dot1;
dot1.cfi(1);
EXPECT_EQ(1, dot1.cfi());
}
TEST_F(Dot1QTest, Id) {
Dot1Q dot1;
dot1.id(3543);
EXPECT_EQ(3543, dot1.id());
}