1
0
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:
Matias Fontanini
2011-08-22 13:12:10 -03:00
parent 7aa6172d8a
commit 0db209c829
2 changed files with 130 additions and 9 deletions

View File

@@ -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;
};
}

View File

@@ -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;
}
}