From dfc0498b702b91ae1f9d460edd45d02de42b59db Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Tue, 26 Mar 2013 14:54:24 -0300 Subject: [PATCH] DNS, RadioTap and Dot1Q work when using PacketSender::send_recv. --- include/dns.h | 9 +++++++++ include/dot1q.h | 17 ++++++++++++++++- include/ethernetII.h | 3 ++- include/radiotap.h | 8 ++++++++ src/dns.cpp | 7 +++++++ src/dot1q.cpp | 27 +++++++++++++++++++++++++++ src/dot3.cpp | 12 ++++++++---- src/ethernetII.cpp | 9 ++++++--- src/radiotap.cpp | 12 ++++++++++++ 9 files changed, 95 insertions(+), 9 deletions(-) diff --git a/include/dns.h b/include/dns.h index c99e08e..c870fb9 100644 --- a/include/dns.h +++ b/include/dns.h @@ -566,6 +566,15 @@ namespace Tins { */ resources_type answers() const; + /** + * \brief Check wether ptr points to a valid response for this PDU. + * + * \sa PDU::matches_response + * \param ptr The pointer to the buffer. + * \param total_sz The size of the buffer. + */ + bool matches_response(uint8_t *ptr, uint32_t total_sz); + /** * \sa PDU::clone */ diff --git a/include/dot1q.h b/include/dot1q.h index 29686cc..d1c9224 100644 --- a/include/dot1q.h +++ b/include/dot1q.h @@ -92,7 +92,11 @@ public: * \return The stored id field value. */ small_uint<12> id() const { - return _header.idL | (_header.idH << 8); + #if TINS_IS_LITTLE_ENDIAN + return _header.idL | (_header.idH << 8); + #else + return _header.id; + #endif } /** @@ -141,6 +145,15 @@ public: * \param new_type The new type field value. */ void payload_type(uint16_t new_type); + + /** + * \brief Check wether ptr points to a valid response for this PDU. + * + * \sa PDU::matches_response + * \param ptr The pointer to the buffer. + * \param total_sz The size of the buffer. + */ + bool matches_response(uint8_t *ptr, uint32_t total_sz); private: void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent); @@ -159,6 +172,8 @@ private: #endif }; + static uint16_t get_id(const dot1q_hdr *hdr); + dot1q_hdr _header; }; } diff --git a/include/ethernetII.h b/include/ethernetII.h index cb472cd..b602b1e 100644 --- a/include/ethernetII.h +++ b/include/ethernetII.h @@ -160,7 +160,8 @@ namespace Tins { void send(PacketSender &sender); #endif // WIN32 - /** \brief Check wether ptr points to a valid response for this PDU. + /** + * \brief Check wether ptr points to a valid response for this PDU. * * \sa PDU::matches_response * \param ptr The pointer to the buffer. diff --git a/include/radiotap.h b/include/radiotap.h index 1340d32..9786091 100644 --- a/include/radiotap.h +++ b/include/radiotap.h @@ -306,6 +306,14 @@ namespace Tins { */ const NetworkInterface &iface() const { return _iface; } + /** \brief Check wether ptr points to a valid response for this PDU. + * + * \sa PDU::matches_response + * \param ptr The pointer to the buffer. + * \param total_sz The size of the buffer. + */ + bool matches_response(uint8_t *ptr, uint32_t total_sz); + /** * \brief Returns the RadioTap frame's header length. * diff --git a/src/dns.cpp b/src/dns.cpp index ab22463..3d49f48 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -476,4 +476,11 @@ DNS::resources_type DNS::answers() const { convert_resources(ans, res); return res; } + +bool DNS::matches_response(uint8_t *ptr, uint32_t total_sz) { + if(total_sz < sizeof(dnshdr)) + return false; + const dnshdr *hdr = (const dnshdr*)ptr; + return hdr->id == dns.id; +} } diff --git a/src/dot1q.cpp b/src/dot1q.cpp index 8693500..6e975b2 100644 --- a/src/dot1q.cpp +++ b/src/dot1q.cpp @@ -68,8 +68,12 @@ void Dot1Q::cfi(small_uint<1> new_cfi) { } void Dot1Q::id(small_uint<12> new_id) { + #if TINS_IS_LITTLE_ENDIAN _header.idL = new_id & 0xff; _header.idH = new_id >> 8; + #else + _header.id = new_id; + #endif } void Dot1Q::payload_type(uint16_t new_type) { @@ -103,4 +107,27 @@ void Dot1Q::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) buffer += sizeof(_header) + inner_pdu()->size(); std::fill(buffer, buffer + trailer, 0); } + +#if TINS_IS_LITTLE_ENDIAN + uint16_t Dot1Q::get_id(const dot1q_hdr *hdr) { + return hdr->idL | (hdr->idH << 8); + } +#else + uint16_t Dot1Q::get_id(const dot1q_hdr *hdr) { + return hdr->id; + } +#endif + +bool Dot1Q::matches_response(uint8_t *ptr, uint32_t total_sz) { + if(total_sz < sizeof(_header)) + return false; + const dot1q_hdr *dot1q_ptr = (const dot1q_hdr*)ptr; + if(get_id(dot1q_ptr) == get_id(&_header)) { + ptr += sizeof(_header); + total_sz -= sizeof(_header); + return inner_pdu() ? inner_pdu()->matches_response(ptr, total_sz) : true; + } + return false; + +} } diff --git a/src/dot3.cpp b/src/dot3.cpp index 0a71451..b6d1269 100644 --- a/src/dot3.cpp +++ b/src/dot3.cpp @@ -118,11 +118,15 @@ void Dot3::send(PacketSender &sender) { bool Dot3::matches_response(uint8_t *ptr, uint32_t total_sz) { if(total_sz < sizeof(ethhdr)) return false; + const size_t addr_sz = address_type::address_size; const ethhdr *eth_ptr = (const ethhdr*)ptr; - if(!memcmp(eth_ptr->dst_mac, _eth.src_mac, sizeof(_eth.src_mac))) { - ptr += sizeof(ethhdr); - total_sz -= sizeof(ethhdr); - return inner_pdu() ? inner_pdu()->matches_response(ptr, total_sz) : true; + if(std::equal(_eth.src_mac, _eth.src_mac + addr_sz, eth_ptr->dst_mac)) { + if(std::equal(_eth.src_mac, _eth.src_mac + addr_sz, eth_ptr->dst_mac) || dst_addr() == BROADCAST) + { + ptr += sizeof(ethhdr); + total_sz -= sizeof(ethhdr); + return inner_pdu() ? inner_pdu()->matches_response(ptr, total_sz) : true; + } } return false; } diff --git a/src/ethernetII.cpp b/src/ethernetII.cpp index c422e75..0457d6c 100644 --- a/src/ethernetII.cpp +++ b/src/ethernetII.cpp @@ -130,10 +130,13 @@ void EthernetII::send(PacketSender &sender) { bool EthernetII::matches_response(uint8_t *ptr, uint32_t total_sz) { if(total_sz < sizeof(ethhdr)) return false; + const size_t addr_sz = address_type::address_size; const ethhdr *eth_ptr = (const ethhdr*)ptr; - if(!memcmp(eth_ptr->dst_mac, _eth.src_mac, address_type::address_size)) { - // chequear broadcast en destino original... - return (inner_pdu()) ? inner_pdu()->matches_response(ptr + sizeof(_eth), total_sz - sizeof(_eth)) : true; + if(std::equal(_eth.src_mac, _eth.src_mac + addr_sz, eth_ptr->dst_mac)) { + if(std::equal(_eth.src_mac, _eth.src_mac + addr_sz, eth_ptr->dst_mac) || dst_addr() == BROADCAST) + { + return (inner_pdu()) ? inner_pdu()->matches_response(ptr + sizeof(_eth), total_sz - sizeof(_eth)) : true; + } } return false; } diff --git a/src/radiotap.cpp b/src/radiotap.cpp index 2da96a0..64413a0 100644 --- a/src/radiotap.cpp +++ b/src/radiotap.cpp @@ -259,6 +259,18 @@ void RadioTap::send(PacketSender &sender) { } #endif +bool RadioTap::matches_response(uint8_t *ptr, uint32_t total_sz) { + if(sizeof(_radio) < total_sz) + return false; + const radiotap_hdr *radio_ptr = (const radiotap_hdr*)ptr; + if(radio_ptr->it_len <= total_sz) { + ptr += radio_ptr->it_len; + total_sz -= radio_ptr->it_len; + return inner_pdu() ? inner_pdu()->matches_response(ptr, total_sz) : true; + } + return false; +} + void RadioTap::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) { uint32_t sz = header_size(); uint8_t *buffer_start = buffer;