mirror of
https://github.com/mfontanini/libtins
synced 2026-01-30 05:24:26 +01:00
Fixed merging conflicts
This commit is contained in:
@@ -30,7 +30,7 @@
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Class representing an Ethernet II packet
|
||||
* \brief Class representing an Ethernet II PDU.
|
||||
*/
|
||||
class EthernetII : public PDU {
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/** \brief ICMP represents the ICMP PDU.
|
||||
/** \brief Class that represents an ICMP PDU.
|
||||
*
|
||||
* ICMP is the representation of the ICMP PDU. Instances of this class
|
||||
* must be sent over a level 3 PDU, this will otherwise fail.
|
||||
|
||||
@@ -38,6 +38,11 @@ namespace Tins {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Broadcast hardware address.
|
||||
*/
|
||||
static const uint8_t *BROADCAST;
|
||||
|
||||
/**
|
||||
* \brief Enum for the different types of 802.11 frames.
|
||||
*
|
||||
@@ -504,7 +509,7 @@ namespace Tins {
|
||||
PDUType pdu_type() const { return PDU::IEEE802_11; }
|
||||
protected:
|
||||
virtual uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) { return 0; }
|
||||
private:
|
||||
protected:
|
||||
/**
|
||||
* Struct that represents the 802.11 header
|
||||
*/
|
||||
@@ -551,6 +556,7 @@ namespace Tins {
|
||||
} __attribute__((__packed__)) seq_control;
|
||||
|
||||
} __attribute__((__packed__));
|
||||
private:
|
||||
|
||||
IEEE802_11(const ieee80211_header *header_ptr);
|
||||
|
||||
@@ -608,7 +614,7 @@ namespace Tins {
|
||||
|
||||
protected:
|
||||
|
||||
ManagementFrame();
|
||||
ManagementFrame(const uint8_t* dst_hw_addr = 0, const uint8_t* src_hw_addr = 0);
|
||||
ManagementFrame(const std::string& iface, const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr) throw (std::runtime_error);
|
||||
|
||||
struct CapabilityInformation {
|
||||
@@ -668,6 +674,76 @@ namespace Tins {
|
||||
private:
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Class that models the RSN information structure.
|
||||
*/
|
||||
class RSNInformation {
|
||||
public:
|
||||
/**
|
||||
* \brief Enum that represents the different cypher suites.
|
||||
*/
|
||||
enum CypherSuites {
|
||||
WEP_40 = 0x01ac0f00,
|
||||
TKIP = 0x02ac0f00,
|
||||
CCMP = 0x04ac0f00,
|
||||
WEP_104 = 0x05ac0f00
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Enum that represents the different akm suites.
|
||||
*/
|
||||
enum AKMSuites {
|
||||
PMKSA = 0x01ac0f00,
|
||||
PSK = 0x02ac0f00
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RSNInformation.
|
||||
*
|
||||
* By default, the version is set to 1.
|
||||
*/
|
||||
RSNInformation();
|
||||
|
||||
/**
|
||||
* \brief Helper function to create a WPA2-PSK RSNInformation
|
||||
* \return An instance RSNInformation which contains information
|
||||
* for a WPA2-PSK AP.
|
||||
*/
|
||||
static RSNInformation wpa2_psk();
|
||||
|
||||
/**
|
||||
* \brief Adds a pairwise cypher suite.
|
||||
* \param cypher The pairwise cypher suite to be added.
|
||||
*/
|
||||
void add_pairwise_cypher(CypherSuites cypher);
|
||||
|
||||
/**
|
||||
* \brief Adds a akm suite.
|
||||
* \param akm The akm suite to be added.
|
||||
*/
|
||||
void add_akm_cypher(AKMSuites akm);
|
||||
|
||||
/**
|
||||
* \brief Sets the group suite cypher.
|
||||
* \param group The group suite cypher to be set.
|
||||
*/
|
||||
void group_suite(CypherSuites group);
|
||||
|
||||
/**
|
||||
* \brief Serializes this object.
|
||||
* \param size Output parameter which will contain the size of
|
||||
* the allocated buffer.
|
||||
* \return The result of the serialization. This pointer should
|
||||
* be free'd using operator delete[].
|
||||
*/
|
||||
uint8_t *serialize(uint32_t &size) const;
|
||||
private:
|
||||
uint16_t _version, _capabilities;
|
||||
CypherSuites _group_suite;
|
||||
std::list<AKMSuites> _akm_cyphers;
|
||||
std::list<CypherSuites> _pairwise_cyphers;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -680,9 +756,10 @@ namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief Default constructor for the beacon frame.
|
||||
*
|
||||
* \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).
|
||||
*/
|
||||
IEEE802_11_Beacon();
|
||||
IEEE802_11_Beacon(const uint8_t* dst_hw_addr = 0, const uint8_t* src_hw_addr = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor for creating a 802.11 Beacon.
|
||||
@@ -966,6 +1043,12 @@ namespace Tins {
|
||||
*/
|
||||
void channel(uint8_t new_channel);
|
||||
|
||||
/**
|
||||
* \brief Helper method to set the RSN information option.
|
||||
*
|
||||
*/
|
||||
void rsn_information(const RSNInformation& info);
|
||||
|
||||
/**
|
||||
* \brief Returns the frame's header length.
|
||||
*
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief IP represents IP PDU.
|
||||
* \brief Class that represents an IP PDU.
|
||||
*/
|
||||
class IP : public PDU {
|
||||
public:
|
||||
|
||||
@@ -32,14 +32,14 @@ namespace Tins {
|
||||
|
||||
class PacketSender;
|
||||
|
||||
/** \brief PDU is the base class for protocol data units.
|
||||
/** \brief Base class for protocol data units.
|
||||
*
|
||||
* Every PDU implementation must inherit this one. PDUs can be serialized,
|
||||
* therefore allowing a PacketSender to send them through sockets. PDUs
|
||||
* are created upwards: upper layers will be children of the lower ones.
|
||||
* Each PDU must provide its flag identifier. This will be most likely added
|
||||
* to its parent's data, hence it should be a valid identifier. For example,
|
||||
* IP should provide IPPROTO_IP.
|
||||
* therefore allowing a PacketSender to send them through the corresponding
|
||||
* sockets. PDUs are created upwards: upper layers will be children of the
|
||||
* lower ones. Each PDU must provide its flag identifier. This will be most
|
||||
* likely added to its parent's data, hence it should be a valid identifier.
|
||||
* For example, IP should provide IPPROTO_IP.
|
||||
*/
|
||||
class PDU {
|
||||
public:
|
||||
|
||||
@@ -33,17 +33,25 @@ namespace Tins {
|
||||
class RadioTap : public PDU {
|
||||
public:
|
||||
/**
|
||||
* Creates an instance of RadioTap.
|
||||
* \brief Creates an instance of RadioTap.
|
||||
* \param iface The name of the interface in which to send this PDU.
|
||||
*/
|
||||
RadioTap(const std::string &iface) throw (std::runtime_error);
|
||||
|
||||
/**
|
||||
* Creates an instance of RadioTap.
|
||||
* \brief Creates an instance of RadioTap.
|
||||
* \param iface_index The index of the interface in which to send this PDU.
|
||||
*/
|
||||
RadioTap(uint32_t iface_index);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a RadioTap 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.
|
||||
*/
|
||||
RadioTap(const uint8_t *buffer, uint32_t total_sz);
|
||||
|
||||
/* Setters */
|
||||
|
||||
/**
|
||||
|
||||
@@ -119,6 +119,7 @@ namespace Tins {
|
||||
pcap_t *handle;
|
||||
bpf_u_int32 ip, mask;
|
||||
bpf_program actual_filter;
|
||||
bool wired;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
namespace Tins {
|
||||
|
||||
/**
|
||||
* \brief TCP represents the TCP PDU.
|
||||
* \brief Class that represents an TCP PDU.
|
||||
*
|
||||
* TCP is the representation of the TCP PDU. Instances of this class
|
||||
* must be sent over a level 3 PDU, this will otherwise fail.
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
namespace Tins {
|
||||
|
||||
/** \brief UDP represents the UDP PDU.
|
||||
/** \brief Class that represents an UDP PDU.
|
||||
*
|
||||
* UDP is the representation of the UDP PDU. Instances of this class
|
||||
* must be sent over a level 3 PDU, this will otherwise fail.
|
||||
|
||||
@@ -153,6 +153,11 @@ namespace Tins {
|
||||
((data & 0x0000ff00) << 8) | ((data & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert 64 bit integer into network byte order.
|
||||
*
|
||||
* \param data The data to convert.
|
||||
*/
|
||||
inline uint64_t net_to_host_ll(uint64_t data) {
|
||||
return (((uint64_t)(net_to_host_l((uint32_t)((data << 32) >> 32))) << 32) |
|
||||
(net_to_host_l(((uint32_t)(data >> 32)))));
|
||||
@@ -164,7 +169,14 @@ namespace Tins {
|
||||
* \param data_size The size of the input buffer.
|
||||
*/
|
||||
uint32_t crc32(uint8_t* data, uint32_t data_size);
|
||||
|
||||
|
||||
/**
|
||||
* \brief Converts a channel number to its mhz representation.
|
||||
* \param channel The channel number.
|
||||
* \return The channel's mhz representation.
|
||||
*/
|
||||
uint16_t channel_to_mhz(uint16_t channel);
|
||||
|
||||
/** \brief Generic function to iterate through interface and collect
|
||||
* data.
|
||||
*
|
||||
|
||||
@@ -48,7 +48,7 @@ Tins::ARP::ARP(uint32_t target_ip, uint32_t sender_ip, const uint8_t *target_hw,
|
||||
|
||||
Tins::ARP::ARP(const uint8_t *buffer, uint32_t total_sz) : PDU(0x0608) {
|
||||
if(total_sz < sizeof(arphdr))
|
||||
throw std::runtime_error("Not enought size for an ARP header in the buffer.");
|
||||
throw std::runtime_error("Not enough size for an ARP header in the buffer.");
|
||||
memcpy(&_arp, buffer, sizeof(arphdr));
|
||||
total_sz -= sizeof(arphdr);
|
||||
if(total_sz)
|
||||
|
||||
@@ -13,7 +13,7 @@ Tins::BootP::BootP() : PDU(255), _vend_size(64) {
|
||||
|
||||
Tins::BootP::BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size) : PDU(255), _vend(0), _vend_size(vend_field_size) {
|
||||
if(total_sz < sizeof(bootphdr) + vend_field_size)
|
||||
throw std::runtime_error("Not enought size for a BootP header in the buffer.");
|
||||
throw std::runtime_error("Not enough size for a BootP header in the buffer.");
|
||||
std::memcpy(&_bootp, buffer, sizeof(bootphdr));
|
||||
buffer += sizeof(bootphdr);
|
||||
total_sz -= sizeof(bootphdr);
|
||||
|
||||
@@ -46,13 +46,13 @@ Tins::DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz) : BootP(buffer, total
|
||||
args[i] = *(buffer++);
|
||||
total_sz--;
|
||||
if(!total_sz)
|
||||
throw std::runtime_error("Not enought size for a DHCP header in the buffer.");
|
||||
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
|
||||
}
|
||||
// If the END-OF-OPTIONS was not found...
|
||||
if(args[0] != END) {
|
||||
// Not enough size for this option
|
||||
if(total_sz < args[1])
|
||||
throw std::runtime_error("Not enought size for a DHCP header in the buffer.");
|
||||
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
|
||||
add_option((Options)args[0], args[1], buffer);
|
||||
buffer += args[1];
|
||||
total_sz -= args[1];
|
||||
|
||||
@@ -58,7 +58,7 @@ Tins::EthernetII::EthernetII(uint32_t iface_index, const uint8_t* dst_hw_addr, c
|
||||
|
||||
Tins::EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz) : PDU(ETHERTYPE_IP) {
|
||||
if(total_sz < sizeof(ethhdr))
|
||||
throw std::runtime_error("Not enought size for an ethernetII header in the buffer.");
|
||||
throw std::runtime_error("Not enough size for an ethernetII header in the buffer.");
|
||||
memcpy(&_eth, buffer, sizeof(ethhdr));
|
||||
PDU *next = 0;
|
||||
switch(payload_type()) {
|
||||
|
||||
@@ -50,7 +50,7 @@ Tins::ICMP::ICMP(Flags flag) : PDU(IPPROTO_ICMP) {
|
||||
|
||||
Tins::ICMP::ICMP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_ICMP) {
|
||||
if(total_sz < sizeof(icmphdr))
|
||||
throw std::runtime_error("Not enought size for an ICMP header in the buffer.");
|
||||
throw std::runtime_error("Not enough size for an ICMP header in the buffer.");
|
||||
std::memcpy(&_icmp, buffer, sizeof(icmphdr));
|
||||
total_sz -= sizeof(icmphdr);
|
||||
if(total_sz)
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
const uint8_t *Tins::IEEE802_11::BROADCAST = (const uint8_t*)"\xff\xff\xff\xff\xff\xff";
|
||||
|
||||
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)
|
||||
@@ -60,10 +62,21 @@ 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), _options_size(0) {
|
||||
Tins::IEEE802_11::IEEE802_11(const ieee80211_header *header_ptr) : PDU(ETHERTYPE_IP) {
|
||||
|
||||
}
|
||||
|
||||
Tins::IEEE802_11::IEEE802_11(const uint8_t *buffer, uint32_t total_sz) : PDU(ETHERTYPE_IP), _options_size(0) {
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an RadioTap header in the buffer.");
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
|
||||
// Tagged arguments missing.
|
||||
// subclass specific parsing missing too.
|
||||
}
|
||||
|
||||
Tins::IEEE802_11::~IEEE802_11() {
|
||||
while(_options.size()) {
|
||||
delete[] _options.front().value;
|
||||
@@ -203,11 +216,12 @@ void Tins::IEEE802_11::write_serialization(uint8_t *buffer, uint32_t total_sz, c
|
||||
}
|
||||
}
|
||||
|
||||
Tins::IEEE802_11::IEEE802_11(const ieee80211_header *header_ptr) : PDU(ETHERTYPE_IP) {
|
||||
|
||||
}
|
||||
/*
|
||||
* ManagementFrame
|
||||
*/
|
||||
|
||||
Tins::ManagementFrame::ManagementFrame() : IEEE802_11() {
|
||||
Tins::ManagementFrame::ManagementFrame(const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr) : IEEE802_11(dst_hw_addr, src_hw_addr) {
|
||||
this->type(IEEE802_11::MANAGEMENT);
|
||||
}
|
||||
|
||||
@@ -217,7 +231,12 @@ Tins::ManagementFrame::ManagementFrame(const std::string& iface,
|
||||
this->type(IEEE802_11::MANAGEMENT);
|
||||
}
|
||||
|
||||
Tins::IEEE802_11_Beacon::IEEE802_11_Beacon() : ManagementFrame() {
|
||||
|
||||
/*
|
||||
* Beacon
|
||||
*/
|
||||
|
||||
Tins::IEEE802_11_Beacon::IEEE802_11_Beacon(const uint8_t* dst_hw_addr, const uint8_t* src_hw_addr) : ManagementFrame() {
|
||||
this->subtype(IEEE802_11::BEACON);
|
||||
memset(&_body, 0, sizeof(_body));
|
||||
}
|
||||
@@ -245,7 +264,7 @@ void Tins::IEEE802_11_Beacon::rates(const std::list<float> &new_rates) {
|
||||
uint8_t *buffer = new uint8_t[new_rates.size()], *ptr = buffer;
|
||||
for(std::list<float>::const_iterator it = new_rates.begin(); it != new_rates.end(); ++it) {
|
||||
uint8_t result = 0x80, left = *it / 0.5;
|
||||
if(*it - left > 0) //arbitrary value
|
||||
if(*it - left > 0)
|
||||
left++;
|
||||
*(ptr++) = (result | left);
|
||||
}
|
||||
@@ -257,6 +276,13 @@ void Tins::IEEE802_11_Beacon::channel(uint8_t new_channel) {
|
||||
add_tagged_option(DS_SET, 1, &new_channel);
|
||||
}
|
||||
|
||||
void Tins::IEEE802_11_Beacon::rsn_information(const RSNInformation& info) {
|
||||
uint32_t size;
|
||||
uint8_t *buffer = info.serialize(size);
|
||||
add_tagged_option(RSN, size, buffer);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
uint32_t Tins::IEEE802_11_Beacon::header_size() const {
|
||||
return IEEE802_11::header_size() + sizeof(BeaconBody);
|
||||
}
|
||||
@@ -294,3 +320,56 @@ uint32_t Tins::IEEE802_11_Disassoc::write_fixed_parameters(uint8_t *buffer, uint
|
||||
memcpy(buffer, &this->_body, sz);
|
||||
return sz;
|
||||
}
|
||||
|
||||
/*
|
||||
* RSNInformation class
|
||||
*/
|
||||
Tins::RSNInformation::RSNInformation() : _version(1), _capabilities(0) {
|
||||
|
||||
}
|
||||
|
||||
void Tins::RSNInformation::add_pairwise_cypher(CypherSuites cypher) {
|
||||
_pairwise_cyphers.push_back(cypher);
|
||||
}
|
||||
|
||||
void Tins::RSNInformation::add_akm_cypher(AKMSuites akm) {
|
||||
_akm_cyphers.push_back(akm);
|
||||
}
|
||||
|
||||
void Tins::RSNInformation::group_suite(CypherSuites group) {
|
||||
_group_suite = group;
|
||||
}
|
||||
|
||||
uint8_t *Tins::RSNInformation::serialize(uint32_t &size) const {
|
||||
size = sizeof(_version) + sizeof(_capabilities) + sizeof(uint32_t);
|
||||
size += (sizeof(uint16_t) << 1); // 2 lists count.
|
||||
size += sizeof(uint32_t) * (_akm_cyphers.size() + _pairwise_cyphers.size());
|
||||
|
||||
uint8_t *buffer = new uint8_t[size], *ptr = buffer;
|
||||
*(uint16_t*)ptr = _version;
|
||||
ptr += sizeof(_version);
|
||||
*(uint32_t*)ptr = _group_suite;
|
||||
ptr += sizeof(uint32_t);
|
||||
*(uint16_t*)ptr = _pairwise_cyphers.size();
|
||||
ptr += sizeof(uint16_t);
|
||||
for(std::list<CypherSuites>::const_iterator it = _pairwise_cyphers.begin(); it != _pairwise_cyphers.end(); ++it) {
|
||||
*(uint32_t*)ptr = *it;
|
||||
ptr += sizeof(uint32_t);
|
||||
}
|
||||
*(uint16_t*)ptr = _akm_cyphers.size();
|
||||
ptr += sizeof(uint16_t);
|
||||
for(std::list<AKMSuites>::const_iterator it = _akm_cyphers.begin(); it != _akm_cyphers.end(); ++it) {
|
||||
*(uint32_t*)ptr = *it;
|
||||
ptr += sizeof(uint32_t);
|
||||
}
|
||||
*(uint16_t*)ptr = _capabilities;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
Tins::RSNInformation Tins::RSNInformation::wpa2_psk() {
|
||||
RSNInformation info;
|
||||
info.group_suite(RSNInformation::CCMP);
|
||||
info.add_pairwise_cypher(RSNInformation::CCMP);
|
||||
info.add_akm_cypher(RSNInformation::PSK);
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ Tins::IP::IP(const string &ip_dst, const string &ip_src, PDU *child) : PDU(IPPRO
|
||||
|
||||
Tins::IP::IP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_IP) {
|
||||
if(total_sz < sizeof(iphdr))
|
||||
throw std::runtime_error("Not enought size for an IP header in the buffer.");
|
||||
throw std::runtime_error("Not enough size for an IP header in the buffer.");
|
||||
std::memcpy(&_ip, buffer, sizeof(iphdr));
|
||||
|
||||
/* Options... */
|
||||
|
||||
@@ -40,6 +40,74 @@ Tins::RadioTap::RadioTap(uint32_t iface_index) : PDU(0xff), _iface_index(iface_i
|
||||
std::memset(&_radio, 0, sizeof(_radio));
|
||||
}
|
||||
|
||||
Tins::RadioTap::RadioTap(const uint8_t *buffer, uint32_t total_sz) : PDU(0xff) {
|
||||
if(total_sz < sizeof(_radio))
|
||||
throw std::runtime_error("Not enough size for an RadioTap header in the buffer.");
|
||||
const uint8_t *buffer_start = buffer;
|
||||
std::memcpy(&_radio, buffer, sizeof(_radio));
|
||||
buffer += sizeof(_radio);
|
||||
total_sz -= sizeof(_radio);
|
||||
if(_radio.tsft) {
|
||||
if(total_sz < sizeof(_tsft))
|
||||
throw std::runtime_error("Not enough size for an RadioTap header in the buffer.");
|
||||
memcpy(&_tsft, buffer, sizeof(_tsft));
|
||||
buffer += sizeof(_tsft);
|
||||
total_sz -= sizeof(_tsft);
|
||||
}
|
||||
if(_radio.flags) {
|
||||
if(total_sz < sizeof(_flags))
|
||||
throw std::runtime_error("Not enough size for an RadioTap header in the buffer.");
|
||||
memcpy(&_flags, buffer, sizeof(_flags));
|
||||
buffer += sizeof(_flags);
|
||||
total_sz -= sizeof(_flags);
|
||||
}
|
||||
if(_radio.rate) {
|
||||
if(total_sz < sizeof(_rate))
|
||||
throw std::runtime_error("Not enough size for an RadioTap header in the buffer.");
|
||||
memcpy(&_rate, buffer, sizeof(_rate));
|
||||
buffer += sizeof(_rate);
|
||||
total_sz -= sizeof(_rate);
|
||||
}
|
||||
if(_radio.channel) {
|
||||
if(((buffer_start - buffer) & 1) == 1) {
|
||||
buffer++;
|
||||
total_sz--;
|
||||
}
|
||||
if(total_sz < sizeof(uint32_t))
|
||||
throw std::runtime_error("Not enough size for an RadioTap header in the buffer.");
|
||||
memcpy(&_channel_freq, buffer, sizeof(_channel_freq));
|
||||
buffer += sizeof(_channel_freq);
|
||||
memcpy(&_channel_type, buffer, sizeof(_channel_type));
|
||||
buffer += sizeof(_channel_type);
|
||||
total_sz -= sizeof(uint32_t);
|
||||
}
|
||||
if(_radio.dbm_signal) {
|
||||
if(total_sz < sizeof(_dbm_signal))
|
||||
throw std::runtime_error("Not enough size for an RadioTap header in the buffer.");
|
||||
memcpy(&_dbm_signal, buffer, sizeof(_dbm_signal));
|
||||
buffer += sizeof(_dbm_signal);
|
||||
total_sz -= sizeof(_dbm_signal);
|
||||
}
|
||||
if(_radio.antenna) {
|
||||
if(total_sz < sizeof(_antenna))
|
||||
throw std::runtime_error("Not enough size for an RadioTap header in the buffer.");
|
||||
memcpy(&_antenna, buffer, sizeof(_antenna));
|
||||
buffer += sizeof(_antenna);
|
||||
total_sz -= sizeof(_antenna);
|
||||
}
|
||||
if(_radio.rx_flags) {
|
||||
if(((buffer_start - buffer) & 1) == 1) {
|
||||
buffer++;
|
||||
total_sz--;
|
||||
}
|
||||
if(total_sz < sizeof(_rx_flags))
|
||||
throw std::runtime_error("Not enough size for an RadioTap header in the buffer.");
|
||||
memcpy(&_rx_flags, buffer, sizeof(_rx_flags));
|
||||
buffer += sizeof(_rx_flags);
|
||||
total_sz -= sizeof(_rx_flags);
|
||||
}
|
||||
}
|
||||
|
||||
void Tins::RadioTap::version(uint8_t new_version) {
|
||||
_radio.it_version = new_version;
|
||||
}
|
||||
@@ -112,7 +180,7 @@ uint32_t Tins::RadioTap::header_size() const {
|
||||
|
||||
uint32_t Tins::RadioTap::trailer_size() const {
|
||||
// will be sizeof(uint32_t) if the FCS-at-the-end bit is on.
|
||||
return ((_radio.flags & 0x10) == 1) ? sizeof(uint32_t) : 0;
|
||||
return ((_flags & 0x10) != 0) ? sizeof(uint32_t) : 0;
|
||||
}
|
||||
|
||||
bool Tins::RadioTap::send(PacketSender* sender) {
|
||||
@@ -174,6 +242,6 @@ void Tins::RadioTap::write_serialization(uint8_t *buffer, uint32_t total_sz, con
|
||||
memcpy(buffer, &_rx_flags, sizeof(_rx_flags));
|
||||
buffer += sizeof(_rx_flags);
|
||||
}
|
||||
if((_radio.flags & 0x10) == 1 && inner_pdu())
|
||||
if((_flags & 0x10) != 0 && inner_pdu())
|
||||
*(uint32_t*)(buffer + inner_pdu()->size()) = Utils::crc32(buffer, inner_pdu()->size());
|
||||
}
|
||||
|
||||
@@ -20,9 +20,11 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <iostream> //borrame
|
||||
#include <stdexcept>
|
||||
#include "sniffer.h"
|
||||
#include "ethernetII.h"
|
||||
#include "radiotap.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
@@ -32,8 +34,9 @@ using namespace std;
|
||||
struct LoopData {
|
||||
pcap_t *handle;
|
||||
Tins::AbstractSnifferHandler *c_handler;
|
||||
bool wired;
|
||||
|
||||
LoopData(pcap_t *_handle, Tins::AbstractSnifferHandler *_handler) : handle(_handle), c_handler(_handler) { }
|
||||
LoopData(pcap_t *_handle, Tins::AbstractSnifferHandler *_handler, bool is_wired) : handle(_handle), c_handler(_handler), wired(is_wired) { }
|
||||
};
|
||||
|
||||
/** \endcond */
|
||||
@@ -41,11 +44,14 @@ struct LoopData {
|
||||
|
||||
Tins::Sniffer::Sniffer(const string &device, unsigned max_packet_size) {
|
||||
char error[PCAP_ERRBUF_SIZE];
|
||||
if (pcap_lookupnet(device.c_str(), &ip, &mask, error) == -1)
|
||||
throw runtime_error(error);
|
||||
if (pcap_lookupnet(device.c_str(), &ip, &mask, error) == -1) {
|
||||
ip = 0;
|
||||
mask = 0;
|
||||
}
|
||||
handle = pcap_open_live(device.c_str(), max_packet_size, 0, 0, error);
|
||||
if(!handle)
|
||||
throw runtime_error(error);
|
||||
wired = (pcap_datalink (handle) != DLT_IEEE802_11_RADIO); //better plx
|
||||
actual_filter.bf_insns = 0;
|
||||
}
|
||||
|
||||
@@ -65,12 +71,17 @@ Tins::PDU *Tins::Sniffer::next_packet(const string &filter) {
|
||||
set_filter(filter);
|
||||
pcap_pkthdr header;
|
||||
PDU *ret = 0;
|
||||
std::cout << "Wired: " << wired << "\n";
|
||||
while(!ret) {
|
||||
const u_char *content = pcap_next(handle, &header);
|
||||
try {
|
||||
ret = new EthernetII((const uint8_t*)content, header.caplen);
|
||||
if(wired)
|
||||
ret = new EthernetII((const uint8_t*)content, header.caplen);
|
||||
else
|
||||
ret = new RadioTap((const uint8_t*)content, header.caplen);
|
||||
}
|
||||
catch(...) {
|
||||
std::cout << "Except!\n";
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
@@ -84,7 +95,7 @@ void Tins::Sniffer::stop_sniff() {
|
||||
void Tins::Sniffer::sniff_loop(AbstractSnifferHandler *cback_handler, const string &filter, uint32_t max_packets) {
|
||||
if(filter.size())
|
||||
set_filter(filter);
|
||||
LoopData data(handle, cback_handler);
|
||||
LoopData data(handle, cback_handler, wired);
|
||||
pcap_loop(handle, max_packets, Sniffer::callback_handler, (u_char*)&data);
|
||||
}
|
||||
|
||||
@@ -97,8 +108,12 @@ bool Tins::Sniffer::set_filter(const std::string &filter) {
|
||||
// Static
|
||||
void Tins::Sniffer::callback_handler(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
|
||||
try {
|
||||
PDU *pdu = new EthernetII((const uint8_t*)packet, header->caplen);
|
||||
PDU *pdu = 0;
|
||||
LoopData *data = reinterpret_cast<LoopData*>(args);
|
||||
if(data->wired)
|
||||
pdu = new EthernetII((const uint8_t*)packet, header->caplen);
|
||||
else
|
||||
pdu = new RadioTap((const uint8_t*)packet, header->caplen);
|
||||
bool ret_val = data->c_handler->handle(pdu);
|
||||
delete pdu;
|
||||
if(!ret_val)
|
||||
|
||||
@@ -44,7 +44,7 @@ Tins::TCP::TCP(uint16_t dport, uint16_t sport) : PDU(IPPROTO_TCP), _options_size
|
||||
|
||||
Tins::TCP::TCP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_TCP) {
|
||||
if(total_sz < sizeof(tcphdr))
|
||||
throw std::runtime_error("Not enought size for an TCP header in the buffer.");
|
||||
throw std::runtime_error("Not enough size for an TCP header in the buffer.");
|
||||
std::memcpy(&_tcp, buffer, sizeof(tcphdr));
|
||||
|
||||
buffer += sizeof(tcphdr);
|
||||
|
||||
@@ -39,7 +39,7 @@ Tins::UDP::UDP(uint16_t dport, uint16_t sport, PDU *child) : PDU(IPPROTO_UDP, ch
|
||||
|
||||
Tins::UDP::UDP(const uint8_t *buffer, uint32_t total_sz) : PDU(IPPROTO_UDP) {
|
||||
if(total_sz < sizeof(udphdr))
|
||||
throw std::runtime_error("Not enought size for an UDP header in the buffer.");
|
||||
throw std::runtime_error("Not enough size for an UDP header in the buffer.");
|
||||
std::memcpy(&_udp, buffer, sizeof(udphdr));
|
||||
total_sz -= sizeof(udphdr);
|
||||
if(total_sz)
|
||||
|
||||
@@ -248,6 +248,10 @@ bool Tins::Utils::interface_id(const string &iface, uint32_t &id) {
|
||||
return (((int32_t)id) != -1);
|
||||
}
|
||||
|
||||
uint16_t Tins::Utils::channel_to_mhz(uint16_t channel) {
|
||||
return 2407 + (channel * 5);
|
||||
}
|
||||
|
||||
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