1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-26 20:01:35 +01:00

Added support for IPSec.

This commit is contained in:
Matias Fontanini
2013-11-04 23:05:00 -03:00
parent de06fee5ab
commit 5345b29f8c
11 changed files with 679 additions and 57 deletions

View File

@@ -28,9 +28,11 @@ libtins_la_SOURCES=src/arp.cpp \
src/icmp.cpp \
src/icmpv6.cpp \
src/internals.cpp \
src/ip.cpp src/ip_address.cpp \
src/ip.cpp \
src/ip_address.cpp \
src/ipv6.cpp \
src/ipv6_address.cpp \
src/ipsec.cpp \
src/llc.cpp \
src/loopback.cpp \
src/network_interface.cpp \
@@ -67,6 +69,7 @@ libtins_HEADERS = include/internals.h \
include/dot3.h \
include/small_uint.h \
include/ip.h \
include/ipsec.h \
include/dns_record.h \
include/eapol.h \
include/tcp_stream.h \

View File

@@ -112,11 +112,12 @@ am_libtins_la_OBJECTS = src/arp.lo src/bootp.lo \
src/dns_record.lo src/dot3.lo src/dot1q.lo src/eapol.lo \
src/ethernetII.lo src/icmp.lo src/icmpv6.lo src/internals.lo \
src/ip.lo src/ip_address.lo src/ipv6.lo src/ipv6_address.lo \
src/llc.lo src/loopback.lo src/network_interface.lo \
src/packet_sender.lo src/packet_writer.lo src/ppi.lo \
src/pdu.lo src/radiotap.lo src/address_range.lo src/rawpdu.lo \
src/rsn_information.lo src/sll.lo src/snap.lo src/sniffer.lo \
src/tcp.lo src/tcp_stream.lo src/udp.lo src/utils.lo \
src/ipsec.lo src/llc.lo src/loopback.lo \
src/network_interface.lo src/packet_sender.lo \
src/packet_writer.lo src/ppi.lo src/pdu.lo src/radiotap.lo \
src/address_range.lo src/rawpdu.lo src/rsn_information.lo \
src/sll.lo src/snap.lo src/sniffer.lo src/tcp.lo \
src/tcp_stream.lo src/udp.lo src/utils.lo \
src/dot11/dot11_base.lo src/dot11/dot11_data.lo \
src/dot11/dot11_mgmt.lo src/dot11/dot11_beacon.lo \
src/dot11/dot11_assoc.lo src/dot11/dot11_auth.lo \
@@ -316,9 +317,11 @@ libtins_la_SOURCES = src/arp.cpp \
src/icmp.cpp \
src/icmpv6.cpp \
src/internals.cpp \
src/ip.cpp src/ip_address.cpp \
src/ip.cpp \
src/ip_address.cpp \
src/ipv6.cpp \
src/ipv6_address.cpp \
src/ipsec.cpp \
src/llc.cpp \
src/loopback.cpp \
src/network_interface.cpp \
@@ -354,6 +357,7 @@ libtins_HEADERS = include/internals.h \
include/dot3.h \
include/small_uint.h \
include/ip.h \
include/ipsec.h \
include/dns_record.h \
include/eapol.h \
include/tcp_stream.h \
@@ -528,6 +532,7 @@ src/ip.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ip_address.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ipv6.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ipv6_address.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/ipsec.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/llc.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/loopback.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/network_interface.lo: src/$(am__dirstamp) \
@@ -630,6 +635,8 @@ mostlyclean-compile:
-rm -f src/ip.lo
-rm -f src/ip_address.$(OBJEXT)
-rm -f src/ip_address.lo
-rm -f src/ipsec.$(OBJEXT)
-rm -f src/ipsec.lo
-rm -f src/ipv6.$(OBJEXT)
-rm -f src/ipv6.lo
-rm -f src/ipv6_address.$(OBJEXT)
@@ -694,6 +701,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/internals.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ip.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ip_address.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ipsec.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ipv6.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ipv6_address.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/llc.Plo@am__quote@

View File

