2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
14 #include <senf/Packets/DefaultBundle/EthernetPacket.hh>
16 #define prefix_ inline
17 ///////////////////////////////cci.p////////////////////////////////////////
20 prefix_ bool senf::emu::VLanId::hasCTag(senf::EthernetPacket const & eth)
22 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
23 return *reinterpret_cast<std::uint16_t*>(ð.data()[12]) == 0x0081u;
25 return *reinterpret_cast<std::uint16_t*>(ð.data()[12]) == 0x8100u;
29 prefix_ bool senf::emu::VLanId::hasSTag(senf::EthernetPacket const & eth)
31 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
32 return *reinterpret_cast<std::uint16_t*>(ð.data()[12]) == 0xa888u;
34 return *reinterpret_cast<std::uint16_t*>(ð.data()[12]) == 0x88a8u;
38 prefix_ bool senf::emu::VLanId::hasTag(senf::EthernetPacket const & eth)
40 return hasCTag(eth) or hasSTag(eth);
43 prefix_ std::uint16_t senf::emu::VLanId::payloadTypeLength(senf::EthernetPacket const & eth)
45 std::uint32_t offset (12); // first typeLength
46 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
47 while (((offset+2) <= eth.size()) and ((*reinterpret_cast<std::uint16_t*>(ð.data()[offset]) == 0x0081u) or (*reinterpret_cast<std::uint16_t*>(ð.data()[offset]) == 0xa888u)))
50 while (((offset+2) <= eth.size()) and ((*reinterpret_cast<std::uint16_t*>(ð.data()[offset]) == 0x8100u) or (*reinterpret_cast<std::uint16_t*>(ð.data()[offset]) == 0x88a8u)))
53 if ((offset+2) <= eth.size())
54 return be16toh(*reinterpret_cast<std::uint16_t*>(ð.data()[offset]));
56 // inavlid TL after VLAN stack
61 prefix_ PKT senf::emu::VLanId::payload(senf::EthernetPacket const & eth)
63 senf::Packet pkt (eth.next(senf::nothrow));
64 while (pkt.is<senf::EthVLanCPacket>() or pkt.is<senf::EthVLanSPacket>()) {
68 if (SENF_LIKELY(pkt.is<PKT>()))
69 return pkt.as<PKT> ();
74 prefix_ senf::Packet senf::emu::VLanId::payloadPkt(senf::EthernetPacket const & eth)
76 senf::Packet pkt (eth.next(senf::nothrow));
77 while (pkt.is<senf::EthVLanCPacket>() or pkt.is<senf::EthVLanSPacket>()) {
84 // Fast path assumption is, we have a tag
85 prefix_ senf::emu::VLanId::VLanId(senf::EthernetPacket const & eth)
87 if (SENF_LIKELY(hasCTag(eth))) {
88 id_ = ((eth.data()[14] & 0xf) << 8) + eth.data()[15];
91 else if (SENF_LIKELY(hasSTag(eth))) {
92 id_ = ((eth.data()[14] & 0xf) << 8) + eth.data()[15];
95 id_ = 0; // id == 0 is treated as untagged
100 prefix_ std::uint16_t senf::emu::VLanId::id()
106 prefix_ senf::emu::VLanId::Type senf::emu::VLanId::type()
112 prefix_ senf::emu::VLanId::operator bool()
115 return type_ != NoTag;
118 prefix_ bool senf::emu::VLanId::stag()
121 return type_ == STag;
124 prefix_ bool senf::emu::VLanId::ctag()
127 return type_ == CTag;
130 prefix_ bool senf::emu::VLanId::sameTagType(VLanId const & other)
133 return type_ == other.type_;
136 prefix_ bool senf::emu::VLanId::operator<(VLanId const & other)
139 // For now, do not differentiate between STag/CTag
140 return ((type_ == NoTag) < (other.type_ == NoTag)) or (((type_ == NoTag) == (other.type_ == NoTag)) and id_ < other.id_);
143 prefix_ bool senf::emu::VLanId::operator==(VLanId const & other)
146 // For now, do not differentiate between STag/CTag
147 return id_ == other.id_ && ((type_ == NoTag) == (other.type_ == NoTag));
150 prefix_ std::size_t std::hash<senf::emu::VLanId>::operator() (senf::emu::VLanId const & v)
153 hash<std::uint16_t> hasher;
154 // id() == 0 ane NoTag both map to 0 (untagged)
155 return hasher(v.id());
158 prefix_ std::size_t senf::emu::hash_value(senf::emu::VLanId const & v)
160 boost::hash<std::uint16_t> hasher;
161 // id() == 0 ane NoTag both map to 0 (untagged)
162 return hasher(v.id());
166 ///////////////////////////////cci.e////////////////////////////////////////