diff --git a/include/snap.h b/include/snap.h index 09f2f8e..7c394be 100644 --- a/include/snap.h +++ b/include/snap.h @@ -41,6 +41,14 @@ namespace Tins { */ SNAP(PDU *child = 0); + /** + * \brief Constructor which creates a SNAP 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. + */ + SNAP(const uint8_t *buffer, uint32_t total_sz); + /** * \brief Returns the SNAP frame's header length. * diff --git a/src/ieee802-11.cpp b/src/ieee802-11.cpp index 97bb740..951ab4e 100644 --- a/src/ieee802-11.cpp +++ b/src/ieee802-11.cpp @@ -32,6 +32,7 @@ #include "radiotap.h" #include "sniffer.h" #include "utils.h" +#include "snap.h" using namespace std; @@ -74,7 +75,10 @@ Tins::IEEE802_11::IEEE802_11(const uint8_t *buffer, uint32_t total_sz) : PDU(ETH std::memcpy(&_header, buffer, sizeof(_header)); buffer += sizeof(_header); total_sz -= sizeof(_header); - + if(type() == 0 && subtype() < 4) { + // It's a data packet + inner_pdu(new Tins::SNAP(buffer, total_sz)); + } // subclass specific parsing missing too. } diff --git a/src/snap.cpp b/src/snap.cpp index 0b0621c..56fcd20 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -21,11 +21,14 @@ #include #include +#include #ifndef WIN32 #include #endif #include "snap.h" #include "utils.h" +#include "arp.h" +#include "ip.h" Tins::SNAP::SNAP(PDU *child) : PDU(0xff, child) { @@ -34,6 +37,22 @@ Tins::SNAP::SNAP(PDU *child) : PDU(0xff, child) { _snap.id = 3; } +Tins::SNAP::SNAP(const uint8_t *buffer, uint32_t total_sz) : PDU(0xff) { + if(total_sz < sizeof(_snap)) + throw std::runtime_error("Not enough size for a SNAP header in the buffer."); + std::memcpy(&_snap, buffer, sizeof(_snap)); + buffer += sizeof(_snap); + total_sz -= sizeof(_snap); + switch(Utils::net_to_host_s(_snap.eth_type)) { + case ETHERTYPE_IP: + inner_pdu(new Tins::IP(buffer, total_sz)); + break; + case ETHERTYPE_ARP: + inner_pdu(new Tins::ARP(buffer, total_sz)); + break; + }; +} + uint32_t Tins::SNAP::header_size() const { return sizeof(_snap); }