@@ -113,10 +113,10 @@ PDU *pdu_from_flag(Constants::Ethernet::e flag, const uint8_t *buffer,
uint32_t size, bool rawpdu_on_no_match = true);
PDU *pdu_from_flag(Constants::IP::e flag, const uint8_t *buffer,
uint32_t size, bool rawpdu_on_no_match = true);
PDU *pdu_from_flag(PDU::PDUType type, const uint8_t *buffer, uint32_t size);
Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag);
Constants::IP::e pdu_flag_to_ip_type(PDU::PDUType flag);
template<typename T>
bool increment_buffer(T &addr) {

264
include/ipsec.h Normal file
View File

@@ -0,0 +1,264 @@
/*
* Copyright (c) 2012, Matias Fontanini
* All rights reserved.
*
* 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
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef TINS_IPSEC_H
#define TINS_IPSEC_H
#include "pdu.h"
#include "endianness.h"
#include "small_uint.h"
namespace Tins {
/**
* \brief Represents an IPSec Authentication Header.
*/
class IPSecAH : public PDU {
public:
/**
* This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::IPSEC_AH;
/**
* \brief Default constructor.
*
* The ICV field is initialized with four 0 bytes. The length
* field is initialized appropriately.
*/
IPSecAH();
/**
* \brief Constructs an IPSecAH object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this
* one.
*
* If there is not enough size for an IPSecAH header, a
* malformed_packet exception is thrown.
*
* \param buffer The buffer from which this PDU will be constructed.
* \param total_sz The total size of the buffer.
*/
IPSecAH(const uint8_t *buffer, uint32_t total_sz);
// Getters
/**
* \brief Getter for the Next header field.
* \return The stored Next header field value.
*/
uint8_t next_header() const {
return _header.next_header;
}
/**
* \brief Getter for the Length field.
* \return The stored Length field value.
*/
uint8_t length() const {
return _header.length;
}
/**
* \brief Getter for the Security Parameters Index field.
* \return The stored Security Parameters Index field value.
*/
uint32_t spi() const {
return Endian::be_to_host(_header.spi);
}
/**
* \brief Getter for the Sequence number field.
* \return The stored Sequence number field value.
*/
uint32_t seq_number() const {
return Endian::be_to_host(_header.seq_number);
}
/**
* \brief Getter for the ICV field.
* \return The stored ICV field value.
*/
const byte_array &icv() const {
return _icv;
}
// Setters
/**
* \brief Setter for the Next header field.
* \param new_next_header The new Next header field value.
*/
void next_header(uint8_t new_next_header);
/**
* \brief Setter for the Length field.
* \param new_length The new Length field value.
*/
void length(uint8_t new_length);
/**
* \brief Setter for the Security Parameters Index field.
* \param new_spi The new Security Parameters Index field value.
*/
void spi(uint32_t new_spi);
/**
* \brief Setter for the Sequence number field.
* \param new_seq_number The new Sequence number field value.
*/
void seq_number(uint32_t new_seq_number);
/**
* \brief Setter for the ICV field.
* \param new_icv The new ICV field value.
*/
void icv(const byte_array &new_icv);
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_size. \sa PDU::header_size
*/
uint32_t header_size() const;
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \sa PDU::clone
*/
IPSecAH *clone() const {
return new IPSecAH(*this);
}
private:
struct header {
uint8_t next_header, length;
uint32_t spi, seq_number;
};
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *);
header _header;
byte_array _icv;
};
/**
* \brief Represents an IPSec Authentication Header.
*/
class IPSecESP : public PDU {
public:
/**
* This PDU's flag.
*/
static const PDU::PDUType pdu_flag = PDU::IPSEC_ESP;
/**
* \brief Default constructor.
*/
IPSecESP();
/**
* \brief Constructs an IPSecESP object from a buffer and adds all
* identifiable PDUs found in the buffer as children of this
* one.
*
* If there is not enough size for an IPSecESP header, a
* malformed_packet exception is thrown.
*
* \param buffer The buffer from which this PDU will be constructed.
* \param total_sz The total size of the buffer.
*/
IPSecESP(const uint8_t *buffer, uint32_t total_sz);
// Getters
/**
* \brief Getter for the Security Parameters Index field.
* \return The stored Security Parameters Index field value.
*/
uint32_t spi() const {
return Endian::be_to_host(_header.spi);
}
/**
* \brief Getter for the Sequence number field.
* \return The stored Sequence number field value.
*/
uint32_t seq_number() const {
return Endian::be_to_host(_header.seq_number);
}
// Setters
/**
* \brief Setter for the Security Parameters Index field.
* \param new_spi The new Security Parameters Index field value.
*/
void spi(uint32_t new_spi);
/**
* \brief Setter for the Sequence number field.
* \param new_seq_number The new Sequence number field value.
*/
void seq_number(uint32_t new_seq_number);
/**
* \brief Returns the header size.
*
* This metod overrides PDU::header_size. \sa PDU::header_size
*/
uint32_t header_size() const;
/**
* \brief Getter for the PDU's type.
* \sa PDU::pdu_type
*/
PDUType pdu_type() const { return pdu_flag; }
/**
* \sa PDU::clone
*/
IPSecESP *clone() const {
return new IPSecESP(*this);
}
private:
struct header {
uint32_t spi, seq_number;
};
void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *);
header _header;
};
}
#endif // TINS_IPSEC_H

