MmapSocketSourceTest.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 <fstream>
15 #include <string>
16 #include <iomanip>
22 #include <senf/PPI/PPI.hh>
23 #include <senf/PPI/Connectors.hh>
24 #include <senf/PPI/SocketSink.hh>
25 #include <senf/PPI/DiscardSink.hh>
26 #include <senf/Utils/membind.hh>
27 #include <senf/Utils/hexdump.hh>
28 #include <boost/unordered/unordered_map.hpp>
29 
33 #include <senf/Ext/NetEmu/WLAN/MmapSocketSourceRadioTap.hh>
34 #include <senf/Ext/NetEmu/Ethernet/MmapSocketSourceEthernet.hh>
39 
40 #include "Configuration.hh"
41 
42 #define prefix_
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
44 
46 {
48 
49  void request() {
51 
52  PayloadMap::iterator it(payloadMap_.find(eth->type_length()));
53  if (it == payloadMap_.end()) {
54  payloadMap_.insert( std::make_pair(eth->type_length(), 1));
55  } else {
56  it->second++;
57  }
58 
59  if (logSeqNoErrors_) {
61  if (qual.flags.framePredecessorLost > 0) {
62  std::cout << "(" << unsigned(qual.flags.framePredecessorLost) << ")" << std::flush;
63  }
64  else {
65  std::cout << "." << std::flush;
66  }
67  }
68 
69  if (eth->type_length() == 0x8847) {
70  senf::MACAddress tmp(eth->source());
71  eth->source() << eth->destination();
72  eth->destination() << tmp;
73  output(eth);
74  }
75  }
76 
77 public:
80 
82  typedef boost::unordered_map<boost::uint16_t, unsigned> EtherTypeMap;
83  EtherTypeMap payloadMap_;
84 
85  Analyzer(bool logSeqNoErrors) :
86  logSeqNoErrors_(logSeqNoErrors)
87  {
88  route(input,output).autoThrottling( false);
91  }
92 
93  void dump(std::ostream &os) {
94  os << "(";
95  for (EtherTypeMap::value_type & entry : payloadMap_) {
96  os << std::hex << "0x" << entry.first << "/" << std::dec << entry.second << ";";
97  }
98  os << ")";
99  payloadMap_.clear();
100  }
101 };
102 
103 class Forwarder : public senf::ppi::module::Module
104 {
105  SENF_PPI_MODULE(Forwarder);
106 
107  void request() {
108  senf::EthernetPacket eth (input());
109  if (eth->type_length() != 0) {
110  output(eth);
111  }
112  }
113 
114 public:
117 
119  {
120  route(input,output).autoThrottling( false);
121  input.onRequest( &Forwarder::request);
123  }
124 };
125 
126 
127 template<class SOURCE_TYPE>
128 class Dummy
129 {
131  SOURCE_TYPE source;
132  Analyzer analyzer;
133  Forwarder forwarder1, forwarder2;
134  senf::emu::MonitorDataFilter monitorDataFilter;
136  senf::ppi::module::DiscardSink discardSink;
137  senf::ppi::module::DiscardSink discardSink2;
138  senf::PacketSocketHandle socketOut;
140 
141 public:
142  Dummy( Configuration & configuration) :
143  source( socket, configuration.numBuffers),
144  analyzer( configuration.logSeqNoErrors),
145  timer( "report", boost::bind(&Dummy::report, this)),
146  sink(socketOut)
147  {
148  socket.bind(senf::LLSocketAddress(configuration.interface));
149 
150  senf::ppi::connect( source, monitorDataFilter);
151  senf::ppi::connect( monitorDataFilter, forwarder1);
152  senf::ppi::connect( monitorDataFilter.monitor, discardSink2); // discard ctrl/mgnt frames
153  senf::ppi::connect( forwarder1, analyzer);
154  senf::ppi::connect( analyzer,forwarder2);
155 
156  if (configuration.outputInterface != "") {
157  socketOut.bind(senf::LLSocketAddress(configuration.outputInterface));
158  senf::ppi::connect( forwarder2, sink);
159  }
160  else {
161  senf::ppi::connect( forwarder2, discardSink);
162  }
163 
164  senf::NetdeviceController netdevCtrl (configuration.interface);
165  monitorDataFilter.id(netdevCtrl.hardwareAddress());
166  monitorDataFilter.promisc(true);
167 
168  report();
169  }
170 
171  void report() {
173  log << "rxDropped " << source.dropped();
174  log << ", filterStats "; monitorDataFilter.stats().dump(log);
175  log << ", etherTypeMap "; analyzer.dump(log);
176  }));
177 
178  timer.timeout( senf::scheduler::now() + senf::ClockService::seconds(1));
179  }
180 };
181 
182 int main(int argc, char const * argv[])
183 {
184  Configuration configuration;
185 
186  if (!configuration.parse( argc, argv)) {
187  exit(1);
188  }
189 
190  if (configuration.monitorInterface != "") {
191  configuration.interface = configuration.monitorInterface;
192  Dummy<senf::MmapSocketSourceRadioTap> dummy( configuration);
193  senf::ppi::run();
194  }
195  else {
196  Dummy<senf::MmapSocketSourceEthernet> dummy( configuration);
197  senf::ppi::run();
198  }
199 }
200 
201 
202 //-/////////////////////////////////////////////////////////////////////////////////////////////////
203 #undef prefix_
204 //#include "MmapSocketSourceTespp.mpp"
205 
206 
207 // Local Variables:
208 // mode: c++
209 // fill-column: 100
210 // c-file-style: "senf"
211 // indent-tabs-mode: nil
212 // ispell-local-dictionary: "american"
213 // compile-command: "scons -u"
214 // comment-column: 40
215 // End:
int main(int argc, char const *argv[])
void dump(std::ostream &os) const
#define SENF_LOG_BLOCK(args)
std::string outputInterface
MonitorDataFilter header.
Route< connector::InputConnector, connector::OutputConnector > & route(connector::InputConnector &input, connector::OutputConnector &output)
std::string interface
static SENF_CLOCKSERVICE_CONSTEXPR clock_type seconds(int64_type const &v)
senf::ppi::connector::ActiveOutput< senf::EthernetPacket > output
Annotations public header.
senf::ppi::connector::PassiveInput< senf::EthernetPacket > input
Definition: Analyzer.cc:114
Dummy(Configuration &configuration)
Analyzer(bool logSeqNoErrors)
void timeout(ClockService::clock_type const &timeout, bool initiallyEnabled=true)
int run(int argc, char const *argv[])
Definition: dfstest.cc:83
std::string monitorInterface
senf::ppi::connector::ActiveOutput< senf::EthernetPacket > output
boost::unordered_map< boost::uint16_t, unsigned > EtherTypeMap
#define SENF_PPI_MODULE(name)
bool parse(int argc, char const *argv[])
void dump(std::ostream &os)
MACAddress hardwareAddress() const
ProtocolClientSocketHandle< PacketSocketProtocol > PacketSocketHandle
void id(senf::MACAddress const &_id)
WLANInterface public header.
EtherTypeMap payloadMap_
MonitorDataFilterStatistics stats()
senf::ppi::connector::PassiveInput< senf::EthernetPacket > input
ConcretePacket< EthernetPacketType > EthernetPacket
void request()
Definition: Analyzer.cc:137
void throttlingDisc(ThrottlingDisc const &disc)