From 988f2382c41aebdc3e0f91b054232b06a7a6a2cb Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Sun, 21 May 2017 12:56:22 -0700 Subject: [PATCH] Make RadioTapParser work using only the options buffer --- include/tins/utils/radiotap_parser.h | 11 ++++++--- src/utils/radiotap_parser.cpp | 34 ++++++++++++++++------------ tests/src/radiotap_test.cpp | 4 ++-- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/include/tins/utils/radiotap_parser.h b/include/tins/utils/radiotap_parser.h index 05b0026..f63ff7d 100644 --- a/include/tins/utils/radiotap_parser.h +++ b/include/tins/utils/radiotap_parser.h @@ -31,9 +31,9 @@ #define TINS_RADIOTAP_PARSER_H #include -#include "macros.h" -#include "radiotap.h" -#include "pdu_option.h" +#include "../macros.h" +#include "../radiotap.h" +#include "../pdu_option.h" namespace Tins { namespace Utils { @@ -104,6 +104,11 @@ public: */ option current_option(); + /** + * Gets the pointer at which the current option is located + */ + const uint8_t* current_option_ptr() const; + /** * \brief Advances to the next option * diff --git a/src/utils/radiotap_parser.cpp b/src/utils/radiotap_parser.cpp index 1aed722..8954af5 100644 --- a/src/utils/radiotap_parser.cpp +++ b/src/utils/radiotap_parser.cpp @@ -142,20 +142,18 @@ void align_buffer(const uint8_t* buffer_start, const uint8_t*& buffer, uint32_t RadioTapParser::RadioTapParser(const vector& buffer) : current_namespace_(RADIOTAP_NS), current_bit_(0), namespace_index_(0) { - if (TINS_UNLIKELY(buffer.empty())) { - throw malformed_packet(); + if (buffer.empty()) { + start_ = 0; + end_ = 0; + current_ptr_ = start_; } - start_ = &*buffer.begin(); - end_ = start_ + buffer.size(); - const size_t max_size = end_ - start_; - if (TINS_UNLIKELY(max_size < sizeof(RadiotapHeader))) { - throw malformed_packet(); + else { + start_ = &*buffer.begin(); + end_ = start_ + buffer.size(); + current_ptr_ = find_options_start(); + // Skip all fields and make this point to the first flags one + advance_to_next_field(true /* start from bit zero */); } - const RadiotapHeader* radio = (const RadiotapHeader*)start_; - end_ = start_ + Endian::le_to_host(radio->length); - current_ptr_ = find_options_start(); - // Skip all fields and make this point to the first flags one - advance_to_next_field(true /* start from bit zero */); } RadioTapParser::NamespaceType RadioTapParser::current_namespace() const { @@ -174,6 +172,10 @@ RadioTapParser::option RadioTapParser::current_option() { return option(current_field(), size, current_ptr_); } +const uint8_t* RadioTapParser::current_option_ptr() const { + return current_ptr_; +} + bool RadioTapParser::advance_field() { // If we manage to advance the field, return true if (advance_to_next_field(false /* keep going from current */)) { @@ -190,7 +192,7 @@ bool RadioTapParser::advance_field() { const uint8_t* RadioTapParser::find_options_start() const { uint32_t total_sz = end_ - start_; - if (TINS_UNLIKELY(total_sz < sizeof(RadiotapHeader))) { + if (TINS_UNLIKELY(total_sz < sizeof(RadioTapFlags))) { throw malformed_packet(); } // Skip fields before the flags one @@ -220,8 +222,10 @@ bool RadioTapParser::advance_to_next_field(bool start_from_zero) { bit++; } if (bit < BIT_LIMIT) { + const uint8_t* radiotap_start = start_ - sizeof(uint32_t); // Skip and align the buffer - align_buffer(start_, current_ptr_, end_ - start_, RADIOTAP_METADATA[bit].alignment); + align_buffer(radiotap_start, current_ptr_, end_ - radiotap_start, + RADIOTAP_METADATA[bit].alignment); current_bit_ = bit; return true; } @@ -257,7 +261,7 @@ bool RadioTapParser::is_field_set(uint32_t bit, const RadioTapFlags* flags) cons } const RadioTapFlags* RadioTapParser::get_flags_ptr() const { - return (const RadioTapFlags*)(start_ + sizeof(uint32_t) * (namespace_index_ + 1)); + return (const RadioTapFlags*)(start_ + sizeof(uint32_t) * namespace_index_); } } // Utils diff --git a/tests/src/radiotap_test.cpp b/tests/src/radiotap_test.cpp index 2f215cb..0166197 100644 --- a/tests/src/radiotap_test.cpp +++ b/tests/src/radiotap_test.cpp @@ -405,7 +405,7 @@ TEST_F(RadioTapTest, SerializationWorksFine) { // RadioTapParser TEST_F(RadioTapTest, RadioTapParsing) { - vector buffer(expected_packet, expected_packet + sizeof(expected_packet)); + vector buffer(expected_packet+4, expected_packet + sizeof(expected_packet)-4); RadioTapParser parser(buffer); EXPECT_EQ(RadioTap::TSTF, parser.current_field()); EXPECT_EQ(616089172U, parser.current_option().to()); @@ -438,7 +438,7 @@ TEST_F(RadioTapTest, RadioTapParsing) { } TEST_F(RadioTapTest, RadioTapParsingMultipleNamespaces) { - vector buffer(expected_packet4, expected_packet4 + sizeof(expected_packet4)); + vector buffer(expected_packet4+4, expected_packet4 + sizeof(expected_packet4)-4); RadioTapParser parser(buffer); EXPECT_EQ(RadioTapParser::RADIOTAP_NS, parser.current_namespace()); while (parser.current_field() != RadioTap::MCS) {