80211Analyzer.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 
16 // Custom includes
17 #include <senf/PPI.hh>
23 
24 #include "FrameAnalyzer.hh"
25 
26 #define prefix_
27 //-/////////////////////////////////////////////////////////////////////////////////////////////////
28 
30 {
33 
34  void onRead( int dummy) {
35  // just read frames from the socket and forget about them
36  handle.read();
37  }
38 
39 public:
41  : handle( addr),
42  event( "bindSocketReader", senf::membind( &SocketReader::onRead, this),
43  handle, senf::scheduler::FdEvent::EV_READ, false)
44  {
45  event.enable();
46  handle.protocol().reuseaddr( true);
47  SENF_LOG((senf::log::IMPORTANT)("BindSocket active (reuseaddr enabled)"));
48  }
49 };
50 
51 void handleSignal(siginfo_t const &)
52 {
54 }
55 
56 namespace {
57  int exitCode_ (0);
58 }
59 
60 void exitCode(int code)
61 {
62  exitCode_ = code;
63 }
64 
65 int main(int argc, char const * argv[])
66 {
68 
69  Configuration configuration;
70 
71  if (!configuration.parse( argc, argv)) {
72  exit(1);
73  }
74 
75  senf::TCPv4ClientSocketHandle *handle = NULL;
76  if (configuration.logDestination.port() != 0) {
77  try {
78  handle = new senf::TCPv4ClientSocketHandle( configuration.logDestination);
79  handle->protocol().sndbuf( 128000); // avoid blocking on temporary TCP issues
80  if (dup2( handle->fd(), fileno(stdout)) == -1) {
81  throw senf::SystemException( "dup2 failed");
82  }
83  }
84  catch (senf::SystemException & ex) {
85  SENF_LOG( (senf::log::CRITICAL) ("Failed to connect to log destination: " << ex.message()) );
86  exit(1);
87  }
88  }
89 
90  if (configuration.bindSocket) {
91  new SocketReader( configuration.destination);
92  }
93 
94  // determine the MAC address of the monitor Device.
95  // This is required for the MonitorDataFilter to perform proper re-ordering
97  try {
98  std::ifstream fs;
99  std::string buf;
100  fs.open( (std::string("/sys/class/net/") + configuration.device + std::string("/address")).c_str());
101  fs >> buf;
102  fs.close();
104  } catch(...) {
105  SENF_LOG( (senf::log::CRITICAL) ("Failed to determine MAC address of monitor device") );
106  exit(1);
107  }
108  SENF_LOG((senf::log::IMPORTANT)("Determined MAC address for " << configuration.device << " is " << mac));
109 
111  socket.protocol().rcvbuf(4096);
112 
113  senf::emu::MonitorDataFilter filter (mac);
114  /*
115  if (configuration.reorderBufferSize > senf::ClockService::milliseconds(0))
116  filter.reorderTimeout(configuration.reorderTimeout);
117  */
118 
119  if (configuration.tsftHistogram) {
120  filter.tsftHistogram().start();
121  }
122 
123  FrameAnalyzer analyzer (configuration);
124 
125  if (configuration.monitorMode) {
126  // monitor mode specific confif
127  filter.promisc(configuration.promisc);
128  filter.annotate(true);
129  filter.airTime(true);
130  if (configuration.analyzeTx) {
132  }
133  else {
135  }
136  // now, create the RT source
138  senf::ppi::connect( *source, filter);
139  senf::ppi::connect( filter, analyzer);
140  } else {
141  // plain ethernet source
143  senf::ppi::connect( *source, filter.input_plain);
144  senf::ppi::connect( filter, analyzer);
145  }
146 
147  if (configuration.csvMode) {
148  SENF_LOG((senf::log::IMPORTANT)("CSV order: flowId,tstamp,pps,brateInKbps,retriesPerSec,len_min,len_avg,len_max,len_stddev,rssi_min,rssi_avg,rssi_max,rssi_stdev,mcs_min,mcs_avg,mcs_max,mcs_stddev,(latency_min,latency_avg,latency_max,latency_stddev,loss%,duplicate,late)(received,data,corrupt,control,management,other,dataNonUDP,nonMGEN)"));
149  }
150 
152  senf::scheduler::SignalEvent sigterm (SIGTERM, handleSignal);
153 
154  SENF_LOG((senf::log::IMPORTANT)("Waiting for first valid frame to start (default dst sock_addr is " << configuration.destination << ")..."));
155 
156  senf::ppi::run();
157 
158  unsigned dropped (socket.protocol().rxQueueDropped());
159  if (dropped > 0) {
160  SENF_LOG((senf::log::IMPORTANT)("Dropped " << dropped << " frames during the capture! CPU overload ?"));
161  }
162  SENF_LOG((senf::log::IMPORTANT) ("Filterstats " << filter.stats().dump()) );
163  if (configuration.tsftHistogram) {
164  filter.tsftHistogram().dump(std::cout);
165  }
166 
167  return exitCode_;
168 }
169 
170 
171 //-/////////////////////////////////////////////////////////////////////////////////////////////////
172 #undef prefix_
173 
174 
175 // Local Variables:
176 // mode: c++
177 // fill-column: 100
178 // c-file-style: "senf"
179 // indent-tabs-mode: nil
180 // ispell-local-dictionary: "american"
181 // compile-command: "scons -u"
182 // comment-column: 40
183 // End:
senf::INet4SocketAddress destination
void dump(std::ostream &os) const
#define SENF_EMU_MAXMTU
Definition: config.hh:40
SocketReader(senf::INet4SocketAddress const &addr)
MonitorDataFilter header.
std::uint8_t mac[6]
static void logToStderr()
bool start(senf::MACAddress const &src)
senf::INet4SocketAddress logDestination
virtual void terminate() const
static void filterMonitorRxFrames(BSDSocket sock)
static MACAddress from_string(std::string const &s)
boost::function< R(Args)> membind(R(T::*fn)(Args), T *ob)
void exitCode(int code)
int run(int argc, char const *argv[])
Definition: dfstest.cc:83
ppi::connector::PassiveInput< EthernetPacket > input_plain
bool parse(int argc, char const *argv[])
ProtocolClientSocketHandle< ConnectedMMapPacketSocketProtocol< QueueReadPolicy > > ConnectedMMapReadPacketSocketHandle
void handleSignal(siginfo_t const &)
ProtocolClientSocketHandle< TCPv4SocketProtocol > TCPv4ClientSocketHandle
std::string message() const
MonitorDataFilterStatistics stats()
static void filterMonitorTxFrames(BSDSocket sock)
unsigned port() const
#define SENF_LOG(args)
void dump(std::ostream &os) const
int main(int argc, char const *argv[])
std::string device
ProtocolClientSocketHandle< UDPv4SocketProtocol > UDPv4ClientSocketHandle