mirror of
https://github.com/mfontanini/libtins
synced 2026-01-29 21:14:28 +01:00
Fixed several Dot11 bugs.
This commit is contained in:
@@ -114,6 +114,7 @@ namespace Tins {
|
||||
*
|
||||
*/
|
||||
enum ControlSubtypes {
|
||||
BLOCK_ACK_REQ = 8,
|
||||
BLOCK_ACK = 9,
|
||||
PS = 10,
|
||||
RTS = 11,
|
||||
@@ -988,7 +989,6 @@ namespace Tins {
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
protected:
|
||||
struct ExtendedHeader {
|
||||
uint8_t addr2[6];
|
||||
@@ -1028,7 +1028,6 @@ namespace Tins {
|
||||
|
||||
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
|
||||
void copy_ext_header(const Dot11ManagementFrame *other);
|
||||
|
||||
private:
|
||||
ExtendedHeader _ext_header;
|
||||
uint8_t _addr4[6];
|
||||
@@ -1036,8 +1035,18 @@ namespace Tins {
|
||||
};
|
||||
|
||||
class Dot11DataFrame : public Dot11 {
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief Constructor which creates a Dot11DataFrame 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.
|
||||
*/
|
||||
Dot11DataFrame(uint32_t iface_index, const uint8_t *dst_hw_addr = 0, const uint8_t *src_hw_addr = 0, PDU* child = 0);
|
||||
Dot11DataFrame(const uint8_t *dst_hw_addr = 0, const uint8_t *src_hw_addr = 0, PDU* child = 0);
|
||||
Dot11DataFrame(const std::string &iface, const uint8_t *dst_hw_addr, const uint8_t *src_hw_addr, PDU* child = 0) throw (std::runtime_error);
|
||||
Dot11DataFrame(const uint8_t *buffer, uint32_t total_sz);
|
||||
Dot11DataFrame(const Dot11DataFrame &other);
|
||||
/**
|
||||
* \brief Getter for the second address.
|
||||
*
|
||||
@@ -1116,6 +1125,11 @@ namespace Tins {
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DOT11_DATA; }
|
||||
protected:
|
||||
struct ExtendedHeader {
|
||||
uint8_t addr2[6];
|
||||
@@ -1131,18 +1145,6 @@ namespace Tins {
|
||||
} __attribute__((__packed__)) seq_control;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a Dot11DataFrame 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.
|
||||
*/
|
||||
Dot11DataFrame(uint32_t iface_index, const uint8_t *dst_hw_addr = 0, const uint8_t *src_hw_addr = 0, PDU* child = 0);
|
||||
Dot11DataFrame(const uint8_t *dst_hw_addr = 0, const uint8_t *src_hw_addr = 0, PDU* child = 0);
|
||||
Dot11DataFrame(const std::string &iface, const uint8_t *dst_hw_addr, const uint8_t *src_hw_addr, PDU* child = 0) throw (std::runtime_error);
|
||||
Dot11DataFrame(const uint8_t *buffer, uint32_t total_sz);
|
||||
Dot11DataFrame(const Dot11DataFrame &other);
|
||||
|
||||
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
|
||||
void copy_ext_header(const Dot11DataFrame *other);
|
||||
|
||||
@@ -1298,7 +1300,6 @@ namespace Tins {
|
||||
void copy_fields(const Dot11Beacon *other);
|
||||
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
|
||||
BeaconBody _body;
|
||||
};
|
||||
|
||||
@@ -1724,6 +1725,12 @@ namespace Tins {
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DOT11_QOS_DATA; }
|
||||
private:
|
||||
void copy_fields(const Dot11QoSData *other);
|
||||
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
|
||||
@@ -1778,6 +1785,12 @@ namespace Tins {
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11Control(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DOT11_CONTROL; }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1853,7 +1866,7 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Getter for the control ta additional fields size.
|
||||
*/
|
||||
uint32_t controlta_size() const { return sizeof(_taddr); }
|
||||
uint32_t controlta_size() const { return sizeof(_taddr) + sizeof(ieee80211_header); }
|
||||
|
||||
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
|
||||
private:
|
||||
@@ -1907,6 +1920,12 @@ namespace Tins {
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11RTS(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DOT11_RTS; }
|
||||
};
|
||||
|
||||
class Dot11PSPoll : public Dot11ControlTA {
|
||||
@@ -2094,6 +2113,12 @@ namespace Tins {
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11Ack(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DOT11_ACK; }
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2268,10 +2293,16 @@ namespace Tins {
|
||||
* \param bit The new bitmap field to be set.
|
||||
*/
|
||||
void bitmap(const uint8_t *bit);
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DOT11_BLOCK_ACK; }
|
||||
private:
|
||||
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
uint8_t _bitmap[128];
|
||||
uint8_t _bitmap[8];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -53,6 +53,12 @@ namespace Tins {
|
||||
RAW,
|
||||
ETHERNET_II,
|
||||
DOT11,
|
||||
DOT11_DATA,
|
||||
DOT11_QOS_DATA,
|
||||
DOT11_CONTROL,
|
||||
DOT11_ACK,
|
||||
DOT11_BLOCK_ACK,
|
||||
DOT11_RTS,
|
||||
SNAP,
|
||||
RADIOTAP,
|
||||
IP,
|
||||
|
||||
@@ -208,17 +208,17 @@ bool Tins::Dot11::send(PacketSender* sender) {
|
||||
void Tins::Dot11::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) {
|
||||
uint32_t my_sz = header_size();
|
||||
assert(total_sz >= my_sz);
|
||||
memcpy(buffer, &this->_header, sizeof(ieee80211_header));
|
||||
buffer += sizeof(ieee80211_header);
|
||||
total_sz -= sizeof(ieee80211_header);
|
||||
memcpy(buffer, &_header, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
|
||||
uint32_t written = this->write_ext_header(buffer, total_sz);
|
||||
buffer += written;
|
||||
total_sz -= written;
|
||||
|
||||
uint32_t child_len = write_fixed_parameters(buffer, total_sz - sizeof(ieee80211_header) - _options_size);
|
||||
uint32_t child_len = write_fixed_parameters(buffer, total_sz - _options_size);
|
||||
buffer += child_len;
|
||||
assert(total_sz > child_len + _options_size);
|
||||
assert(total_sz >= child_len + _options_size);
|
||||
for(std::list<Dot11_Option>::const_iterator it = _options.begin(); it != _options.end(); ++it) {
|
||||
*(buffer++) = it->option;
|
||||
*(buffer++) = it->length;
|
||||
@@ -233,11 +233,33 @@ Tins::PDU *Tins::Dot11::from_bytes(const uint8_t *buffer, uint32_t total_sz) {
|
||||
throw std::runtime_error("Not enough size for a IEEE 802.11 header in the buffer.");
|
||||
const ieee80211_header *hdr = (const ieee80211_header*)buffer;
|
||||
PDU *ret = 0;
|
||||
if(hdr->control.type == 0 && hdr->control.subtype == 8) {
|
||||
if(hdr->control.type == MANAGEMENT && hdr->control.subtype == 8) {
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an IEEE 802.11 header in the buffer.");
|
||||
ret = new Dot11Beacon(buffer, total_sz);
|
||||
}
|
||||
else if(hdr->control.type == DATA){
|
||||
if(hdr->control.subtype <= 4)
|
||||
ret = new Dot11DataFrame(buffer, total_sz);
|
||||
else
|
||||
ret = new Dot11QoSData(buffer, total_sz);
|
||||
}
|
||||
else if(hdr->control.type == CONTROL){
|
||||
if(hdr->control.subtype == ACK)
|
||||
ret = new Dot11Ack(buffer, total_sz);
|
||||
else if(hdr->control.subtype == CF_END)
|
||||
ret = new Dot11CFEnd(buffer, total_sz);
|
||||
else if(hdr->control.subtype == CF_END_ACK)
|
||||
ret = new Dot11EndCFAck(buffer, total_sz);
|
||||
else if(hdr->control.subtype == PS)
|
||||
ret = new Dot11PSPoll(buffer, total_sz);
|
||||
else if(hdr->control.subtype == RTS)
|
||||
ret = new Dot11RTS(buffer, total_sz);
|
||||
else if(hdr->control.subtype == BLOCK_ACK)
|
||||
ret = new Dot11BlockAck(buffer, total_sz);
|
||||
else if(hdr->control.subtype == BLOCK_ACK_REQ)
|
||||
ret = new Dot11BlockAckRequest(buffer, total_sz);
|
||||
}
|
||||
else
|
||||
ret = new Dot11(buffer, total_sz);
|
||||
return ret;
|
||||
@@ -261,24 +283,30 @@ Tins::Dot11ManagementFrame::Dot11ManagementFrame(const uint8_t *buffer, uint32_t
|
||||
|
||||
Tins::Dot11ManagementFrame::Dot11ManagementFrame(const uint8_t *dst_hw_addr, const uint8_t *src_hw_addr) : Dot11(dst_hw_addr) {
|
||||
this->type(Dot11::MANAGEMENT);
|
||||
this->addr2(src_hw_addr);
|
||||
if(src_hw_addr)
|
||||
addr2(src_hw_addr);
|
||||
else
|
||||
std::memset(_ext_header.addr2, 0, sizeof(_ext_header.addr2));
|
||||
}
|
||||
|
||||
Tins::Dot11ManagementFrame::Dot11ManagementFrame(const std::string &iface,
|
||||
const uint8_t *dst_hw_addr,
|
||||
const uint8_t *src_hw_addr) throw (std::runtime_error) : Dot11(iface, dst_hw_addr) {
|
||||
this->type(Dot11::MANAGEMENT);
|
||||
this->addr2(src_hw_addr);
|
||||
if(src_hw_addr)
|
||||
addr2(src_hw_addr);
|
||||
else
|
||||
std::memset(_ext_header.addr2, 0, sizeof(_ext_header.addr2));
|
||||
}
|
||||
|
||||
Tins::Dot11ManagementFrame::Dot11ManagementFrame(const Dot11ManagementFrame &other) : Dot11(other) {
|
||||
|
||||
copy_ext_header(&other);
|
||||
}
|
||||
|
||||
void Tins::Dot11ManagementFrame::copy_ext_header(const Dot11ManagementFrame* other) {
|
||||
Dot11::copy_80211_fields(other);
|
||||
std::memcpy(&this->_ext_header, &other->_ext_header, sizeof(this->_ext_header));
|
||||
std::memcpy(this->_addr4, other->_addr4, 6);
|
||||
std::memcpy(&_ext_header, &other->_ext_header, sizeof(_ext_header));
|
||||
std::memcpy(_addr4, other->_addr4, 6);
|
||||
}
|
||||
|
||||
uint32_t Tins::Dot11ManagementFrame::header_size() const {
|
||||
@@ -309,15 +337,14 @@ void Tins::Dot11ManagementFrame::addr4(const uint8_t* new_addr4) {
|
||||
}
|
||||
|
||||
uint32_t Tins::Dot11ManagementFrame::write_ext_header(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t written = sizeof(this->_ext_header);
|
||||
memcpy(buffer, &this->_ext_header, sizeof(this->_ext_header));
|
||||
buffer += sizeof(this->_ext_header);
|
||||
if (this->from_ds() && this->to_ds()) {
|
||||
uint32_t written = sizeof(_ext_header);
|
||||
memcpy(buffer, &_ext_header, sizeof(this->_ext_header));
|
||||
buffer += sizeof(_ext_header);
|
||||
if (from_ds() && to_ds()) {
|
||||
written += 6;
|
||||
memcpy(buffer, this->_addr4, 6);
|
||||
memcpy(buffer, _addr4, 6);
|
||||
}
|
||||
return written;
|
||||
|
||||
}
|
||||
|
||||
void Tins::Dot11ManagementFrame::ssid(const std::string &new_ssid) {
|
||||
@@ -481,9 +508,7 @@ uint32_t Tins::Dot11DataFrame::write_ext_header(uint8_t *buffer, uint32_t total_
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Beacon
|
||||
*/
|
||||
/* Dot11Beacon */
|
||||
|
||||
Tins::Dot11Beacon::Dot11Beacon(const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr) : Dot11ManagementFrame() {
|
||||
this->subtype(Dot11::BEACON);
|
||||
@@ -509,7 +534,7 @@ Tins::Dot11Beacon::Dot11Beacon(const uint8_t *buffer, uint32_t total_sz) : Dot11
|
||||
}
|
||||
|
||||
Tins::Dot11Beacon::Dot11Beacon(const Dot11Beacon &other) : Dot11ManagementFrame(other) {
|
||||
|
||||
copy_fields(&other);
|
||||
}
|
||||
|
||||
Tins::Dot11Beacon &Tins::Dot11Beacon::operator= (const Dot11Beacon &other) {
|
||||
@@ -594,11 +619,11 @@ bool Tins::Dot11Beacon::rsn_information(RSNInformation *rsn) {
|
||||
}
|
||||
|
||||
uint32_t Tins::Dot11Beacon::header_size() const {
|
||||
return Dot11ManagementFrame::header_size() + sizeof(BeaconBody);
|
||||
return Dot11ManagementFrame::header_size() + sizeof(_body);
|
||||
}
|
||||
|
||||
uint32_t Tins::Dot11Beacon::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(BeaconBody);
|
||||
uint32_t sz = sizeof(_body);
|
||||
assert(sz <= total_sz);
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
@@ -876,8 +901,9 @@ Tins::Dot11QoSData::Dot11QoSData(uint32_t iface_index, const uint8_t* dst_hw_add
|
||||
}
|
||||
|
||||
Tins::Dot11QoSData::Dot11QoSData(const uint8_t *buffer, uint32_t total_sz) : Dot11DataFrame(buffer, total_sz) {
|
||||
buffer += sizeof(ieee80211_header);
|
||||
total_sz -= sizeof(ieee80211_header);
|
||||
uint32_t sz = Dot11DataFrame::header_size();
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
assert(total_sz >= sizeof(this->_qos_control));
|
||||
this->_qos_control = *(uint16_t*)buffer;
|
||||
total_sz -= sizeof(uint16_t);
|
||||
@@ -1092,7 +1118,7 @@ Tins::Dot11BlockAckRequest::Dot11BlockAckRequest(const uint8_t *buffer, uint32_t
|
||||
}
|
||||
|
||||
void Tins::Dot11BlockAckRequest::init_block_ack() {
|
||||
subtype(BLOCK_ACK);
|
||||
subtype(BLOCK_ACK_REQ);
|
||||
std::memset(&_bar_control, 0, sizeof(_bar_control));
|
||||
std::memset(&_start_sequence, 0, sizeof(_start_sequence));
|
||||
}
|
||||
@@ -1120,14 +1146,17 @@ uint32_t Tins::Dot11BlockAckRequest::header_size() const {
|
||||
|
||||
/* Dot11BlockAck */
|
||||
Tins::Dot11BlockAck::Dot11BlockAck(const uint8_t* dst_addr , const uint8_t* target_addr, PDU* child) : Dot11BlockAckRequest(dst_addr, target_addr, child) {
|
||||
subtype(BLOCK_ACK);
|
||||
std::memset(_bitmap, 0, sizeof(_bitmap));
|
||||
}
|
||||
|
||||
Tins::Dot11BlockAck::Dot11BlockAck(const std::string& iface, const uint8_t* dst_addr, const uint8_t *target_addr, PDU* child) throw (std::runtime_error) : Dot11BlockAckRequest(iface, dst_addr, target_addr, child) {
|
||||
subtype(BLOCK_ACK);
|
||||
std::memset(_bitmap, 0, sizeof(_bitmap));
|
||||
}
|
||||
|
||||
Tins::Dot11BlockAck::Dot11BlockAck(uint32_t iface_index, const uint8_t* dst_addr, const uint8_t *target_addr, PDU* child) : Dot11BlockAckRequest(iface_index, dst_addr, target_addr, child) {
|
||||
subtype(BLOCK_ACK);
|
||||
std::memset(_bitmap, 0, sizeof(_bitmap));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user