EthernetReassembler.cc
Go to the documentation of this file.
1 //
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
6 //
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
11 //
12 
13 
14 #include "EthernetReassembler.hh"
16 
17 // Custom includes
18 
19 #define prefix_
20 
23 // senf::emu::EthernetReassembler
24 
26  : nextFragmentNr_(1), packetsUnfragmented_(0), packetsReassembled_(0), fragmentsInvalid_(0), fragmentsProcessed_(0)
27 {
28 }
29 
31 {
32  return reassembledPacket_;
33 }
34 
35 
37 {
38  std::uint8_t fragmentNr (fragment->fragmentNr());
39  if (SENF_UNLIKELY(fragmentNr != nextFragmentNr_)){
40  fragmentsInvalid_++;
41  if (fragmentNr != 1)
42  return false;
43  }
44 
45  fragmentsProcessed_++;
46 
47  if (fragmentNr == 1) {
48  bool vlanCPresent (eth->type_length() == senf::EthVLanCPacketType::etherType);
49  bool vlanSPresent (eth->type_length() == senf::EthVLanSPacketType::etherType);
50  reassembledPacket_ = eth.clone();
51  senf::Packet p (reassembledPacket_);
52  if (vlanSPresent) {
53  p = p.next();
54  reassembledPacket_.next<senf::EthVLanSPacket>()->type_length() << fragment->type_length();
55  } else if (vlanCPresent) {
56  p = p.next();
57  reassembledPacket_.next<senf::EthVLanCPacket>()->type_length() << fragment->type_length();
58  } else {
59  reassembledPacket_->type_length() << fragment->type_length();
60  }
61  payloadIter_ = (senf::DataPacket::createAfter(p, fragment->size(), senf::noinit)).data().begin();
62  }
63  payloadIter_ = std::copy(
64  fragment.next().data().begin(),
65  std::next( fragment.next().data().begin(), std::min( senf::Packet::size_type(fragment->size()), fragment.next().data().size())),
66  payloadIter_);
67  nextFragmentNr_ = fragmentNr + 1;
68 
69  if (! fragment->moreFragment()) {
70  nextFragmentNr_ = 1;
71  reassembledPacket_.reparse();
72  packetsReassembled_++;
73  return true;
74  }
75 
76  return false;
77 }
78 
80 {
81  unsigned tmp (fragmentsProcessed_);
82  fragmentsProcessed_ = 0;
83  return tmp;
84 }
85 
87 {
88  unsigned tmp (fragmentsInvalid_);
89  fragmentsInvalid_ = 0;
90  return tmp;
91 }
92 
94 {
95  unsigned tmp (packetsReassembled_);
96  packetsReassembled_ = 0;
97  return tmp;
98 }
99 
101 {
102  unsigned tmp (packetsUnfragmented_);
103  packetsUnfragmented_ = 0;
104  return tmp;
105 }
106 
108 {
109 }
110 
112 {
113  route( input, output).autoThrottling(false);
114  input.onRequest( &EthernetReassemblerModule::onRequest);
115  input.throttlingDisc( senf::ppi::ThrottlingDiscipline::NONE);
116 }
117 
118 prefix_ void senf::emu::EthernetReassemblerModule::onRequest()
119 {
120  senf::EthernetPacket const & eth (input());
121 
123  output(eth);
124  return;
125  }
126 
127  auto const & extOUI (VLanId::payload<EthOUIExtensionPacket>(eth));
128  if (extOUI.next<EthernetFragmentPacket>(senf::nothrow)) {
129  if (processFrame(eth, extOUI.next<EthernetFragmentPacket>())) {
130  output(reassembledPacket());
131  }
132  } else {
133  output(eth);
134  }
135 }
136 
138 #undef prefix_
bool processFrame(senf::EthernetPacket const &eth, EthernetFragmentPacket const &fragment)
ConcretePacket< EthVLanSPacketType > EthVLanSPacket
static const EtherTypes::key_t etherType
#define SENF_LIKELY(x)
iterator begin() const
std::int32_t min
noinit
PacketData & data() const
static const EtherTypes::key_t etherType
Packet next() const
static std::uint16_t payloadTypeLength(senf::EthernetPacket const &eth)
senf::EthernetPacket & reassembledPacket()
senf::detail::packet::size_type size_type
static const EtherTypes::key_t etherType
ConcretePacket< EthVLanCPacketType > EthVLanCPacket
nothrow
size_type size() const
ConcretePacket< EthernetPacketType > EthernetPacket
#define SENF_UNLIKELY(x)
#define prefix_