diff --git a/include/ieee802-11.h b/include/ieee802-11.h index fbef570..d9f4201 100644 --- a/include/ieee802-11.h +++ b/include/ieee802-11.h @@ -1221,6 +1221,15 @@ namespace Tins { */ IEEE802_11_Assoc_Request(const std::string& iface, const uint8_t* dst_hw_addr = 0, const uint8_t* src_hw_addr = 0) throw (std::runtime_error); + /** + * \brief Constructor which creates a IEEE802_11_Assoc_Request object from a + * buffer and adds all identifiable PDUs found in the buffer as children of this one. + * + * \param buffer The buffer from which this PDU will be constructed. + * \param total_sz The total size of the buffer. + */ + IEEE802_11_Assoc_Request(const uint8_t *buffer, uint32_t total_sz); + /** * \brief Getter for the Capabilities Information. * diff --git a/src/ieee802-11.cpp b/src/ieee802-11.cpp index 01e4cc6..ed8bd4a 100644 --- a/src/ieee802-11.cpp +++ b/src/ieee802-11.cpp @@ -500,6 +500,17 @@ Tins::IEEE802_11_Assoc_Request::IEEE802_11_Assoc_Request(const std::string& ifac memset(&_body, 0, sizeof(_body)); } +Tins::IEEE802_11_Assoc_Request::IEEE802_11_Assoc_Request(const uint8_t *buffer, uint32_t total_sz) : ManagementFrame(buffer, total_sz) { + buffer += sizeof(ieee80211_header); + total_sz -= sizeof(ieee80211_header); + if(total_sz < sizeof(_body)) + throw std::runtime_error("Not enough size for an IEEE 802.11 association header in the buffer."); + memcpy(&_body, buffer, sizeof(_body)); + buffer += sizeof(_body); + total_sz -= sizeof(_body); + parse_tagged_parameters(buffer, total_sz); +} + void Tins::IEEE802_11_Assoc_Request::listen_interval(uint16_t new_listen_interval) { this->_body.listen_interval = new_listen_interval; }