From 83646d60647c891bdf35a355dfbfb2011f99552c Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Thu, 8 Sep 2011 11:27:01 -0300 Subject: [PATCH] Added PDU::matches_flag override on Dot11 subclasses. --- include/dot11.h | 277 ++++++++++++++++++++++++++++++++++++++++++++++-- include/pdu.h | 5 +- src/dot11.cpp | 36 +++++-- 3 files changed, 296 insertions(+), 22 deletions(-) diff --git a/include/dot11.h b/include/dot11.h index be6888f..ef6d857 100644 --- a/include/dot11.h +++ b/include/dot11.h @@ -458,6 +458,15 @@ namespace Tins { */ PDUType pdu_type() const { return PDU::DOT11; } + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11; + } + /** * \brief Allocates an Dot11 PDU from a buffer. * \param buffer The buffer from which to take the PDU data. @@ -989,6 +998,22 @@ namespace Tins { * \sa PDU::header_size() */ uint32_t header_size() const; + + /** + * \brief Getter for the PDU's type. + * + * \sa PDU::pdu_type + */ + PDUType pdu_type() const { return PDU::DOT11_MANAGEMENT; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_MANAGEMENT || Dot11::matches_flag(flag); + } protected: struct ExtendedHeader { uint8_t addr2[6]; @@ -1369,6 +1394,15 @@ namespace Tins { * \sa PDU::header_size() */ uint32_t header_size() const; + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_BEACON || Dot11ManagementFrame::matches_flag(flag); + } /** * \brief Clones this PDU. @@ -1453,6 +1487,21 @@ namespace Tins { */ uint32_t header_size() const; + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ + PDUType pdu_type() const { return PDU::DOT11_DIASSOC; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_DIASSOC || Dot11ManagementFrame::matches_flag(flag); + } + /** * \brief Clones this PDU. * @@ -1592,6 +1641,21 @@ namespace Tins { */ uint32_t header_size() const; + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ + PDUType pdu_type() const { return PDU::DOT11_ASSOC_REQ; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_ASSOC_REQ || Dot11ManagementFrame::matches_flag(flag); + } + /** * \brief Clones this PDU. * @@ -1720,6 +1784,21 @@ namespace Tins { */ uint32_t header_size() const; + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ + PDUType pdu_type() const { return PDU::DOT11_ASSOC_RESP; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_ASSOC_RESP || Dot11ManagementFrame::matches_flag(flag); + } + /** * \brief Clones this PDU. * @@ -1803,6 +1882,21 @@ namespace Tins { */ void request_information(const std::list elements); + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ + PDUType pdu_type() const { return PDU::DOT11_PROBE_REQ; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_PROBE_REQ || Dot11ManagementFrame::matches_flag(flag); + } + /** * \brief Clones this PDU. * @@ -2066,6 +2160,20 @@ namespace Tins { */ PDU* clone_pdu() const; + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ + PDUType pdu_type() const { return PDU::DOT11_PROBE_RESP; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_PROBE_RESP || Dot11ManagementFrame::matches_flag(flag); + } protected: private: @@ -2175,6 +2283,15 @@ namespace Tins { */ PDUType pdu_type() const { return PDU::DOT11_DATA; } + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_DATA || Dot11::matches_flag(flag); + } + /** * \brief Clones this PDU. * @@ -2297,6 +2414,15 @@ namespace Tins { * \sa PDU::pdu_type */ PDUType pdu_type() const { return PDU::DOT11_QOS_DATA; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_QOS_DATA || Dot11Data::matches_flag(flag); + } private: void copy_fields(const Dot11QoSData *other); uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz); @@ -2357,6 +2483,15 @@ namespace Tins { * \sa PDU::pdu_type */ PDUType pdu_type() const { return PDU::DOT11_CONTROL; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_CONTROL || Dot11::matches_flag(flag); + } }; /** @@ -2499,6 +2634,15 @@ namespace Tins { * \sa PDU::pdu_type */ PDUType pdu_type() const { return PDU::DOT11_RTS; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_RTS || Dot11Control::matches_flag(flag); + } }; class Dot11PSPoll : public Dot11ControlTA { @@ -2554,6 +2698,21 @@ namespace Tins { * \sa PDU::clone_pdu */ PDU *clone_pdu() const; + + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ + PDUType pdu_type() const { return PDU::DOT11_PS_POLL; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_PS_POLL || Dot11Control::matches_flag(flag); + } }; class Dot11CFEnd : public Dot11ControlTA { @@ -2609,6 +2768,21 @@ namespace Tins { * \sa PDU::clone_pdu */ PDU *clone_pdu() const; + + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ + PDUType pdu_type() const { return PDU::DOT11_CF_END; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_CF_END || Dot11Control::matches_flag(flag); + } }; class Dot11EndCFAck : public Dot11ControlTA { @@ -2661,6 +2835,21 @@ namespace Tins { * \sa PDU::clone_pdu */ PDU *clone_pdu() const; + + /** + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type + */ + PDUType pdu_type() const { return PDU::DOT11_END_CF_ACK; } + + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_END_CF_ACK || Dot11Control::matches_flag(flag); + } }; class Dot11Ack : public Dot11Control { @@ -2707,6 +2896,13 @@ namespace Tins { * \param total_sz The total size of the buffer. */ Dot11Ack(const uint8_t *buffer, uint32_t total_sz); + + /** + * \brief Clones this PDU. + * + * \sa PDU::clone_pdu + */ + PDU *clone_pdu() const; /** * \brief Getter for the PDU's type. @@ -2715,12 +2911,13 @@ namespace Tins { PDUType pdu_type() const { return PDU::DOT11_ACK; } /** - * \brief Clones this PDU. - * - * \sa PDU::clone_pdu + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag */ - PDU *clone_pdu() const; - + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_ACK || Dot11Control::matches_flag(flag); + } }; /** @@ -2811,12 +3008,22 @@ namespace Tins { * \sa PDU::clone_pdu */ PDU *clone_pdu() const; - protected: + /** - * \brief Getter for the control ta additional fields size. + * \brief Getter for the PDU's type. + * \sa PDU::pdu_type */ - uint32_t blockack_request_size() const { return controlta_size() + sizeof(_bar_control) + sizeof(_start_sequence); } + PDUType pdu_type() const { return PDU::DOT11_BLOCK_ACK_REQ; } + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_BLOCK_ACK_REQ || Dot11Control::matches_flag(flag); + } + protected: uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz); private: struct BarControl { @@ -2838,7 +3045,7 @@ namespace Tins { /** * \brief Class that represents an 802.11 block ack frame. */ - class Dot11BlockAck : public Dot11BlockAckRequest { + class Dot11BlockAck : public Dot11ControlTA { public: /** * \brief Constructor for creating a 802.11 Block Ack frame PDU. @@ -2882,6 +3089,19 @@ namespace Tins { */ Dot11BlockAck(const uint8_t *buffer, uint32_t total_sz); + /* Getters */ + + /** + * \brief Getter for the bar control field. + * \return The bar control field. + */ + uint16_t bar_control() const { return _bar_control.tid; } + + /** + * \brief Getter for the start sequence field. + * \return The bar start sequence. + */ + uint16_t start_sequence() const { return (_start_sequence.frag << 12) | (_start_sequence.seq); } /** * \brief Returns the 802.11 frame's header length. * @@ -2890,6 +3110,20 @@ namespace Tins { */ uint32_t header_size() const; + /* Setters */ + + /** + * \brief Setter for the bar control field. + * \param bar The new bar control field. + */ + void bar_control(uint16_t bar); + + /** + * \brief Setter for the start sequence field. + * \param bar The new start sequence field. + */ + void start_sequence(uint16_t seq); + /** * \brief Getter for the bitmap field. * \return The bitmap field. @@ -2908,6 +3142,15 @@ namespace Tins { */ PDUType pdu_type() const { return PDU::DOT11_BLOCK_ACK; } + /** + * \brief Check wether this PDU matches the specified flag. + * \param flag The flag to match + * \sa PDU::matches_flag + */ + bool matches_flag(PDUType flag) { + return flag == PDU::DOT11_BLOCK_ACK || Dot11Control::matches_flag(flag); + } + /** * \brief Clones this PDU. * @@ -2915,8 +3158,22 @@ namespace Tins { */ PDU *clone_pdu() const; private: - uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz); + struct BarControl { + uint16_t reserved:12, + tid:4; + } __attribute__((__packed__)); + struct StartSequence { + uint16_t frag:4, + seq:12; + } __attribute__((__packed__)); + + void init_block_ack(); + uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz); + + + BarControl _bar_control; + StartSequence _start_sequence; uint8_t _bitmap[8]; }; }; diff --git a/include/pdu.h b/include/pdu.h index 77f7c10..ba716d0 100644 --- a/include/pdu.h +++ b/include/pdu.h @@ -59,12 +59,13 @@ namespace Tins { DOT11_ASSOC_RESP, DOT11_BEACON, DOT11_BLOCK_ACK, - DOT11_CFEND, + DOT11_BLOCK_ACK_REQ, + DOT11_CF_END, DOT11_DATA, DOT11_CONTROL, DOT11_DEAUTH, DOT11_DIASSOC, - DOT11_ENDCFACK, + DOT11_END_CF_ACK, DOT11_MANAGEMENT, DOT11_PROBE_REQ, DOT11_PROBE_RESP, diff --git a/src/dot11.cpp b/src/dot11.cpp index 3b0ad8f..c011f44 100644 --- a/src/dot11.cpp +++ b/src/dot11.cpp @@ -1472,7 +1472,7 @@ uint32_t Tins::Dot11BlockAckRequest::write_ext_header(uint8_t *buffer, uint32_t std::memcpy(buffer, &_bar_control, sizeof(_bar_control)); buffer += sizeof(_bar_control); std::memcpy(buffer, &_start_sequence, sizeof(_start_sequence)); - return parent_size + sizeof(_start_sequence); + return parent_size + sizeof(_start_sequence) + sizeof(_bar_control); } void Tins::Dot11BlockAckRequest::bar_control(uint16_t bar) { @@ -1494,43 +1494,59 @@ Tins::PDU *Tins::Dot11BlockAckRequest::clone_pdu() const { } /* Dot11BlockAck */ -Tins::Dot11BlockAck::Dot11BlockAck(const uint8_t* dst_addr , const uint8_t* target_addr, PDU* child) : Dot11BlockAckRequest(dst_addr, target_addr, child) { +Tins::Dot11BlockAck::Dot11BlockAck(const uint8_t* dst_addr , const uint8_t* target_addr, PDU* child) : Dot11ControlTA(dst_addr, target_addr, child) { subtype(BLOCK_ACK); std::memset(_bitmap, 0, sizeof(_bitmap)); } -Tins::Dot11BlockAck::Dot11BlockAck(const std::string& iface, const uint8_t* dst_addr, const uint8_t *target_addr, PDU* child) throw (std::runtime_error) : Dot11BlockAckRequest(iface, dst_addr, target_addr, child) { +Tins::Dot11BlockAck::Dot11BlockAck(const std::string& iface, const uint8_t* dst_addr, const uint8_t *target_addr, PDU* child) throw (std::runtime_error) : Dot11ControlTA(iface, dst_addr, target_addr, child) { subtype(BLOCK_ACK); std::memset(_bitmap, 0, sizeof(_bitmap)); } -Tins::Dot11BlockAck::Dot11BlockAck(uint32_t iface_index, const uint8_t* dst_addr, const uint8_t *target_addr, PDU* child) : Dot11BlockAckRequest(iface_index, dst_addr, target_addr, child) { +Tins::Dot11BlockAck::Dot11BlockAck(uint32_t iface_index, const uint8_t* dst_addr, const uint8_t *target_addr, PDU* child) : Dot11ControlTA(iface_index, dst_addr, target_addr, child) { subtype(BLOCK_ACK); std::memset(_bitmap, 0, sizeof(_bitmap)); } -Tins::Dot11BlockAck::Dot11BlockAck(const uint8_t *buffer, uint32_t total_sz) : Dot11BlockAckRequest(buffer, total_sz) { - uint32_t padding = blockack_request_size(); +Tins::Dot11BlockAck::Dot11BlockAck(const uint8_t *buffer, uint32_t total_sz) : Dot11ControlTA(buffer, total_sz) { + uint32_t padding = controlta_size(); buffer += padding; total_sz -= padding; - if(total_sz < sizeof(_bitmap)) + 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."); + std::memcpy(&_bar_control, buffer, sizeof(_bar_control)); + buffer += sizeof(_bar_control); + std::memcpy(&_start_sequence, buffer, sizeof(_start_sequence)); + buffer += sizeof(_start_sequence); std::memcpy(&_bitmap, buffer, sizeof(_bitmap)); } +void Tins::Dot11BlockAck::bar_control(uint16_t bar) { + std::memcpy(&_bar_control, &bar, sizeof(bar)); +} + +void Tins::Dot11BlockAck::start_sequence(uint16_t seq) { + std::memcpy(&_start_sequence, &seq, sizeof(seq)); +} + void Tins::Dot11BlockAck::bitmap(const uint8_t *bit) { std::memcpy(_bitmap, bit, sizeof(_bitmap)); } uint32_t Tins::Dot11BlockAck::write_ext_header(uint8_t *buffer, uint32_t total_sz) { - uint32_t parent_size = Dot11BlockAckRequest::write_ext_header(buffer, total_sz); + uint32_t parent_size = Dot11ControlTA::write_ext_header(buffer, total_sz); buffer += parent_size; + std::memcpy(buffer, &_bar_control, sizeof(_bar_control)); + buffer += sizeof(_bar_control); + std::memcpy(buffer, &_start_sequence, sizeof(_start_sequence)); + buffer += sizeof(_start_sequence); std::memcpy(buffer, _bitmap, sizeof(_bitmap)); - return parent_size + sizeof(_bitmap); + return parent_size + sizeof(_bitmap) + sizeof(_bar_control) + sizeof(_start_sequence); } uint32_t Tins::Dot11BlockAck::header_size() const { - return Dot11BlockAckRequest::header_size() + sizeof(_bitmap); + return Dot11ControlTA::header_size() + sizeof(_start_sequence) + sizeof(_start_sequence) + sizeof(_bitmap); } Tins::PDU *Tins::Dot11BlockAck::clone_pdu() const {