View File

@@ -119,6 +119,8 @@ namespace Tins {
PPPOE,
STP,
PPI,
IPSEC_AH,
IPSEC_ESP,
USER_DEFINED_PDU = 1000
};

View File

@@ -36,6 +36,7 @@
#include "ipv6.h"
#include "tcp.h"
#include "udp.h"
#include "ipsec.h"
#include "icmp.h"
#include "icmpv6.h"
#include "arp.h"
@@ -120,6 +121,10 @@ Tins::PDU *pdu_from_flag(Constants::IP::e flag, const uint8_t *buffer,
return new Tins::ICMPv6(buffer, size);
case Constants::IP::PROTO_IPV6:
return new Tins::IPv6(buffer, size);
case Constants::IP::PROTO_AH:
return new Tins::IPSecAH(buffer, size);
case Constants::IP::PROTO_ESP:
return new Tins::IPSecESP(buffer, size);
default:
break;
}
@@ -194,6 +199,27 @@ Constants::Ethernet::e pdu_flag_to_ether_type(PDU::PDUType flag) {
}
}
Constants::IP::e pdu_flag_to_ip_type(PDU::PDUType flag) {
switch(flag) {
case PDU::IP:
return Constants::IP::PROTO_IPIP;
case PDU::TCP:
return Constants::IP::PROTO_TCP;
case PDU::UDP:
return Constants::IP::PROTO_UDP;
case PDU::ICMP:
return Constants::IP::PROTO_ICMP;
case PDU::ICMPv6:
return Constants::IP::PROTO_ICMPV6;
case PDU::IPSEC_AH:
return Constants::IP::PROTO_AH;
case PDU::IPSEC_ESP:
return Constants::IP::PROTO_ESP;
default:
return static_cast<Constants::IP::e>(0xff);
};
}
bool increment(IPv4Address &addr) {
uint32_t addr_int = Endian::be_to_host<uint32_t>(addr);
bool reached_end = ++addr_int == 0xffffffff;

View File

@@ -385,29 +385,12 @@ void IP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU* pare
#endif
checksum(0);
if(inner_pdu()) {
uint32_t new_flag;
switch(inner_pdu()->pdu_type()) {
case PDU::IP:
new_flag = Constants::IP::PROTO_IPIP;
break;
case PDU::TCP:
new_flag = Constants::IP::PROTO_TCP;
break;
case PDU::UDP:
new_flag = Constants::IP::PROTO_UDP;
break;
case PDU::ICMP:
new_flag = Constants::IP::PROTO_ICMP;
break;
default:
if(Internals::pdu_type_registered<IP>(inner_pdu()->pdu_type()))
new_flag = static_cast<Constants::IP::e>(
Internals::pdu_type_to_id<IP>(inner_pdu()->pdu_type())
);
else
// check for other protos
new_flag = 0xff;
};
uint32_t new_flag = Internals::pdu_flag_to_ip_type(inner_pdu()->pdu_type());
if(new_flag == 0xff && Internals::pdu_type_registered<IP>(inner_pdu()->pdu_type())) {
new_flag = static_cast<Constants::IP::e>(
Internals::pdu_type_to_id<IP>(inner_pdu()->pdu_type())
);
}
protocol(new_flag);
//flag(new_flag);
}

135
src/ipsec.cpp Normal file
View File

@@ -0,0 +1,135 @@
/*
* Copyright (c) 2012, Matias Fontanini
* All rights reserved.
*
* 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
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <cstring>
#include "ipsec.h"
#include "internals.h"
#include "rawpdu.h"
namespace Tins {
IPSecAH::IPSecAH()
: _header(), _icv(4) {
length(2);
}
IPSecAH::IPSecAH(const uint8_t *buffer, uint32_t total_sz) {
// At least size for the header + 32bits of ICV
if(total_sz < sizeof(_header) + sizeof(uint32_t))
throw malformed_packet();
std::memcpy(&_header, buffer, sizeof(_header));
const uint32_t ah_len = 4 * (static_cast<uint16_t>(length()) + 2);
if(ah_len > total_sz)
throw malformed_packet();
_icv.assign(buffer + sizeof(_header), buffer + ah_len);
buffer += ah_len;
total_sz -= ah_len;
if(total_sz) {
inner_pdu(
Internals::pdu_from_flag(
static_cast<Constants::IP::e>(next_header()),
buffer,
total_sz,
true
)
);
}
}
void IPSecAH::next_header(uint8_t new_next_header) {
_header.next_header = new_next_header;
}
void IPSecAH::length(uint8_t new_length) {
_header.length = new_length;
}
void IPSecAH::spi(uint32_t new_spi) {
_header.spi = Endian::host_to_be(new_spi);
}
void IPSecAH::seq_number(uint32_t new_seq_number) {
_header.seq_number = Endian::host_to_be(new_seq_number);
}
void IPSecAH::icv(const byte_array &new_icv) {
_icv = new_icv;
}
uint32_t IPSecAH::header_size() const {
return sizeof(_header) + _icv.size();
}
void IPSecAH::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
if(inner_pdu())
next_header(Internals::pdu_flag_to_ip_type(inner_pdu()->pdu_type()));
std::memcpy(buffer, &_header, sizeof(_header));
std::copy(
_icv.begin(),
_icv.end(),
buffer + sizeof(_header)
);
}
// IPSecESP
IPSecESP::IPSecESP()
: _header()
{
}
IPSecESP::IPSecESP(const uint8_t *buffer, uint32_t total_sz) {
if(total_sz < sizeof(_header))
throw malformed_packet();
std::memcpy(&_header, buffer, sizeof(_header));
buffer += sizeof(_header);
total_sz -= sizeof(_header);
if(total_sz) {
inner_pdu(new RawPDU(buffer, total_sz));
}
}
void IPSecESP::spi(uint32_t new_spi) {
_header.spi = Endian::host_to_be(new_spi);
}
void IPSecESP::seq_number(uint32_t new_seq_number) {
_header.seq_number = Endian::host_to_be(new_seq_number);
}
uint32_t IPSecESP::header_size() const {
return sizeof(_header);
}
void IPSecESP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
std::memcpy(buffer, &_header, sizeof(_header));
}
}

View File

@@ -200,30 +200,12 @@ void IPv6::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *pa
assert(total_sz >= header_size());
#endif
if(inner_pdu()) {
uint8_t new_flag = 0xff;
switch(inner_pdu()->pdu_type()) {
case PDU::IP:
new_flag = Constants::IP::PROTO_IPIP;
break;
case PDU::TCP:
new_flag = Constants::IP::PROTO_TCP;
break;
case PDU::UDP:
new_flag = Constants::IP::PROTO_UDP;
break;
case PDU::ICMP:
new_flag = Constants::IP::PROTO_ICMP;
break;
case PDU::ICMPv6:
new_flag = Constants::IP::PROTO_ICMPV6;
break;
default:
if(Internals::pdu_type_registered<IPv6>(inner_pdu()->pdu_type()))
new_flag = static_cast<Constants::IP::e>(
Internals::pdu_type_to_id<IPv6>(inner_pdu()->pdu_type())
);
break;
};
uint8_t new_flag = Internals::pdu_flag_to_ip_type(inner_pdu()->pdu_type());
if(new_flag == 0xff && Internals::pdu_type_registered<IPv6>(inner_pdu()->pdu_type())) {
new_flag = static_cast<Constants::IP::e>(
Internals::pdu_type_to_id<IPv6>(inner_pdu()->pdu_type())
);
}
set_last_next_header(new_flag);
}
payload_length(total_sz - sizeof(_header));

View File

@@ -901,7 +901,8 @@
../include/dot11/../pdu_option.h ../include/dot11/../small_uint.h \
../include/dot11/../hw_address.h ../include/dot11/../endianness.h \
../include/dot11/../cxxstd.h ../include/dot11/../macros.h \
../include/ipv6.h ../include/ipv6_address.h ../include/arp.h \
../include/ipv6.h ../include/ipv6_address.h ../include/tcp.h \
../include/udp.h ../include/icmp.h ../include/icmpv6.h ../include/arp.h \
../include/eapol.h ../include/rawpdu.h ../include/dot1q.h \
../include/pppoe.h ../include/ip_address.h ../include/ipv6_address.h \
../include/pdu_allocator.h
@@ -958,6 +959,14 @@
../include/ipv6_address.h:
../include/tcp.h:
../include/udp.h:
../include/icmp.h:
../include/icmpv6.h:
../include/arp.h:
../include/eapol.h:
@@ -1060,6 +1069,23 @@
../include/exceptions.h:
../include/hw_address.h:
../src/ipsec.o: ../src/ipsec.cpp ../include/ipsec.h ../include/pdu.h \
../include/macros.h ../include/cxxstd.h ../include/exceptions.h \
../include/endianness.h ../include/small_uint.h
../include/ipsec.h:
../include/pdu.h:
../include/macros.h:
../include/cxxstd.h:
../include/exceptions.h:
../include/endianness.h:
../include/small_uint.h:
../src/ipv6.o: ../src/ipv6.cpp ../include/ipv6.h ../include/macros.h \
../include/pdu.h ../include/cxxstd.h ../include/exceptions.h \
../include/endianness.h ../include/small_uint.h ../include/pdu_option.h \
@@ -1067,7 +1093,8 @@
../include/packet_sender.h ../include/network_interface.h \
../include/hw_address.h ../include/ip_address.h ../include/ip.h \
../include/tcp.h ../include/udp.h ../include/icmp.h ../include/icmpv6.h \
../include/rawpdu.h ../include/exceptions.h ../include/pdu_allocator.h
../include/rawpdu.h ../include/exceptions.h ../include/pdu_allocator.h \
../include/internals.h ../include/constants.h
../include/ipv6.h:
@@ -1112,6 +1139,10 @@
../include/exceptions.h:
../include/pdu_allocator.h:
../include/internals.h:
../include/constants.h:
../src/ipv6_address.o: ../src/ipv6_address.cpp ../include/macros.h \
../include/ipv6_address.h ../include/cxxstd.h ../include/address_range.h \
../include/endianness.h ../include/macros.h ../include/internals.h \
@@ -3126,6 +3157,23 @@ src/ipaddress.o: src/ipaddress.cpp ../include/ip_address.h \
../include/pdu.h:
../include/exceptions.h:
src/ipsec.o: src/ipsec.cpp ../include/ipsec.h ../include/pdu.h \
../include/macros.h ../include/cxxstd.h ../include/exceptions.h \
../include/endianness.h ../include/small_uint.h
../include/ipsec.h:
../include/pdu.h:
../include/macros.h:
../include/cxxstd.h:
../include/exceptions.h:
../include/endianness.h:
../include/small_uint.h:
src/ipv6.o: src/ipv6.cpp ../include/ipv6.h ../include/macros.h \
../include/pdu.h ../include/cxxstd.h ../include/exceptions.h \
../include/endianness.h ../include/small_uint.h ../include/pdu_option.h \

171
tests/src/ipsec.cpp Normal file
View File

@@ -0,0 +1,171 @@
#include <gtest/gtest.h>
#include <algorithm>
#include "ipsec.h"
#include "ethernetII.h"
#include "rawpdu.h"
using namespace Tins;
class IPSecAHTest : public testing::Test {
public:
static const uint8_t expected_packet[];
};
class IPSecESPTest : public testing::Test {
public:
static const uint8_t expected_packet[];
};
const uint8_t whole_packet[] = {
194, 1, 87, 117, 0, 0, 194, 0, 87, 117, 0, 0, 8, 0, 69, 0, 0, 180,
0, 107, 0, 0, 255, 51, 166, 169, 10, 0, 0, 1, 10, 0, 0, 2, 50, 4, 0,
0, 129, 121, 183, 5, 0, 0, 0, 1, 39, 207, 192, 165, 228, 61, 105,
179, 114, 142, 197, 176, 72, 218, 194, 228, 0, 0, 0, 1, 7, 65, 190,
127, 138, 222, 64, 192, 43, 216, 26, 238, 15, 80, 111, 44, 70, 220,
189, 73, 172, 173, 48, 187, 90, 9, 112, 128, 195, 214, 136, 212,
155, 95, 34, 92, 232, 113, 132, 209, 249, 248, 173, 98, 103, 250,
26, 162, 24, 151, 15, 209, 53, 182, 153, 55, 36, 84, 68, 95, 107,
211, 204, 25, 177, 95, 183, 1, 178, 52, 217, 74, 7, 236, 107, 252,
45, 61, 19, 53, 179, 1, 53, 102, 180, 116, 215, 195, 37, 155, 127,
228, 185, 34, 165, 191, 163, 208, 144, 200, 154, 155, 109, 106, 183,
242, 186, 17, 255, 199, 163, 135, 182, 5, 88, 122, 36, 168, 41, 156,
125, 137, 194, 33, 153, 161, 189, 0
};
const uint8_t IPSecAHTest::expected_packet[] = {
50, 4, 0, 0, 129, 121, 183, 5, 0, 0, 0, 1, 39, 207, 192, 165, 228,
61, 105, 179, 114, 142, 197, 176, 72, 218, 194, 228, 0, 0, 0, 1, 7,
65, 190, 127, 138, 222, 64, 192, 43, 216, 26, 238, 15, 80, 111, 44,
70, 220, 189, 73, 172, 173, 48, 187, 90, 9, 112, 128, 195, 214, 136,
212, 155, 95, 34, 92, 232, 113, 132, 209, 249, 248, 173, 98, 103,
250, 26, 162, 24, 151, 15, 209, 53, 182, 153, 55, 36, 84, 68, 95,
107, 211, 204, 25, 177, 95, 183, 1, 178, 52, 217, 74, 7, 236, 107,
252, 45, 61, 19, 53, 179, 1, 53, 102, 180, 116, 215, 195, 37, 155,
127, 228, 185, 34, 165, 191, 163, 208, 144, 200, 154, 155, 109, 106,
183, 242, 186, 17, 255, 199, 163, 135, 182, 5, 88, 122, 36, 168, 41,
156, 125, 137, 194, 33, 153, 161, 189, 0
};
const uint8_t IPSecESPTest::expected_packet[] = {
72, 218, 194, 228, 0, 0, 0, 1, 7, 65, 190, 127, 138, 222, 64, 192,
43, 216, 26, 238, 15, 80, 111, 44, 70, 220, 189, 73, 172, 173, 48,
187, 90, 9, 112, 128, 195, 214, 136, 212, 155, 95, 34, 92, 232, 113,
132, 209, 249, 248, 173, 98, 103, 250, 26, 162, 24, 151, 15, 209,
53, 182, 153, 55, 36, 84, 68, 95, 107, 211, 204, 25, 177, 95, 183,
1, 178, 52, 217, 74, 7, 236, 107, 252, 45, 61, 19, 53, 179, 1, 53,
102, 180, 116, 215, 195, 37, 155, 127, 228, 185, 34, 165, 191, 163,
208, 144, 200, 154, 155, 109, 106, 183, 242, 186, 17, 255, 199, 163,
135, 182, 5, 88, 122, 36, 168, 41, 156, 125, 137, 194, 33, 153, 161,
189, 0
};
// AH
TEST_F(IPSecAHTest, DefaultConstructor) {
IPSecAH ipsec;
EXPECT_EQ(0, ipsec.next_header());
EXPECT_EQ(2, ipsec.length());
EXPECT_EQ(0, ipsec.spi());
EXPECT_EQ(0, ipsec.seq_number());
EXPECT_EQ(4, ipsec.icv().size());
}
TEST_F(IPSecAHTest, EthPacket) {
EthernetII eth(whole_packet, sizeof(whole_packet));
EXPECT_TRUE(eth.find_pdu<IPSecAH>());
EXPECT_TRUE(eth.find_pdu<IPSecESP>());
EXPECT_TRUE(eth.find_pdu<RawPDU>());
}
TEST_F(IPSecAHTest, ConstructorFromBuffer) {
IPSecAH ipsec(expected_packet, sizeof(expected_packet));
const char *icv_ptr = "\x27\xcf\xc0\xa5\xe4\x3d\x69\xb3\x72\x8e\xc5\xb0";
EXPECT_EQ(0x32, ipsec.next_header());
EXPECT_EQ(4, ipsec.length());
EXPECT_EQ(0x8179b705, ipsec.spi());
EXPECT_EQ(1, ipsec.seq_number());
ASSERT_EQ(12, ipsec.icv().size());
EXPECT_EQ(ipsec.icv(), byte_array(icv_ptr, icv_ptr + 12));
EXPECT_TRUE(ipsec.find_pdu<IPSecESP>());
EXPECT_TRUE(ipsec.find_pdu<RawPDU>());
}
TEST_F(IPSecAHTest, Serialize) {
IPSecAH ipsec(expected_packet, sizeof(expected_packet));
EXPECT_EQ(
byte_array(expected_packet, expected_packet + sizeof(expected_packet)),
ipsec.serialize()
);
}
TEST_F(IPSecAHTest, NextHeader) {
IPSecAH ipsec;
ipsec.next_header(0x73);
EXPECT_EQ(0x73, ipsec.next_header());
}
TEST_F(IPSecAHTest, Length) {
IPSecAH ipsec;
ipsec.length(0x73);
EXPECT_EQ(0x73, ipsec.length());
}
TEST_F(IPSecAHTest, SPI) {
IPSecAH ipsec;
ipsec.spi(0x73a625fa);
EXPECT_EQ(0x73a625fa, ipsec.spi());
}
TEST_F(IPSecAHTest, SeqNumber) {
IPSecAH ipsec;
ipsec.seq_number(0x73a625fa);
EXPECT_EQ(0x73a625fa, ipsec.seq_number());
}
TEST_F(IPSecAHTest, ICV) {
IPSecAH ipsec;
byte_array data;
data.push_back(0x29);
data.push_back(0x52);
data.push_back(0x9a);
data.push_back(0x73);
ipsec.icv(data);
EXPECT_EQ(data, ipsec.icv());
}
// IPSecESP
TEST_F(IPSecESPTest, DefaultConstructor) {
IPSecESP ipsec;
EXPECT_EQ(0, ipsec.spi());
EXPECT_EQ(0, ipsec.seq_number());
}
TEST_F(IPSecESPTest, ConstructorFromBuffer) {
IPSecESP ipsec(expected_packet, sizeof(expected_packet));
EXPECT_EQ(0x48dac2e4, ipsec.spi());
EXPECT_EQ(1, ipsec.seq_number());
EXPECT_TRUE(ipsec.find_pdu<RawPDU>());
}
TEST_F(IPSecESPTest, SPI) {
IPSecESP ipsec;
ipsec.spi(0x73a625fa);
EXPECT_EQ(0x73a625fa, ipsec.spi());
}
TEST_F(IPSecESPTest, SeqNumber) {
IPSecESP ipsec;
ipsec.seq_number(0x73a625fa);
EXPECT_EQ(0x73a625fa, ipsec.seq_number());
}
TEST_F(IPSecESPTest, Serialize) {
IPSecESP ipsec(expected_packet, sizeof(expected_packet));
EXPECT_EQ(
byte_array(expected_packet, expected_packet + sizeof(expected_packet)),
ipsec.serialize()
);
}