1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 02:35:57 +01:00

Add input memory stream class and port some PDUs to use it

This commit is contained in:
Matias Fontanini
2015-12-24 15:21:07 -08:00
parent 6d90b0ce32
commit 13c05fbdb1
20 changed files with 408 additions and 295 deletions

View File

@@ -49,6 +49,9 @@
#include "icmp_extension.h"
namespace Tins {
namespace Memory {
class InputMemoryStream;
} // memory
/**
* \class ICMP
@@ -460,7 +463,7 @@ private:
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
uint32_t get_adjusted_inner_pdu_size() const;
void try_parse_extensions(const uint8_t* buffer, uint32_t& total_sz);
void try_parse_extensions(Memory::InputMemoryStream& stream);
bool are_extensions_allowed() const;
icmphdr _icmp;

View File

@@ -44,6 +44,10 @@
#include "cxxstd.h"
namespace Tins {
namespace Memory {
class InputMemoryStream;
} // memory
/**
* \class ICMPv6
* \brief Represents an ICMPv6 PDU.
@@ -1376,12 +1380,12 @@ private:
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent);
bool has_options() const;
uint8_t *write_option(const option &opt, uint8_t *buffer);
void parse_options(const uint8_t *&buffer, uint32_t &total_sz);
void parse_options(Memory::InputMemoryStream& stream);
void add_addr_list(uint8_t type, const addr_list_type &value);
addr_list_type search_addr_list(OptionTypes type) const;
options_type::const_iterator search_option_iterator(OptionTypes type) const;
options_type::iterator search_option_iterator(OptionTypes type);
void try_parse_extensions(const uint8_t* buffer, uint32_t& total_sz);
void try_parse_extensions(Memory::InputMemoryStream& stream);
bool are_extensions_allowed() const;
uint32_t get_adjusted_inner_pdu_size() const;

View File

@@ -45,6 +45,9 @@
* \cond
*/
namespace Tins {
namespace Memory {
class InputMemoryStream;
} // Memory
class IPv4Address;
class IPv6Address;
class ICMPExtensionsStructure;
@@ -126,7 +129,7 @@ Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag);
Constants::IP::e pdu_flag_to_ip_type(PDU::PDUType flag);
uint32_t get_padded_icmp_inner_pdu_size(const PDU* inner_pdu, uint32_t pad_alignment);
void try_parse_icmp_extensions(const uint8_t* buffer, uint32_t& total_sz,
void try_parse_icmp_extensions(Memory::InputMemoryStream& stream,
uint32_t payload_length, ICMPExtensionsStructure& extensions);
template<typename T>

View File

@@ -34,19 +34,25 @@
#include <sys/param.h>
#endif
// Packing directives....
// Check if this is Visual Studio
#ifdef _MSC_VER
// This is Visual Studio
#define TINS_BEGIN_PACK __pragma( pack(push, 1) )
#define TINS_END_PACK __pragma( pack(pop) )
#define TINS_PACKED(DECLARATION) __pragma( pack(push, 1) ) DECLARATION __pragma( pack(pop) )
#define TINS_DEPRECATED(func) __declspec(deprecated) func
#define TINS_NOEXCEPT
#define TINS_LIKELY(x) (x)
#define TINS_UNLIKELY(x) (x)
#else
// Not Vistual Studio. Assume this is gcc compatible
#define TINS_BEGIN_PACK
#define TINS_END_PACK __attribute__((packed))
#define TINS_PACKED(DECLARATION) DECLARATION __attribute__((packed))
#define TINS_DEPRECATED(func) func __attribute__ ((deprecated))
#define TINS_NOEXCEPT noexcept
#endif
#define TINS_LIKELY(x) __builtin_expect((x),1)
#define TINS_UNLIKELY(x) __builtin_expect((x),0)
#endif //
#endif
#endif // TINS_MACROS_H

View File

@@ -0,0 +1,101 @@
#ifndef TINS_MEMORY_HELPERS_H
#define TINS_MEMORY_HELPERS_H
#include <stdint.h>
#include <cstring>
#include "exceptions.h"
#include "ip_address.h"
#include "ipv6_address.h"
namespace Tins {
namespace Memory {
inline void read_data(const uint8_t* buffer, uint8_t* output_buffer, uint32_t size) {
std::memcpy(output_buffer, buffer, size);
}
template <typename T>
void read_value(const uint8_t* buffer, T& value) {
std::memcpy(&value, buffer, sizeof(value));
}
template <typename T>
void write_value(uint8_t* buffer, const T& value) {
std::memcpy(buffer, &value, sizeof(value));
}
class InputMemoryStream {
public:
InputMemoryStream(const uint8_t* buffer, uint32_t total_sz)
: buffer_(buffer), size_(total_sz) {
}
void skip(uint32_t size) {
buffer_ += size;
size_ -= size;
}
bool can_read(uint32_t byte_count) const {
return TINS_LIKELY(size_ >= byte_count);
}
template <typename T>
T read() {
T output;
read(output);
return output;
}
template <typename T>
void read(T& value) {
if (!can_read(sizeof(value))) {
throw malformed_packet();
}
read_value(buffer_, value);
skip(sizeof(value));
}
void read(IPv4Address& address) {
address = IPv4Address(read<uint32_t>());
}
void read(IPv6Address& address) {
if (!can_read(IPv6Address::address_size)) {
throw malformed_packet();
}
address = pointer();
skip(IPv6Address::address_size);
}
void read(void* output_buffer, uint32_t output_buffer_size) {
if (!can_read(output_buffer_size)) {
throw malformed_packet();
}
read_data(buffer_, (uint8_t*)output_buffer, output_buffer_size);
skip(output_buffer_size);
}
const uint8_t* pointer() const {
return buffer_;
}
uint32_t size() const {
return size_;
}
void size(uint32_t new_size) {
size_ = new_size;
}
operator bool() const {
return size_ > 0;
}
private:
const uint8_t* buffer_;
uint32_t size_;
};
} // Memory
} // Tins
#endif // TINS_MEMORY_HELPERS_H