From e6e3e8453bccad719992db75fbeb3511e46cf92c Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Mon, 26 Nov 2012 19:47:15 -0300 Subject: [PATCH] Fixed some bugs in ICMPv6. --- include/ipv6.h | 2 +- src/icmpv6.cpp | 20 ++++++++++++++++++++ src/ipv6.cpp | 3 +++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/include/ipv6.h b/include/ipv6.h index 1adef10..2d6a4a3 100644 --- a/include/ipv6.h +++ b/include/ipv6.h @@ -49,7 +49,7 @@ public: /** * This PDU's flag. */ - static const PDU::PDUType pdu_flag = PDU::IP; + static const PDU::PDUType pdu_flag = PDU::IPv6; /** * The type used to store addresses. diff --git a/src/icmpv6.cpp b/src/icmpv6.cpp index ea4f5a4..dd9308f 100644 --- a/src/icmpv6.cpp +++ b/src/icmpv6.cpp @@ -30,7 +30,10 @@ #include #include #include "icmpv6.h" +#include "ipv6.h" #include "rawpdu.h" +#include "utils.h" +#include "constants.h" namespace Tins { @@ -159,7 +162,10 @@ void ICMPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU * #ifdef TINS_DEBUG assert(total_sz >= header_size()); #endif + icmp6hdr* ptr_header = (icmp6hdr*)buffer; std::memcpy(buffer, &_header, sizeof(_header)); + buffer += sizeof(_header); + total_sz -= sizeof(_header); for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) { #ifdef TINS_DEBUG assert(total_sz >= it->data_size() + sizeof(uint8_t) * 2); @@ -167,6 +173,20 @@ void ICMPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU * #endif buffer = write_option(*it, buffer); } + if(!_header.cksum) { + const Tins::IPv6 *ipv6 = dynamic_cast(parent); + if(ipv6) { + uint32_t checksum = Utils::pseudoheader_checksum( + ipv6->src_addr(), + ipv6->dst_addr(), + size(), + Constants::IP::PROTO_ICMPV6 + ) + Utils::do_checksum((uint8_t*)ptr_header, buffer); + while (checksum >> 16) + checksum = (checksum & 0xffff) + (checksum >> 16); + ptr_header->cksum = Endian::host_to_be(~checksum); + } + } } // can i haz more? diff --git a/src/ipv6.cpp b/src/ipv6.cpp index 9b2da08..e82c273 100644 --- a/src/ipv6.cpp +++ b/src/ipv6.cpp @@ -149,6 +149,9 @@ void IPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *pa case PDU::ICMP: new_flag = Constants::IP::PROTO_ICMP; break; + case PDU::ICMPv6: + new_flag = Constants::IP::PROTO_ICMPV6; + break; default: break; };