From 53efc67f6f246530cfd2e30a0828fa8f0f3a507a Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Wed, 17 Oct 2012 18:44:46 -0300 Subject: [PATCH] Added some unit tests for RadioTap. --- include/radiotap.h | 15 ++++++- include/utils.h | 7 +++ src/radiotap.cpp | 7 ++- src/utils.cpp | 4 ++ tests/src/radiotap.cpp | 98 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 4 deletions(-) create mode 100644 tests/src/radiotap.cpp diff --git a/include/radiotap.h b/include/radiotap.h index 9d45687..dc8c06d 100644 --- a/include/radiotap.h +++ b/include/radiotap.h @@ -96,6 +96,7 @@ namespace Tins { * \brief Flags used in the RadioTap::flags() method. */ enum FrameFlags { + #if TINS_IS_LITTLE_ENDIAN CFP = 1, PREAMBLE = 2, WEP = 4, @@ -103,6 +104,15 @@ namespace Tins { FCS = 16, PADDING = 32, FAILED_FCS = 64 + #else + CFP = 64, + PREAMBLE = 32, + WEP = 16, + FRAGMENTATION = 8, + FCS = 4, + PADDING = 2, + FAILED_FCS = 1 + #endif }; /** @@ -110,7 +120,8 @@ namespace Tins { * \param iface The interface in which to send this PDU. * \param child The child PDU.(optional) */ - RadioTap(const NetworkInterface &iface, PDU *child = 0); + RadioTap(const NetworkInterface &iface = NetworkInterface(), + PDU *child = 0); /** * \brief Constructor which creates a RadioTap object from a buffer and adds all @@ -186,7 +197,7 @@ namespace Tins { * \brief Setter for the rx flag field. * \param new_rx_flag The antenna signal. */ - void rx_flag(uint16_t new_rx_flag); + void rx_flags(uint16_t new_rx_flag); /* Getters */ diff --git a/include/utils.h b/include/utils.h index bdfa5d7..b3a5fc9 100644 --- a/include/utils.h +++ b/include/utils.h @@ -162,6 +162,13 @@ namespace Tins { * \return The channel's mhz representation. */ uint16_t channel_to_mhz(uint16_t channel); + + /** + * \brief Converts mhz units to the appropriate channel number. + * \param channel The mhz units to be converted. + * \return The channel number. + */ + uint16_t mhz_to_channel(uint16_t mhz); /** \brief Does the 16 bits sum of all 2 bytes elements between start and end. * diff --git a/src/radiotap.cpp b/src/radiotap.cpp index 3b37e6b..4fa212c 100644 --- a/src/radiotap.cpp +++ b/src/radiotap.cpp @@ -131,7 +131,7 @@ void Tins::RadioTap::init() { flags(FCS); tsft(0); dbm_signal(0xce); - rx_flag(0); + rx_flags(0); antenna(0); } @@ -189,7 +189,7 @@ void Tins::RadioTap::antenna(uint8_t new_antenna) { _radio.antenna = 1; } -void Tins::RadioTap::rx_flag(uint16_t new_rx_flag) { +void Tins::RadioTap::rx_flags(uint16_t new_rx_flag) { _rx_flags = Endian::host_to_le(new_rx_flag); if(!_radio.rx_flags) _options_size += sizeof(_rx_flags); @@ -211,6 +211,9 @@ uint32_t Tins::RadioTap::trailer_size() const { } bool Tins::RadioTap::send(PacketSender &sender) { + if(!_iface) + throw std::runtime_error("Interface has not been set"); + struct sockaddr_ll addr; memset(&addr, 0, sizeof(struct sockaddr_ll)); diff --git a/src/utils.cpp b/src/utils.cpp index d3f656d..e46bf89 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -164,6 +164,10 @@ uint16_t Utils::channel_to_mhz(uint16_t channel) { return 2407 + (channel * 5); } +uint16_t Utils::mhz_to_channel(uint16_t mhz) { + return (mhz - 2407) / 5; +} + uint32_t Utils::do_checksum(const uint8_t *start, const uint8_t *end) { uint32_t checksum(0); uint16_t *ptr = (uint16_t*)start, *last = (uint16_t*)end, padding(0); diff --git a/tests/src/radiotap.cpp b/tests/src/radiotap.cpp new file mode 100644 index 0000000..a00e99b --- /dev/null +++ b/tests/src/radiotap.cpp @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include "radiotap.h" +#include "utils.h" + +using namespace std; +using namespace Tins; + +class RadioTapTest : public testing::Test { +public: + static const uint8_t expected_packet[]; + + void test_equals(const RadioTap &radio1, const RadioTap &radio2); +}; + +const uint8_t RadioTapTest::expected_packet[] = { + '\x1f', '\x00', ' ', '\x00', 'g', '\x08', '\x04', '\x00', '\x80', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', 'd', '\x00', '\x00', '\x00' +}; + +TEST_F(RadioTapTest, DefaultConstructor) { + RadioTap radio; + EXPECT_TRUE(radio.flags() & RadioTap::FCS); + EXPECT_EQ(Utils::mhz_to_channel(radio.channel_freq()), 1); + EXPECT_EQ(radio.channel_type(), 0xa0); + EXPECT_EQ(radio.tsft(), 0); + EXPECT_EQ(radio.dbm_signal(), 0xce); + EXPECT_EQ(radio.antenna(), 0); + EXPECT_EQ(radio.rx_flags(), 0); +} + +//version=0x1f, pad=0x3a, present="TSFT+Antenna" +TEST_F(RadioTapTest, ConstructorFromBuffer) { + RadioTap radio(expected_packet, sizeof(expected_packet)); + EXPECT_EQ(radio.version(), 0x1f); + EXPECT_EQ(radio.padding(), 0); + EXPECT_EQ(radio.antenna(), 2); + EXPECT_EQ(radio.rate(), 6); + EXPECT_EQ(radio.rx_flags(), 0); + EXPECT_EQ(radio.channel_freq(), 5180); + EXPECT_EQ(radio.channel_type(), 0x140); +} + +TEST_F(RadioTapTest, Channel) { + RadioTap radio; + radio.channel(0xfa23, 0xfb6a); + EXPECT_EQ(radio.channel_freq(), 0xfa23); + EXPECT_EQ(radio.channel_type(), 0xfb6a); +} + +TEST_F(RadioTapTest, Antenna) { + RadioTap radio; + radio.antenna(0x7a); + EXPECT_EQ(radio.antenna(), 0x7a); +} + +TEST_F(RadioTapTest, Padding) { + RadioTap radio; + radio.padding(0x7a); + EXPECT_EQ(radio.padding(), 0x7a); +} + +TEST_F(RadioTapTest, Version) { + RadioTap radio; + radio.version(0x7a); + EXPECT_EQ(radio.version(), 0x7a); +} + +TEST_F(RadioTapTest, Length) { + RadioTap radio; + radio.length(0x7a); + EXPECT_EQ(radio.length(), 0x7a); +} + +TEST_F(RadioTapTest, DBMSignal) { + RadioTap radio; + radio.dbm_signal(0x7a); + EXPECT_EQ(radio.dbm_signal(), 0x7a); +} + +TEST_F(RadioTapTest, RXFlags) { + RadioTap radio; + radio.rx_flags(0x7afb); + EXPECT_EQ(radio.rx_flags(), 0x7afb); +} + +TEST_F(RadioTapTest, Rate) { + RadioTap radio; + radio.rate(0x7a); + EXPECT_EQ(radio.rate(), 0x7a); +} + +TEST_F(RadioTapTest, TSFT) { + RadioTap radio; + radio.tsft(0x7afb9a8d); + EXPECT_EQ(radio.tsft(), 0x7afb9a8d); +}