From 9cd0e40600a773f90b8e3715443fbb84a270cb22 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Thu, 23 Aug 2012 00:20:22 -0300 Subject: [PATCH] Finished Dot11 taged option getters/unit tests. Added Dot11Disassoc tests. --- include/dot11.h | 342 +++++++++++++++++++++++------------ src/dot11.cpp | 212 ++++++++++++++-------- tests/include/tests/dot11.h | 59 +++++- tests/src/dot11/beacon.cpp | 121 ++++++++++--- tests/src/dot11/disassoc.cpp | 78 ++++++++ tests/src/dot11/dot11.cpp | 2 +- 6 files changed, 594 insertions(+), 220 deletions(-) create mode 100644 tests/src/dot11/disassoc.cpp diff --git a/include/dot11.h b/include/dot11.h index ac4e7e5..d052dba 100644 --- a/include/dot11.h +++ b/include/dot11.h @@ -223,91 +223,91 @@ namespace Tins { * * \return The protocol version in an uint8_t. */ - uint8_t protocol() const { return this->_header.control.protocol; } + uint8_t protocol() const { return _header.control.protocol; } /** * \brief Getter for the 802.11 frame's type. * * \return The type of the 802.11 frame in an uint8_t. */ - uint8_t type() const { return this->_header.control.type; } + uint8_t type() const { return _header.control.type; } /** * \brief Getter for the 802.11 frame's subtype. * * \return The subtype of the 802.11 frame in an uint8_t. */ - uint8_t subtype() const { return this->_header.control.subtype; } + uint8_t subtype() const { return _header.control.subtype; } /** * \brief Getter for the 802.11 frame's "To DS" bit. * * \return Boolean indicating if the "To DS" bit is set. */ - bool to_ds() const { return this->_header.control.to_ds; } + bool to_ds() const { return _header.control.to_ds; } /** * \brief Getter for the 802.11 frame's "From DS" bit. * * \return Boolean indicating if the "From DS" bit is set. */ - bool from_ds() const { return this->_header.control.from_ds; } + bool from_ds() const { return _header.control.from_ds; } /** * \brief Getter for the 802.11 frame's "More Frag" bit. * * \return Boolean indicating if the "More Frag" bit is set. */ - bool more_frag() const { return this->_header.control.more_frag; } + bool more_frag() const { return _header.control.more_frag; } /** * \brief Getter for the 802.11 frame's "Retry" bit. * * \return Boolean indicating if the "Retry" bit is set. */ - bool retry() const { return this->_header.control.retry; } + bool retry() const { return _header.control.retry; } /** * \brief Getter for the 802.11 frame's "Power Management" bit. * * \return Boolean indicating if the "Power Management" bit is set. */ - bool power_mgmt() const { return this->_header.control.power_mgmt; } + bool power_mgmt() const { return _header.control.power_mgmt; } /** * \brief Getter for the 802.11 frame's "WEP" bit. * * \return Boolean indicating if the "WEP" bit is set. */ - bool wep() const { return this->_header.control.wep; } + bool wep() const { return _header.control.wep; } /** * \brief Getter for the 802.11 frame's "Order" bit. * * \return Boolean indicating if the "Order" bit is set. */ - bool order() const { return this->_header.control.order; } + bool order() const { return _header.control.order; } /** * \brief Getter for the duration/id field. * * \return The value of the duration/id field in an uint16_t. */ - uint16_t duration_id() const { return Utils::le_to_host(this->_header.duration_id); } + uint16_t duration_id() const { return Utils::le_to_host(_header.duration_id); } /** * \brief Getter for the first address. * * \return The first address as a constant uint8_t pointer. */ - address_type addr1() const { return this->_header.addr1; } + address_type addr1() const { return _header.addr1; } /** * \brief Getter for the interface. * * \return The interface's index as an uint32_t. */ - const NetworkInterface &iface() const { return this->_iface; } + const NetworkInterface &iface() const { return _iface; } /** * \brief Setter for the protocol version. @@ -718,224 +718,224 @@ namespace Tins { * * \return Bool indicating the flag's value. */ - bool ess() const { return this->_ess; } + bool ess() const { return _ess; } /** * \brief Getter for the ibss flag. * * \return Bool indicating the flag's value. */ - bool ibss() const { return this->_ibss; } + bool ibss() const { return _ibss; } /** * \brief Getter for the cf_poll flag. * * \return Bool indicating the flag's value. */ - bool cf_poll() const { return this->_cf_poll; } + bool cf_poll() const { return _cf_poll; } /** * \brief Getter for the cf_poll_req flag. * * \return Bool indicating the flag's value. */ - bool cf_poll_req() const { return this->_cf_poll_req; } + bool cf_poll_req() const { return _cf_poll_req; } /** * \brief Getter for the privacy flag. * * \return Bool indicating the flag's value. */ - bool privacy() const { return this->_privacy; } + bool privacy() const { return _privacy; } /** * \brief Getter for the short_preamble flag. * * \return Bool indicating the flag's value. */ - bool short_preamble() const { return this->_short_preamble; } + bool short_preamble() const { return _short_preamble; } /** * \brief Getter for the pbcc flag. * * \return Bool indicating the flag's value. */ - bool pbcc() const { return this->_pbcc; } + bool pbcc() const { return _pbcc; } /** * \brief Getter for the channel_agility flag. * * \return Bool indicating the flag's value. */ - bool channel_agility() const { return this->_channel_agility; } + bool channel_agility() const { return _channel_agility; } /** * \brief Getter for the spectrum_mgmt flag. * * \return Bool indicating the flag's value. */ - bool spectrum_mgmt() const { return this->_spectrum_mgmt; } + bool spectrum_mgmt() const { return _spectrum_mgmt; } /** * \brief Getter for the qos flag. * * \return Bool indicating the flag's value. */ - bool qos() const { return this->_qos; } + bool qos() const { return _qos; } /** * \brief Getter for the sst flag. * * \return Bool indicating the flag's value. */ - bool sst() const { return this->_sst; } + bool sst() const { return _sst; } /** * \brief Getter for the apsd flag. * * \return Bool indicating the flag's value. */ - bool apsd() const { return this->_apsd; } + bool apsd() const { return _apsd; } /** * \brief Getter for the reserved flag. * * \return Bool indicating the flag's value. */ - bool reserved() const { return this->_reserved; } + bool reserved() const { return _reserved; } /** * \brief Getter for the dsss_ofdm flag. * * \return Bool indicating the flag's value. */ - bool dsss_ofdm() const { return this->_dsss_ofdm; } + bool dsss_ofdm() const { return _dsss_ofdm; } /** * \brief Getter for the delayed_block_ack flag. * * \return Bool indicating the flag's value. */ - bool delayed_block_ack() const { return this->_delayed_block_ack; } + bool delayed_block_ack() const { return _delayed_block_ack; } /** * \brief Getter for the immediate_block_ack flag. * * \return Bool indicating the flag's value. */ - bool immediate_block_ack() const { return this->_immediate_block_ack; } + bool immediate_block_ack() const { return _immediate_block_ack; } /** * \brief Setter for the ess flag. * * \param new_value bool indicating the flag's new value. */ - void ess(bool new_value) { this->_ess = new_value; } + void ess(bool new_value) { _ess = new_value; } /** * \brief Setter for the ibss flag. * * \param new_value bool indicating the flag's new value. */ - void ibss(bool new_value) { this->_ibss = new_value; } + void ibss(bool new_value) { _ibss = new_value; } /** * \brief Setter for the cf_poll flag. * * \param new_value bool indicating the flag's new value. */ - void cf_poll(bool new_value) { this->_cf_poll = new_value; } + void cf_poll(bool new_value) { _cf_poll = new_value; } /** * \brief Setter for the cf_poll_req flag. * * \param new_value bool indicating the flag's new value. */ - void cf_poll_req(bool new_value) { this->_cf_poll_req = new_value; } + void cf_poll_req(bool new_value) { _cf_poll_req = new_value; } /** * \brief Setter for the privacy flag. * * \param new_value bool indicating the flag's new value. */ - void privacy(bool new_value) { this->_privacy = new_value; } + void privacy(bool new_value) { _privacy = new_value; } /** * \brief Setter for the short_preamble flag. * * \param new_value bool indicating the flag's new value. */ - void short_preamble(bool new_value) { this->_short_preamble = new_value; } + void short_preamble(bool new_value) { _short_preamble = new_value; } /** * \brief Setter for the pbcc flag. * * \param new_value bool indicating the flag's new value. */ - void pbcc(bool new_value) { this->_pbcc = new_value; } + void pbcc(bool new_value) { _pbcc = new_value; } /** * \brief Setter for the channel_agility flag. * * \param new_value bool indicating the flag's new value. */ - void channel_agility(bool new_value) { this->_channel_agility = new_value; } + void channel_agility(bool new_value) { _channel_agility = new_value; } /** * \brief Setter for the spectrum_mgmt flag. * * \param new_value bool indicating the flag's new value. */ - void spectrum_mgmt(bool new_value) { this->_spectrum_mgmt = new_value; } + void spectrum_mgmt(bool new_value) { _spectrum_mgmt = new_value; } /** * \brief Setter for the qos flag. * * \param new_value bool indicating the flag's new value. */ - void qos(bool new_value) { this->_qos = new_value; } + void qos(bool new_value) { _qos = new_value; } /** * \brief Setter for the sst flag. * * \param new_value bool indicating the flag's new value. */ - void sst(bool new_value) { this->_sst = new_value; } + void sst(bool new_value) { _sst = new_value; } /** * \brief Setter for the apsd flag. * * \param new_value bool indicating the flag's new value. */ - void apsd(bool new_value) { this->_apsd = new_value; } + void apsd(bool new_value) { _apsd = new_value; } /** * \brief Setter for the reserved flag. * * \param new_value bool indicating the flag's new value. */ - void reserved(bool new_value) { this->_reserved = new_value; } + void reserved(bool new_value) { _reserved = new_value; } /** * \brief Setter for the dsss_ofdm flag. * * \param new_value bool indicating the flag's new value. */ - void dsss_ofdm(bool new_value) { this->_dsss_ofdm = new_value; } + void dsss_ofdm(bool new_value) { _dsss_ofdm = new_value; } /** * \brief Setter for the delayed_block_ack flag. * * \param new_value bool indicating the flag's new value. */ - void delayed_block_ack(bool new_value) { this->_delayed_block_ack = new_value; } + void delayed_block_ack(bool new_value) { _delayed_block_ack = new_value; } /** * \brief Setter for the immediate_block_ack flag. * * \param new_value bool indicating the flag's new value. */ - void immediate_block_ack(bool new_value) { this->_immediate_block_ack = new_value; } + void immediate_block_ack(bool new_value) { _immediate_block_ack = new_value; } } __attribute__((__packed__)); @@ -1005,9 +1005,57 @@ namespace Tins { fh_pattern_type() {} fh_pattern_type(uint8_t flag, uint8_t sets, uint8_t modulus, - uint8_t offset, const container_type& table) : flag(flag), - number_of_sets(sets), modulus(modulus), offset(offset), - random_table(table) {} + uint8_t offset, const container_type& table) + : flag(flag), number_of_sets(sets), modulus(modulus), + offset(offset), random_table(table) {} + }; + + struct channel_switch_type { + uint8_t switch_mode, new_channel, switch_count; + + channel_switch_type() {} + + channel_switch_type(uint8_t mode, uint8_t channel, uint8_t count) + : switch_mode(mode), new_channel(channel), switch_count(count) { } + }; + + struct quiet_type { + uint8_t quiet_count, quiet_period; + uint16_t quiet_duration, quiet_offset; + + quiet_type() {} + + quiet_type(uint8_t count, uint8_t period, uint16_t duration, + uint16_t offset) + : quiet_count(count), quiet_period(period), + quiet_duration(duration), quiet_offset(offset) {} + }; + + struct bss_load_type { + uint16_t station_count; + uint16_t available_capacity; + uint8_t channel_utilization; + + bss_load_type() {} + + bss_load_type(uint16_t count, uint8_t utilization, + uint16_t capacity) + : station_count(count), available_capacity(capacity), + channel_utilization(utilization) {} + }; + + struct tim_type { + typedef std::vector container_type; + + uint8_t dtim_count, dtim_period, bitmap_control; + container_type partial_virtual_bitmap; + + tim_type() {} + + tim_type(uint8_t count, uint8_t period, uint8_t control, + const container_type &bitmap) + : dtim_count(count), dtim_period(period), bitmap_control(control), + partial_virtual_bitmap(bitmap) {} }; /** @@ -1015,21 +1063,21 @@ namespace Tins { * * \return The second address as a constant uint8_t pointer. */ - address_type addr2() const { return this->_ext_header.addr2; } + address_type addr2() const { return _ext_header.addr2; } /** * \brief Getter for the third address. * * \return The third address as a constant uint8_t pointer. */ - address_type addr3() const { return this->_ext_header.addr3; } + address_type addr3() const { return _ext_header.addr3; } /** * \brief Getter for the fragment number. * * \return The fragment number as an uint8_t. */ - uint8_t frag_num() const { return this->_ext_header.seq_control.frag_number; } + uint8_t frag_num() const { return _ext_header.seq_control.frag_number; } /** * \brief Getter for the sequence number. @@ -1043,7 +1091,7 @@ namespace Tins { * * \return The fourth address as a constant uint8_t pointer. */ - const address_type &addr4() const { return this->_addr4; } + const address_type &addr4() const { return _addr4; } /** * \brief Setter for the second address. @@ -1209,28 +1257,23 @@ namespace Tins { /** * \brief Helper method to set the Power Constraint tagged option. * - * \param local_power_constraint uint8_t with the value of the local power constraint field. + * \param local_power_constraint The value of the local power constraint field. */ void power_constraint(uint8_t local_power_constraint); /** * \brief Helper method to set the Channel Switch tagged option. * - * \param switch_mode uint8_t with the value of the switch mode field. - * \param new_channel uint8_t with the value of the new channel field. - * \param switch_count uint8_t with the value of the switch count field. + * \param data The value of the Channel Switch option. */ - void channel_switch(uint8_t switch_mode, uint8_t new_channel, uint8_t switch_count); + void channel_switch(const channel_switch_type &data); /** * \brief Helper method to set the Quiet tagged option. * - * \param quiet_count uint8_t with the value of the quiet count field. - * \param quiet_period uint8_t with the value of the quiet period field. - * \param quiet_duration uint16_t with the value of the quiet duration field. - * \param quiet_offset uint16_t with the value of the quiet offset field. + * \param data The value of the quiet count field. */ - void quiet(uint8_t quiet_count, uint8_t quiet_period, uint16_t quiet_duration, uint16_t quiet_offset); + void quiet(const quiet_type &data); /** * \brief Helper method to set the TPC Report tagged option. @@ -1243,37 +1286,30 @@ namespace Tins { /** * \brief Helper method to set the ERP Information tagged option. * - * \param value with the value to set as argument of the tagged option. + * \param value The value to set in this erp information option. */ void erp_information(uint8_t value); /** * \brief Helper method to set the BSS Load tagged option. * - * \param station_count uint16_t with the value of the station count field. - * \param channel_utilization uint8_t with the value of the channel utilization field. - * \param available_capacity uint16_t with the value of the available capacity field. + * \param data The value to set in this bss load option. */ - void bss_load(uint16_t station_count, uint8_t channel_utilization, uint16_t avaliable_capacity); + void bss_load(const bss_load_type &data); /** * \brief Helper method to set the TIM tagged option. * - * \brief dtim_count uint8_t with the value of the DTIM count field. - * \brief dtim_period uint8_t with the value of the DTIM period field. - * \brief bitmap_control uint8_t with the value of the Bitmap Control field. - * \brief partial_virtual_bitmap uint8_t array with the value fo the Partial Virtual Bitmap field. - * \brief partial_virtual_bitmap_sz uint8_t with the size of the partial_virtual_bitmap array. + * \brief data The value to set in this tim option. */ - void tim(uint8_t dtim_count, uint8_t dtim_period, uint8_t bitmap_control, uint8_t* partial_virtual_bitmap, uint8_t partial_virtual_bitmap_sz); + void tim(const tim_type &data); /** * \brief Helper method to set the Challenge Text tagged option. * - * \brief ch_text uint8_t array with the challenge_text. - * \brief ch_text_sz uint8_t with the ch_text's length. + * \brief text The challenge text to be added. */ - void challenge_text(uint8_t* ch_text, uint8_t ch_text_sz); + void challenge_text(const std::string &text); // Option searching helpers @@ -1399,7 +1435,7 @@ namespace Tins { * * Throws a std::runtime_error if the option has not been set. * - * \return ibss_dfs_params containing the fh parameters. + * \return std::pair containing the fh parameters. */ std::pair fh_parameters() const; @@ -1408,10 +1444,82 @@ namespace Tins { * * Throws a std::runtime_error if the option has not been set. * - * \return ibss_dfs_params containing the fh patterns. + * \return fh_pattern_type containing the fh patterns. */ fh_pattern_type fh_pattern_table() const; + /** + * \brief Helper method to get the power constraint option. + * + * Throws a std::runtime_error if the option has not been set. + * + * \return uint8_t containing the power constraint. + */ + uint8_t power_constraint() const; + + /** + * \brief Helper method to get the channel switch option. + * + * Throws a std::runtime_error if the option has not been set. + * + * \return channel_switch_type containing the channel switch. + */ + channel_switch_type channel_switch() const; + + /** + * \brief Helper method to get the quiet option. + * + * Throws a std::runtime_error if the option has not been set. + * + * \return quiet_type containing the quiet option value. + */ + quiet_type quiet() const; + + /** + * \brief Helper method to get the tpc report option. + * + * Throws a std::runtime_error if the option has not been set. + * + * \return quiet_type containing the tpc report option value. + */ + std::pair tpc_report() const; + + /** + * \brief Helper method to get the erp information option. + * + * Throws a std::runtime_error if the option has not been set. + * + * \return quiet_type containing the erp information option value. + */ + uint8_t erp_information() const; + + /** + * \brief Helper method to get the bss load option. + * + * Throws a std::runtime_error if the option has not been set. + * + * \return quiet_type containing the bss load option value. + */ + bss_load_type bss_load() const; + + /** + * \brief Helper method to get the tim option. + * + * Throws a std::runtime_error if the option has not been set. + * + * \return tim_type containing the tim option value. + */ + tim_type tim() const; + + /** + * \brief Helper method to get the challenge text option. + * + * Throws a std::runtime_error if the option has not been set. + * + * \return std::string containing the challenge text option value. + */ + std::string challenge_text() const; + // ************************ /** @@ -1521,28 +1629,28 @@ namespace Tins { * * \return Timestamp value in an uint64_t. */ - uint64_t timestamp() const { return Utils::le_to_host(this->_body.timestamp); } + uint64_t timestamp() const { return Utils::le_to_host(_body.timestamp); } /** * \brief Getter for the interval field. * * \return Timestamp value in an uint16_t. */ - uint16_t interval() const { return Utils::le_to_host(this->_body.interval); } + uint16_t interval() const { return Utils::le_to_host(_body.interval); } /** * \brief Getter for the Capabilities Information structure. * * \return const CapabilityInformation&. */ - const CapabilityInformation& capabilities() const { return this->_body.capability; } + const CapabilityInformation& capabilities() const { return _body.capability; } /** * \brief Getter for the Capabilities Information. * * \return CapabilityInformation&. */ - CapabilityInformation& capabilities() { return this->_body.capability; } + CapabilityInformation& capabilities() { return _body.capability; } /** * \brief Setter for the timestamp field. @@ -1580,7 +1688,7 @@ namespace Tins { * * \sa PDU::clone_pdu */ - PDU *clone_pdu() const { + Dot11Beacon *clone_pdu() const { return PDU::do_clone_pdu(); } @@ -1640,7 +1748,7 @@ namespace Tins { * * \return uint16_t with the reason code. */ - uint16_t reason_code() const { return this->_body.reason_code; } + uint16_t reason_code() const { return Utils::le_to_host(_body.reason_code); } /** * \brief Setter for the reason code. @@ -1669,7 +1777,7 @@ namespace Tins { * \sa PDU::matches_flag */ bool matches_flag(PDUType flag) { - return flag == PDU::DOT11_DIASSOC || Dot11ManagementFrame::matches_flag(flag); + return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag); } /** @@ -1677,7 +1785,9 @@ namespace Tins { * * \sa PDU::clone_pdu */ - PDU *clone_pdu() const; + Dot11Disassoc *clone_pdu() const { + return PDU::do_clone_pdu(); + } private: struct DisassocBody { uint16_t reason_code; @@ -1727,21 +1837,21 @@ namespace Tins { * * \return CapabilityInformation Structure in a CapabilityInformation&. */ - const CapabilityInformation& capabilities() const { return this->_body.capability;} + const CapabilityInformation& capabilities() const { return _body.capability;} /** * \brief Getter for the Capabilities Information. * * \return CapabilityInformation Structure in a CapabilityInformation&. */ - CapabilityInformation& capabilities() { return this->_body.capability;} + CapabilityInformation& capabilities() { return _body.capability;} /** * \brief Getter for the listen interval. * * \return The listen interval in an uint16_t. */ - uint16_t listen_interval() const { return this->_body.listen_interval; } + uint16_t listen_interval() const { return _body.listen_interval; } /** * \brief Setter for the listen interval. @@ -1770,7 +1880,7 @@ namespace Tins { * \sa PDU::matches_flag */ bool matches_flag(PDUType flag) { - return flag == PDU::DOT11_ASSOC_REQ || Dot11ManagementFrame::matches_flag(flag); + return flag == pdu_flag || Dot11ManagementFrame::matches_flag(flag); } /** @@ -1829,28 +1939,28 @@ namespace Tins { * * \return CapabilityInformation Structure in a CapabilityInformation&. */ - const CapabilityInformation& capabilities() const { return this->_body.capability;} + const CapabilityInformation& capabilities() const { return _body.capability;} /** * \brief Getter for the Capabilities Information. * * \return CapabilityInformation Structure in a CapabilityInformation&. */ - CapabilityInformation& capabilities() { return this->_body.capability;} + CapabilityInformation& capabilities() { return _body.capability;} /** * \brief Getter for the status code. * * \return The status code in an uint16_t. */ - uint16_t status_code() const { return this->_body.status_code; } + uint16_t status_code() const { return _body.status_code; } /** * \brief Getter for the AID field. * * \return The AID field value in an uint16_t. */ - uint16_t aid() const { return this->_body.aid; } + uint16_t aid() const { return _body.aid; } /** * \brief Setter for the status code. @@ -1946,28 +2056,28 @@ namespace Tins { * * \return CapabilityInformation Structure in a CapabilityInformation&. */ - const CapabilityInformation& capabilities() const { return this->_body.capability;} + const CapabilityInformation& capabilities() const { return _body.capability;} /** * \brief Getter for the Capabilities Information. * * \return CapabilityInformation Structure in a CapabilityInformation&. */ - CapabilityInformation& capabilities() { return this->_body.capability;} + CapabilityInformation& capabilities() { return _body.capability;} /** * \brief Getter for the listen interval. * * \return The listen interval in an uint16_t. */ - uint16_t listen_interval() const { return this->_body.listen_interval; } + uint16_t listen_interval() const { return _body.listen_interval; } /** * \brief Getter for the current ap field. * * \return The current ap in an array of 6 uint8_t. */ - const uint8_t* current_ap() const { return this->_body.current_ap; } + const uint8_t* current_ap() const { return _body.current_ap; } /** * \brief Setter for the listen interval. @@ -2063,28 +2173,28 @@ namespace Tins { * * \return CapabilityInformation Structure in a CapabilityInformation&. */ - const CapabilityInformation& capabilities() const { return this->_body.capability;} + const CapabilityInformation& capabilities() const { return _body.capability;} /** * \brief Getter for the Capabilities Information. * * \return CapabilityInformation Structure in a CapabilityInformation&. */ - CapabilityInformation& capabilities() { return this->_body.capability;} + CapabilityInformation& capabilities() { return _body.capability;} /** * \brief Getter for the status code. * * \return The status code in an uint16_t. */ - uint16_t status_code() const { return this->_body.status_code; } + uint16_t status_code() const { return _body.status_code; } /** * \brief Getter for the AID field. * * \return The AID field value in an uint16_t. */ - uint16_t aid() const { return this->_body.aid; } + uint16_t aid() const { return _body.aid; } /** * \brief Setter for the status code. @@ -2180,21 +2290,21 @@ namespace Tins { * * \return The authentication algorithm number in an uint16_t. */ - uint16_t auth_algorithm() const {return this->_body.auth_algorithm; } + uint16_t auth_algorithm() const {return _body.auth_algorithm; } /** * \brief Getter for the Authetication Sequence Number. * * \return The authentication sequence number in an uint16_t. */ - uint16_t auth_seq_number() const {return this->_body.auth_seq_number; } + uint16_t auth_seq_number() const {return _body.auth_seq_number; } /** * \brief Getter for the status code. * * \return The status code in an uint16_t. */ - uint16_t status_code() const { return this->_body.status_code; } + uint16_t status_code() const { return _body.status_code; } /** * \brief Setter for the Authetication Algorithm Number. @@ -2298,7 +2408,7 @@ namespace Tins { * * \return uint16_t with the reason code. */ - uint16_t reason_code() const { return this->_body.reason_code; } + uint16_t reason_code() const { return _body.reason_code; } /** * \brief Setter for the reason code. @@ -2443,28 +2553,28 @@ namespace Tins { * * \return Timestamp value in an uint64_t. */ - uint64_t timestamp() const { return this->_body.timestamp; } + uint64_t timestamp() const { return _body.timestamp; } /** * \brief Getter for the interval field. * * \return Timestamp value in an uint16_t. */ - uint16_t interval() const { return this->_body.interval; } + uint16_t interval() const { return _body.interval; } /** * \brief Getter for the Capabilities Information. * * \return CapabilityInformation Structure in a CapabilityInformation&. */ - const CapabilityInformation& capabilities() const { return this->_body.capability;} + const CapabilityInformation& capabilities() const { return _body.capability;} /** * \brief Getter for the Capabilities Information. * * \return CapabilityInformation Structure in a CapabilityInformation&. */ - CapabilityInformation& capabilities() { return this->_body.capability;} + CapabilityInformation& capabilities() { return _body.capability;} /** * \brief Setter for the timestamp field. @@ -2548,35 +2658,35 @@ namespace Tins { * * \return The second address as a constant uint8_t pointer. */ - address_type addr2() const { return this->_ext_header.addr2; } + address_type addr2() const { return _ext_header.addr2; } /** * \brief Getter for the third address. * * \return The third address as a constant uint8_t pointer. */ - address_type addr3() const { return this->_ext_header.addr3; } + address_type addr3() const { return _ext_header.addr3; } /** * \brief Getter for the fragment number. * * \return The fragment number as an uint8_t. */ - uint8_t frag_num() const { return this->_ext_header.seq_control.frag_number; } + uint8_t frag_num() const { return _ext_header.seq_control.frag_number; } /** * \brief Getter for the sequence number. * * \return The sequence number as an uint16_t. */ - uint16_t seq_num() const { return this->_ext_header.seq_control.seq_number; } + uint16_t seq_num() const { return _ext_header.seq_control.seq_number; } /** * \brief Getter for the fourth address. * * \return The fourth address as a constant uint8_t pointer. */ - const uint8_t* addr4() const { return this->_addr4; } + const uint8_t* addr4() const { return _addr4; } /** * \brief Setter for the second address. @@ -2712,7 +2822,7 @@ namespace Tins { * * \return The value of the qos_control field in an uint16_t. */ - uint16_t qos_control() const { return this->_qos_control; } + uint16_t qos_control() const { return _qos_control; } /** * \brief Setter for the qos_control field. diff --git a/src/dot11.cpp b/src/dot11.cpp index dd94c6e..317283e 100644 --- a/src/dot11.cpp +++ b/src/dot11.cpp @@ -201,7 +201,6 @@ void Dot11::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *p for(std::list::const_iterator it = _options.begin(); it != _options.end(); ++it) { *(buffer++) = it->option(); *(buffer++) = it->data_size(); - //std::memcpy(buffer, it->value, it->length); std::copy(it->data_ptr(), it->data_ptr() + it->data_size(), buffer); buffer += it->data_size(); } @@ -213,10 +212,12 @@ PDU *Dot11::from_bytes(const uint8_t *buffer, uint32_t total_sz) { throw runtime_error("Not enough size for a IEEE 802.11 header in the buffer."); const ieee80211_header *hdr = (const ieee80211_header*)buffer; PDU *ret = 0; - if(hdr->control.type == MANAGEMENT && hdr->control.subtype == 8) { - if(total_sz < sizeof(_header)) - throw runtime_error("Not enough size for an IEEE 802.11 header in the buffer."); - ret = new Dot11Beacon(buffer, total_sz); + if(hdr->control.type == MANAGEMENT) { + if(hdr->control.subtype == BEACON) + ret = new Dot11Beacon(buffer, total_sz); + //else if(hdr->control.subtype == DISASSOC) + else + ret = new Dot11Disassoc(buffer, total_sz); } else if(hdr->control.type == DATA){ if(hdr->control.subtype <= 4) @@ -413,9 +414,9 @@ void Dot11ManagementFrame::request_information(const request_info_type elements) void Dot11ManagementFrame::fh_parameter_set(fh_params_set fh_params) { fh_params.dwell_time = Utils::host_to_le(fh_params.dwell_time); - fh_params.hop_set = Utils::host_to_le(fh_params.hop_set); - fh_params.hop_pattern = Utils::host_to_le(fh_params.hop_pattern); - fh_params.hop_index = Utils::host_to_le(fh_params.hop_index); + 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); } @@ -425,8 +426,8 @@ void Dot11ManagementFrame::ds_parameter_set(uint8_t current_channel) { } void Dot11ManagementFrame::cf_parameter_set(cf_params_set params) { - params.cfp_count = Utils::host_to_le(params.cfp_count); - params.cfp_period = Utils::host_to_le(params.cfp_period); + params.cfp_count = params.cfp_count; + params.cfp_period = params.cfp_period; params.cfp_max_duration = Utils::host_to_le(params.cfp_max_duration); params.cfp_dur_remaining = Utils::host_to_le(params.cfp_dur_remaining); add_tagged_option(CF_SET, sizeof(params), (uint8_t*)¶ms); @@ -452,7 +453,6 @@ void Dot11ManagementFrame::ibss_dfs(const ibss_dfs_params ¶ms) { add_tagged_option(IBSS_DFS, sz, buffer); delete[] buffer; - } void Dot11ManagementFrame::country(const country_params ¶ms) { @@ -483,17 +483,6 @@ void Dot11ManagementFrame::fh_parameters(uint8_t prime_radix, uint8_t number_cha } void Dot11ManagementFrame::fh_pattern_table(const fh_pattern_type ¶ms) { - /*uint8_t sz = 4 + random_table.size(); - uint8_t* buffer = new uint8_t[sz]; - buffer[0] = flag; - buffer[1] = number_of_sets; - buffer[2] = modulus; - buffer[3] = offset; - uint8_t* ptr_buffer = &buffer[4]; - for (vector::const_iterator it = random_table.begin(); it != random_table.end(); it++) - *(ptr_buffer++) = *it; - add_tagged_option(HOPPING_PATTERN_TABLE, sz, buffer); - delete[] buffer;*/ std::vector data(sizeof(uint8_t) * 4 + params.random_table.size()); uint8_t *ptr = &data[0]; *(ptr++) = params.flag; @@ -510,24 +499,24 @@ void Dot11ManagementFrame::power_constraint(uint8_t local_power_constraint) { add_tagged_option(POWER_CONSTRAINT, 1, &local_power_constraint); } -void Dot11ManagementFrame::channel_switch(uint8_t switch_mode, uint8_t new_channel, uint8_t switch_count) { +void Dot11ManagementFrame::channel_switch(const channel_switch_type &data) { uint8_t buffer[3]; - buffer[0] = switch_mode; - buffer[1] = new_channel; - buffer[2] = switch_count; + buffer[0] = data.switch_mode; + buffer[1] = data.new_channel; + buffer[2] = data.switch_count; add_tagged_option(CHANNEL_SWITCH, 3, buffer); } -void Dot11ManagementFrame::quiet(uint8_t quiet_count, uint8_t quiet_period, uint16_t quiet_duration, uint16_t quiet_offset) { +void Dot11ManagementFrame::quiet(const quiet_type &data) { uint8_t buffer[6]; - uint16_t* ptr_buffer = (uint16_t*)buffer; + uint16_t* ptr_buffer = (uint16_t*)(buffer + 2); - buffer[0] = quiet_count; - buffer[1] = quiet_period; - ptr_buffer[1] = quiet_duration; - ptr_buffer[2] = quiet_offset; - add_tagged_option(QUIET, 6, buffer); + buffer[0] = data.quiet_count; + buffer[1] = data.quiet_period; + ptr_buffer[0] = Utils::host_to_le(data.quiet_duration); + ptr_buffer[1] = Utils::host_to_le(data.quiet_offset); + add_tagged_option(QUIET, sizeof(buffer), buffer); } @@ -543,36 +532,38 @@ void Dot11ManagementFrame::erp_information(uint8_t value) { add_tagged_option(ERP_INFORMATION, 1, &value); } -void Dot11ManagementFrame::bss_load(uint16_t station_count, uint8_t channel_utilization, uint16_t available_capacity) { +void Dot11ManagementFrame::bss_load(const bss_load_type &data) { uint8_t buffer[5]; - buffer[0] = station_count & 0xFF; - buffer[1] = station_count >> 8; - buffer[2] = channel_utilization; - buffer[3] = available_capacity & 0xFF; - buffer[4] = available_capacity >> 8; - add_tagged_option(BSS_LOAD, 5, buffer); + *(uint16_t*)buffer = Utils::host_to_le(data.station_count); + buffer[2] = data.channel_utilization; + *(uint16_t*)(buffer + 3) = Utils::host_to_le(data.available_capacity); + add_tagged_option(BSS_LOAD, sizeof(buffer), buffer); } -void Dot11ManagementFrame::tim(uint8_t dtim_count, - uint8_t dtim_period, - uint8_t bitmap_control, - uint8_t* partial_virtual_bitmap, - uint8_t partial_virtual_bitmap_sz) { - - uint8_t sz = 3 + partial_virtual_bitmap_sz; - uint8_t* buffer = new uint8_t[sz]; - buffer[0] = dtim_count; - buffer[1] = dtim_period; - buffer[2] = bitmap_control; - memcpy(buffer + 3, partial_virtual_bitmap, partial_virtual_bitmap_sz); - add_tagged_option(TIM, sz, buffer); +void Dot11ManagementFrame::tim(const tim_type &data) { + std::vector buffer(sizeof(uint8_t) * 3 + data.partial_virtual_bitmap.size()); + buffer[0] = data.dtim_count; + buffer[1] = data.dtim_period; + buffer[2] = data.bitmap_control; + std::copy( + data.partial_virtual_bitmap.begin(), + data.partial_virtual_bitmap.end(), + &buffer[3] + ); + add_tagged_option(TIM, buffer.size(), &buffer[0]); } -void Dot11ManagementFrame::challenge_text(uint8_t* ch_text, uint8_t ch_text_sz) { - add_tagged_option(CHALLENGE_TEXT, ch_text_sz, ch_text); +void Dot11ManagementFrame::challenge_text(const std::string &text) { + add_tagged_option( + CHALLENGE_TEXT, + text.size(), + (const uint8_t*)text.c_str() + ); } +// Getters + bool Dot11ManagementFrame::rsn_information(RSNInformation *rsn) { const Dot11::Dot11Option *option = search_option(RSN); if(!option || option->data_size() < (sizeof(uint16_t) << 1) + sizeof(uint32_t)) @@ -616,21 +607,21 @@ bool Dot11ManagementFrame::rsn_information(RSNInformation *rsn) { string Dot11ManagementFrame::ssid() const { const Dot11::Dot11Option *option = search_option(SSID); - if(!option) + if(!option || option->data_size() == 0) throw std::runtime_error("SSID not set"); return string((const char*)option->data_ptr(), option->data_size()); } Dot11ManagementFrame::rates_type Dot11ManagementFrame::supported_rates() const { const Dot11::Dot11Option *option = search_option(SUPPORTED_RATES); - if(!option) + if(!option || option->data_size() == 0) throw std::runtime_error("Supported rates not set"); return deserialize_rates(option); } Dot11ManagementFrame::rates_type Dot11ManagementFrame::extended_supported_rates() const { const Dot11::Dot11Option *option = search_option(EXT_SUPPORTED_RATES); - if(!option) + if(!option || option->data_size() == 0) throw std::runtime_error("Extended supported rates not set"); return deserialize_rates(option); } @@ -665,12 +656,10 @@ Dot11ManagementFrame::channels_type Dot11ManagementFrame::supported_channels() c Dot11ManagementFrame::request_info_type Dot11ManagementFrame::request_information() const { const Dot11::Dot11Option *option = search_option(REQUEST_INFORMATION); - if(!option) + if(!option || option->data_size() == 0) throw std::runtime_error("Request information not set"); request_info_type output; const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size(); - //while(ptr != end) - // output.push_back(*(ptr++)); output.assign(ptr, end); return output; } @@ -681,9 +670,9 @@ Dot11ManagementFrame::fh_params_set Dot11ManagementFrame::fh_parameter_set() con throw std::runtime_error("FH parameters set not set"); fh_params_set output = *reinterpret_cast(option->data_ptr()); output.dwell_time = Utils::le_to_host(output.dwell_time); - output.hop_set = Utils::le_to_host(output.hop_set); - output.hop_pattern = Utils::le_to_host(output.hop_pattern); - output.hop_index = Utils::le_to_host(output.hop_index); + output.hop_set = output.hop_set; + output.hop_pattern = output.hop_pattern; + output.hop_index = output.hop_index; return output; } @@ -762,6 +751,91 @@ Dot11ManagementFrame::fh_pattern_type Dot11ManagementFrame::fh_pattern_table() c return output; } +uint8_t Dot11ManagementFrame::power_constraint() const { + const Dot11::Dot11Option *option = search_option(POWER_CONSTRAINT); + if(!option || option->data_size() != 1) + throw std::runtime_error("Power constraint option not set"); + return *option->data_ptr(); +} + +Dot11ManagementFrame::channel_switch_type Dot11ManagementFrame::channel_switch() const { + const Dot11::Dot11Option *option = search_option(CHANNEL_SWITCH); + if(!option || option->data_size() != sizeof(uint8_t) * 3) + throw std::runtime_error("Channel switch option not set"); + const uint8_t *ptr = option->data_ptr(); + channel_switch_type output; + output.switch_mode = *(ptr++); + output.new_channel = *(ptr++); + output.switch_count = *(ptr++); + return output; +} + +Dot11ManagementFrame::quiet_type Dot11ManagementFrame::quiet() const { + const Dot11::Dot11Option *option = search_option(QUIET); + if(!option || option->data_size() != (sizeof(uint8_t) * 2 + sizeof(uint16_t) * 2)) + throw std::runtime_error("Quiet option not set"); + const uint8_t *ptr = option->data_ptr(); + quiet_type output; + + output.quiet_count = *(ptr++); + output.quiet_period = *(ptr++); + const uint16_t *ptr_16 = (const uint16_t*)ptr; + output.quiet_duration = Utils::le_to_host(*(ptr_16++)); + output.quiet_offset = Utils::le_to_host(*ptr_16); + return output; +} + +std::pair Dot11ManagementFrame::tpc_report() const { + const Dot11::Dot11Option *option = search_option(TPC_REPORT); + if(!option || option->data_size() != sizeof(uint8_t) * 2) + throw std::runtime_error("TPC Report option not set"); + const uint8_t *ptr = option->data_ptr(); + uint8_t first = *(ptr++); + return std::make_pair(first, *ptr); +} + +uint8_t Dot11ManagementFrame::erp_information() const { + const Dot11::Dot11Option *option = search_option(ERP_INFORMATION); + if(!option || option->data_size() != sizeof(uint8_t)) + throw std::runtime_error("ERP Information option not set"); + return *option->data_ptr(); +} + +Dot11ManagementFrame::bss_load_type Dot11ManagementFrame::bss_load() const { + const Dot11::Dot11Option *option = search_option(BSS_LOAD); + if(!option || option->data_size() != sizeof(uint8_t) + 2 * sizeof(uint16_t)) + throw std::runtime_error("BSS Load option not set"); + bss_load_type output; + + const uint8_t *ptr = option->data_ptr(); + output.station_count = Utils::le_to_host(*(uint16_t*)ptr); + output.channel_utilization = ptr[2]; + output.available_capacity = Utils::le_to_host(*(uint16_t*)(ptr + 3)); + return output; +} + +Dot11ManagementFrame::tim_type Dot11ManagementFrame::tim() const { + const Dot11::Dot11Option *option = search_option(TIM); + if(!option || option->data_size() < 4 * sizeof(uint8_t)) + throw std::runtime_error("TIM option not set"); + const uint8_t *ptr = option->data_ptr(), *end = ptr + option->data_size(); + tim_type output; + + output.dtim_count = *(ptr++); + output.dtim_period = *(ptr++); + output.bitmap_control = *(ptr++); + + output.partial_virtual_bitmap.assign(ptr, end); + return output; +} + +std::string Dot11ManagementFrame::challenge_text() const { + const Dot11::Dot11Option *option = search_option(CHALLENGE_TEXT); + if(!option || option->data_size() == 0) + throw std::runtime_error("Challenge text option not set"); + return std::string(option->data_ptr(), option->data_ptr() + option->data_size()); +} + /* Dot11Beacon */ Dot11Beacon::Dot11Beacon(const NetworkInterface& iface, @@ -828,7 +902,7 @@ Dot11Disassoc::Dot11Disassoc(const uint8_t *buffer, uint32_t total_sz) } void Dot11Disassoc::reason_code(uint16_t new_reason_code) { - this->_body.reason_code = new_reason_code; + this->_body.reason_code = Utils::host_to_le(new_reason_code); } uint32_t Dot11Disassoc::header_size() const { @@ -842,14 +916,6 @@ uint32_t Dot11Disassoc::write_fixed_parameters(uint8_t *buffer, uint32_t total_s return sz; } -PDU *Dot11Disassoc::clone_pdu() const { - Dot11Disassoc *new_pdu = new Dot11Disassoc(); - new_pdu->copy_80211_fields(this); - new_pdu->copy_ext_header(this); - memcpy(&new_pdu->_body, &this->_body, sizeof(this->_body)); - return new_pdu; -} - /* Assoc request. */ Dot11AssocRequest::Dot11AssocRequest(const NetworkInterface& iface, diff --git a/tests/include/tests/dot11.h b/tests/include/tests/dot11.h index 4e400ef..3cb63ed 100644 --- a/tests/include/tests/dot11.h +++ b/tests/include/tests/dot11.h @@ -3,7 +3,10 @@ #include "dot11.h" -inline void test_equals(const Tins::Dot11 &dot1, const Tins::Dot11 &dot2) { +using Tins::Dot11; +using Tins::Dot11ManagementFrame; + +inline void test_equals(const Dot11 &dot1, const Dot11 &dot2) { EXPECT_EQ(dot1.protocol(), dot2.protocol()); EXPECT_EQ(dot1.type(), dot2.type()); EXPECT_EQ(dot1.subtype(), dot2.subtype()); @@ -18,4 +21,58 @@ inline void test_equals(const Tins::Dot11 &dot1, const Tins::Dot11 &dot2) { EXPECT_EQ(dot1.addr1(), dot2.addr1()); } +inline void test_equals(const Dot11ManagementFrame& b1, const Dot11ManagementFrame& b2) { + EXPECT_EQ(b1.addr2(), b2.addr2()); + EXPECT_EQ(b1.addr3(), b2.addr3()); + EXPECT_EQ(b1.addr4(), b2.addr4()); + EXPECT_EQ(b1.frag_num(), b2.frag_num()); + EXPECT_EQ(b1.seq_num(), b2.seq_num()); + + test_equals(static_cast(b1), static_cast(b2)); +} + +inline void test_equals_expected(const Dot11ManagementFrame &dot11) { + EXPECT_EQ(dot11.protocol(), 1); + EXPECT_EQ(dot11.type(), Dot11::MANAGEMENT); + EXPECT_EQ(dot11.to_ds(), 1); + EXPECT_EQ(dot11.from_ds(), 0); + EXPECT_EQ(dot11.more_frag(), 0); + EXPECT_EQ(dot11.retry(), 0); + EXPECT_EQ(dot11.power_mgmt(), 0); + EXPECT_EQ(dot11.wep(), 0); + EXPECT_EQ(dot11.order(), 0); + EXPECT_EQ(dot11.duration_id(), 0x234f); + EXPECT_EQ(dot11.addr1(), "00:01:02:03:04:05"); + EXPECT_EQ(dot11.addr2(), "01:02:03:04:05:06"); + EXPECT_EQ(dot11.addr3(), "02:03:04:05:06:07"); +} + +inline void test_equals_empty(const Dot11 &dot11) { + Dot11::address_type empty_addr; + + EXPECT_EQ(dot11.protocol(), 0); + EXPECT_EQ(dot11.to_ds(), 0); + EXPECT_EQ(dot11.from_ds(), 0); + EXPECT_EQ(dot11.more_frag(), 0); + EXPECT_EQ(dot11.retry(), 0); + EXPECT_EQ(dot11.power_mgmt(), 0); + EXPECT_EQ(dot11.wep(), 0); + EXPECT_EQ(dot11.order(), 0); + EXPECT_EQ(dot11.duration_id(), 0); + EXPECT_EQ(dot11.addr1(), empty_addr); +} + +inline void test_equals_empty(const Dot11ManagementFrame &dot11) { + Dot11::address_type empty_addr; + + EXPECT_EQ(dot11.type(), Dot11::MANAGEMENT); + EXPECT_EQ(dot11.addr2(), empty_addr); + EXPECT_EQ(dot11.addr3(), empty_addr); + EXPECT_EQ(dot11.addr4(), empty_addr); + EXPECT_EQ(dot11.frag_num(), 0); + EXPECT_EQ(dot11.seq_num(), 0); + + test_equals_empty(static_cast(dot11)); +} + #endif // TINS_DOT11_TEST diff --git a/tests/src/dot11/beacon.cpp b/tests/src/dot11/beacon.cpp index 2522b78..7e0ef87 100644 --- a/tests/src/dot11/beacon.cpp +++ b/tests/src/dot11/beacon.cpp @@ -16,7 +16,6 @@ class Dot11BeaconTest : public testing::Test { public: static const address_type empty_addr, hwaddr; static const uint8_t expected_packet[]; - static void test_equals_expected(const Dot11Beacon&dot11); }; const address_type Dot11BeaconTest::empty_addr, @@ -30,22 +29,8 @@ const uint8_t Dot11BeaconTest::expected_packet[] = { '\x95', ' ' }; -void Dot11BeaconTest::test_equals_expected(const Dot11Beacon &dot11) { - EXPECT_EQ(dot11.protocol(), 1); - EXPECT_EQ(dot11.type(), Dot11::MANAGEMENT); +void test_equals_expected(const Dot11Beacon &dot11) { EXPECT_EQ(dot11.subtype(), 8); - EXPECT_EQ(dot11.to_ds(), 1); - EXPECT_EQ(dot11.from_ds(), 0); - EXPECT_EQ(dot11.more_frag(), 0); - EXPECT_EQ(dot11.retry(), 0); - EXPECT_EQ(dot11.power_mgmt(), 0); - EXPECT_EQ(dot11.wep(), 0); - EXPECT_EQ(dot11.order(), 0); - EXPECT_EQ(dot11.duration_id(), 0x234f); - EXPECT_EQ(dot11.addr1(), "00:01:02:03:04:05"); - EXPECT_EQ(dot11.addr2(), "01:02:03:04:05:06"); - EXPECT_EQ(dot11.addr3(), "02:03:04:05:06:07"); - EXPECT_EQ(dot11.timestamp(), 0x1fad2341289301faLL); EXPECT_EQ(dot11.interval(), 0x14fa); @@ -66,19 +51,16 @@ void Dot11BeaconTest::test_equals_expected(const Dot11Beacon &dot11) { EXPECT_EQ(info.dsss_ofdm(), 1); EXPECT_EQ(info.delayed_block_ack(), 0); EXPECT_EQ(info.immediate_block_ack(), 0); + + ::test_equals_expected(static_cast(dot11)); } void test_equals(const Dot11Beacon& b1, const Dot11Beacon& b2) { - EXPECT_EQ(b1.addr2(), b2.addr2()); - EXPECT_EQ(b1.addr3(), b2.addr3()); - EXPECT_EQ(b1.addr4(), b2.addr4()); - EXPECT_EQ(b1.frag_num(), b2.frag_num()); - EXPECT_EQ(b1.seq_num(), b2.seq_num()); EXPECT_EQ(b1.interval(), b2.interval()); EXPECT_EQ(b1.timestamp(), b2.timestamp()); - const Dot11Beacon::CapabilityInformation& info1 = b1.capabilities(), - info2 = b2.capabilities(); + const Dot11Beacon::CapabilityInformation &info1 = b1.capabilities(), + &info2 = b2.capabilities(); EXPECT_EQ(info1.ess(), info2.ess()); EXPECT_EQ(info1.ibss(), info2.ibss()); EXPECT_EQ(info1.cf_poll(), info2.cf_poll()); @@ -96,16 +78,15 @@ void test_equals(const Dot11Beacon& b1, const Dot11Beacon& b2) { EXPECT_EQ(info1.delayed_block_ack(), info2.delayed_block_ack()); EXPECT_EQ(info1.immediate_block_ack(), info2.immediate_block_ack()); - test_equals(static_cast(b1), static_cast(b2)); + test_equals( + static_cast(b1), + static_cast(b2) + ); } TEST_F(Dot11BeaconTest, DefaultConstructor) { Dot11Beacon dot11; - EXPECT_EQ(dot11.addr2(), empty_addr); - EXPECT_EQ(dot11.addr3(), empty_addr); - EXPECT_EQ(dot11.addr4(), empty_addr); - EXPECT_EQ(dot11.frag_num(), 0); - EXPECT_EQ(dot11.seq_num(), 0); + test_equals_empty(static_cast(dot11)); const Dot11Beacon::CapabilityInformation& info = dot11.capabilities(); EXPECT_EQ(info.ess(), 0); @@ -127,6 +108,7 @@ TEST_F(Dot11BeaconTest, DefaultConstructor) { EXPECT_EQ(dot11.interval(), 0); EXPECT_EQ(dot11.timestamp(), 0); + EXPECT_EQ(dot11.subtype(), Dot11::BEACON); } // beacon_interval=0x14fa, timestamp=0x1fad2341289301fa, cap="ESS+CFP+privacy+DSSS-OFDM" @@ -326,3 +308,84 @@ TEST_F(Dot11BeaconTest, FHPattern) { EXPECT_EQ(data.offset, data.offset); EXPECT_EQ(data.random_table, data.random_table); } + +TEST_F(Dot11BeaconTest, PowerConstraint) { + Dot11Beacon dot11; + dot11.power_constraint(0x1e); + EXPECT_EQ(dot11.power_constraint(), 0x1e); +} + +TEST_F(Dot11BeaconTest, ChannelSwitch) { + Dot11Beacon dot11; + Dot11Beacon::channel_switch_type data(13, 42, 98), output; + dot11.channel_switch(data); + + output = dot11.channel_switch(); + EXPECT_EQ(output.switch_mode, data.switch_mode); + EXPECT_EQ(output.new_channel, data.new_channel); + EXPECT_EQ(output.switch_count, data.switch_count); +} + + +TEST_F(Dot11BeaconTest, Quiet) { + Dot11Beacon dot11; + Dot11Beacon::quiet_type data(13, 42, 0x928f, 0xf1ad), output; + dot11.quiet(data); + + output = dot11.quiet(); + EXPECT_EQ(output.quiet_count, data.quiet_count); + EXPECT_EQ(output.quiet_period, data.quiet_period); + EXPECT_EQ(output.quiet_duration, data.quiet_duration); + EXPECT_EQ(output.quiet_offset, data.quiet_offset); +} + +TEST_F(Dot11BeaconTest, TPCReport) { + Dot11Beacon dot11; + std::pair data(42, 193); + dot11.tpc_report(data.first, data.second); + EXPECT_EQ(dot11.tpc_report(), data); +} + +TEST_F(Dot11BeaconTest, ERPInformation) { + Dot11Beacon dot11; + dot11.erp_information(0x1e); + EXPECT_EQ(dot11.erp_information(), 0x1e); +} + +TEST_F(Dot11BeaconTest, BSSLoad) { + Dot11Beacon dot11; + Dot11Beacon::bss_load_type data(0x129f, 42, 0xf5a2), output; + dot11.bss_load(data); + output = dot11.bss_load(); + + EXPECT_EQ(data.station_count, output.station_count); + EXPECT_EQ(data.channel_utilization, output.channel_utilization); + EXPECT_EQ(data.available_capacity, output.available_capacity); +} + +TEST_F(Dot11BeaconTest, TIM) { + Dot11Beacon dot11; + Dot11Beacon::tim_type data, output; + data.dtim_count = 42; + data.dtim_period = 59; + data.bitmap_control = 191; + + data.partial_virtual_bitmap.push_back(92); + data.partial_virtual_bitmap.push_back(182); + data.partial_virtual_bitmap.push_back(212); + + dot11.tim(data); + output = dot11.tim(); + + EXPECT_EQ(data.dtim_count, output.dtim_count); + EXPECT_EQ(data.dtim_period, output.dtim_period); + EXPECT_EQ(data.bitmap_control, output.bitmap_control); + EXPECT_EQ(data.partial_virtual_bitmap, output.partial_virtual_bitmap); +} + +TEST_F(Dot11BeaconTest, ChallengeText) { + Dot11Beacon dot11; + dot11.challenge_text("libtins ftw"); + EXPECT_EQ(dot11.challenge_text(), "libtins ftw"); +} + diff --git a/tests/src/dot11/disassoc.cpp b/tests/src/dot11/disassoc.cpp new file mode 100644 index 0000000..4b7789e --- /dev/null +++ b/tests/src/dot11/disassoc.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include "dot11.h" +#include "tests/dot11.h" + + +using namespace std; +using namespace Tins; + +typedef Dot11::address_type address_type; + +class Dot11DisassocTest : public testing::Test { +public: + static const address_type empty_addr, hwaddr; + static const uint8_t expected_packet[]; + //static void test_equals_expected(const Dot11Beacon&dot11); +}; + +const uint8_t Dot11DisassocTest::expected_packet[] = { + '\xa1', '\x01', 'O', '#', '\x00', '\x01', '\x02', '\x03', '\x04', + '\x05', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x02', + '\x03', '\x04', '\x05', '\x06', '\x07', '\x00', '\x00', '\x12', '#' +}; + +void test_equals(const Dot11Disassoc &dot1, const Dot11Disassoc &dot2) { + EXPECT_EQ(dot1.reason_code(), dot2.reason_code()); + test_equals( + static_cast(dot1), + static_cast(dot2) + ); +} + +void test_equals_expected(const Dot11Disassoc &dot11) { + test_equals_expected(static_cast(dot11)); + EXPECT_EQ(dot11.reason_code(), 0x2312); + EXPECT_EQ(dot11.subtype(), Dot11::DISASSOC); +} + +TEST_F(Dot11DisassocTest, Constructor) { + Dot11Disassoc dot11; + test_equals_empty(static_cast(dot11)); + EXPECT_EQ(dot11.reason_code(), 0); +} + +TEST_F(Dot11DisassocTest, ConstructorFromBuffer) { + Dot11Disassoc dot11(expected_packet, sizeof(expected_packet)); + test_equals_expected(dot11); +} + +TEST_F(Dot11DisassocTest, CopyConstructor) { + Dot11Disassoc dot1(expected_packet, sizeof(expected_packet)); + Dot11Disassoc dot2(dot1); + test_equals(dot1, dot2); +} + +TEST_F(Dot11DisassocTest, CopyAssignmentOperator) { + Dot11Disassoc dot1(expected_packet, sizeof(expected_packet)); + Dot11Disassoc dot2; + dot2 = dot1; + test_equals(dot1, dot2); +} + +TEST_F(Dot11DisassocTest, ClonePDU) { + Dot11Disassoc dot1(expected_packet, sizeof(expected_packet)); + std::auto_ptr dot2(dot1.clone_pdu()); + test_equals(dot1, *dot2); +} + +TEST_F(Dot11DisassocTest, FromBytes) { + std::auto_ptr dot11(Dot11::from_bytes(expected_packet, sizeof(expected_packet))); + ASSERT_TRUE(dot11.get()); + std::cout << (int)dot11->pdu_type() << std::endl; + const Dot11Disassoc *disassoc = dot11->find_inner_pdu(); + ASSERT_TRUE(disassoc); + test_equals_expected(*disassoc); +} diff --git a/tests/src/dot11/dot11.cpp b/tests/src/dot11/dot11.cpp index e856ed4..5b5a617 100644 --- a/tests/src/dot11/dot11.cpp +++ b/tests/src/dot11/dot11.cpp @@ -55,7 +55,7 @@ TEST_F(Dot11Test, CopyAssignmentOperator) { test_equals(dot1, dot2); } -//type="Control", subtype=3, proto=1, FCfield="to-DS", ID=0x234f, addr1="00:01:02:03:04:05") +// type="Control", subtype=3, proto=1, FCfield="to-DS", ID=0x234f, addr1="00:01:02:03:04:05" TEST_F(Dot11Test, ConstructorFromBuffer) { Dot11 dot11(expected_packet, sizeof(expected_packet)); EXPECT_EQ(dot11.protocol(), 1);