From 730dcdea440a8ddf7cc205b47f4dfc39516fdd4c Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 23 Aug 2011 12:01:59 -0300 Subject: [PATCH 1/9] Added Utils::channel_to_mhz to convert channel to mhz frequency. --- include/utils.h | 9 ++++++++- src/utils.cpp | 4 ++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/utils.h b/include/utils.h index 4ab9bed..ece8024 100644 --- a/include/utils.h +++ b/include/utils.h @@ -164,7 +164,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. * diff --git a/src/utils.cpp b/src/utils.cpp index 4c033de..adcc1ce 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -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[] = { From e323be12e63a36f5110ece4bd2ab0cae8de47474 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 23 Aug 2011 12:03:49 -0300 Subject: [PATCH 2/9] Added IEEE802_11::BROADCAST. --- include/ieee802-11.h | 5 +++++ src/ieee802-11.cpp | 2 ++ 2 files changed, 7 insertions(+) diff --git a/include/ieee802-11.h b/include/ieee802-11.h index 4088535..88cd27f 100644 --- a/include/ieee802-11.h +++ b/include/ieee802-11.h @@ -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. * diff --git a/src/ieee802-11.cpp b/src/ieee802-11.cpp index 29e207a..e14f198 100644 --- a/src/ieee802-11.cpp +++ b/src/ieee802-11.cpp @@ -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) From 8afe3d7429d6dde9c0d1564b3855cff45355a0ae Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 23 Aug 2011 12:04:15 -0300 Subject: [PATCH 3/9] Fixed RadioTap FCS flag check. --- src/radiotap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/radiotap.cpp b/src/radiotap.cpp index a1826e0..46e6b13 100644 --- a/src/radiotap.cpp +++ b/src/radiotap.cpp @@ -112,7 +112,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 +174,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()); } From 2510c825cd688ceb480e4742c5cd86b5c800ddbf Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 23 Aug 2011 21:32:13 -0300 Subject: [PATCH 4/9] Fixed/added documentation to several classes. --- include/ethernetII.h | 2 +- include/icmp.h | 2 +- include/ip.h | 2 +- include/pdu.h | 12 ++++++------ include/tcp.h | 2 +- include/udp.h | 2 +- include/utils.h | 5 +++++ 7 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/ethernetII.h b/include/ethernetII.h index ca1adc0..dd3e30b 100644 --- a/include/ethernetII.h +++ b/include/ethernetII.h @@ -30,7 +30,7 @@ namespace Tins { /** - * \brief Class representing an Ethernet II packet + * \brief Class representing an Ethernet II PDU. */ class EthernetII : public PDU { diff --git a/include/icmp.h b/include/icmp.h index e63dcf6..28b30a8 100644 --- a/include/icmp.h +++ b/include/icmp.h @@ -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. diff --git a/include/ip.h b/include/ip.h index e8b09dd..5c0cb3b 100644 --- a/include/ip.h +++ b/include/ip.h @@ -34,7 +34,7 @@ namespace Tins { /** - * \brief IP represents IP PDU. + * \brief Class that represents an IP PDU. */ class IP : public PDU { public: diff --git a/include/pdu.h b/include/pdu.h index c1be273..47b3ea1 100644 --- a/include/pdu.h +++ b/include/pdu.h @@ -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: diff --git a/include/tcp.h b/include/tcp.h index abf6a2f..16e8f39 100644 --- a/include/tcp.h +++ b/include/tcp.h @@ -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. diff --git a/include/udp.h b/include/udp.h index 096d5b3..82d2405 100644 --- a/include/udp.h +++ b/include/udp.h @@ -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. diff --git a/include/utils.h b/include/utils.h index ece8024..9c82b97 100644 --- a/include/utils.h +++ b/include/utils.h @@ -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))))); From 422b9f93ff723e825a2cd7d73f4ab4cddb11ebf2 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 23 Aug 2011 21:33:26 -0300 Subject: [PATCH 5/9] Added RSNInformation class. Added helper function in IEEE802_11_Beacon to add a RSN information option. --- include/ieee802-11.h | 86 ++++++++++++++++++++++++++++++++++++++++---- src/ieee802-11.cpp | 81 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 156 insertions(+), 11 deletions(-) diff --git a/include/ieee802-11.h b/include/ieee802-11.h index 88cd27f..09e0ba5 100644 --- a/include/ieee802-11.h +++ b/include/ieee802-11.h @@ -578,7 +578,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 { @@ -638,6 +638,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 _akm_cyphers; + std::list _pairwise_cyphers; }; /** @@ -650,9 +720,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. @@ -935,6 +1006,12 @@ namespace Tins { * \param new_channel The new channel to be set. */ 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. @@ -956,9 +1033,6 @@ namespace Tins { uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz); }; - - - } #endif diff --git a/src/ieee802-11.cpp b/src/ieee802-11.cpp index e14f198..c274f31 100644 --- a/src/ieee802-11.cpp +++ b/src/ieee802-11.cpp @@ -62,6 +62,10 @@ 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 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) { } @@ -205,11 +209,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); } @@ -219,7 +224,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)); } @@ -247,7 +257,7 @@ void Tins::IEEE802_11_Beacon::rates(const std::list &new_rates) { uint8_t *buffer = new uint8_t[new_rates.size()], *ptr = buffer; for(std::list::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); } @@ -259,6 +269,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); } @@ -270,3 +287,57 @@ uint32_t Tins::IEEE802_11_Beacon::write_fixed_parameters(uint8_t *buffer, uint32 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::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::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; +} + From 22b84e5df00b2d930e79680729fef871baf24128 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 23 Aug 2011 23:57:35 -0300 Subject: [PATCH 6/9] Created IEEE802_11 constructor from buffer. Tagged option parsing and subclass parsing is missing. --- include/ieee802-11.h | 5 +++-- src/ieee802-11.cpp | 11 +++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/include/ieee802-11.h b/include/ieee802-11.h index 09e0ba5..fb44950 100644 --- a/include/ieee802-11.h +++ b/include/ieee802-11.h @@ -509,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 */ @@ -556,7 +556,8 @@ namespace Tins { } __attribute__((__packed__)) seq_control; } __attribute__((__packed__)); - + private: + IEEE802_11(const ieee80211_header *header_ptr); void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent); diff --git a/src/ieee802-11.cpp b/src/ieee802-11.cpp index c274f31..adb409b 100644 --- a/src/ieee802-11.cpp +++ b/src/ieee802-11.cpp @@ -63,11 +63,18 @@ Tins::IEEE802_11::IEEE802_11(uint32_t iface_index, const uint8_t* dst_hw_addr, c } 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() { From 2fa66c814d818996a17ef92c4bf32398408c3b9e Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 23 Aug 2011 23:58:05 -0300 Subject: [PATCH 7/9] Added RadioTap constructor from buffer. It's working, although some flags are not implemented yet. --- include/radiotap.h | 12 ++++++-- src/radiotap.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/include/radiotap.h b/include/radiotap.h index e620d8e..fe702ab 100644 --- a/include/radiotap.h +++ b/include/radiotap.h @@ -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 */ /** diff --git a/src/radiotap.cpp b/src/radiotap.cpp index 46e6b13..f65e383 100644 --- a/src/radiotap.cpp +++ b/src/radiotap.cpp @@ -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; } From b746451b75b3a525cbe91c1b4e2f64b8b68a50db Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 23 Aug 2011 23:58:59 -0300 Subject: [PATCH 8/9] Sniffing now returns a RadioTap PDU when performed on wireless interfaces. --- include/sniffer.h | 1 + src/sniffer.cpp | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/include/sniffer.h b/include/sniffer.h index c683d4e..8782d8f 100644 --- a/include/sniffer.h +++ b/include/sniffer.h @@ -119,6 +119,7 @@ namespace Tins { pcap_t *handle; bpf_u_int32 ip, mask; bpf_program actual_filter; + bool wired; }; /** diff --git a/src/sniffer.cpp b/src/sniffer.cpp index eb66844..ba644b5 100644 --- a/src/sniffer.cpp +++ b/src/sniffer.cpp @@ -20,9 +20,11 @@ */ +#include //borrame #include #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(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) From 7ccae0c9948b47339794532bcb06723778743057 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Wed, 24 Aug 2011 00:00:24 -0300 Subject: [PATCH 9/9] Fixed exception syntax error.. --- src/arp.cpp | 2 +- src/bootp.cpp | 2 +- src/dhcp.cpp | 4 ++-- src/ethernetII.cpp | 2 +- src/icmp.cpp | 2 +- src/ip.cpp | 2 +- src/tcp.cpp | 2 +- src/udp.cpp | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/arp.cpp b/src/arp.cpp index ab58e43..6e01902 100644 --- a/src/arp.cpp +++ b/src/arp.cpp @@ -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) diff --git a/src/bootp.cpp b/src/bootp.cpp index 0199e5f..9b5105f 100644 --- a/src/bootp.cpp +++ b/src/bootp.cpp @@ -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); diff --git a/src/dhcp.cpp b/src/dhcp.cpp index d26d44c..47f2215 100644 --- a/src/dhcp.cpp +++ b/src/dhcp.cpp @@ -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]; diff --git a/src/ethernetII.cpp b/src/ethernetII.cpp index 9a3f38e..7fa793c 100644 --- a/src/ethernetII.cpp +++ b/src/ethernetII.cpp @@ -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()) { diff --git a/src/icmp.cpp b/src/icmp.cpp index e3ca194..e7bc639 100644 --- a/src/icmp.cpp +++ b/src/icmp.cpp @@ -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) diff --git a/src/ip.cpp b/src/ip.cpp index ab62951..1ba0834 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -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... */ diff --git a/src/tcp.cpp b/src/tcp.cpp index 5f662e0..60560ad 100644 --- a/src/tcp.cpp +++ b/src/tcp.cpp @@ -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); diff --git a/src/udp.cpp b/src/udp.cpp index ca0250c..a274c91 100644 --- a/src/udp.cpp +++ b/src/udp.cpp @@ -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)