diff --git a/include/eapol.h b/include/eapol.h index 1ebe37c..6da76af 100644 --- a/include/eapol.h +++ b/include/eapol.h @@ -22,6 +22,7 @@ namespace Tins { enum EAPOLTYPE { RC4 = 1, RSN, + EAPOL_WPA = 254 }; /** @@ -282,6 +283,13 @@ namespace Tins { */ RSNEAPOL(); + /** + * \brief Constructor which creates an RSNEAPOL object from a buffer. + * \param buffer The buffer from which this PDU will be constructed. + * \param total_sz The total size of the buffer. + */ + RSNEAPOL(const uint8_t *buffer, uint32_t total_sz); + /** * \brief Destructor. * diff --git a/src/eapol.cpp b/src/eapol.cpp index 90330ee..c032819 100644 --- a/src/eapol.cpp +++ b/src/eapol.cpp @@ -26,6 +26,10 @@ Tins::EAPOL *Tins::EAPOL::from_bytes(const uint8_t *buffer, uint32_t total_sz) { case RC4: return new RC4EAPOL(buffer, total_sz); break; + case RSN: + case EAPOL_WPA: + return new RSNEAPOL(buffer, total_sz); + break; } return 0; } @@ -61,7 +65,7 @@ Tins::RC4EAPOL::RC4EAPOL() : EAPOL(0x03, RC4), _key(0), _key_size(0) { std::memset(&_header, 0, sizeof(_header)); } -Tins::RC4EAPOL::RC4EAPOL(const uint8_t *buffer, uint32_t total_sz) : EAPOL(buffer, total_sz) { +Tins::RC4EAPOL::RC4EAPOL(const uint8_t *buffer, uint32_t total_sz) : EAPOL(buffer, total_sz), _key_size(0) { buffer += sizeof(eapolhdr); total_sz -= sizeof(eapolhdr); if(total_sz < sizeof(_header)) @@ -136,6 +140,23 @@ Tins::RSNEAPOL::RSNEAPOL() : EAPOL(0x03, RSN), _key(0), _key_size(0) { std::memset(&_header, 0, sizeof(_header)); } +Tins::RSNEAPOL::RSNEAPOL(const uint8_t *buffer, uint32_t total_sz) : EAPOL(0x03, RSN), _key_size(0) { + buffer += sizeof(eapolhdr); + total_sz -= sizeof(eapolhdr); + if(total_sz < sizeof(_header)) + throw std::runtime_error("Not enough size for an EAPOL header in the buffer."); + std::memcpy(&_header, buffer, sizeof(_header)); + buffer += sizeof(_header); + total_sz -= sizeof(_header); + if(total_sz == wpa_length()) { + _key = new uint8_t[total_sz]; + _key_size = total_sz; + std::memcpy(_key, buffer, total_sz); + } + else + _key = 0; +} + Tins::RSNEAPOL::~RSNEAPOL() { delete[] _key; } diff --git a/src/ieee802-11.cpp b/src/ieee802-11.cpp index e8ab425..1f5ce29 100644 --- a/src/ieee802-11.cpp +++ b/src/ieee802-11.cpp @@ -78,7 +78,7 @@ Tins::IEEE802_11::IEEE802_11(const uint8_t *buffer, uint32_t total_sz) : PDU(ETH std::memcpy(&_header, buffer, sz); buffer += sz; total_sz -= sz; - if(type() == 0 && subtype() < 4) { + if(type() == 2 && subtype() < 4) { // It's a data packet inner_pdu(new Tins::SNAP(buffer, total_sz)); } @@ -704,7 +704,10 @@ Tins::IEEE802_11_QoS_Data::IEEE802_11_QoS_Data(const uint8_t *buffer, uint32_t t total_sz -= sizeof(ieee80211_header); assert(total_sz >= sizeof(this->_qos_control)); this->_qos_control = *(uint16_t*)buffer; - + total_sz -= sizeof(uint16_t); + buffer += sizeof(uint16_t); + if(total_sz) + inner_pdu(new Tins::SNAP(buffer, total_sz)); } void Tins::IEEE802_11_QoS_Data::qos_control(uint16_t new_qos_control) { diff --git a/src/snap.cpp b/src/snap.cpp index fd6cfe8..28b8f9b 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -29,6 +29,7 @@ #include "utils.h" #include "arp.h" #include "ip.h" +#include "eapol.h" Tins::SNAP::SNAP(PDU *child) : PDU(0xff, child) { @@ -50,6 +51,9 @@ Tins::SNAP::SNAP(const uint8_t *buffer, uint32_t total_sz) : PDU(0xff) { case ETHERTYPE_ARP: inner_pdu(new Tins::ARP(buffer, total_sz)); break; + case 0x888e: + inner_pdu(Tins::EAPOL::from_bytes(buffer, total_sz)); + break; }; }