From 2414edd1e7f481d185e268a34d86e391d241817c Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Sun, 22 Sep 2013 19:37:02 -0300 Subject: [PATCH] Fixed a bug in PPI and Dot1Q triggered when constructing from buffer/serializing. Done some documentation fixes. --- include/dot11/dot11_base.h | 100 +++++++++++++++++----------------- include/dot11/dot11_mgmt.h | 103 +++++++++++++++++++++++++++++------- include/exceptions.h | 10 ++++ src/dot11/dot11_base.cpp | 2 +- src/dot11/dot11_control.cpp | 6 +-- src/dot11/dot11_mgmt.cpp | 80 ++++++++++++++++++++++------ src/dot1q.cpp | 4 +- src/ppi.cpp | 2 +- src/radiotap.cpp | 6 +-- tests/src/dot11/beacon.cpp | 26 ++++++++- 10 files changed, 243 insertions(+), 96 deletions(-) diff --git a/include/dot11/dot11_base.h b/include/dot11/dot11_base.h index 4b1ef25..085906a 100644 --- a/include/dot11/dot11_base.h +++ b/include/dot11/dot11_base.h @@ -118,7 +118,8 @@ public: TCLAS_PROCESSING, QOS_CAPABILITY = 46, RSN = 48, - EXT_SUPPORTED_RATES = 50 + EXT_SUPPORTED_RATES = 50, + VENDOR_SPECIFIC = 221 }; /** @@ -175,10 +176,7 @@ public: }; /** - * \brief Constructor for creating an 802.11 PDU - * - * Constructor that builds an 802.11 PDU taking the interface index, - * destination's and source's MAC. + * \brief Constructs an 802.11 PDU. * * \param dst_hw_addr The destination hardware address. */ @@ -199,163 +197,165 @@ public: Dot11(const uint8_t *buffer, uint32_t total_sz); /** - * \brief Getter for the protocol version. + * \brief Getter for the protocol version field. * - * \return uint8_t containing the protocol version. + * \return The stored protocol version field. */ small_uint<2> protocol() const { return _header.control.protocol; } /** - * \brief Getter for the 802.11 frame's type. + * \brief Getter for the Type field. * - * \return uint8_t containing the type of this 802.11 frame. + * \return The stored Type field. */ small_uint<2> type() const { return _header.control.type; } /** - * \brief Getter for the 802.11 frame's subtype. + * \brief Getter for the Subtype field. * - * \return uint8_t cotaining the subtype of this 802.11 frame. + * \return The stored Subtype field. */ small_uint<4> subtype() const { return _header.control.subtype; } /** - * \brief Getter for the 802.11 frame's To-DS field. + * \brief Getter for the To-DS field. * - * \return small_uint<1> containing the To-DS field. + * \return The stored To-DS field. */ small_uint<1> to_ds() const { return _header.control.to_ds; } /** - * \brief Getter for the 802.11 frame's From-DS field. + * \brief Getter for the From-DS field. * - * \return small_uint<1> containing the From-DS field. + * \return The stored From-DS field. */ small_uint<1> from_ds() const { return _header.control.from_ds; } /** - * \brief Getter for the 802.11 frame's More-Frag field. + * \brief Getter for the More-Frag field. * - * \return small_uint<1> containing the More-Frag field. + * \return The stored More-Frag field. */ small_uint<1> more_frag() const { return _header.control.more_frag; } /** - * \brief Getter for the 802.11 frame's Retry field. + * \brief Getter for the Retry field. * - * \return small_uint<1> containing the Retry field. + * \return The stored Retry field. */ small_uint<1> retry() const { return _header.control.retry; } /** - * \brief Getter for the 802.11 frame's Power-Management field. + * \brief Getter for the Power-Management field. * - * \return small_uint<1> containing the Power-Management field. + * \return The stored Power-Management field. */ small_uint<1> power_mgmt() const { return _header.control.power_mgmt; } /** - * \brief Getter for the 802.11 frame's WEP field. + * \brief Getter for the WEP field. * - * \return small_uint<1> containing the WEP field. + * \return The stored WEP field. */ small_uint<1> wep() const { return _header.control.wep; } /** - * \brief Getter for the 802.11 frame's Order field. + * \brief Getter for the Order field. * - * \return small_uint<1> containing the Order field. + * \return The stored Order field. */ small_uint<1> order() const { return _header.control.order; } /** * \brief Getter for the Duration-ID field. * - * \return uint16_t containing the Duration-ID field. + * \return The stored Duration-ID field. */ uint16_t duration_id() const { return Endian::le_to_host(_header.duration_id); } /** * \brief Getter for the first address. * - * \return address_type containing the first address. + * \return The stored first address. */ address_type addr1() const { return _header.addr1; } + // Setters + /** - * \brief Setter for the protocol version. + * \brief Setter for the protocol version field. * - * \param new_proto The new protocol version. + * \param new_proto The new protocol version field value. */ void protocol(small_uint<2> new_proto); /** - * \brief Setter for the 802.11 frame's type. + * \brief Setter for the type field. * - * \param new_type The new type of this 802.11 frame. + * \param new_type The new type field value. */ void type(small_uint<2> new_type); /** - * \brief Setter for the 802.11 frame's subtype. + * \brief Setter for the subtype field. * - * \param new_subtype The new subtype of this 802.11 frame. + * \param new_subtype The new subtype field value. */ void subtype(small_uint<4> new_subtype); /** - * \brief Setter for the 802.11 frame's To-DS field. + * \brief Setter for the To-DS field. * - * \param new_value The new value of the To-DS field. + * \param new_value The new To-DS field value. */ void to_ds(small_uint<1> new_value); /** - * \brief Setter for the 802.11 frame's From-DS field. + * \brief Setter for the From-DS field. * - * \param new_value The new value of the From-DS field. + * \param new_value The new From-DS field value. */ void from_ds(small_uint<1> new_value); /** - * \brief Setter for the 802.11 frame's More-Frag field. + * \brief Setter for the More-Frag field. * - * \param new_value The new value of the More-Frag field. + * \param new_value The new More-Frag field value. */ void more_frag(small_uint<1> new_value); /** - * \brief Setter for the 802.11 frame's Retry field. + * \brief Setter for the Retry field. * - * \param new_value sThe new value of the Retry field. + * \param new_value The new Retry field value. */ void retry(small_uint<1> new_value); /** - * \brief Setter for the 802.11 frame's Power-Management field. + * \brief Setter for the Power-Management field. * - * \param new_value The new value of the Power-Management field. + * \param new_value The new Power-Management field value. */ void power_mgmt(small_uint<1> new_value); /** - * \brief Setter for the 802.11 frame's WEP field. + * \brief Setter for the WEP field. * - * \param new_value The new value of the WEP field. + * \param new_value The new WEP field value. */ void wep(small_uint<1> new_value); /** - * \brief Setter for the 802.11 frame's Order field. + * \brief Setter for the Order field. * - * \param new_value The new value of the Order field. + * \param new_value The new Order field value. */ void order(small_uint<1> new_value); /** * \brief Setter for the Duration-ID field. * - * \param new_duration_id The new value of the Duration-ID field. + * \param new_duration_id The new Duration-ID field value. */ void duration_id(uint16_t new_duration_id); @@ -445,7 +445,9 @@ public: * \brief Allocates an Dot11 PDU from a buffer. * * This can be used somehow as a "virtual constructor". This - * method instantiates a subclass of Dot11 from the given buffer. + * method instantiates the appropriate subclass of Dot11 from the + * given buffer. + * * The allocated class' type will be figured out from the * information provided in the buffer. * diff --git a/include/dot11/dot11_mgmt.h b/include/dot11/dot11_mgmt.h index 8097625..798f813 100644 --- a/include/dot11/dot11_mgmt.h +++ b/include/dot11/dot11_mgmt.h @@ -363,7 +363,9 @@ public: } TINS_END_PACK; - TINS_BEGIN_PACK + /** + * The type used to store the FS parameters set option data. + */ struct fh_params_set { uint16_t dwell_time; uint8_t hop_set, hop_pattern, hop_index; @@ -374,9 +376,11 @@ public: uint8_t hop_pattern, uint8_t hop_index) : dwell_time(dwell_time), hop_set(hop_set), hop_pattern(hop_pattern), hop_index(hop_index) {} - } TINS_END_PACK; + }; - TINS_BEGIN_PACK + /** + * The type used to store the CF parameters set option data. + */ struct cf_params_set { uint8_t cfp_count, cfp_period; uint16_t cfp_max_duration, cfp_dur_remaining; @@ -388,8 +392,11 @@ public: : cfp_count(cfp_count), cfp_period(cfp_period), cfp_max_duration(cfp_max_duration), cfp_dur_remaining(cfp_dur_remaining) {} - } TINS_END_PACK; + }; + /** + * The type used to store the IBSS DFS parameters option data. + */ struct ibss_dfs_params { static const size_t minimum_size = address_type::address_size + sizeof(uint8_t) + 2 * sizeof(uint8_t); @@ -405,37 +412,44 @@ public: channel_map(channels) {} }; + /** + * The type used to store the Country parameters option data. + */ struct country_params { - typedef std::vector container_type; // String identifier: 3 bytes static const size_t minimum_size = 3 + sizeof(uint8_t) * 3; std::string country; - container_type first_channel, number_channels, max_transmit_power; + byte_array first_channel, number_channels, max_transmit_power; country_params() {} - country_params(const std::string &country, const container_type &first, - const container_type &number, const container_type &max) + country_params(const std::string &country, const byte_array &first, + const byte_array &number, const byte_array &max) : country(country), first_channel(first), number_channels(number), max_transmit_power(max) {} }; + /** + * The type used to store the FH pattern option data. + */ struct fh_pattern_type { - typedef std::vector container_type; static const size_t minimum_size = sizeof(uint8_t) * 4; uint8_t flag, number_of_sets, modulus, offset; - container_type random_table; + byte_array random_table; fh_pattern_type() {} fh_pattern_type(uint8_t flag, uint8_t sets, uint8_t modulus, - uint8_t offset, const container_type& table) + uint8_t offset, const byte_array& table) : flag(flag), number_of_sets(sets), modulus(modulus), offset(offset), random_table(table) {} }; + /** + * The type used to store the Channel Switch option data. + */ struct channel_switch_type { uint8_t switch_mode, new_channel, switch_count; @@ -445,6 +459,9 @@ public: : switch_mode(mode), new_channel(channel), switch_count(count) { } }; + /** + * The type used to store the Quiet option data. + */ struct quiet_type { uint8_t quiet_count, quiet_period; uint16_t quiet_duration, quiet_offset; @@ -456,7 +473,10 @@ public: : quiet_count(count), quiet_period(period), quiet_duration(duration), quiet_offset(offset) {} }; - + + /** + * The type used to store the BSS Load option data. + */ struct bss_load_type { uint16_t station_count; uint16_t available_capacity; @@ -470,20 +490,37 @@ public: channel_utilization(utilization) {} }; + /** + * The type used to store the TIM option data. + */ struct tim_type { - typedef std::vector container_type; - uint8_t dtim_count, dtim_period, bitmap_control; - container_type partial_virtual_bitmap; + byte_array partial_virtual_bitmap; tim_type() {} tim_type(uint8_t count, uint8_t period, uint8_t control, - const container_type &bitmap) + const byte_array &bitmap) : dtim_count(count), dtim_period(period), bitmap_control(control), partial_virtual_bitmap(bitmap) {} }; + /** + * The type used to store the Vendor Specific option data. + */ + struct vendor_specific_type { + typedef HWAddress<3> oui_type; + + oui_type oui; + byte_array data; + + vendor_specific_type(const oui_type &oui = oui_type(), + const byte_array &data = byte_array()) + : oui(oui), data(data) { } + + static vendor_specific_type from_bytes(const uint8_t *buffer, uint32_t sz); + }; + /** * \brief Getter for the second address. * @@ -527,7 +564,7 @@ public: /** * \brief Getter for the fourth address. * - * \return address_type containing the fourth address. + * \return The stored fourth address. */ const address_type &addr4() const { return _addr4; } @@ -640,7 +677,7 @@ public: * * \param fh_params the fh parameter set. */ - void fh_parameter_set(fh_params_set fh_params); + void fh_parameter_set(const fh_params_set &fh_params); /** * \brief Helper method to set the DS parameter. @@ -654,7 +691,7 @@ public: * * \param params the CF parammeters to be set. */ - void cf_parameter_set(cf_params_set params); + void cf_parameter_set(const cf_params_set ¶ms); /** * \brief Helper method to set the IBSS parameter. @@ -748,6 +785,13 @@ public: * \brief text The challenge text to be added. */ void challenge_text(const std::string &text); + + /** + * \brief Helper method to add a Vendor Specific tagged option. + * + * \brief text The option to be added. + */ + void vendor_specific(const vendor_specific_type &data); // Option searching helpers @@ -851,6 +895,17 @@ public: * \return uint8_t containing the ds parameter set. */ uint8_t ds_parameter_set() const; + + /** + * \brief Helper method to get the cf parameter set. + * + * An option_not_found exception is thrown if the option has not + * been set. + * + * \return uint8_t containing the cf parameter set. + */ + cf_params_set cf_parameter_set() const; + /** * \brief Helper method to get the ibss parameter set. @@ -982,6 +1037,16 @@ public: */ std::string challenge_text() const; + /** + * \brief Helper method to get a Vendor Specific option. + * + * An option_not_found exception is thrown if the option has not + * been set. + * + * \return vendor_specific_type containing the option value. + */ + vendor_specific_type vendor_specific() const; + // ************************ /** diff --git a/include/exceptions.h b/include/exceptions.h index e0d8466..99873cf 100644 --- a/include/exceptions.h +++ b/include/exceptions.h @@ -135,6 +135,16 @@ public: return "The sniffed link layer PDU type is unknown"; } }; + +/** + * \brief Exception thrown when a malformed option is found. + */ +class malformed_option : public std::exception { +public: + const char *what() const throw() { + return "Malformed option"; + } +}; } #endif // TINS_EXCEPTIONS_H diff --git a/src/dot11/dot11_base.cpp b/src/dot11/dot11_base.cpp index c779120..18347ce 100644 --- a/src/dot11/dot11_base.cpp +++ b/src/dot11/dot11_base.cpp @@ -96,7 +96,7 @@ void Dot11::parse_tagged_parameters(const uint8_t *buffer, uint32_t total_sz) { void Dot11::add_tagged_option(OptionTypes opt, uint8_t len, const uint8_t *val) { uint32_t opt_size = len + sizeof(uint8_t) * 2; - _options.push_back(option((uint8_t)opt, len, val)); + _options.push_back(option((uint8_t)opt, val, val + len)); _options_size += opt_size; } diff --git a/src/dot11/dot11_control.cpp b/src/dot11/dot11_control.cpp index 7c8be54..1faa8a4 100644 --- a/src/dot11/dot11_control.cpp +++ b/src/dot11/dot11_control.cpp @@ -58,7 +58,7 @@ Dot11ControlTA::Dot11ControlTA(const uint8_t *buffer, uint32_t total_sz) : Dot11 buffer += sizeof(ieee80211_header); total_sz -= sizeof(ieee80211_header); if(total_sz < sizeof(_taddr)) - throw std::runtime_error("Not enough size for an IEEE 802.11 RTS frame in the buffer."); + throw malformed_packet(); //std::memcpy(_taddr, buffer, sizeof(_taddr)); _taddr = buffer; } @@ -166,7 +166,7 @@ Dot11BlockAckRequest::Dot11BlockAckRequest(const uint8_t *buffer, uint32_t total buffer += padding; total_sz -= padding; if(total_sz < sizeof(_bar_control) + sizeof(_start_sequence)) - throw std::runtime_error("Not enough size for an IEEE 802.11 Block Ack frame in the buffer."); + throw malformed_packet(); std::memcpy(&_bar_control, buffer, sizeof(_bar_control)); buffer += sizeof(_bar_control); std::memcpy(&_start_sequence, buffer, sizeof(_start_sequence)); @@ -230,7 +230,7 @@ Dot11BlockAck::Dot11BlockAck(const uint8_t *buffer, uint32_t total_sz) : Dot11Co buffer += padding; total_sz -= padding; if(total_sz < sizeof(_bitmap) + sizeof(_bar_control) + sizeof(_start_sequence)) - throw std::runtime_error("Not enough size for an IEEE 802.11 Block Ack frame in the buffer."); + throw malformed_packet(); std::memcpy(&_bar_control, buffer, sizeof(_bar_control)); buffer += sizeof(_bar_control); std::memcpy(&_start_sequence, buffer, sizeof(_start_sequence)); diff --git a/src/dot11/dot11_mgmt.cpp b/src/dot11/dot11_mgmt.cpp index e77df84..8f64279 100644 --- a/src/dot11/dot11_mgmt.cpp +++ b/src/dot11/dot11_mgmt.cpp @@ -189,12 +189,13 @@ void Dot11ManagementFrame::request_information(const request_info_type elements) delete[] buffer; } -void Dot11ManagementFrame::fh_parameter_set(fh_params_set fh_params) { - fh_params.dwell_time = Endian::host_to_le(fh_params.dwell_time); - fh_params.hop_set = fh_params.hop_set; - fh_params.hop_pattern = fh_params.hop_pattern; - fh_params.hop_index = fh_params.hop_index; - add_tagged_option(FH_SET, sizeof(fh_params_set), (uint8_t*)&fh_params); +void Dot11ManagementFrame::fh_parameter_set(const fh_params_set &fh_params) { + uint8_t data[5]; + *(uint16_t*)data = Endian::host_to_le(fh_params.dwell_time); + data[2] = fh_params.hop_set; + data[3] = fh_params.hop_pattern; + data[4] = fh_params.hop_index; + add_tagged_option(FH_SET, sizeof(data), data); } @@ -202,12 +203,17 @@ void Dot11ManagementFrame::ds_parameter_set(uint8_t current_channel) { add_tagged_option(DS_SET, 1, ¤t_channel); } -void Dot11ManagementFrame::cf_parameter_set(cf_params_set params) { - params.cfp_count = params.cfp_count; +void Dot11ManagementFrame::cf_parameter_set(const cf_params_set ¶ms) { + uint8_t data[6]; + data[0] = params.cfp_count; + data[1] = params.cfp_period; + *(uint16_t*)&data[2] = Endian::host_to_le(params.cfp_max_duration); + *(uint16_t*)&data[4] = Endian::host_to_le(params.cfp_dur_remaining); + /*params.cfp_count = params.cfp_count; params.cfp_period = params.cfp_period; params.cfp_max_duration = Endian::host_to_le(params.cfp_max_duration); - params.cfp_dur_remaining = Endian::host_to_le(params.cfp_dur_remaining); - add_tagged_option(CF_SET, sizeof(params), (uint8_t*)¶ms); + params.cfp_dur_remaining = Endian::host_to_le(params.cfp_dur_remaining);*/ + add_tagged_option(CF_SET, sizeof(data), data); } void Dot11ManagementFrame::ibss_parameter_set(uint16_t atim_window) { @@ -266,7 +272,7 @@ void Dot11ManagementFrame::fh_pattern_table(const fh_pattern_type ¶ms) { *(ptr++) = params.number_of_sets; *(ptr++) = params.modulus; *(ptr++) = params.offset; - fh_pattern_type::container_type::const_iterator it(params.random_table.begin()); + byte_array::const_iterator it(params.random_table.begin()); for(; it != params.random_table.end(); ++it) *(ptr++) = *it; add_tagged_option(HOPPING_PATTERN_TABLE, data.size(), &data[0]); @@ -355,6 +361,16 @@ void Dot11ManagementFrame::challenge_text(const std::string &text) { ); } +void Dot11ManagementFrame::vendor_specific(const vendor_specific_type &data) { + byte_array buffer(3 + data.data.size()); + std::copy( + data.data.begin(), + data.data.end(), + data.oui.copy(buffer.begin()) + ); + add_tagged_option(VENDOR_SPECIFIC, buffer.size(), &buffer[0]); +} + // Getters RSNInformation Dot11ManagementFrame::rsn_information() { @@ -428,13 +444,13 @@ Dot11ManagementFrame::request_info_type Dot11ManagementFrame::request_informatio Dot11ManagementFrame::fh_params_set Dot11ManagementFrame::fh_parameter_set() const { const Dot11::option *option = search_option(FH_SET); - if(!option || option->data_size() != sizeof(fh_params_set)) + if(!option || option->data_size() != 5) throw option_not_found(); - fh_params_set output = *reinterpret_cast(option->data_ptr()); - output.dwell_time = Endian::le_to_host(output.dwell_time); - output.hop_set = output.hop_set; - output.hop_pattern = output.hop_pattern; - output.hop_index = output.hop_index; + fh_params_set output; + output.dwell_time = Endian::le_to_host(*(uint16_t*)option->data_ptr()); + output.hop_set = option->data_ptr()[2]; + output.hop_pattern = option->data_ptr()[3]; + output.hop_index = option->data_ptr()[4]; return output; } @@ -445,6 +461,18 @@ uint8_t Dot11ManagementFrame::ds_parameter_set() const { return *option->data_ptr(); } +Dot11ManagementFrame::cf_params_set Dot11ManagementFrame::cf_parameter_set() const { + const Dot11::option *option = search_option(CF_SET); + if(!option || option->data_size() != 6) + throw option_not_found(); + cf_params_set output; + output.cfp_count = *option->data_ptr(); + output.cfp_period = option->data_ptr()[1]; + output.cfp_max_duration = Endian::le_to_host(*(uint16_t*)&option->data_ptr()[2]); + output.cfp_dur_remaining = Endian::le_to_host(*(uint16_t*)&option->data_ptr()[4]); + return output; +} + uint16_t Dot11ManagementFrame::ibss_parameter_set() const { const Dot11::option *option = search_option(IBSS_SET); if(!option || option->data_size() != sizeof(uint16_t)) @@ -598,4 +626,22 @@ std::string Dot11ManagementFrame::challenge_text() const { return std::string(option->data_ptr(), option->data_ptr() + option->data_size()); } +Dot11ManagementFrame::vendor_specific_type Dot11ManagementFrame::vendor_specific() const { + const Dot11::option *option = search_option(VENDOR_SPECIFIC); + if(!option || option->data_size() < 3) + throw option_not_found(); + return vendor_specific_type::from_bytes(option->data_ptr(), option->data_size()); +} + +Dot11ManagementFrame::vendor_specific_type + Dot11ManagementFrame::vendor_specific_type::from_bytes(const uint8_t *buffer, uint32_t sz) +{ + if(sz < 3) + throw malformed_option(); + return vendor_specific_type( + buffer, + byte_array(buffer + 3, buffer + sz) + ); +} + } // namespace Tins \ No newline at end of file diff --git a/src/dot1q.cpp b/src/dot1q.cpp index 2eb44f0..b4e7f91 100644 --- a/src/dot1q.cpp +++ b/src/dot1q.cpp @@ -111,7 +111,9 @@ void Dot1Q::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) } std::memcpy(buffer, &_header, sizeof(_header)); - buffer += sizeof(_header) + inner_pdu()->size(); + buffer += sizeof(_header); + if(inner_pdu()) + buffer += inner_pdu()->size(); std::fill(buffer, buffer + trailer, 0); } diff --git a/src/ppi.cpp b/src/ppi.cpp index 766d658..52a989f 100644 --- a/src/ppi.cpp +++ b/src/ppi.cpp @@ -47,7 +47,7 @@ PPI::PPI(const uint8_t *buffer, uint32_t total_sz) { if(total_sz < sizeof(_header)) throw malformed_packet(); std::memcpy(&_header, buffer, sizeof(_header)); - if(length() > total_sz) + if(length() > total_sz || length() < sizeof(_header)) throw malformed_packet(); buffer += sizeof(_header); total_sz -= sizeof(_header); diff --git a/src/radiotap.cpp b/src/radiotap.cpp index 2a8868c..cc53f63 100644 --- a/src/radiotap.cpp +++ b/src/radiotap.cpp @@ -72,7 +72,7 @@ RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) check_size(total_sz, sizeof(_radio)); const uint8_t *buffer_start = buffer; std::memcpy(&_radio, buffer, sizeof(_radio)); - uint32_t radiotap_hdr_size = Endian::le_to_host(_radio.it_len); + uint32_t radiotap_hdr_size = length(); check_size(total_sz, radiotap_hdr_size); buffer += sizeof(_radio); radiotap_hdr_size -= sizeof(_radio); @@ -132,14 +132,14 @@ RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) read_field(buffer, radiotap_hdr_size, _max_power); } - total_sz -= Endian::le_to_host(_radio.it_len); + total_sz -= length(); buffer += radiotap_hdr_size; if(_radio.flags && (flags() & FCS) != 0) { check_size(total_sz, sizeof(uint32_t)); total_sz -= sizeof(uint32_t); if((flags() & FAILED_FCS) !=0) - throw malformed_packet(); + throw malformed_packet(); } if(total_sz) diff --git a/tests/src/dot11/beacon.cpp b/tests/src/dot11/beacon.cpp index 2750ce6..5c5fd27 100644 --- a/tests/src/dot11/beacon.cpp +++ b/tests/src/dot11/beacon.cpp @@ -210,6 +210,17 @@ TEST_F(Dot11BeaconTest, DSParameterSet) { EXPECT_EQ(dot11.ds_parameter_set(), 0x1e); } +TEST_F(Dot11BeaconTest, CFParameterSet) { + Dot11Beacon dot11; + Dot11Beacon::cf_params_set params(67, 42, 0x482f, 0x9af1), output; + dot11.cf_parameter_set(params); + output = dot11.cf_parameter_set(); + EXPECT_EQ(output.cfp_count, params.cfp_count); + EXPECT_EQ(output.cfp_period, params.cfp_period); + EXPECT_EQ(output.cfp_max_duration, params.cfp_max_duration); + EXPECT_EQ(output.cfp_dur_remaining, params.cfp_dur_remaining); +} + TEST_F(Dot11BeaconTest, IBSSParameterSet) { Dot11Beacon dot11; dot11.ibss_parameter_set(0x1ef3); @@ -364,6 +375,17 @@ TEST_F(Dot11BeaconTest, ChallengeText) { EXPECT_EQ(dot11.challenge_text(), "libtins ftw"); } +TEST_F(Dot11BeaconTest, VendorSpecific) { + Dot11Beacon dot11; + Dot11Beacon::vendor_specific_type input("03:03:02"), output; + input.data.push_back(0x22); + input.data.push_back(0x35); + dot11.vendor_specific(input); + output = dot11.vendor_specific(); + EXPECT_EQ(input.oui, output.oui); + EXPECT_EQ(input.data, output.data); +} + TEST_F(Dot11BeaconTest, RSNInformationTest) { Dot11Beacon dot11; RSNInformation rsn_info, found; @@ -394,13 +416,13 @@ TEST_F(Dot11BeaconTest, PCAPLoad1) { 221, 24, 0, 80, 242, 2, 1, 1, 3, 0, 3, 164, 0, 0, 39, 164, 0, 0, 66, 67, 94, 0, 98, 50, 47, 0, 221, 9, 0, 3, 127, 1, 1, 0, 0, 255, 127 }; - typedef Dot11Beacon::country_params::container_type country_container; + typedef byte_array country_container; Dot11Beacon dot11(buffer, sizeof(buffer)); float rates[] = { 1.0f, 2.0f, 5.5f, 11.0f, 6.0f, 9.0f, 12.0f, 18.0f}, ext_rates[] = { 24.0f, 36.0f, 48.0f, 54.0f }; Dot11Beacon::rates_type rates_parsed = dot11.supported_rates(); Dot11Beacon::rates_type ext_rates_parsed = dot11.extended_supported_rates(); - Dot11Beacon::tim_type tim(0, 1, 0, Dot11Beacon::tim_type::container_type(1)), + Dot11Beacon::tim_type tim(0, 1, 0, byte_array(1)), tim_parsed = dot11.tim(); Dot11Beacon::country_params country("US ", country_container(1, 1),