mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Added support for IEEE802_11 tagged parameters.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#ifndef __IEEE802_11_h
|
||||
#define __IEEE802_11_h
|
||||
|
||||
#include <list>
|
||||
#include <stdint.h>
|
||||
#include <stdexcept>
|
||||
|
||||
@@ -46,6 +47,45 @@ namespace Tins {
|
||||
CONTROL = 1,
|
||||
DATA = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enum for the different types of tagged options.
|
||||
*/
|
||||
enum TaggedOption {
|
||||
SSID,
|
||||
SUPPORTED_RATES,
|
||||
FH_SET,
|
||||
DS_SET,
|
||||
CF_SET,
|
||||
TIM,
|
||||
BSS,
|
||||
COUNTRY,
|
||||
HOPPING_PATTERN_PARAMS,
|
||||
HOPPING_PATTERN_TABLE,
|
||||
REQUEST,
|
||||
BSS_LOAD,
|
||||
EDCA,
|
||||
TSPEC,
|
||||
TCLAS,
|
||||
SCHEDULE,
|
||||
CHALLENGE_TEXT,
|
||||
POWER_CONSTRAINT = 32,
|
||||
POWER_CAPABILITY,
|
||||
TPC_REQUEST,
|
||||
TPC_REPORT,
|
||||
SUPPORTED_CHANNELS,
|
||||
CHANNEL_SWITCH,
|
||||
MEASUREMENT_REQUEST,
|
||||
MEASUREMENT_REPORT,
|
||||
QUIET,
|
||||
IBSS_DFS,
|
||||
ERP_INFORMATION,
|
||||
TS_DELAY,
|
||||
TCLAS_PROCESSING,
|
||||
QOS_CAPABILITY = 46,
|
||||
RSN = 48,
|
||||
EXT_SUPPORTED_RATES = 50
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enum for the different subtypes of 802.11 management frames.
|
||||
@@ -93,6 +133,35 @@ namespace Tins {
|
||||
CF_ACK_POLL = 7
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief IEEE 802.11 options struct.
|
||||
*/
|
||||
struct IEEE802_11_Option {
|
||||
/**
|
||||
* \brief The option number.
|
||||
*/
|
||||
uint8_t option;
|
||||
/**
|
||||
* \brief The value's length in bytes.
|
||||
*/
|
||||
uint8_t length;
|
||||
/**
|
||||
* \brief The option's value.
|
||||
*/
|
||||
uint8_t *value;
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of IEEE802_11_Option.
|
||||
*
|
||||
* The option's value is copied, therefore the user should
|
||||
* manually free any memory pointed by the "val" parameter.
|
||||
* \param opt The option number.
|
||||
* \param len The length of the option's value in bytes.
|
||||
* \param val The option's value.
|
||||
*/
|
||||
IEEE802_11_Option(uint8_t opt, uint8_t len, const uint8_t *val);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 PDU
|
||||
*
|
||||
@@ -137,7 +206,14 @@ namespace Tins {
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
IEEE802_11(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
|
||||
/**
|
||||
* \brief IEEE802_11 destructor.
|
||||
*
|
||||
* Releases the memory allocated for tagged options.
|
||||
*/
|
||||
~IEEE802_11();
|
||||
|
||||
/**
|
||||
* \brief Getter for the protocol version.
|
||||
*
|
||||
@@ -410,12 +486,24 @@ namespace Tins {
|
||||
* \sa PDU::send()
|
||||
*/
|
||||
bool send(PacketSender* sender);
|
||||
|
||||
/**
|
||||
* \brief Adds a new option to this IEEE802_11 PDU.
|
||||
*
|
||||
* This copies the value buffer.
|
||||
* \param opt The option identifier.
|
||||
* \param len The length of the value field.
|
||||
* \param val The value of this option.
|
||||
*/
|
||||
void add_tagged_option(TaggedOption opt, uint8_t len, const uint8_t *val);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::IEEE802_11; }
|
||||
protected:
|
||||
virtual size_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) { return 0; }
|
||||
private:
|
||||
/**
|
||||
* Struct that represents the 802.11 header
|
||||
@@ -465,11 +553,14 @@ namespace Tins {
|
||||
} __attribute__((__packed__));
|
||||
|
||||
IEEE802_11(const ieee80211_header *header_ptr);
|
||||
|
||||
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
|
||||
ieee80211_header _header;
|
||||
uint8_t _opt_addr[6];
|
||||
uint32_t _iface_index;
|
||||
uint32_t _iface_index, _options_size;
|
||||
std::list<IEEE802_11_Option> _options;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
Tins::IEEE802_11::IEEE802_11(const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) : PDU(ETHERTYPE_IP, child) {
|
||||
Tins::IEEE802_11::IEEE802_11(const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) : PDU(ETHERTYPE_IP, child), _options_size(0) {
|
||||
memset(&this->_header, 0, sizeof(ieee80211_header));
|
||||
if(dst_hw_addr)
|
||||
this->dst_addr(dst_hw_addr);
|
||||
@@ -43,7 +43,7 @@ Tins::IEEE802_11::IEEE802_11(const uint8_t* dst_hw_addr, const uint8_t* src_hw_a
|
||||
this->src_addr(src_hw_addr);
|
||||
}
|
||||
|
||||
Tins::IEEE802_11::IEEE802_11(const std::string& iface, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) throw (std::runtime_error) : PDU(ETHERTYPE_IP, child) {
|
||||
Tins::IEEE802_11::IEEE802_11(const std::string& iface, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) throw (std::runtime_error) : PDU(ETHERTYPE_IP, child), _options_size(0) {
|
||||
memset(&this->_header, 0, sizeof(ieee80211_header));
|
||||
if(dst_hw_addr)
|
||||
this->dst_addr(dst_hw_addr);
|
||||
@@ -53,7 +53,7 @@ Tins::IEEE802_11::IEEE802_11(const std::string& iface, const uint8_t* dst_hw_add
|
||||
}
|
||||
|
||||
|
||||
Tins::IEEE802_11::IEEE802_11(uint32_t iface_index, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) : PDU(ETHERTYPE_IP, child) {
|
||||
Tins::IEEE802_11::IEEE802_11(uint32_t iface_index, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) : PDU(ETHERTYPE_IP, child), _options_size(0) {
|
||||
memset(&this->_header, 0, sizeof(ieee80211_header));
|
||||
if(dst_hw_addr)
|
||||
this->dst_addr(dst_hw_addr);
|
||||
@@ -62,10 +62,28 @@ Tins::IEEE802_11::IEEE802_11(uint32_t iface_index, const uint8_t* dst_hw_addr, c
|
||||
this->iface(iface_index);
|
||||
}
|
||||
|
||||
Tins::IEEE802_11::IEEE802_11(const uint8_t *buffer, uint32_t total_sz) : PDU(ETHERTYPE_IP) {
|
||||
Tins::IEEE802_11::IEEE802_11(const uint8_t *buffer, uint32_t total_sz) : PDU(ETHERTYPE_IP), _options_size(0) {
|
||||
|
||||
}
|
||||
|
||||
Tins::IEEE802_11::~IEEE802_11() {
|
||||
while(_options.size()) {
|
||||
delete[] _options.front().value;
|
||||
_options.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
Tins::IEEE802_11::IEEE802_11_Option::IEEE802_11_Option(uint8_t opt, uint8_t len, const uint8_t *val) {
|
||||
value = new uint8_t[len];
|
||||
std::memcpy(value, val, len);
|
||||
}
|
||||
|
||||
void Tins::IEEE802_11::add_tagged_option(TaggedOption opt, uint8_t len, const uint8_t *val) {
|
||||
uint32_t opt_size = len + (sizeof(uint8_t) << 1);
|
||||
_options.push_back(IEEE802_11_Option((uint8_t)opt, len, val));
|
||||
_options_size += opt_size;
|
||||
}
|
||||
|
||||
void Tins::IEEE802_11::protocol(uint8_t new_proto) {
|
||||
this->_header.control.protocol = new_proto;
|
||||
}
|
||||
@@ -145,7 +163,7 @@ void Tins::IEEE802_11::iface(const std::string& new_iface) throw (std::runtime_e
|
||||
}
|
||||
|
||||
uint32_t Tins::IEEE802_11::header_size() const {
|
||||
uint32_t sz = sizeof(ieee80211_header);
|
||||
uint32_t sz = sizeof(ieee80211_header) + _options_size;
|
||||
if (this->to_ds() && this->from_ds())
|
||||
sz += 6;
|
||||
return sz;
|
||||
@@ -170,8 +188,20 @@ void Tins::IEEE802_11::write_serialization(uint8_t *buffer, uint32_t total_sz, c
|
||||
assert(total_sz >= my_sz);
|
||||
|
||||
memcpy(buffer, &this->_header, sizeof(ieee80211_header));
|
||||
buffer += sizeof(ieee80211_header);
|
||||
if (this->to_ds() && this->from_ds()) {
|
||||
memcpy(buffer + sizeof(ieee80211_header), this->_opt_addr, 6);
|
||||
memcpy(buffer, this->_opt_addr, 6);
|
||||
buffer += 6;
|
||||
total_sz -= 6;
|
||||
}
|
||||
|
||||
uint32_t child_len = write_fixed_parameters(buffer, total_sz - sizeof(ieee80211_header) - _options_size);
|
||||
buffer += child_len;
|
||||
for(std::list<IEEE802_11_Option>::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
*(buffer++) = it->option;
|
||||
*(buffer++) = it->length;
|
||||
std::memcpy(buffer, it->value, it->length);
|
||||
buffer += it->length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user