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:
@@ -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 \
|
||||
|
||||
20
Makefile.in
20
Makefile.in
@@ -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@
|
||||
|
||||
@@ -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
264
include/ipsec.h
Normal 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
|
||||
@@ -119,6 +119,8 @@ namespace Tins {
|
||||
PPPOE,
|
||||
STP,
|
||||
PPI,
|
||||
IPSEC_AH,
|
||||
IPSEC_ESP,
|
||||
USER_DEFINED_PDU = 1000
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
29
src/ip.cpp
29
src/ip.cpp
@@ -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
135
src/ipsec.cpp
Normal 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));
|
||||
}
|
||||
|
||||
}
|
||||
30
src/ipv6.cpp
30
src/ipv6.cpp
@@ -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));
|
||||
|
||||
@@ -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
171
tests/src/ipsec.cpp
Normal 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()
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user