diff --git a/include/dot1q.h b/include/dot1q.h index d1c9224..0fb234b 100644 --- a/include/dot1q.h +++ b/include/dot1q.h @@ -44,7 +44,7 @@ public: /** * Default constructor */ - Dot1Q(); + Dot1Q(small_uint<12> tag_id = 0, bool append_pad = true); /** * \brief Constructor which creates an Dot1Q object from a buffer and @@ -120,6 +120,14 @@ public: return new Dot1Q(*this); } + /** + * \brief Retrieves the flag indicating whether padding will be + * appended at the end of this packet. + */ + bool append_padding() const { + return _append_padding; + } + // Setters /** @@ -146,6 +154,18 @@ public: */ void payload_type(uint16_t new_type); + /** + * \brief Indicates whether the appropriate padding will be + * at the end of the packet. + * + * This flag could be disabled in case two or more contiguous Dot1Q + * PDUs are added to a packet. In that case, only the Dot1Q which is + * closer to the link layer should add the padding at the end. + * + * \param value A boolean indicating whether padding will be appended. + */ + void append_padding(bool value); + /** * \brief Check wether ptr points to a valid response for this PDU. * @@ -175,6 +195,7 @@ private: static uint16_t get_id(const dot1q_hdr *hdr); dot1q_hdr _header; + bool _append_padding; }; } diff --git a/include/tins.h b/include/tins.h index 50b266c..6e6b464 100644 --- a/include/tins.h +++ b/include/tins.h @@ -41,6 +41,8 @@ #include "icmp.h" #include "icmpv6.h" #include "dot11.h" +#include "dot1q.h" +#include "dot3.h" #include "ip.h" #include "ipv6.h" #include "packet_sender.h" diff --git a/src/dot1q.cpp b/src/dot1q.cpp index 6e975b2..e344e8b 100644 --- a/src/dot1q.cpp +++ b/src/dot1q.cpp @@ -35,10 +35,10 @@ namespace Tins { -Dot1Q::Dot1Q() -: _header() +Dot1Q::Dot1Q(small_uint<12> tag_id, bool append_pad) +: _header(), _append_padding(append_pad) { - + id(tag_id); } Dot1Q::Dot1Q(const uint8_t *buffer, uint32_t total_sz) { @@ -85,10 +85,14 @@ uint32_t Dot1Q::header_size() const { } 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); + if(_append_padding) { + uint32_t total_size = sizeof(_header); + if(inner_pdu()) + total_size += inner_pdu()->size(); + return (total_size > 50) ? 0 : (50 - total_size); + } + else + return 0; } void Dot1Q::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) { @@ -118,6 +122,10 @@ void Dot1Q::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) } #endif +void Dot1Q::append_padding(bool value) { + _append_padding = value; +} + bool Dot1Q::matches_response(uint8_t *ptr, uint32_t total_sz) { if(total_sz < sizeof(_header)) return false; diff --git a/src/internals.cpp b/src/internals.cpp index 045edef..2c87c08 100644 --- a/src/internals.cpp +++ b/src/internals.cpp @@ -136,6 +136,8 @@ Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag) { return Constants::Ethernet::IPV6; case PDU::ARP: return Constants::Ethernet::ARP; + case PDU::DOT1Q: + return Constants::Ethernet::VLAN; default: return Constants::Ethernet::UNKNOWN; }