diff --git a/include/tins/address_range.h b/include/tins/address_range.h index 5d9f9e7..9880151 100644 --- a/include/tins/address_range.h +++ b/include/tins/address_range.h @@ -5,14 +5,14 @@ * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -125,10 +125,10 @@ private: * \brief Represents a range of addresses. * * This class provides a begin()/end() interface which allows - * iterating through every address stored in it. + * iterating through every address stored in it. * * Note that when iterating a range that was created using - * operator/(IPv4Address, int) and the analog for IPv6, the + * operator/(IPv4Address, int) and the analog for IPv6, the * network and broadcast addresses are discarded: * * \code @@ -139,12 +139,12 @@ private: * } * * // That's only valid for iteration, not for AddressRange<>::contains - * + * * assert(range.contains("192.168.5.0")); // works * assert(range.contains("192.168.5.255")); // works * \endcode * - * Ranges created using AddressRange(address_type, address_type) + * Ranges created using AddressRange(address_type, address_type) * will allow the iteration over the entire range: * * \code @@ -153,11 +153,11 @@ private: * // process 192.168.5.0-255, no addresses are discarded * process(addr); * } - * + * * assert(range.contains("192.168.5.0")); // still valid * assert(range.contains("192.168.5.255")); // still valid * \endcode - * + * */ template class AddressRange { @@ -186,10 +186,10 @@ public: * The range will consist of the addresses [first, last]. * * If only_hosts is true, then the network and broadcast addresses - * will not be available when iterating the range. + * will not be available when iterating the range. * * If last < first, an std::runtime_error exception is thrown. - * + * * \param first The first address in the range. * \param last The last address(inclusive) in the range. * \param only_hosts Indicates whether only host addresses @@ -211,8 +211,8 @@ public: */ static AddressRange from_mask(const address_type& first, const address_type& mask) { return AddressRange( - first, - Internals::last_address_from_mask(first, mask), + Internals::first_address_from_mask(first, mask), + Internals::last_address_from_mask(first, mask), true ); } @@ -253,15 +253,15 @@ public: /** * \brief Indicates whether this range is iterable. * - * Iterable ranges are those for which there is at least one + * Iterable ranges are those for which there is at least one * address that could represent a host. For IPv4 ranges, a /31 or * /32 ranges does not contain any, therefore it's not iterable. * The same is true for /127 and /128 IPv6 ranges. * * If is_iterable returns false for a range, then iterating it - * through the iterators returned by begin() and end() is - * undefined. - * + * through the iterators returned by begin() and end() is + * undefined. + * * \return bool indicating whether this range is iterable. */ bool is_iterable() const { diff --git a/include/tins/internals.h b/include/tins/internals.h index 09c09f4..47df50d 100644 --- a/include/tins/internals.h +++ b/include/tins/internals.h @@ -134,7 +134,7 @@ Constants::IP::e pdu_flag_to_ip_type(PDU::PDUType flag); PDU::PDUType ip_type_to_pdu_flag(Constants::IP::e flag); uint32_t get_padded_icmp_inner_pdu_size(const PDU* inner_pdu, uint32_t pad_alignment); -void try_parse_icmp_extensions(Memory::InputMemoryStream& stream, +void try_parse_icmp_extensions(Memory::InputMemoryStream& stream, uint32_t payload_length, ICMPExtensionsStructure& extensions); template @@ -183,6 +183,18 @@ bool decrement(HWAddress& addr) { // Compares sequence numbers as defined by RFC 1982. int seq_compare(uint32_t seq1, uint32_t seq2); + +IPv4Address first_address_from_mask(IPv4Address addr, IPv4Address mask); +IPv6Address first_address_from_mask(IPv6Address addr, const IPv6Address& mask); +template +HWAddress first_address_from_mask(HWAddress addr, const HWAddress& mask) { + typename HWAddress::iterator addr_iter = addr.begin(); + for (typename HWAddress::const_iterator it = mask.begin(); it != mask.end(); ++it, ++addr_iter) { + *addr_iter = *addr_iter & *it; + } + return addr; +} + IPv4Address last_address_from_mask(IPv4Address addr, IPv4Address mask); IPv6Address last_address_from_mask(IPv6Address addr, const IPv6Address& mask); template @@ -230,10 +242,10 @@ template struct accepts_type : std::false_type { }; template -struct accepts_type()(std::declval

()) ), bool>::value - >::type + >::type > : std::true_type { }; // use enable_if to invoke the Packet&& version of the sniff_loop handler if possible - otherwise fail to old behavior diff --git a/src/internals.cpp b/src/internals.cpp index 748f9ae..2449db6 100644 --- a/src/internals.cpp +++ b/src/internals.cpp @@ -5,14 +5,14 @@ * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: - * + * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR @@ -138,7 +138,7 @@ Tins::PDU* pdu_from_flag(Constants::Ethernet::e flag, { PDU* pdu = Internals::allocate( static_cast(flag), - buffer, + buffer, size ); if (pdu) { @@ -149,8 +149,8 @@ Tins::PDU* pdu_from_flag(Constants::Ethernet::e flag, }; } -Tins::PDU* pdu_from_flag(Constants::IP::e flag, - const uint8_t* buffer, +Tins::PDU* pdu_from_flag(Constants::IP::e flag, + const uint8_t* buffer, uint32_t size, bool rawpdu_on_no_match) { switch (flag) { @@ -179,8 +179,8 @@ Tins::PDU* pdu_from_flag(Constants::IP::e flag, return 0; } -PDU* pdu_from_dlt_flag(int flag, - const uint8_t* buffer, +PDU* pdu_from_dlt_flag(int flag, + const uint8_t* buffer, uint32_t size, bool rawpdu_on_no_match) { switch (flag) { @@ -338,8 +338,8 @@ uint32_t get_padded_icmp_inner_pdu_size(const PDU* inner_pdu, uint32_t pad_align } } -void try_parse_icmp_extensions(InputMemoryStream& stream, - uint32_t payload_length, +void try_parse_icmp_extensions(InputMemoryStream& stream, + uint32_t payload_length, ICMPExtensionsStructure& extensions) { if (!stream) { return; @@ -355,7 +355,7 @@ void try_parse_icmp_extensions(InputMemoryStream& stream, extensions_size = stream.size() - payload_length; } else if (stream.can_read(minimum_payload)) { - // This packet might be non-rfc compliant. In that case the length + // This packet might be non-rfc compliant. In that case the length // field can contain garbage. extensions_ptr = stream.pointer() + minimum_payload; extensions_size = stream.size() - minimum_payload; @@ -443,5 +443,19 @@ IPv6Address last_address_from_mask(IPv6Address addr, const IPv6Address& mask) { return addr; } +IPv4Address first_address_from_mask(IPv4Address addr, IPv4Address mask) { + uint32_t addr_int = Endian::be_to_host(addr), + mask_int = Endian::be_to_host(mask); + return IPv4Address(Endian::host_to_be(addr_int & mask_int)); +} + +IPv6Address first_address_from_mask(IPv6Address addr, const IPv6Address& mask) { + IPv6Address::iterator addr_iter = addr.begin(); + for (IPv6Address::const_iterator it = mask.begin(); it != mask.end(); ++it, ++addr_iter) { + *addr_iter = *addr_iter & *it; + } + return addr; +} + } // namespace Internals } // namespace Tins