1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-27 04:11:35 +01:00

Add OutputMemoryStream and port most classes to use it

This commit is contained in:
Matias Fontanini
2015-12-26 06:30:00 -08:00
parent 9750f46c6d
commit 02e2b278de
34 changed files with 438 additions and 418 deletions

View File

@@ -42,6 +42,7 @@
#include "memory_helpers.h"
using Tins::Memory::InputMemoryStream;
using Tins::Memory::OutputMemoryStream;
namespace Tins {
@@ -207,23 +208,7 @@ void ICMP::use_length_field(bool value) {
}
void ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
#ifdef TINS_DEBUG
assert(total_sz >= sizeof(icmphdr));
#endif
uint32_t uint32_t_buffer;
if(type() == TIMESTAMP_REQUEST || type() == TIMESTAMP_REPLY) {
uint32_t_buffer = original_timestamp();
memcpy(buffer + sizeof(icmphdr), &uint32_t_buffer, sizeof(uint32_t));
uint32_t_buffer = receive_timestamp();
memcpy(buffer + sizeof(icmphdr) + sizeof(uint32_t), &uint32_t_buffer, sizeof(uint32_t));
uint32_t_buffer = transmit_timestamp();
memcpy(buffer + sizeof(icmphdr) + 2 * sizeof(uint32_t), &uint32_t_buffer, sizeof(uint32_t));
}
else if(type() == ADDRESS_MASK_REQUEST || type() == ADDRESS_MASK_REPLY) {
uint32_t_buffer = address_mask();
memcpy(buffer + sizeof(icmphdr), &uint32_t_buffer, sizeof(uint32_t));
}
OutputMemoryStream stream(buffer, total_sz);
// If extensions are allowed and we have to set the length field
if (are_extensions_allowed()) {
@@ -236,6 +221,19 @@ void ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *)
}
}
// Write the header using checksum 0
_icmp.check = 0;
stream.write(_icmp);
if(type() == TIMESTAMP_REQUEST || type() == TIMESTAMP_REPLY) {
stream.write(original_timestamp());
stream.write(receive_timestamp());
stream.write(transmit_timestamp());
}
else if(type() == ADDRESS_MASK_REQUEST || type() == ADDRESS_MASK_REPLY) {
stream.write(address_mask());
}
if (has_extensions()) {
uint8_t* extensions_ptr = buffer + sizeof(icmphdr);
if (inner_pdu()) {
@@ -258,14 +256,12 @@ void ICMP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *)
extensions_.serialize(extensions_ptr, total_sz - (extensions_ptr - buffer));
}
// checksum calc
_icmp.check = 0;
memcpy(buffer, &_icmp, sizeof(icmphdr));
// Calculate checksum
uint32_t checksum = Utils::do_checksum(buffer, buffer + total_sz);
while (checksum >> 16)
while (checksum >> 16) {
checksum = (checksum & 0xffff) + (checksum >> 16);
}
// Write back only the 2 checksum bytes
_icmp.check = Endian::host_to_be<uint16_t>(~checksum);
memcpy(buffer + 2, &_icmp.check, sizeof(uint16_t));
}