mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Fix merging problems
This commit is contained in:
528
include/dot11.h
528
include/dot11.h
@@ -307,7 +307,7 @@ namespace Tins {
|
||||
*
|
||||
* \return The value of the duration/id field in an uint16_t.
|
||||
*/
|
||||
inline uint16_t duration_id() const { return Utils::net_to_host_s(this->_header.duration_id); }
|
||||
inline uint16_t duration_id() const { return this->_header.duration_id; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the first address.
|
||||
@@ -938,7 +938,7 @@ namespace Tins {
|
||||
*
|
||||
* \return The sequence number as an uint16_t.
|
||||
*/
|
||||
inline uint16_t seq_num() const { return Utils::net_to_host_s(this->_ext_header.seq_control.seq_number); }
|
||||
inline uint16_t seq_num() const { return this->_ext_header.seq_control.seq_number; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the fourth address.
|
||||
@@ -995,11 +995,11 @@ namespace Tins {
|
||||
uint8_t addr3[6];
|
||||
struct {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int seq_number:12;
|
||||
unsigned int frag_number:4;
|
||||
unsigned int seq_number:12;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int frag_number:4;
|
||||
unsigned int seq_number:12;
|
||||
unsigned int frag_number:4;
|
||||
#endif
|
||||
} __attribute__((__packed__)) seq_control;
|
||||
} __attribute__((__packed__));
|
||||
@@ -1042,125 +1042,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];
|
||||
|
||||
};
|
||||
|
||||
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.
|
||||
*
|
||||
* \return The second address as a constant uint8_t pointer.
|
||||
*/
|
||||
inline const uint8_t* addr2() const { return this->_ext_header.addr2; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the third address.
|
||||
*
|
||||
* \return The third address as a constant uint8_t pointer.
|
||||
*/
|
||||
inline const uint8_t* addr3() const { return this->_ext_header.addr3; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the fragment number.
|
||||
*
|
||||
* \return The fragment number as an uint8_t.
|
||||
*/
|
||||
inline uint8_t frag_num() const { return this->_ext_header.seq_control.frag_number; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the sequence number.
|
||||
*
|
||||
* \return The sequence number as an uint16_t.
|
||||
*/
|
||||
inline uint16_t seq_num() const { return Utils::net_to_host_s(this->_ext_header.seq_control.seq_number); }
|
||||
|
||||
/**
|
||||
* \brief Getter for the fourth address.
|
||||
*
|
||||
* \return The fourth address as a constant uint8_t pointer.
|
||||
*/
|
||||
inline const uint8_t* addr4() const { return this->_addr4; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the second address.
|
||||
*
|
||||
* \param new_addr2 const uint8_t array of 6 bytes containing the new second's address.
|
||||
*/
|
||||
void addr2(const uint8_t* new_addr2);
|
||||
|
||||
/**
|
||||
* \brief Setter for the third address.
|
||||
*
|
||||
* \param new_addr3 const uint8_t array of 6 bytes containing the new third address.
|
||||
*/
|
||||
void addr3(const uint8_t* new_addr3);
|
||||
|
||||
/**
|
||||
* \brief Setter for the fragment number.
|
||||
*
|
||||
* \param new_frag_num uint8_t with the new fragment number.
|
||||
*/
|
||||
void frag_num(uint8_t new_frag_num);
|
||||
|
||||
/**
|
||||
* \brief Setter for the sequence number.
|
||||
*
|
||||
* \param new_seq_num uint16_t with the new sequence number.
|
||||
*/
|
||||
void seq_num(uint16_t new_seq_num);
|
||||
|
||||
/**
|
||||
* \brief Setter for the fourth address.
|
||||
*
|
||||
* \param new_addr4 const uint8_t array of 6 bytes containing the new fourth address.
|
||||
*/
|
||||
void addr4(const uint8_t* new_addr4);
|
||||
|
||||
/**
|
||||
* \brief Returns the 802.11 frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \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_DATA; }
|
||||
protected:
|
||||
struct ExtendedHeader {
|
||||
uint8_t addr2[6];
|
||||
uint8_t addr3[6];
|
||||
struct {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int seq_number:12;
|
||||
unsigned int frag_number:4;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int frag_number:4;
|
||||
unsigned int seq_number:12;
|
||||
#endif
|
||||
} __attribute__((__packed__)) seq_control;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
|
||||
void copy_ext_header(const Dot11DataFrame *other);
|
||||
|
||||
private:
|
||||
ExtendedHeader _ext_header;
|
||||
@@ -1224,7 +1105,7 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Getter for the interval field.
|
||||
*
|
||||
* \return Timestamp value in an uint64_t.
|
||||
* \return Timestamp value in an uint16_t.
|
||||
*/
|
||||
inline uint16_t interval() const { return Utils::net_to_host_s(this->_body.interval); }
|
||||
|
||||
@@ -1304,6 +1185,19 @@ namespace Tins {
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DOT11_BEACON; }
|
||||
private:
|
||||
struct BeaconBody {
|
||||
uint64_t timestamp;
|
||||
@@ -1374,6 +1268,13 @@ namespace Tins {
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
private:
|
||||
struct DisassocBody {
|
||||
uint16_t reason_code;
|
||||
@@ -1516,6 +1417,13 @@ namespace Tins {
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
private:
|
||||
struct AssocReqBody {
|
||||
CapabilityInformation capability;
|
||||
@@ -1646,6 +1554,13 @@ namespace Tins {
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
private:
|
||||
struct AssocRespBody {
|
||||
CapabilityInformation capability;
|
||||
@@ -1659,303 +1574,129 @@ namespace Tins {
|
||||
AssocRespBody _body;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Class representing an ReAssociation Request frame in the IEEE 802.11 Protocol.
|
||||
*
|
||||
*/
|
||||
class Dot11ReAssocRequest : public Dot11ManagementFrame {
|
||||
|
||||
class Dot11Data : public Dot11 {
|
||||
public:
|
||||
/**
|
||||
* \brief Default constructor for the ReAssociation Request frame.
|
||||
*
|
||||
*/
|
||||
Dot11ReAssocRequest();
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 ReAssociation Request.
|
||||
*
|
||||
* Constructor that builds a 802.11 ReAssociation Request taking the interface name,
|
||||
* destination's and source's MAC.
|
||||
*
|
||||
* \param iface string containing the interface's name from where to send the packet.
|
||||
* \param dst_hw_addr uint8_t array of 6 bytes containing the destination's MAC(optional).
|
||||
* \param src_hw_addr uint8_t array of 6 bytes containing the source's MAC(optional).
|
||||
*/
|
||||
Dot11ReAssocRequest(const std::string& iface, const uint8_t* dst_hw_addr = 0, const uint8_t* src_hw_addr = 0) throw (std::runtime_error);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a Dot11ReAssocRequest object from a
|
||||
* buffer and adds all identifiable PDUs found in the buffer as children of this one.
|
||||
*
|
||||
* \brief Constructor which creates a Dot11Data 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.
|
||||
*/
|
||||
Dot11ReAssocRequest(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
Dot11Data(uint32_t iface_index, const uint8_t *dst_hw_addr = 0, const uint8_t *src_hw_addr = 0, PDU* child = 0);
|
||||
Dot11Data(const uint8_t *dst_hw_addr = 0, const uint8_t *src_hw_addr = 0, PDU* child = 0);
|
||||
Dot11Data(const std::string &iface, const uint8_t *dst_hw_addr, const uint8_t *src_hw_addr, PDU* child = 0) throw (std::runtime_error);
|
||||
Dot11Data(const uint8_t *buffer, uint32_t total_sz);
|
||||
/**
|
||||
* \brief Copy constructor.
|
||||
*/
|
||||
Dot11ReAssocRequest(const Dot11ReAssocRequest &other);
|
||||
|
||||
/**
|
||||
* \brief Copy assignment operator.
|
||||
*/
|
||||
Dot11ReAssocRequest &operator= (const Dot11ReAssocRequest &other);
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
* \brief Getter for the second address.
|
||||
*
|
||||
* \return CapabilityInformation Structure in a CapabilityInformation&.
|
||||
* \return The second address as a constant uint8_t pointer.
|
||||
*/
|
||||
inline const CapabilityInformation& capabilities() const { return this->_body.capability;}
|
||||
inline const uint8_t* addr2() const { return this->_ext_header.addr2; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
* \brief Getter for the third address.
|
||||
*
|
||||
* \return CapabilityInformation Structure in a CapabilityInformation&.
|
||||
* \return The third address as a constant uint8_t pointer.
|
||||
*/
|
||||
inline CapabilityInformation& capabilities() { return this->_body.capability;}
|
||||
inline const uint8_t* addr3() const { return this->_ext_header.addr3; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the listen interval.
|
||||
* \brief Getter for the fragment number.
|
||||
*
|
||||
* \return The listen interval in an uint16_t.
|
||||
* \return The fragment number as an uint8_t.
|
||||
*/
|
||||
inline uint16_t listen_interval() const { return this->_body.listen_interval; }
|
||||
inline uint8_t frag_num() const { return this->_ext_header.seq_control.frag_number; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the current AP field.
|
||||
* \brief Getter for the sequence number.
|
||||
*
|
||||
* \return The current AP value in an uint8_t*.
|
||||
* \return The sequence number as an uint16_t.
|
||||
*/
|
||||
inline const uint8_t* current_ap() const {return this->_body.current_ap; }
|
||||
inline uint16_t seq_num() const { return this->_ext_header.seq_control.seq_number; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the listen interval.
|
||||
* \brief Getter for the fourth address.
|
||||
*
|
||||
* \param new_listen_interval uint16_t with the new listen interval.
|
||||
* \return The fourth address as a constant uint8_t pointer.
|
||||
*/
|
||||
void listen_interval(uint16_t new_listen_interval);
|
||||
inline const uint8_t* addr4() const { return this->_addr4; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the current AP field.
|
||||
* \brief Setter for the second address.
|
||||
*
|
||||
* \param new_current_ap uint8_t array of 6 bytes with the new current_ap
|
||||
* \param new_addr2 const uint8_t array of 6 bytes containing the new second's address.
|
||||
*/
|
||||
void current_ap(const uint8_t* new_current_ap);
|
||||
void addr2(const uint8_t* new_addr2);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the essid.
|
||||
* \brief Setter for the third address.
|
||||
*
|
||||
* \param new_ssid The ssid to be set.
|
||||
* \param new_addr3 const uint8_t array of 6 bytes containing the new third address.
|
||||
*/
|
||||
void ssid(const std::string &new_ssid);
|
||||
void addr3(const uint8_t* new_addr3);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the supported rates.
|
||||
* \brief Setter for the fragment number.
|
||||
*
|
||||
* \param new_rates A list of rates to be set.
|
||||
* \param new_frag_num uint8_t with the new fragment number.
|
||||
*/
|
||||
void supported_rates(const std::list<float> &new_rates);
|
||||
void frag_num(uint8_t new_frag_num);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the extended supported rates.
|
||||
* \brief Setter for the sequence number.
|
||||
*
|
||||
* \param new_rates A list of rates to be set.
|
||||
* \param new_seq_num uint16_t with the new sequence number.
|
||||
*/
|
||||
void extended_supported_rates(const std::list<float> &new_rates);
|
||||
void seq_num(uint16_t new_seq_num);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the power capabilities.
|
||||
* \brief Setter for the fourth address.
|
||||
*
|
||||
* \param min_power uint8_t indicating the minimum transmiting power capability.
|
||||
* \param max_power uint8_t indicating the maximum transmiting power capability.
|
||||
* \param new_addr4 const uint8_t array of 6 bytes containing the new fourth address.
|
||||
*/
|
||||
void power_capabilities(uint8_t min_power, uint8_t max_power);
|
||||
void addr4(const uint8_t* new_addr4);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the supported channels.
|
||||
*
|
||||
* \param new_channels A list of channels to be set.
|
||||
*/
|
||||
void supported_channels(const std::list<std::pair<uint8_t, uint8_t> > &new_channels);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the RSN information option.
|
||||
*
|
||||
* \param info The RSNInformation structure to be set.
|
||||
*/
|
||||
void rsn_information(const RSNInformation& info);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the QoS capabilities.
|
||||
*
|
||||
* \param new_qos_capabilities uint8_t with the capabilities.
|
||||
*/
|
||||
void qos_capabilities(uint8_t new_qos_capabilities);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
* \brief Returns the 802.11 frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \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_DATA; }
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
protected:
|
||||
struct ExtendedHeader {
|
||||
uint8_t addr2[6];
|
||||
uint8_t addr3[6];
|
||||
struct {
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned int seq_number:12;
|
||||
unsigned int frag_number:4;
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned int frag_number:4;
|
||||
unsigned int seq_number:12;
|
||||
#endif
|
||||
} __attribute__((__packed__)) seq_control;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
|
||||
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
|
||||
void copy_ext_header(const Dot11Data *other);
|
||||
|
||||
private:
|
||||
struct ReAssocReqBody {
|
||||
CapabilityInformation capability;
|
||||
uint16_t listen_interval;
|
||||
uint8_t current_ap[6];
|
||||
};
|
||||
|
||||
void copy_fields(const Dot11ReAssocRequest* other);
|
||||
uint32_t write_fixed_parameters(uint8_t* buffer, uint32_t total_sz);
|
||||
|
||||
ReAssocReqBody _body;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Class representing an ReAssociation Response frame in the IEEE 802.11 Protocol.
|
||||
*
|
||||
*/
|
||||
class Dot11ReAssocResponse : public Dot11ManagementFrame {
|
||||
|
||||
public:
|
||||
/**
|
||||
* \brief Default constructor for the Association Response frame.
|
||||
*
|
||||
*/
|
||||
Dot11ReAssocResponse();
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 ReAssociation Response.
|
||||
*
|
||||
* Constructor that builds a 802.11 ReAssociation Response taking the interface name,
|
||||
* destination's and source's MAC.
|
||||
*
|
||||
* \param iface string containing the interface's name from where to send the packet.
|
||||
* \param dst_hw_addr uint8_t array of 6 bytes containing the destination's MAC(optional).
|
||||
* \param src_hw_addr uint8_t array of 6 bytes containing the source's MAC(optional).
|
||||
*/
|
||||
Dot11ReAssocResponse(const std::string& iface, const uint8_t* dst_hw_addr = 0, const uint8_t* src_hw_addr = 0) throw (std::runtime_error);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a Dot11ReAssocResponse 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.
|
||||
*/
|
||||
Dot11ReAssocResponse(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Copy constructor.
|
||||
*/
|
||||
Dot11ReAssocResponse(const Dot11ReAssocResponse &other);
|
||||
|
||||
/**
|
||||
* \brief Copy assignment operator
|
||||
*/
|
||||
Dot11ReAssocResponse &operator= (const Dot11ReAssocResponse &other);
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
*
|
||||
* \return CapabilityInformation Structure in a CapabilityInformation&.
|
||||
*/
|
||||
inline const CapabilityInformation& capabilities() const { return this->_body.capability;}
|
||||
|
||||
/**
|
||||
* \brief Getter for the Capabilities Information.
|
||||
*
|
||||
* \return CapabilityInformation Structure in a CapabilityInformation&.
|
||||
*/
|
||||
inline CapabilityInformation& capabilities() { return this->_body.capability;}
|
||||
|
||||
/**
|
||||
* \brief Getter for the status code.
|
||||
*
|
||||
* \return The status code in an uint16_t.
|
||||
*/
|
||||
inline uint16_t status_code() const { return this->_body.status_code; }
|
||||
|
||||
/**
|
||||
* \brief Getter for the AID field.
|
||||
*
|
||||
* \return The AID field value in an uint16_t.
|
||||
*/
|
||||
inline uint16_t aid() const { return this->_body.aid; }
|
||||
|
||||
/**
|
||||
* \brief Setter for the status code.
|
||||
*
|
||||
* \param new_status_code uint16_t with the new status code.
|
||||
*/
|
||||
void status_code(uint16_t new_status_code);
|
||||
|
||||
/**
|
||||
* \brief Setter for the AID field.
|
||||
*
|
||||
* \param new_aid uint16_t with the new AID value.
|
||||
*/
|
||||
void aid(uint16_t new_aid);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the supported rates.
|
||||
*
|
||||
* \param new_rates A list of rates to be set.
|
||||
*/
|
||||
void supported_rates(const std::list<float> &new_rates);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the extended supported rates.
|
||||
*
|
||||
* \param new_rates A list of rates to be set.
|
||||
*/
|
||||
void extended_supported_rates(const std::list<float> &new_rates);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the EDCA Parameter Set.
|
||||
*
|
||||
* \param ac_be uint32_t with the value of the ac_be field.
|
||||
* \param ac_bk uint32_t with the value of the ac_bk field.
|
||||
* \param ac_vi uint32_t with the value of the ac_vi field.
|
||||
* \param ac_vo uint32_t with the value of the ac_vo field.
|
||||
*/
|
||||
void edca_parameter_set(uint32_t ac_be, uint32_t ac_bk, uint32_t ac_vi, uint32_t ac_vo);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
*
|
||||
* \return An uint32_t with the header's size.
|
||||
* \sa PDU::header_size()
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
struct ReAssocRespBody {
|
||||
CapabilityInformation capability;
|
||||
uint16_t status_code;
|
||||
uint16_t aid;
|
||||
};
|
||||
|
||||
void copy_fields(const Dot11ReAssocResponse *other);
|
||||
uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
ReAssocRespBody _body;
|
||||
|
||||
ExtendedHeader _ext_header;
|
||||
uint8_t _addr4[6];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2093,7 +1834,7 @@ namespace Tins {
|
||||
|
||||
};
|
||||
|
||||
class Dot11QoSData : public Dot11DataFrame {
|
||||
class Dot11QoSData : public Dot11Data {
|
||||
|
||||
public:
|
||||
|
||||
@@ -2174,6 +1915,13 @@ namespace Tins {
|
||||
*/
|
||||
uint32_t header_size() const;
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
@@ -2369,6 +2117,13 @@ namespace Tins {
|
||||
*/
|
||||
Dot11RTS(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
|
||||
/**
|
||||
* \brief Getter for the PDU's type.
|
||||
* \sa PDU::pdu_type
|
||||
@@ -2422,6 +2177,13 @@ namespace Tins {
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11PSPoll(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
};
|
||||
|
||||
class Dot11CFEnd : public Dot11ControlTA {
|
||||
@@ -2470,6 +2232,13 @@ namespace Tins {
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11CFEnd(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
};
|
||||
|
||||
class Dot11EndCFAck : public Dot11ControlTA {
|
||||
@@ -2515,6 +2284,13 @@ namespace Tins {
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
Dot11EndCFAck(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
};
|
||||
|
||||
class Dot11Ack : public Dot11Control {
|
||||
@@ -2567,6 +2343,14 @@ namespace Tins {
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DOT11_ACK; }
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2650,6 +2434,13 @@ namespace Tins {
|
||||
* \param bar The new start sequence field.
|
||||
*/
|
||||
void start_sequence(uint16_t seq);
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
protected:
|
||||
/**
|
||||
* \brief Getter for the control ta additional fields size.
|
||||
@@ -2746,6 +2537,13 @@ namespace Tins {
|
||||
* \sa PDU::pdu_type
|
||||
*/
|
||||
PDUType pdu_type() const { return PDU::DOT11_BLOCK_ACK; }
|
||||
|
||||
/**
|
||||
* \brief Clones this PDU.
|
||||
*
|
||||
* \sa PDU::clone_pdu
|
||||
*/
|
||||
PDU *clone_pdu() const;
|
||||
private:
|
||||
uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ namespace Tins {
|
||||
DOT11,
|
||||
DOT11_DATA,
|
||||
DOT11_QOS_DATA,
|
||||
DOT11_BEACON,
|
||||
DOT11_CONTROL,
|
||||
DOT11_ACK,
|
||||
DOT11_BLOCK_ACK,
|
||||
@@ -174,7 +175,7 @@ namespace Tins {
|
||||
/* Should be pure virtual. It's this way to avoid compiling issues.
|
||||
* Once every pdu has implemented it, make it pure virtual. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Send the stack of PDUs through a PacketSender.
|
||||
*
|
||||
@@ -259,27 +260,6 @@ namespace Tins {
|
||||
* \param parent The PDU that's one level below this one on the stack. Might be 0.
|
||||
*/
|
||||
virtual void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) = 0;
|
||||
|
||||
/** \brief Does the 16 bits sum of all 2 bytes elements between start and end.
|
||||
*
|
||||
* This is the checksum used by IP, UDP and TCP. If there's and odd number of
|
||||
* bytes, the last one is padded and added to the checksum. The checksum is performed
|
||||
* using network endiannes.
|
||||
* \param start The pointer to the start of the buffer.
|
||||
* \param end The pointer to the end of the buffer(excluding the last element).
|
||||
* \return Returns the checksum between start and end(non inclusive).
|
||||
*/
|
||||
static uint32_t do_checksum(uint8_t *start, uint8_t *end);
|
||||
|
||||
/** \brief Performs the pseudo header checksum used in TCP and UDP PDUs.
|
||||
*
|
||||
* \param source_ip The source ip address.
|
||||
* \param dest_ip The destination ip address.
|
||||
* \param len The length to be included in the pseudo header.
|
||||
* \param flag The flag to use in the protocol field of the pseudo header.
|
||||
* \return The pseudo header checksum.
|
||||
*/
|
||||
static uint32_t pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag);
|
||||
private:
|
||||
uint32_t _flag;
|
||||
PDU *_inner_pdu;
|
||||
|
||||
@@ -29,6 +29,11 @@ namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Class that represents the IEEE 802.11 radio tap header.
|
||||
*
|
||||
* By default, RadioTap PDUs set the necesary fields to send an 802.11
|
||||
* PDU as its inner pdu, avoiding packet drops. As a consequence,
|
||||
* the FCS-at-end flag is on, the channel is set to 1, TSFT is set to 0,
|
||||
* dbm_signal is set to 0xce, and the rx_flag and antenna fields to 0.
|
||||
*/
|
||||
class RadioTap : public PDU {
|
||||
public:
|
||||
@@ -88,14 +93,16 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Creates an instance of RadioTap.
|
||||
* \param iface The name of the interface in which to send this PDU.
|
||||
* \param child The child PDU.(optional)
|
||||
*/
|
||||
RadioTap(const std::string &iface) throw (std::runtime_error);
|
||||
RadioTap(const std::string &iface, PDU *child = 0) throw (std::runtime_error);
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RadioTap.
|
||||
* \param iface_index The index of the interface in which to send this PDU.
|
||||
* \param child The child PDU.(optional)
|
||||
*/
|
||||
RadioTap(uint32_t iface_index);
|
||||
RadioTap(uint32_t iface_index, PDU *child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a RadioTap object from a buffer and adds all
|
||||
@@ -297,6 +304,7 @@ namespace Tins {
|
||||
ext:1;
|
||||
} __attribute__((__packed__));
|
||||
|
||||
void init();
|
||||
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <pcap.h>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include "pdu.h"
|
||||
|
||||
namespace Tins {
|
||||
@@ -65,8 +66,9 @@ namespace Tins {
|
||||
* \brief Creates an instance of sniffer.
|
||||
* \param device The device which will be sniffed.
|
||||
* \param max_packet_size The maximum packet size to be read.
|
||||
* \param filter A capture filter to compile and use for sniffing sessions.(optional);
|
||||
*/
|
||||
Sniffer(const std::string &device, unsigned max_packet_size);
|
||||
Sniffer(const std::string &device, unsigned max_packet_size, const std::string &filter = "") throw(std::runtime_error);
|
||||
|
||||
/**
|
||||
* \brief Sniffer destructor.
|
||||
@@ -77,15 +79,13 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Compiles a filter and uses it to capture one packet.
|
||||
*
|
||||
* This method returns the first sniffed PDU that matches the given
|
||||
* filter. If no filter is given, the previously set filter will be used.
|
||||
* If no filter has been set, then no filtering is applied to sniffed
|
||||
* packets.
|
||||
* \param filter The filter which will be used while sniffing.
|
||||
* This method returns the first sniffed packet that matches the
|
||||
* sniffer's filter, or the first sniffed packet if no filter has
|
||||
* been set.
|
||||
* \return The captured packet, matching the given filter, 0 if an
|
||||
* error occured(probably compiling the filter).
|
||||
*/
|
||||
PDU *next_packet(const std::string &filter = "");
|
||||
PDU *next_packet();
|
||||
|
||||
/**
|
||||
* \brief Starts a sniffing loop, using a callback object for every
|
||||
@@ -95,10 +95,9 @@ namespace Tins {
|
||||
* or it could be a specific SnifferHandler specialization. This method deletes
|
||||
* packets after they are handled, therefore the handlers MUST NOT delete them.
|
||||
* \param cback_handler The callback handler object which should process packets.
|
||||
* \param filter The filter to use when sniffing(optional).
|
||||
* \param max_packets The maximum amount of packets to sniff. 0 == infinite.
|
||||
*/
|
||||
void sniff_loop(AbstractSnifferHandler *cback_handler, const std::string &filter = "", uint32_t max_packets = 0);
|
||||
void sniff_loop(AbstractSnifferHandler *cback_handler, uint32_t max_packets = 0);
|
||||
|
||||
/**
|
||||
* \brief Sets a filter on this sniffer.
|
||||
|
||||
@@ -368,6 +368,8 @@ namespace Tins {
|
||||
static const uint16_t DEFAULT_WINDOW;
|
||||
|
||||
void copy_fields(const TCP *other);
|
||||
|
||||
void cleanup();
|
||||
/** \brief Serialices this TCP PDU.
|
||||
* \param buffer The buffer in which the PDU will be serialized.
|
||||
* \param total_sz The size available in the buffer.
|
||||
|
||||
@@ -177,6 +177,27 @@ namespace Tins {
|
||||
*/
|
||||
uint16_t channel_to_mhz(uint16_t channel);
|
||||
|
||||
/** \brief Does the 16 bits sum of all 2 bytes elements between start and end.
|
||||
*
|
||||
* This is the checksum used by IP, UDP and TCP. If there's and odd number of
|
||||
* bytes, the last one is padded and added to the checksum. The checksum is performed
|
||||
* using network endiannes.
|
||||
* \param start The pointer to the start of the buffer.
|
||||
* \param end The pointer to the end of the buffer(excluding the last element).
|
||||
* \return Returns the checksum between start and end(non inclusive).
|
||||
*/
|
||||
uint32_t do_checksum(uint8_t *start, uint8_t *end);
|
||||
|
||||
/** \brief Performs the pseudo header checksum used in TCP and UDP PDUs.
|
||||
*
|
||||
* \param source_ip The source ip address.
|
||||
* \param dest_ip The destination ip address.
|
||||
* \param len The length to be included in the pseudo header.
|
||||
* \param flag The flag to use in the protocol field of the pseudo header.
|
||||
* \return The pseudo header checksum.
|
||||
*/
|
||||
uint32_t pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag);
|
||||
|
||||
/** \brief Generic function to iterate through interface and collect
|
||||
* data.
|
||||
*
|
||||
|
||||
401
src/dot11.cpp
401
src/dot11.cpp
@@ -24,6 +24,7 @@
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#ifndef WIN32
|
||||
#include <net/ethernet.h>
|
||||
#include <netpacket/packet.h>
|
||||
@@ -42,8 +43,10 @@ const uint8_t *Tins::Dot11::BROADCAST = (const uint8_t*)"\xff\xff\xff\xff\xff\xf
|
||||
|
||||
Tins::Dot11::Dot11(const uint8_t* dst_hw_addr, PDU* child) : PDU(ETHERTYPE_IP, child), _options_size(0) {
|
||||
memset(&this->_header, 0, sizeof(ieee80211_header));
|
||||
if(dst_hw_addr)
|
||||
if(dst_hw_addr) {
|
||||
|
||||
this->addr1(dst_hw_addr);
|
||||
}
|
||||
}
|
||||
|
||||
Tins::Dot11::Dot11(const std::string& iface, const uint8_t* dst_hw_addr, PDU* child) throw (std::runtime_error) : PDU(ETHERTYPE_IP, child), _options_size(0) {
|
||||
@@ -72,10 +75,6 @@ Tins::Dot11::Dot11(const uint8_t *buffer, uint32_t total_sz) : PDU(ETHERTYPE_IP)
|
||||
std::memcpy(&_header, buffer, sz);
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(type() == 2 && subtype() < 4) {
|
||||
// It's a data packet
|
||||
inner_pdu(new Tins::SNAP(buffer, total_sz));
|
||||
}
|
||||
}
|
||||
|
||||
Tins::Dot11::Dot11(const Dot11 &other) : PDU(other) {
|
||||
@@ -169,7 +168,7 @@ void Tins::Dot11::order(bool new_value) {
|
||||
}
|
||||
|
||||
void Tins::Dot11::duration_id(uint16_t new_duration_id) {
|
||||
this->_header.duration_id = Utils::net_to_host_s(new_duration_id);
|
||||
this->_header.duration_id = new_duration_id;
|
||||
}
|
||||
|
||||
void Tins::Dot11::addr1(const uint8_t* new_addr1) {
|
||||
@@ -240,7 +239,7 @@ Tins::PDU *Tins::Dot11::from_bytes(const uint8_t *buffer, uint32_t total_sz) {
|
||||
}
|
||||
else if(hdr->control.type == DATA){
|
||||
if(hdr->control.subtype <= 4)
|
||||
ret = new Dot11DataFrame(buffer, total_sz);
|
||||
ret = new Dot11Data(buffer, total_sz);
|
||||
else
|
||||
ret = new Dot11QoSData(buffer, total_sz);
|
||||
}
|
||||
@@ -273,12 +272,16 @@ void Tins::Dot11::copy_80211_fields(const Dot11 *other) {
|
||||
_options.push_back(Dot11_Option(it->option, it->length, it->value));
|
||||
}
|
||||
|
||||
/*
|
||||
* Dot11ManagementFrame
|
||||
*/
|
||||
/* Dot11ManagementFrame */
|
||||
|
||||
Tins::Dot11ManagementFrame::Dot11ManagementFrame(const uint8_t *buffer, uint32_t total_sz) : Dot11(buffer, total_sz) {
|
||||
|
||||
buffer += sizeof(ieee80211_header);
|
||||
total_sz -= sizeof(ieee80211_header);
|
||||
if(total_sz < sizeof(_ext_header))
|
||||
throw std::runtime_error("Not enough size for an IEEE 802.11 header in the buffer.");
|
||||
std::memcpy(&_ext_header, buffer, sizeof(_ext_header));
|
||||
if(from_ds() && to_ds())
|
||||
std::memcpy(_addr4, buffer + sizeof(_ext_header), sizeof(_addr4));
|
||||
}
|
||||
|
||||
Tins::Dot11ManagementFrame::Dot11ManagementFrame(const uint8_t *dst_hw_addr, const uint8_t *src_hw_addr) : Dot11(dst_hw_addr) {
|
||||
@@ -290,8 +293,8 @@ Tins::Dot11ManagementFrame::Dot11ManagementFrame(const uint8_t *dst_hw_addr, con
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
if(src_hw_addr)
|
||||
addr2(src_hw_addr);
|
||||
@@ -329,7 +332,7 @@ void Tins::Dot11ManagementFrame::frag_num(uint8_t new_frag_num) {
|
||||
}
|
||||
|
||||
void Tins::Dot11ManagementFrame::seq_num(uint16_t new_seq_num) {
|
||||
this->_ext_header.seq_control.seq_number = Utils::net_to_host_s(new_seq_num);
|
||||
this->_ext_header.seq_control.seq_number = new_seq_num;
|
||||
}
|
||||
|
||||
void Tins::Dot11ManagementFrame::addr4(const uint8_t* new_addr4) {
|
||||
@@ -589,82 +592,6 @@ void Tins::Dot11ManagementFrame::tpc_report(uint8_t transmit_power, uint8_t link
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Dot11DataFrame
|
||||
*/
|
||||
|
||||
Tins::Dot11DataFrame::Dot11DataFrame(const uint8_t *buffer, uint32_t total_sz) : Dot11(buffer, total_sz) {
|
||||
|
||||
}
|
||||
|
||||
Tins::Dot11DataFrame::Dot11DataFrame(uint32_t iface_index, const uint8_t *dst_hw_addr, const uint8_t *src_hw_addr, PDU* child) : Dot11(iface_index, dst_hw_addr, child) {
|
||||
this->type(Dot11::DATA);
|
||||
this->addr2(src_hw_addr);
|
||||
}
|
||||
|
||||
Tins::Dot11DataFrame::Dot11DataFrame(const uint8_t *dst_hw_addr, const uint8_t *src_hw_addr, PDU* child) : Dot11(dst_hw_addr, child) {
|
||||
this->type(Dot11::DATA);
|
||||
this->addr2(src_hw_addr);
|
||||
}
|
||||
|
||||
|
||||
Tins::Dot11DataFrame::Dot11DataFrame(const std::string &iface,
|
||||
const uint8_t *dst_hw_addr,
|
||||
const uint8_t *src_hw_addr,
|
||||
PDU* child) throw (std::runtime_error) : Dot11(iface, dst_hw_addr, child) {
|
||||
this->type(Dot11::DATA);
|
||||
this->addr2(src_hw_addr);
|
||||
}
|
||||
|
||||
Tins::Dot11DataFrame::Dot11DataFrame(const Dot11DataFrame &other) : Dot11(other) {
|
||||
|
||||
}
|
||||
|
||||
void Tins::Dot11DataFrame::copy_ext_header(const Dot11DataFrame* 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);
|
||||
}
|
||||
|
||||
uint32_t Tins::Dot11DataFrame::header_size() const {
|
||||
uint32_t sz = Dot11::header_size() + sizeof(_ext_header);
|
||||
if (this->from_ds() && this->to_ds())
|
||||
sz += 6;
|
||||
return sz;
|
||||
}
|
||||
|
||||
void Tins::Dot11DataFrame::addr2(const uint8_t* new_addr2) {
|
||||
memcpy(this->_ext_header.addr2, new_addr2, 6);
|
||||
}
|
||||
|
||||
void Tins::Dot11DataFrame::addr3(const uint8_t* new_addr3) {
|
||||
memcpy(this->_ext_header.addr3, new_addr3, 6);
|
||||
}
|
||||
|
||||
void Tins::Dot11DataFrame::frag_num(uint8_t new_frag_num) {
|
||||
this->_ext_header.seq_control.frag_number = new_frag_num;
|
||||
}
|
||||
|
||||
void Tins::Dot11DataFrame::seq_num(uint16_t new_seq_num) {
|
||||
this->_ext_header.seq_control.seq_number = Utils::net_to_host_s(new_seq_num);
|
||||
}
|
||||
|
||||
void Tins::Dot11DataFrame::addr4(const uint8_t* new_addr4) {
|
||||
memcpy(this->_addr4, new_addr4, 6);
|
||||
}
|
||||
|
||||
uint32_t Tins::Dot11DataFrame::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()) {
|
||||
written += 6;
|
||||
memcpy(buffer, this->_addr4, 6);
|
||||
}
|
||||
return written;
|
||||
|
||||
}
|
||||
|
||||
/* Dot11Beacon */
|
||||
|
||||
Tins::Dot11Beacon::Dot11Beacon(const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr) : Dot11ManagementFrame() {
|
||||
@@ -680,8 +607,9 @@ Tins::Dot11Beacon::Dot11Beacon(const std::string& iface,
|
||||
}
|
||||
|
||||
Tins::Dot11Beacon::Dot11Beacon(const uint8_t *buffer, uint32_t total_sz) : Dot11ManagementFrame(buffer, total_sz) {
|
||||
buffer += sizeof(ieee80211_header);
|
||||
total_sz -= sizeof(ieee80211_header);
|
||||
uint32_t sz = Dot11ManagementFrame::header_size();
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw std::runtime_error("Not enough size for a IEEE 802.11 beacon header in the buffer.");
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
@@ -786,6 +714,12 @@ uint32_t Tins::Dot11Beacon::write_fixed_parameters(uint8_t *buffer, uint32_t tot
|
||||
return sz;
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Dot11Beacon::clone_pdu() const {
|
||||
Dot11Beacon *new_pdu = new Dot11Beacon();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
/* 802.11 diassoc */
|
||||
|
||||
Tins::Dot11Disassoc::Dot11Disassoc() : Dot11ManagementFrame() {
|
||||
@@ -830,9 +764,14 @@ uint32_t Tins::Dot11Disassoc::write_fixed_parameters(uint8_t *buffer, uint32_t t
|
||||
return sz;
|
||||
}
|
||||
|
||||
/*
|
||||
* RSNInformation class
|
||||
*/
|
||||
Tins::PDU *Tins::Dot11Disassoc::clone_pdu() const {
|
||||
Dot11Disassoc *new_pdu = new Dot11Disassoc();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
/* RSNInformation */
|
||||
|
||||
Tins::RSNInformation::RSNInformation() : _version(1), _capabilities(0) {
|
||||
|
||||
}
|
||||
@@ -906,8 +845,9 @@ Tins::Dot11AssocRequest::Dot11AssocRequest(const std::string& iface,
|
||||
}
|
||||
|
||||
Tins::Dot11AssocRequest::Dot11AssocRequest(const uint8_t *buffer, uint32_t total_sz) : Dot11ManagementFrame(buffer, total_sz) {
|
||||
buffer += sizeof(ieee80211_header);
|
||||
total_sz -= sizeof(ieee80211_header);
|
||||
uint32_t sz = Dot11ManagementFrame::header_size();
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw std::runtime_error("Not enough size for an IEEE 802.11 association header in the buffer.");
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
@@ -974,6 +914,12 @@ uint32_t Tins::Dot11AssocRequest::write_fixed_parameters(uint8_t *buffer, uint32
|
||||
return sz;
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Dot11AssocRequest::clone_pdu() const {
|
||||
Dot11AssocRequest *new_pdu = new Dot11AssocRequest();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
/* Assoc response. */
|
||||
|
||||
Tins::Dot11AssocResponse::Dot11AssocResponse() : Dot11ManagementFrame() {
|
||||
@@ -1045,164 +991,116 @@ uint32_t Tins::Dot11AssocResponse::write_fixed_parameters(uint8_t *buffer, uint3
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* ReAssoc Request */
|
||||
|
||||
Tins::Dot11ReAssocRequest::Dot11ReAssocRequest() : Dot11ManagementFrame() {
|
||||
this->subtype(Dot11::REASSOC_REQ);
|
||||
memset(&_body, 0, sizeof(_body));
|
||||
Tins::PDU *Tins::Dot11AssocResponse::clone_pdu() const {
|
||||
Dot11AssocResponse *new_pdu = new Dot11AssocResponse();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
Tins::Dot11ReAssocRequest::Dot11ReAssocRequest(const std::string& iface,
|
||||
const uint8_t* dst_hw_addr,
|
||||
const uint8_t* src_hw_addr) throw (std::runtime_error) : Dot11ManagementFrame(iface, dst_hw_addr, src_hw_addr) {
|
||||
this->subtype(Dot11::REASSOC_REQ);
|
||||
memset(&_body, 0, sizeof(_body));
|
||||
}
|
||||
/* Dot11Data */
|
||||
|
||||
Tins::Dot11ReAssocRequest::Dot11ReAssocRequest(const uint8_t *buffer, uint32_t total_sz) : Dot11ManagementFrame(buffer, total_sz) {
|
||||
uint32_t sz = Dot11ManagementFrame::header_size();
|
||||
Tins::Dot11Data::Dot11Data(const uint8_t *buffer, uint32_t total_sz) : Dot11(buffer, total_sz) {
|
||||
uint32_t sz = Dot11::header_size();
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw std::runtime_error("Not enough size for an IEEE 802.11 association header in the buffer.");
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
parse_tagged_parameters(buffer, total_sz);
|
||||
if(total_sz < sizeof(_ext_header))
|
||||
throw std::runtime_error("Not enough size for an IEEE 802.11 data header in the buffer.");
|
||||
std::memcpy(&_ext_header, buffer, sizeof(_ext_header));
|
||||
buffer += sizeof(_ext_header);
|
||||
total_sz -= sizeof(_ext_header);
|
||||
if(from_ds() && to_ds()) {
|
||||
if(total_sz < sizeof(_addr4))
|
||||
throw std::runtime_error("Not enough size for an IEEE 802.11 data header in the buffer.");
|
||||
std::memcpy(&_addr4, buffer, sizeof(_addr4));
|
||||
buffer += sizeof(_addr4);
|
||||
total_sz -= sizeof(_addr4);
|
||||
}
|
||||
inner_pdu(new Tins::SNAP(buffer, total_sz));
|
||||
}
|
||||
|
||||
Tins::Dot11ReAssocRequest::Dot11ReAssocRequest(const Dot11ReAssocRequest &other) : Dot11ManagementFrame(other) {
|
||||
copy_fields(&other);
|
||||
Tins::Dot11Data::Dot11Data(uint32_t iface_index, const uint8_t *dst_hw_addr, const uint8_t *src_hw_addr, PDU* child) : Dot11(iface_index, dst_hw_addr, child) {
|
||||
this->type(Dot11::DATA);
|
||||
if(src_hw_addr)
|
||||
this->addr2(src_hw_addr);
|
||||
else
|
||||
std::memset(_ext_header.addr2, 0, sizeof(_ext_header.addr2));
|
||||
}
|
||||
|
||||
Tins::Dot11ReAssocRequest &Tins::Dot11ReAssocRequest::operator= (const Dot11ReAssocRequest &other) {
|
||||
copy_inner_pdu(other);
|
||||
copy_fields(&other);
|
||||
return *this;
|
||||
Tins::Dot11Data::Dot11Data(const uint8_t *dst_hw_addr, const uint8_t *src_hw_addr, PDU* child) : Dot11(dst_hw_addr, child) {
|
||||
this->type(Dot11::DATA);
|
||||
if(src_hw_addr)
|
||||
this->addr2(src_hw_addr);
|
||||
else
|
||||
std::memset(_ext_header.addr2, 0, sizeof(_ext_header.addr2));
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocRequest::copy_fields(const Dot11ReAssocRequest *other) {
|
||||
Dot11ManagementFrame::copy_ext_header(other);
|
||||
std::memcpy(&_body, &other->_body, sizeof(_body));
|
||||
|
||||
Tins::Dot11Data::Dot11Data(const std::string &iface,
|
||||
const uint8_t *dst_hw_addr,
|
||||
const uint8_t *src_hw_addr,
|
||||
PDU* child) throw (std::runtime_error) : Dot11(iface, dst_hw_addr, child) {
|
||||
this->type(Dot11::DATA);
|
||||
if(src_hw_addr)
|
||||
this->addr2(src_hw_addr);
|
||||
else
|
||||
std::memset(_ext_header.addr2, 0, sizeof(_ext_header.addr2));
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocRequest::listen_interval(uint16_t new_listen_interval) {
|
||||
this->_body.listen_interval = new_listen_interval;
|
||||
void Tins::Dot11Data::copy_ext_header(const Dot11Data* 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);
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocRequest::current_ap(const uint8_t* new_current_ap) {
|
||||
memcpy(this->_body.current_ap, new_current_ap, 6);
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocRequest::ssid(const std::string &new_ssid) {
|
||||
Dot11ManagementFrame::ssid(new_ssid);
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocRequest::supported_rates(const std::list<float> &new_rates) {
|
||||
Dot11ManagementFrame::supported_rates(new_rates);
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocRequest::extended_supported_rates(const std::list<float> &new_rates) {
|
||||
Dot11ManagementFrame::extended_supported_rates(new_rates);
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocRequest::power_capabilities(uint8_t min_power, uint8_t max_power) {
|
||||
Dot11ManagementFrame::power_capabilities(min_power, max_power);
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocRequest::supported_channels(const std::list<pair<uint8_t, uint8_t> > &new_channels) {
|
||||
Dot11ManagementFrame::supported_channels(new_channels);
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocRequest::rsn_information(const RSNInformation& info) {
|
||||
Dot11ManagementFrame::rsn_information(info);
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocRequest::qos_capabilities(uint8_t new_qos_capabilities) {
|
||||
Dot11ManagementFrame::qos_capabilities(new_qos_capabilities);
|
||||
}
|
||||
|
||||
uint32_t Tins::Dot11ReAssocRequest::header_size() const {
|
||||
return Dot11ManagementFrame::header_size() + sizeof(this->_body);
|
||||
}
|
||||
|
||||
uint32_t Tins::Dot11ReAssocRequest::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(this->_body);
|
||||
assert(sz <= total_sz);
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
uint32_t Tins::Dot11Data::header_size() const {
|
||||
uint32_t sz = Dot11::header_size() + sizeof(_ext_header);
|
||||
if (this->from_ds() && this->to_ds())
|
||||
sz += 6;
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* ReAssociation Response */
|
||||
|
||||
Tins::Dot11ReAssocResponse::Dot11ReAssocResponse() : Dot11ManagementFrame() {
|
||||
this->subtype(Dot11::REASSOC_RESP);
|
||||
memset(&_body, 0, sizeof(_body));
|
||||
void Tins::Dot11Data::addr2(const uint8_t* new_addr2) {
|
||||
memcpy(this->_ext_header.addr2, new_addr2, 6);
|
||||
}
|
||||
|
||||
Tins::Dot11ReAssocResponse::Dot11ReAssocResponse(const std::string& iface,
|
||||
const uint8_t* dst_hw_addr,
|
||||
const uint8_t* src_hw_addr) throw (std::runtime_error) : Dot11ManagementFrame(iface, dst_hw_addr, src_hw_addr) {
|
||||
this->subtype(Dot11::REASSOC_RESP);
|
||||
memset(&_body, 0, sizeof(_body));
|
||||
void Tins::Dot11Data::addr3(const uint8_t* new_addr3) {
|
||||
memcpy(this->_ext_header.addr3, new_addr3, 6);
|
||||
}
|
||||
|
||||
Tins::Dot11ReAssocResponse::Dot11ReAssocResponse(const uint8_t *buffer, uint32_t total_sz) : Dot11ManagementFrame(buffer, total_sz) {
|
||||
uint32_t sz = Dot11ManagementFrame::header_size();
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
if(total_sz < sizeof(_body))
|
||||
throw std::runtime_error("Not enough size for an IEEE 802.11 reassociation response header in the buffer.");
|
||||
memcpy(&_body, buffer, sizeof(_body));
|
||||
buffer += sizeof(_body);
|
||||
total_sz -= sizeof(_body);
|
||||
parse_tagged_parameters(buffer, total_sz);
|
||||
void Tins::Dot11Data::frag_num(uint8_t new_frag_num) {
|
||||
this->_ext_header.seq_control.frag_number = new_frag_num;
|
||||
}
|
||||
|
||||
Tins::Dot11ReAssocResponse::Dot11ReAssocResponse(const Dot11ReAssocResponse &other) : Dot11ManagementFrame(other) {
|
||||
copy_fields(&other);
|
||||
void Tins::Dot11Data::seq_num(uint16_t new_seq_num) {
|
||||
this->_ext_header.seq_control.seq_number = new_seq_num;
|
||||
}
|
||||
|
||||
Tins::Dot11ReAssocResponse &Tins::Dot11ReAssocResponse::operator= (const Dot11ReAssocResponse &other) {
|
||||
copy_inner_pdu(other);
|
||||
copy_fields(&other);
|
||||
return *this;
|
||||
void Tins::Dot11Data::addr4(const uint8_t* new_addr4) {
|
||||
memcpy(this->_addr4, new_addr4, 6);
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocResponse::copy_fields(const Dot11ReAssocResponse *other) {
|
||||
Dot11ManagementFrame::copy_ext_header(other);
|
||||
std::memcpy(&_body, &other->_body, sizeof(_body));
|
||||
uint32_t Tins::Dot11Data::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()) {
|
||||
written += 6;
|
||||
memcpy(buffer, this->_addr4, 6);
|
||||
}
|
||||
return written;
|
||||
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocResponse::status_code(uint16_t new_status_code) {
|
||||
this->_body.status_code = new_status_code;
|
||||
Tins::PDU *Tins::Dot11Data::clone_pdu() const {
|
||||
Dot11Data *new_pdu = new Dot11Data();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocResponse::aid(uint16_t new_aid) {
|
||||
this->_body.aid = new_aid;
|
||||
}
|
||||
/* QoS data. */
|
||||
|
||||
void Tins::Dot11ReAssocResponse::supported_rates(const std::list<float> &new_rates) {
|
||||
Dot11ManagementFrame::supported_rates(new_rates);
|
||||
}
|
||||
Tins::Dot11QoSData::Dot11QoSData(const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) : Dot11Data(dst_hw_addr, src_hw_addr, child) {
|
||||
|
||||
void Tins::Dot11ReAssocResponse::extended_supported_rates(const std::list<float> &new_rates) {
|
||||
Dot11ManagementFrame::extended_supported_rates(new_rates);
|
||||
}
|
||||
|
||||
void Tins::Dot11ReAssocResponse::edca_parameter_set(uint32_t ac_be, uint32_t ac_bk, uint32_t ac_vi, uint32_t ac_vo) {
|
||||
Dot11ManagementFrame::edca_parameter_set(ac_be, ac_bk, ac_vi, ac_vo);
|
||||
}
|
||||
|
||||
uint32_t Tins::Dot11ReAssocResponse::header_size() const {
|
||||
return Dot11ManagementFrame::header_size() + sizeof(this->_body);
|
||||
}
|
||||
|
||||
uint32_t Tins::Dot11ReAssocResponse::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) {
|
||||
uint32_t sz = sizeof(this->_body);
|
||||
assert(sz <= total_sz);
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
|
||||
/* Probe Request */
|
||||
@@ -1245,18 +1143,18 @@ Tins::PDU* Tins::Dot11ProbeRequest::clone_pdu() const {
|
||||
|
||||
/* QoS data. */
|
||||
|
||||
Tins::Dot11QoSData::Dot11QoSData(const std::string& iface, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) throw (std::runtime_error) : Dot11DataFrame(iface, dst_hw_addr, src_hw_addr, child) {
|
||||
Tins::Dot11QoSData::Dot11QoSData(const std::string& iface, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) throw (std::runtime_error) : Dot11Data(iface, dst_hw_addr, src_hw_addr, child) {
|
||||
this->subtype(Dot11::QOS_DATA_DATA);
|
||||
this->_qos_control = 0;
|
||||
}
|
||||
|
||||
Tins::Dot11QoSData::Dot11QoSData(uint32_t iface_index, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) : Dot11DataFrame(iface_index, dst_hw_addr, src_hw_addr, child) {
|
||||
Tins::Dot11QoSData::Dot11QoSData(uint32_t iface_index, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr, PDU* child) : Dot11Data(iface_index, dst_hw_addr, src_hw_addr, child) {
|
||||
this->subtype(Dot11::QOS_DATA_DATA);
|
||||
this->_qos_control = 0;
|
||||
}
|
||||
|
||||
Tins::Dot11QoSData::Dot11QoSData(const uint8_t *buffer, uint32_t total_sz) : Dot11DataFrame(buffer, total_sz) {
|
||||
uint32_t sz = Dot11DataFrame::header_size();
|
||||
Tins::Dot11QoSData::Dot11QoSData(const uint8_t *buffer, uint32_t total_sz) : Dot11Data(buffer, total_sz) {
|
||||
uint32_t sz = Dot11Data::header_size();
|
||||
buffer += sz;
|
||||
total_sz -= sz;
|
||||
assert(total_sz >= sizeof(this->_qos_control));
|
||||
@@ -1267,7 +1165,7 @@ Tins::Dot11QoSData::Dot11QoSData(const uint8_t *buffer, uint32_t total_sz) : Dot
|
||||
inner_pdu(new Tins::SNAP(buffer, total_sz));
|
||||
}
|
||||
|
||||
Tins::Dot11QoSData::Dot11QoSData(const Dot11QoSData &other) : Dot11DataFrame(other) {
|
||||
Tins::Dot11QoSData::Dot11QoSData(const Dot11QoSData &other) : Dot11Data(other) {
|
||||
copy_fields(&other);
|
||||
}
|
||||
|
||||
@@ -1278,7 +1176,7 @@ Tins::Dot11QoSData &Tins::Dot11QoSData::operator= (const Dot11QoSData &other) {
|
||||
}
|
||||
|
||||
void Tins::Dot11QoSData::copy_fields(const Dot11QoSData *other) {
|
||||
Dot11DataFrame::copy_ext_header(other);
|
||||
Dot11Data::copy_ext_header(other);
|
||||
_qos_control = other->_qos_control;
|
||||
}
|
||||
|
||||
@@ -1297,7 +1195,14 @@ uint32_t Tins::Dot11QoSData::write_fixed_parameters(uint8_t *buffer, uint32_t to
|
||||
return sz;
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Dot11QoSData::clone_pdu() const {
|
||||
Dot11QoSData *new_pdu = new Dot11QoSData();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
/* Dot11Control */
|
||||
|
||||
Tins::Dot11Control::Dot11Control(const uint8_t* dst_addr, PDU* child) : Dot11(dst_addr, child) {
|
||||
type(CONTROL);
|
||||
}
|
||||
@@ -1375,6 +1280,12 @@ Tins::Dot11RTS::Dot11RTS(const uint8_t *buffer, uint32_t total_sz) : Dot11Contro
|
||||
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Dot11RTS::clone_pdu() const {
|
||||
Dot11RTS *new_pdu = new Dot11RTS();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
/* Dot11PSPoll */
|
||||
|
||||
Tins::Dot11PSPoll::Dot11PSPoll(const uint8_t* dst_addr , const uint8_t* target_addr, PDU* child) : Dot11ControlTA(dst_addr, target_addr, child) {
|
||||
@@ -1393,6 +1304,12 @@ Tins::Dot11PSPoll::Dot11PSPoll(const uint8_t *buffer, uint32_t total_sz) : Dot11
|
||||
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Dot11PSPoll::clone_pdu() const {
|
||||
Dot11PSPoll *new_pdu = new Dot11PSPoll();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
/* Dot11CFEnd */
|
||||
|
||||
Tins::Dot11CFEnd::Dot11CFEnd(const uint8_t* dst_addr , const uint8_t* target_addr, PDU* child) : Dot11ControlTA(dst_addr, target_addr, child) {
|
||||
@@ -1411,6 +1328,12 @@ Tins::Dot11CFEnd::Dot11CFEnd(const uint8_t *buffer, uint32_t total_sz) : Dot11Co
|
||||
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Dot11CFEnd::clone_pdu() const {
|
||||
Dot11CFEnd *new_pdu = new Dot11CFEnd();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
/* Dot11EndCFAck */
|
||||
|
||||
Tins::Dot11EndCFAck::Dot11EndCFAck(const uint8_t* dst_addr , const uint8_t* target_addr, PDU* child) : Dot11ControlTA(dst_addr, target_addr, child) {
|
||||
@@ -1429,6 +1352,12 @@ Tins::Dot11EndCFAck::Dot11EndCFAck(const uint8_t *buffer, uint32_t total_sz) : D
|
||||
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Dot11EndCFAck::clone_pdu() const {
|
||||
Dot11EndCFAck *new_pdu = new Dot11EndCFAck();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
/* Dot11Ack */
|
||||
|
||||
Tins::Dot11Ack::Dot11Ack(const uint8_t* dst_addr, PDU* child) : Dot11Control(dst_addr, child) {
|
||||
@@ -1447,6 +1376,12 @@ Tins::Dot11Ack::Dot11Ack(const uint8_t *buffer, uint32_t total_sz) : Dot11Contro
|
||||
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Dot11Ack::clone_pdu() const {
|
||||
Dot11Ack *ack = new Dot11Ack();
|
||||
ack->copy_80211_fields(this);
|
||||
return ack;
|
||||
}
|
||||
|
||||
/* Dot11BlockAck */
|
||||
|
||||
Tins::Dot11BlockAckRequest::Dot11BlockAckRequest(const uint8_t* dst_addr , const uint8_t* target_addr, PDU* child) : Dot11ControlTA(dst_addr, target_addr, child) {
|
||||
@@ -1499,6 +1434,12 @@ uint32_t Tins::Dot11BlockAckRequest::header_size() const {
|
||||
return Dot11ControlTA::header_size() + sizeof(_start_sequence) + sizeof(_start_sequence);
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Dot11BlockAckRequest::clone_pdu() const {
|
||||
Dot11BlockAckRequest *new_pdu = new Dot11BlockAckRequest();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
@@ -1538,3 +1479,9 @@ uint32_t Tins::Dot11BlockAck::write_ext_header(uint8_t *buffer, uint32_t total_s
|
||||
uint32_t Tins::Dot11BlockAck::header_size() const {
|
||||
return Dot11BlockAckRequest::header_size() + sizeof(_bitmap);
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Dot11BlockAck::clone_pdu() const {
|
||||
Dot11BlockAck *new_pdu = new Dot11BlockAck();
|
||||
new_pdu->copy_80211_fields(this);
|
||||
return new_pdu;
|
||||
}
|
||||
|
||||
@@ -177,7 +177,8 @@ void Tins::ICMP::set_redirect(uint8_t icode, uint32_t address) {
|
||||
void Tins::ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
assert(total_sz >= sizeof(icmphdr));
|
||||
if(!_icmp.check) {
|
||||
uint32_t checksum = PDU::do_checksum(buffer + sizeof(icmphdr), buffer + total_sz) + PDU::do_checksum((uint8_t*)&_icmp, ((uint8_t*)&_icmp) + sizeof(icmphdr));
|
||||
uint32_t checksum = Utils::do_checksum(buffer + sizeof(icmphdr), buffer + total_sz) +
|
||||
Utils::do_checksum((uint8_t*)&_icmp, ((uint8_t*)&_icmp) + sizeof(icmphdr));
|
||||
while (checksum >> 16)
|
||||
checksum = (checksum & 0xffff) + (checksum >> 16);
|
||||
_icmp.check = Utils::net_to_host_s(~checksum);
|
||||
|
||||
33
src/ip.cpp
33
src/ip.cpp
@@ -105,23 +105,22 @@ Tins::IP::IP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_IP) {
|
||||
this->_ip_options.push_back(opt_to_add);
|
||||
this->_options_size += 1 + opt_to_add.optional_data_size;
|
||||
}
|
||||
|
||||
total_sz -= head_len() * sizeof(uint32_t);
|
||||
if (total_sz == 0)
|
||||
return;
|
||||
switch(_ip.protocol) {
|
||||
case IPPROTO_TCP:
|
||||
inner_pdu(new Tins::TCP(buffer, total_sz));
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
inner_pdu(new Tins::UDP(buffer, total_sz));
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
inner_pdu(new Tins::ICMP(buffer, total_sz));
|
||||
break;
|
||||
default:
|
||||
inner_pdu(new Tins::RawPDU(buffer, total_sz));
|
||||
break;
|
||||
if (total_sz) {
|
||||
switch(_ip.protocol) {
|
||||
case IPPROTO_TCP:
|
||||
inner_pdu(new Tins::TCP(buffer, total_sz));
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
inner_pdu(new Tins::UDP(buffer, total_sz));
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
inner_pdu(new Tins::ICMP(buffer, total_sz));
|
||||
break;
|
||||
default:
|
||||
inner_pdu(new Tins::RawPDU(buffer, total_sz));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +301,7 @@ void Tins::IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU
|
||||
memset(buffer + sizeof(iphdr) + this->_options_size, 0, this->_padded_options_size - this->_options_size);
|
||||
|
||||
if (parent && !_ip.check) {
|
||||
uint32_t checksum = PDU::do_checksum(buffer, buffer + sizeof(iphdr) + _padded_options_size);
|
||||
uint32_t checksum = Utils::do_checksum(buffer, buffer + sizeof(iphdr) + _padded_options_size);
|
||||
while (checksum >> 16)
|
||||
checksum = (checksum & 0xffff) + (checksum >> 16);
|
||||
((iphdr*)buffer)->check = Utils::net_to_host_s(~checksum);
|
||||
|
||||
27
src/pdu.cpp
27
src/pdu.cpp
@@ -102,30 +102,3 @@ Tins::PDU *Tins::PDU::clone_packet() const {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Static methods */
|
||||
uint32_t Tins::PDU::do_checksum(uint8_t *start, uint8_t *end) {
|
||||
uint32_t checksum(0);
|
||||
uint16_t *ptr = (uint16_t*)start, *last = (uint16_t*)end, padding(0);
|
||||
if(((end - start) & 1) == 1) {
|
||||
last = (uint16_t*)end - 1;
|
||||
padding = *(end - 1) << 8;
|
||||
}
|
||||
while(ptr < last)
|
||||
checksum += Utils::net_to_host_s(*(ptr++));
|
||||
return checksum + padding;
|
||||
}
|
||||
|
||||
uint32_t Tins::PDU::pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag) {
|
||||
uint32_t checksum(0);
|
||||
source_ip = Utils::net_to_host_l(source_ip);
|
||||
dest_ip = Utils::net_to_host_l(dest_ip);
|
||||
uint16_t *ptr = (uint16_t*)&source_ip;
|
||||
|
||||
checksum += (uint32_t)(*ptr) + (uint32_t)(*(ptr+1));
|
||||
ptr = (uint16_t*)&dest_ip;
|
||||
checksum += (uint32_t)(*ptr) + (uint32_t)(*(ptr+1));
|
||||
checksum += flag + len;
|
||||
return checksum;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,14 +30,16 @@
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
Tins::RadioTap::RadioTap(const std::string &iface) throw (std::runtime_error) : PDU(0xff), _options_size(0) {
|
||||
Tins::RadioTap::RadioTap(const std::string &iface, PDU *child) throw (std::runtime_error) : PDU(0xff, child), _options_size(0) {
|
||||
if(!Utils::interface_id(iface, _iface_index))
|
||||
throw std::runtime_error("Invalid interface name!");
|
||||
std::memset(&_radio, 0, sizeof(_radio));
|
||||
init();
|
||||
}
|
||||
|
||||
Tins::RadioTap::RadioTap(uint32_t iface_index) : PDU(0xff), _iface_index(iface_index) {
|
||||
Tins::RadioTap::RadioTap(uint32_t iface_index, PDU *child) : PDU(0xff, child), _iface_index(iface_index) {
|
||||
std::memset(&_radio, 0, sizeof(_radio));
|
||||
init();
|
||||
}
|
||||
|
||||
Tins::RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) : PDU(0xff) {
|
||||
@@ -111,6 +113,15 @@ Tins::RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) : PDU(0xff) {
|
||||
inner_pdu(Dot11::from_bytes(buffer, total_sz));
|
||||
}
|
||||
|
||||
void Tins::RadioTap::init() {
|
||||
channel(Utils::channel_to_mhz(1), 0xa0);
|
||||
flags(FCS);
|
||||
tsft(0);
|
||||
dbm_signal(0xce);
|
||||
rx_flag(0);
|
||||
antenna(0);
|
||||
}
|
||||
|
||||
void Tins::RadioTap::version(uint8_t new_version) {
|
||||
_radio.it_version = new_version;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <stdexcept>
|
||||
#include "sniffer.h"
|
||||
#include "ethernetII.h"
|
||||
#include "radiotap.h"
|
||||
@@ -41,7 +40,7 @@ struct LoopData {
|
||||
/** \endcond */
|
||||
|
||||
|
||||
Tins::Sniffer::Sniffer(const string &device, unsigned max_packet_size) {
|
||||
Tins::Sniffer::Sniffer(const string &device, unsigned max_packet_size, const string &filter) throw(std::runtime_error) {
|
||||
char error[PCAP_ERRBUF_SIZE];
|
||||
if (pcap_lookupnet(device.c_str(), &ip, &mask, error) == -1) {
|
||||
ip = 0;
|
||||
@@ -52,6 +51,8 @@ Tins::Sniffer::Sniffer(const string &device, unsigned max_packet_size) {
|
||||
throw runtime_error(error);
|
||||
wired = (pcap_datalink (handle) != DLT_IEEE802_11_RADIO); //better plx
|
||||
actual_filter.bf_insns = 0;
|
||||
if(filter.size() && !set_filter(filter))
|
||||
throw runtime_error("Invalid filter");
|
||||
}
|
||||
|
||||
Tins::Sniffer::~Sniffer() {
|
||||
@@ -65,9 +66,7 @@ bool Tins::Sniffer::compile_set_filter(const string &filter, bpf_program &prog)
|
||||
return (pcap_compile(handle, &prog, filter.c_str(), 0, ip) != -1 && pcap_setfilter(handle, &prog) != -1);
|
||||
}
|
||||
|
||||
Tins::PDU *Tins::Sniffer::next_packet(const string &filter) {
|
||||
if(filter.size())
|
||||
set_filter(filter);
|
||||
Tins::PDU *Tins::Sniffer::next_packet() {
|
||||
pcap_pkthdr header;
|
||||
PDU *ret = 0;
|
||||
while(!ret) {
|
||||
@@ -91,9 +90,7 @@ void Tins::Sniffer::stop_sniff() {
|
||||
pcap_breakloop(handle);
|
||||
}
|
||||
|
||||
void Tins::Sniffer::sniff_loop(AbstractSnifferHandler *cback_handler, const string &filter, uint32_t max_packets) {
|
||||
if(filter.size())
|
||||
set_filter(filter);
|
||||
void Tins::Sniffer::sniff_loop(AbstractSnifferHandler *cback_handler, uint32_t max_packets) {
|
||||
LoopData data(handle, cback_handler, wired);
|
||||
pcap_loop(handle, max_packets, Sniffer::callback_handler, (u_char*)&data);
|
||||
}
|
||||
|
||||
86
src/tcp.cpp
86
src/tcp.cpp
@@ -56,48 +56,58 @@ Tins::TCP::TCP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_TCP) {
|
||||
if(total_sz < sizeof(tcphdr))
|
||||
throw std::runtime_error("Not enough size for an TCP header in the buffer.");
|
||||
std::memcpy(&_tcp, buffer, sizeof(tcphdr));
|
||||
|
||||
buffer += sizeof(tcphdr);
|
||||
total_sz -= sizeof(tcphdr);
|
||||
|
||||
uint32_t index = 0, header_end = (data_offset() * sizeof(uint32_t)) - sizeof(tcphdr);
|
||||
if(total_sz >= header_end) {
|
||||
uint8_t args[2] = {0};
|
||||
while(index < header_end) {
|
||||
for(unsigned i(0); i < 2 && args[0] != NOP; ++i) {
|
||||
args[i] = buffer[index++];
|
||||
if(index == header_end)
|
||||
throw std::runtime_error("Not enought size for a TCP header in the buffer.");
|
||||
}
|
||||
// We don't want to store NOPs and EOLs
|
||||
if(args[0] != NOP && args[0] != EOL) {
|
||||
if(args[1]) {
|
||||
// Not enough size for this option
|
||||
if(header_end - index < args[1] - (sizeof(uint8_t) << 1)) {
|
||||
try {
|
||||
buffer += sizeof(tcphdr);
|
||||
total_sz -= sizeof(tcphdr);
|
||||
|
||||
_total_options_size = 0;
|
||||
_options_size = 0;
|
||||
|
||||
uint32_t index = 0, header_end = (data_offset() * sizeof(uint32_t)) - sizeof(tcphdr);
|
||||
if(total_sz >= header_end) {
|
||||
uint8_t args[2] = {0};
|
||||
while(index < header_end) {
|
||||
for(unsigned i(0); i < 2 && args[0] != NOP; ++i) {
|
||||
args[i] = buffer[index++];
|
||||
if(index == header_end)
|
||||
throw std::runtime_error("Not enought size for a TCP header in the buffer.");
|
||||
}
|
||||
args[1] -= (sizeof(uint8_t) << 1);
|
||||
add_option((Options)args[0], args[1], buffer + index);
|
||||
}
|
||||
index += args[1];
|
||||
// We don't want to store NOPs and EOLs
|
||||
if(args[0] != NOP && args[0] != EOL) {
|
||||
args[1] -= (sizeof(uint8_t) << 1);
|
||||
if(args[1]) {
|
||||
// Not enough size for this option
|
||||
if(header_end - index < args[1])
|
||||
throw std::runtime_error("Not enought size for a TCP header in the buffer.");
|
||||
add_option((Options)args[0], args[1], buffer + index);
|
||||
}
|
||||
index += args[1];
|
||||
}
|
||||
else if(args[0] == EOL)
|
||||
index = header_end;
|
||||
else // Skip the NOP
|
||||
args[0] = 0;
|
||||
}
|
||||
else if(args[0] == EOL)
|
||||
index = header_end;
|
||||
else // Skip the NOP
|
||||
args[0] = 0;
|
||||
buffer += index;
|
||||
total_sz -= index;
|
||||
}
|
||||
buffer += index;
|
||||
total_sz -= index;
|
||||
_total_options_size = header_end;
|
||||
_options_size = (_total_options_size / 4) * 4;
|
||||
}
|
||||
catch(std::runtime_error &err) {
|
||||
cleanup();
|
||||
throw;
|
||||
}
|
||||
if(total_sz)
|
||||
inner_pdu(new RawPDU(buffer, total_sz));
|
||||
}
|
||||
|
||||
Tins::TCP::~TCP() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void Tins::TCP::cleanup() {
|
||||
for(std::list<TCPOption>::iterator it = _options.begin(); it != _options.end(); ++it)
|
||||
delete[] it->data;
|
||||
_options.clear();
|
||||
}
|
||||
|
||||
void Tins::TCP::dport(uint16_t new_dport) {
|
||||
@@ -208,8 +218,11 @@ void Tins::TCP::set_flag(Flags tcp_flag, uint8_t value) {
|
||||
}
|
||||
|
||||
void Tins::TCP::add_option(Options tcp_option, uint8_t length, const uint8_t *data) {
|
||||
uint8_t *new_data = new uint8_t[length], padding;
|
||||
memcpy(new_data, data, length);
|
||||
uint8_t *new_data = 0, padding;
|
||||
if(length) {
|
||||
new_data = new uint8_t[length];
|
||||
memcpy(new_data, data, length);
|
||||
}
|
||||
_options.push_back(TCPOption(tcp_option, length, new_data));
|
||||
_options_size += length + (sizeof(uint8_t) << 1);
|
||||
padding = _options_size & 3;
|
||||
@@ -239,8 +252,8 @@ void Tins::TCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD
|
||||
const Tins::IP *ip_packet = dynamic_cast<const Tins::IP*>(parent);
|
||||
memcpy(tcp_start, &_tcp, sizeof(tcphdr));
|
||||
if(!_tcp.check && ip_packet) {
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->src_addr(), ip_packet->dst_addr(), size(), IPPROTO_TCP) +
|
||||
PDU::do_checksum(tcp_start, tcp_start + total_sz);
|
||||
uint32_t checksum = Utils::pseudoheader_checksum(ip_packet->src_addr(), ip_packet->dst_addr(), size(), IPPROTO_TCP) +
|
||||
Utils::do_checksum(tcp_start, tcp_start + total_sz);
|
||||
while (checksum >> 16)
|
||||
checksum = (checksum & 0xffff) + (checksum >> 16);
|
||||
((tcphdr*)tcp_start)->check = Utils::net_to_host_s(~checksum);
|
||||
@@ -259,8 +272,9 @@ uint8_t *Tins::TCP::TCPOption::write(uint8_t *buffer) {
|
||||
else {
|
||||
buffer[0] = kind;
|
||||
buffer[1] = length + (sizeof(uint8_t) << 1);
|
||||
memcpy(buffer + 2, data, length);
|
||||
return buffer + length + (sizeof(uint8_t) << 1);
|
||||
if(data)
|
||||
memcpy(buffer + 2, data, length);
|
||||
return buffer + buffer[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,8 +83,8 @@ void Tins::UDP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PD
|
||||
length(sizeof(udphdr) + inner_pdu()->size());
|
||||
std::memcpy(buffer, &_udp, sizeof(udphdr));
|
||||
if(!_udp.check && ip_packet) {
|
||||
uint32_t checksum = PDU::pseudoheader_checksum(ip_packet->src_addr(), ip_packet->dst_addr(), size(), IPPROTO_UDP) +
|
||||
PDU::do_checksum(buffer, buffer + total_sz);
|
||||
uint32_t checksum = Utils::pseudoheader_checksum(ip_packet->src_addr(), ip_packet->dst_addr(), size(), IPPROTO_UDP) +
|
||||
Utils::do_checksum(buffer, buffer + total_sz);
|
||||
while (checksum >> 16)
|
||||
checksum = (checksum & 0xffff)+(checksum >> 16);
|
||||
((udphdr*)buffer)->check = Utils::net_to_host_s(~checksum);
|
||||
|
||||
@@ -252,6 +252,31 @@ uint16_t Tins::Utils::channel_to_mhz(uint16_t channel) {
|
||||
return 2407 + (channel * 5);
|
||||
}
|
||||
|
||||
uint32_t Tins::Utils::do_checksum(uint8_t *start, uint8_t *end) {
|
||||
uint32_t checksum(0);
|
||||
uint16_t *ptr = (uint16_t*)start, *last = (uint16_t*)end, padding(0);
|
||||
if(((end - start) & 1) == 1) {
|
||||
last = (uint16_t*)end - 1;
|
||||
padding = *(end - 1) << 8;
|
||||
}
|
||||
while(ptr < last)
|
||||
checksum += Utils::net_to_host_s(*(ptr++));
|
||||
return checksum + padding;
|
||||
}
|
||||
|
||||
uint32_t Tins::Utils::pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag) {
|
||||
uint32_t checksum(0);
|
||||
source_ip = Utils::net_to_host_l(source_ip);
|
||||
dest_ip = Utils::net_to_host_l(dest_ip);
|
||||
uint16_t *ptr = (uint16_t*)&source_ip;
|
||||
|
||||
checksum += (uint32_t)(*ptr) + (uint32_t)(*(ptr+1));
|
||||
ptr = (uint16_t*)&dest_ip;
|
||||
checksum += (uint32_t)(*ptr) + (uint32_t)(*(ptr+1));
|
||||
checksum += flag + len;
|
||||
return checksum;
|
||||
}
|
||||
|
||||
uint32_t Tins::Utils::crc32(uint8_t* data, uint32_t data_size) {
|
||||
uint32_t i, crc = 0;
|
||||
static uint32_t crc_table[] = {
|
||||
|
||||
Reference in New Issue
Block a user