packetInjector.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 <boost/format.hpp>
18 #include <senf/PPI.hh>
28 
29 #include "Configuration.hh"
30 
31 #define prefix_
32 //-/////////////////////////////////////////////////////////////////////////////////////////////////
33 
34 prefix_ std::string initInterface(Configuration & config)
35 {
37 
38  // first, remove all existing interfaces of the phy device
39  for (std::string const & iface : wnlc.all_interfaces()) {
40  {
41  senf::NetdeviceController netdevCtrl (iface);
42  netdevCtrl.down();
43  }
44  wnlc.del_interface(iface);
45  }
46 
47  std::string name ((boost::format("phy%d-mon") % wnlc.phyIndex()).str());
48 
49  wnlc.add_monInterface(name,
54 
55  usleep(500000);
56 
62 
63  return name;
64 }
65 
66 int main(int argc, char const * argv[])
67 {
69 
70  Configuration configuration;
71 
72  if (!configuration.parse( argc, argv)) {
73  exit(1);
74  }
75 
76  std::string ifName (initInterface(configuration));
77 
79  handle.bind(senf::LLSocketAddress(ifName));
80  handle.protocol().sndbuf(configuration.sndBuf);
81 
82  // Radiotap
83  senf::RadiotapPacket radiotap (senf::RadiotapPacket::create());
84  // radiotap rate() unit is 500 Kbps
86  radiotap->init_rate() << rate / 500;
87  // WlanData
88  senf::WLANPacket_DataFrame wlanData (senf::WLANPacket_DataFrame::createAfter(radiotap));
89  wlanData->receiverAddress() << configuration.destination;
90  wlanData->destinationAddress() << configuration.destination;
91  wlanData->transmitterAddress() << senf::MACAddress::from_string("00:1b:21:65:f6:5e");
92  wlanData->sourceAddress() << senf::MACAddress::from_string("00:1b:21:65:f6:5e");
93  // LLC - EthExtOUI - Data
94  senf::LlcSnapPacket llc (senf::LlcSnapPacket::createAfter(wlanData));
95  senf::EthOUIExtensionPacket ouiExt (senf::EthOUIExtensionPacket::createAfter(llc));
97  radiotap.finalizeAll();
98  senf::DataPacket::createAfter(ouiExt, configuration.txFrameLength - wlanData.size());
99  radiotap->init_dbmTxAttenuation() = configuration.txPower;
100  radiotap->init_txFlags().noAck(true);
101  radiotap->txFlags().noSeq(true);
102  radiotap.finalizeAll();
103 
104  std::cout << " * radio " << ifName << ", frequency " << configuration.frequency << " kHz, txPower " << configuration.txPower << " dBm" << std::endl;
105  // we could improve this to properly include preamable, fcs, etc. in airtime calculation...
106  std::uint64_t airTime (wlanData.size() * 8 * 1000 / rate);
107  unsigned burst (senf::ClockService::in_microseconds(configuration.txDuration) / airTime);
108  std::cout << " * txPeriod " << senf::ClockService::in_microseconds(configuration.txPeriod) << " us, txDuration " << senf::ClockService::in_microseconds(configuration.txDuration) << " us";
109  std::cout << ", rate " << rate << " kbps" << std::endl;
110  std::cout << " * frameLength (without FCS) " << wlanData.size() << " bytes, frameAirTime " << airTime << " us, pktBurst " << burst << " (" << airTime * burst << " us)" << std::endl;
111 
112  if (configuration.txPeriod and configuration.txDuration) {
113  handle.blocking(false);
114  }
115  else if (!configuration.txPeriod and !configuration.txDuration) {
116  handle.blocking(true);
117  }
118  else {
119  std::cerr << "Invalid TX configuration. Either specify txPeriod and txDuration or set both to 0 for 'send-as-fast-as-possible'" << std::endl;
120  exit(1);
121  }
122 
123  std::uint64_t sent (0), dropped (0);
124 
126  senf::ClockService::clock_type nextTime (startTime);
127  while (senf::ClockService::now() - startTime < configuration.duration) {
128  if (configuration.txPeriod and configuration.txDuration) {
129  for (unsigned b = 0; b < burst; b++) {
130  radiotap.next<senf::WLANPacket_DataFrame>()->sequenceNumber(
131  radiotap.next<senf::WLANPacket_DataFrame>()->sequenceNumber() + 1);
132  if (write(handle.fd(), radiotap.data().begin(), radiotap.size()) == signed(radiotap.size())) {
133  sent++;
134  }
135  else {
136  dropped++;
137  if (configuration.verbose) {
138  std::cerr << "!" << std::flush;
139  }
140  }
141  }
142  nextTime += configuration.txPeriod;
143  while (senf::ClockService::now() < nextTime);
144  } else {
145  if (write(handle.fd(), radiotap.data().begin(), radiotap.size()) == signed(radiotap.size())) {
146  sent++;
147  }
148  else {
149  dropped++;
150  if (configuration.verbose) {
151  std::cerr << "!" << std::flush;
152  }
153  }
154  }
155  }
157 
158  // +4 => incl. FCS in calculation
159  unsigned actualTxRate ((sent * (wlanData.size() + 4) * 8 * 1000) / senf::ClockService::in_microseconds(endTime - startTime));
160  std::cout << "=> pkts sent " << sent << ", pkts dropped " << dropped << ", actual txRate (incl. FCS) " << actualTxRate << " kbps (" << (actualTxRate * 100) / rate << " %)." << std::endl;
161 
162  return 0;
163 }
164 
165 
166 //-/////////////////////////////////////////////////////////////////////////////////////////////////
167 #undef prefix_
168 
169 
170 // Local Variables:
171 // mode: c++
172 // fill-column: 100
173 // c-file-style: "senf"
174 // indent-tabs-mode: nil
175 // ispell-local-dictionary: "american"
176 // compile-command: "scons -u"
177 // comment-column: 40
178 // End:
senf::ClockService::clock_type duration
config::time_type clock_type
senf::INet4SocketAddress destination
unsigned sndBuf
static void logToStderr()
std::string str(T const &t)
std::string phyName
static const std::uint32_t OUI_Fraunhofer_FIT
static MACAddress from_string(std::string const &s)
unsigned txFrameLength
std::string initInterface(Configuration &config)
WLANPacket_DataFrameType::packet WLANPacket_DataFrame
unsigned frequency
static std::vector< LegacyModulationInfo > getLegacyModulationInfosOFDM()
static SENF_CLOCKSERVICE_CONSTEXPR int64_type in_microseconds(clock_type const &v)
unsigned txPower
senf::ClockService::clock_type txDuration
unsigned rateIdx
int main(int argc, char const *argv[])
bool parse(int argc, char const *argv[])
ProtocolClientSocketHandle< PacketSocketProtocol > PacketSocketHandle
senf::ClockService::clock_type txPeriod
WirelessNLController public header.
ConcretePacket< LlcSnapPacketType > LlcSnapPacket
unspecified_keyword_type name
void set_frequency(frequency_type freq, ChannelMode::Enum=ChannelMode::NoHT20)
#define prefix_
static clock_type now()
std::string const & phyName() const
HardwareWLANInterface public header.