diff --git a/src/icmp_extension.cpp b/src/icmp_extension.cpp index dfa9620..66b6f89 100644 --- a/src/icmp_extension.cpp +++ b/src/icmp_extension.cpp @@ -53,7 +53,6 @@ ICMPExtension::ICMPExtension(uint8_t ext_class, uint8_t ext_type) } - ICMPExtension::ICMPExtension(const uint8_t* buffer, uint32_t total_sz) { InputMemoryStream stream(buffer, total_sz); @@ -138,10 +137,11 @@ bool ICMPExtensionsStructure::validate_extensions(const uint8_t* buffer, uint32_ if (total_sz < BASE_HEADER_SIZE) { return false; } - uint16_t checksum = *(const uint16_t*)(buffer + sizeof(uint16_t)); + InputMemoryStream input(buffer, total_sz); // The buffer is read only, so we can't set the initial checksum to 0. Therefore, // we sum the first 2 bytes and then the payload - uint32_t actual_checksum = *(const uint16_t*)buffer; + uint32_t actual_checksum = input.read(); + uint16_t checksum = input.read(); buffer += BASE_HEADER_SIZE; total_sz -= BASE_HEADER_SIZE; // Now do the checksum over the payload diff --git a/src/pdu_option.cpp b/src/pdu_option.cpp index de85404..6dbbd52 100644 --- a/src/pdu_option.cpp +++ b/src/pdu_option.cpp @@ -34,6 +34,7 @@ #include "hw_address.h" #include "endianness.h" #include "pdu_option.h" +#include "memory_helpers.h" using std::vector; using std::pair; @@ -41,6 +42,8 @@ using std::string; using std::memcpy; using std::distance; +using Tins::Memory::InputMemoryStream; + namespace Tins { namespace Internals { namespace Converters { @@ -61,21 +64,21 @@ T convert_to_integral(const uint8_t* ptr, uint32_t data_size, PDU::endian_type e } template -vector convert_vector(const uint8_t* u8_ptr, uint32_t data_size, PDU::endian_type endian) { +vector convert_vector(const uint8_t* ptr, uint32_t data_size, PDU::endian_type endian) { if (data_size % sizeof(T) != 0) { throw malformed_option(); } - const T* ptr = (const T*)u8_ptr; - const T* end = (const T*)(ptr + data_size / sizeof(T)); + InputMemoryStream input(ptr, data_size); - vector output(distance(ptr, end)); + vector output(data_size / sizeof(T)); typename vector::iterator it = output.begin(); - while (ptr < end) { + while (input) { + const T value = input.read(); if (endian == PDU::BE) { - *it++ = Endian::be_to_host(*ptr++); + *it++ = Endian::be_to_host(value); } else { - *it++ = Endian::le_to_host(*ptr++); + *it++ = Endian::le_to_host(value); } } return output; @@ -88,14 +91,14 @@ convert_vector(const uint8_t* ptr, uint32_t data_size, PDU::endian_type endian) if (data_size % (sizeof(T) + sizeof(U)) != 0) { throw malformed_option(); } - const uint8_t* end = ptr + data_size; + InputMemoryStream input(ptr, data_size); std::vector > output; - while (ptr < end) { + while (input) { pair data; - data.first = *(const T*)ptr; + data.first = input.read(); ptr += sizeof(T); - data.second = *(const U*)ptr; + data.second = input.read(); ptr += sizeof(U); if (endian == PDU::BE) { data.first = Endian::be_to_host(data.first); @@ -117,9 +120,10 @@ convert_pair(const uint8_t* ptr, uint32_t data_size, PDU::endian_type endian) { if (data_size != sizeof(T) + sizeof(U)) { throw malformed_option(); } + InputMemoryStream input(ptr, data_size); pair output; - memcpy(&output.first, ptr, sizeof(T)); - memcpy(&output.second, ptr + sizeof(T), sizeof(U)); + output.first = input.read(); + output.second = input.read(); if (endian == PDU::BE) { output.first = Endian::be_to_host(output.first); output.second = Endian::be_to_host(output.second); @@ -169,17 +173,18 @@ HWAddress<6> convert(const uint8_t* ptr, uint32_t data_size, PDU::endian_type, return HWAddress<6>(ptr); } -IPv4Address convert(const uint8_t* u8_ptr, uint32_t data_size, PDU::endian_type endian, +IPv4Address convert(const uint8_t* ptr, uint32_t data_size, PDU::endian_type endian, type_to_type) { if (data_size != sizeof(uint32_t)) { throw malformed_option(); } - const uint32_t* ptr = (const uint32_t*)u8_ptr; + InputMemoryStream input(ptr, data_size); + const uint32_t ip_int = input.read(); if (endian == PDU::BE) { - return IPv4Address(*ptr); + return IPv4Address(ip_int); } else { - return IPv4Address(Endian::change_endian(*ptr)); + return IPv4Address(Endian::change_endian(ip_int)); } } @@ -221,22 +226,22 @@ vector convert(const uint8_t* ptr, uint32_t data_size, PDU::endian_typ return convert_vector(ptr, data_size, endian); } -vector convert(const uint8_t* u8_ptr, uint32_t data_size, PDU::endian_type endian, +vector convert(const uint8_t* ptr, uint32_t data_size, PDU::endian_type endian, type_to_type >) { if (data_size % 4 != 0) { throw malformed_option(); } - const uint32_t* ptr = (const uint32_t*)u8_ptr; - const uint32_t* end = (const uint32_t*)(ptr + data_size / sizeof(uint32_t)); - vector output(distance(ptr, end)); + InputMemoryStream input(ptr, data_size); + vector output(data_size / sizeof(uint32_t)); vector::iterator it = output.begin(); - while (ptr < end) { + while (input) { + const uint32_t ip_int = input.read(); if (endian == PDU::BE) { - *it++ = IPv4Address(*ptr++); + *it++ = IPv4Address(ip_int); } else { - *it++ = IPv4Address(Endian::change_endian(*ptr++)); + *it++ = IPv4Address(Endian::change_endian(ip_int)); } } return output;