mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Added malformed_packet exception. Every class except Dot11* use it.
This commit is contained in:
@@ -97,4 +97,5 @@ libtins_include_HEADERS = include/internals.h \
|
||||
include/constants.h \
|
||||
include/utils.h \
|
||||
include/cxxstd.h \
|
||||
include/stp.h
|
||||
include/stp.h \
|
||||
include/exceptions.h
|
||||
|
||||
@@ -57,7 +57,8 @@ subdir = .
|
||||
DIST_COMMON = README $(am__configure_deps) $(libtins_include_HEADERS) \
|
||||
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
|
||||
$(srcdir)/libtins.pc.in $(top_srcdir)/configure AUTHORS THANKS \
|
||||
config.guess config.sub depcomp install-sh ltmain.sh missing
|
||||
TODO config.guess config.sub depcomp install-sh ltmain.sh \
|
||||
missing
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
|
||||
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||
|
||||
@@ -82,8 +82,14 @@ namespace Tins {
|
||||
const hwaddress_type &sender_hw = hwaddress_type());
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an ARP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \brief Constructs an ARP object from a buffer.
|
||||
*
|
||||
* If there is not enough size for an ARP header in the buffer,
|
||||
* a malformed_packet exception is thrown.
|
||||
*
|
||||
* If the buffer is bigger than the size of the ARP header,
|
||||
* then the extra data is stored in a RawPDU.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
|
||||
@@ -84,8 +84,11 @@ namespace Tins {
|
||||
BootP();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a BootP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \brief Constructs a BootP object from a buffer .
|
||||
*
|
||||
* If there's not enough size for a BootP header, then 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.
|
||||
* \param vend_field_size The vend field size to allocate.
|
||||
|
||||
@@ -163,8 +163,12 @@ namespace Tins {
|
||||
DHCP();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a DHCP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \brief Constructs a DHCP object from a buffer.
|
||||
*
|
||||
* If there is not enough size for a BootP header, or any of
|
||||
* the TLV options contain an invalid size field, then 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.
|
||||
* Subclasses might use 0 to provide their own interpretation of this field.
|
||||
|
||||
@@ -388,9 +388,12 @@ public:
|
||||
DHCPv6();
|
||||
|
||||
/**
|
||||
* \brief Constructor which constructs a DHCPv6 object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
* \brief Constructs a DHCPv6 object from a buffer.
|
||||
*
|
||||
* If there is not enough size for the DHCPv6 header, or any
|
||||
* of the TLV options contains an invalid size field, 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.
|
||||
*/
|
||||
|
||||
@@ -252,7 +252,11 @@ namespace Tins {
|
||||
DNS();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a DNS object from a buffer.
|
||||
* \brief Constructs a DNS object from a buffer.
|
||||
*
|
||||
* If there's not enough size for the DNS header, or any of the
|
||||
* records are malformed, a malformed_packet is be thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be
|
||||
* constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
|
||||
@@ -68,6 +68,10 @@ public:
|
||||
|
||||
/**
|
||||
* \brief Constructs a record.
|
||||
*
|
||||
* If the input data is malformed, a malformed_packet exception
|
||||
* is thrown.
|
||||
*
|
||||
* \param buffer A pointer to the start of the data buffer.
|
||||
* \param len The length of the data.
|
||||
*/
|
||||
|
||||
@@ -48,10 +48,15 @@ public:
|
||||
Dot1Q(small_uint<12> tag_id = 0, bool append_pad = true);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an Dot1Q object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children of this
|
||||
* \brief Constructs a Dot1Q object from a buffer and adds all
|
||||
* identifiable PDUs found in the buffer as children of this
|
||||
* one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for a Dot1Q header in the buffer,
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -76,8 +76,12 @@ namespace Tins {
|
||||
PDU* child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an Dot3 object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \brief Constructs a Dot3 object from a buffer and adds a
|
||||
* LLC object with the remaining data as the inner PDU.
|
||||
*
|
||||
* If there is not enough size for a Dot3 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.
|
||||
*/
|
||||
|
||||
@@ -67,6 +67,12 @@ namespace Tins {
|
||||
/**
|
||||
* \brief Static method to instantiate the correct EAPOL subclass
|
||||
* based on a raw buffer.
|
||||
*
|
||||
* If no valid EAPOL type is detected, a null pointer is returned.
|
||||
*
|
||||
* \sa RC4EAPOL
|
||||
* \sa RSNEAPOL
|
||||
*
|
||||
* \param buffer The buffer from which the data will be taken.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
@@ -197,12 +203,16 @@ namespace Tins {
|
||||
static const size_t key_sign_size = 16;
|
||||
|
||||
/**
|
||||
* \brief Creates an instance of RC4EAPOL
|
||||
* \brief Default constructor.
|
||||
*/
|
||||
RC4EAPOL();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an RC4EAPOL object from a buffer.
|
||||
* \brief Constructs a RC4EAPOL object from a buffer.
|
||||
*
|
||||
* If there is not enough size for a RC4EAPOL header in the
|
||||
* buffer, 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.
|
||||
*/
|
||||
@@ -396,7 +406,11 @@ namespace Tins {
|
||||
RSNEAPOL();
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an RSNEAPOL object from a buffer.
|
||||
* \brief Constructs a RSNEAPOL object from a buffer.
|
||||
*
|
||||
* If there is not enough size for the RSNEAPOL 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.
|
||||
*/
|
||||
|
||||
@@ -76,8 +76,14 @@ namespace Tins {
|
||||
PDU* child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an EthernetII object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \brief Constructs a EthernetII object from a buffer and adds
|
||||
* all identifiable PDUs found in the buffer as children of
|
||||
* this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for a EthernetII header in the
|
||||
* buffer, 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.
|
||||
|
||||
@@ -71,8 +71,13 @@ namespace Tins {
|
||||
ICMP(Flags flag = ECHO_REQUEST);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an ICMP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \brief Constructs an ICMP object from a buffer.
|
||||
*
|
||||
* If there is not enough size for an ICMP header, a
|
||||
* malformed_packet exception is thrown.
|
||||
*
|
||||
* Any extra data in the buffer will be stored in a RawPDU.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
|
||||
@@ -434,8 +434,12 @@ public:
|
||||
ICMPv6(Types tp = ECHO_REQUEST);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an ICMP object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children of this one.
|
||||
* \brief Constructs an ICMPv6 object from a buffer.
|
||||
*
|
||||
* If there is not enough size for an ICMPv6 header, a
|
||||
* malformed_packet exception is thrown.
|
||||
*
|
||||
* Any extra data is stored in a RawPDU.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
|
||||
10
include/ip.h
10
include/ip.h
@@ -239,9 +239,13 @@ namespace Tins {
|
||||
PDU *child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which constructs an IP object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
* \brief Constructs an IP 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 IP 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.
|
||||
*/
|
||||
|
||||
@@ -84,17 +84,6 @@ public:
|
||||
NO_NEXT_HEADER = 59
|
||||
};
|
||||
|
||||
/**
|
||||
* Exception thrown when an invalid extension header size is
|
||||
* encountered.
|
||||
*/
|
||||
class header_size_error : public std::exception {
|
||||
public:
|
||||
const char *what() const throw() {
|
||||
return "Not enough size for an extension header";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Constructs an IPv6 object.
|
||||
*
|
||||
@@ -108,9 +97,11 @@ public:
|
||||
PDU *child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an IPv6 object from a buffer and
|
||||
* adds all identifiable PDUs found in the buffer as children of this
|
||||
* one.
|
||||
* \brief Constructs an IPv6 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 IPv6 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.
|
||||
|
||||
@@ -104,8 +104,12 @@ namespace Tins {
|
||||
LLC(uint8_t dsap, uint8_t ssap, PDU* child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a LLC object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \brief Constructs a LLC 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 a LLC 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.
|
||||
*/
|
||||
|
||||
@@ -61,7 +61,14 @@ public:
|
||||
Loopback(const NetworkInterface &iface, PDU *inner_pdu = 0);
|
||||
|
||||
/**
|
||||
* \brief Construct a Loopback object from a buffer.
|
||||
* \brief Construct a Loopback object from a buffer and adds
|
||||
* all identifiable PDUs found in the buffer as children of
|
||||
* this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for a Loopback 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.
|
||||
|
||||
@@ -133,14 +133,14 @@ namespace Tins {
|
||||
*
|
||||
* \param rhs The PDU to be moved.
|
||||
*/
|
||||
PDU(PDU &&rhs);
|
||||
PDU(PDU &&rhs) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Move assignment operator.
|
||||
*
|
||||
* \param rhs The PDU to be moved.
|
||||
*/
|
||||
PDU& operator=(PDU &&rhs);
|
||||
PDU& operator=(PDU &&rhs) noexcept;
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,18 +33,9 @@
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <stdint.h>
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
/**
|
||||
* \brief Exception thrown when an option is not found.
|
||||
*/
|
||||
class option_not_found : public std::exception {
|
||||
public:
|
||||
const char* what() const throw() {
|
||||
return "Option not found";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* \class PDUOption
|
||||
* \brief Represents a PDU option field.
|
||||
|
||||
@@ -107,6 +107,9 @@ public:
|
||||
/**
|
||||
* \brief Constructor which creates an PPPoE object from a buffer.
|
||||
*
|
||||
* If there is not enough size for a PPPoE 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.
|
||||
*/
|
||||
|
||||
@@ -116,8 +116,12 @@ namespace Tins {
|
||||
PDU *child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a RadioTap object from a buffer and adds all
|
||||
* \brief Constructs a RadioTap 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 a RadioTap 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.
|
||||
*/
|
||||
|
||||
@@ -89,7 +89,10 @@ namespace Tins{
|
||||
RSNInformation(const serialization_type &buffer);
|
||||
|
||||
/**
|
||||
* \brief Constructor from buffer.
|
||||
* \brief Constructs a RSNInformation from a buffer.
|
||||
*
|
||||
* If the input is malformed, a malformed_packet exception is
|
||||
* thrown.
|
||||
*
|
||||
* \param buffer The buffer from which this object will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
|
||||
@@ -54,9 +54,14 @@ public:
|
||||
SLL();
|
||||
|
||||
/**
|
||||
* \brief Constructor which constructs an SLL object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
* \brief Constructs a SLL object from a buffer and adds all
|
||||
* identifiable PDUs found in the buffer as children of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for a SLL header in the
|
||||
* buffer, 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.
|
||||
*/
|
||||
|
||||
@@ -61,8 +61,14 @@ namespace Tins {
|
||||
SNAP(PDU *child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates a SNAP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \brief Constructs a SNAP object from a buffer and adds all
|
||||
* identifiable PDUs found in the buffer as children of this one.
|
||||
*
|
||||
* If the next PDU is not recognized, then a RawPDU is used.
|
||||
*
|
||||
* If there is not enough size for a SNAP header in the
|
||||
* buffer, 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.
|
||||
*/
|
||||
|
||||
@@ -48,9 +48,11 @@ public:
|
||||
STP();
|
||||
|
||||
/**
|
||||
* \brief Constructor which constructs an STP object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
* \brief Constructs a STP object from a buffer.
|
||||
*
|
||||
* If there is not enough size for a STP 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.
|
||||
*/
|
||||
|
||||
@@ -129,9 +129,14 @@ namespace Tins {
|
||||
TCP(uint16_t dport = 0, uint16_t sport = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an TCP object from a buffer
|
||||
* and adds all identifiable PDUs found in the buffer as children
|
||||
* of this one.
|
||||
* \brief Constructs TCP object from a buffer.
|
||||
*
|
||||
* If there is not enough size for a TCP header, or any of the
|
||||
* TLV options are malformed a malformed_packet exception is
|
||||
* thrown.
|
||||
*
|
||||
* Any extra data will be stored in a RawPDU.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
|
||||
@@ -60,8 +60,13 @@ namespace Tins {
|
||||
UDP(uint16_t dport = 0, uint16_t sport = 0, PDU *child = 0);
|
||||
|
||||
/**
|
||||
* \brief Constructor which creates an UDP object from a buffer and adds all identifiable
|
||||
* PDUs found in the buffer as children of this one.
|
||||
* \brief Constructs an UDP object from a buffer.
|
||||
*
|
||||
* If there is not enough size for a UDP header a malformed_packet
|
||||
* exception is thrown.
|
||||
*
|
||||
* Any extra data will be stored in a RawPDU.
|
||||
*
|
||||
* \param buffer The buffer from which this PDU will be constructed.
|
||||
* \param total_sz The total size of the buffer.
|
||||
*/
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "rawpdu.h"
|
||||
#include "constants.h"
|
||||
#include "network_interface.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
|
||||
using std::runtime_error;
|
||||
@@ -59,7 +60,7 @@ ARP::ARP(ipaddress_type target_ip, ipaddress_type sender_ip,
|
||||
ARP::ARP(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(arphdr))
|
||||
throw runtime_error("Not enough size for an ARP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_arp, buffer, sizeof(arphdr));
|
||||
total_sz -= sizeof(arphdr);
|
||||
if(total_sz)
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include "bootp.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins{
|
||||
BootP::BootP()
|
||||
@@ -42,7 +43,7 @@ BootP::BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size)
|
||||
: _vend(vend_field_size)
|
||||
{
|
||||
if(total_sz < sizeof(bootphdr) + vend_field_size)
|
||||
throw std::runtime_error("Not enough size for a BootP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_bootp, buffer, sizeof(bootphdr));
|
||||
buffer += sizeof(bootphdr);
|
||||
total_sz -= sizeof(bootphdr);
|
||||
|
||||
11
src/dhcp.cpp
11
src/dhcp.cpp
@@ -32,6 +32,7 @@
|
||||
#include "endianness.h"
|
||||
#include "dhcp.h"
|
||||
#include "ethernetII.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
using std::string;
|
||||
using std::list;
|
||||
@@ -52,7 +53,7 @@ DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz)
|
||||
total_sz -= BootP::header_size() - vend().size();
|
||||
uint8_t args[2] = {0};
|
||||
if(total_sz < sizeof(uint32_t) || *(uint32_t*)buffer != Endian::host_to_be<uint32_t>(0x63825363))
|
||||
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
buffer += sizeof(uint32_t);
|
||||
total_sz -= sizeof(uint32_t);
|
||||
while(total_sz) {
|
||||
@@ -64,11 +65,13 @@ DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz)
|
||||
i = 2;
|
||||
}
|
||||
else if(!total_sz)
|
||||
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
}
|
||||
if(total_sz < args[1])
|
||||
throw std::runtime_error("Not enough size for a DHCP header in the buffer.");
|
||||
add_option(option((OptionTypes)args[0], args[1], buffer));
|
||||
throw malformed_packet();
|
||||
add_option(
|
||||
option((OptionTypes)args[0], args[1], buffer)
|
||||
);
|
||||
buffer += args[1];
|
||||
total_sz -= args[1];
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "dhcpv6.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
DHCPv6::DHCPv6() : options_size() {
|
||||
@@ -39,21 +40,19 @@ DHCPv6::DHCPv6() : options_size() {
|
||||
DHCPv6::DHCPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
: options_size()
|
||||
{
|
||||
const char *err_msg = "Not enough size for a DHCPv6 header",
|
||||
*opt_err_msg = "Not enough size for a DHCPv6 option";
|
||||
if(total_sz == 0)
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
// Relay Agent/Server Messages
|
||||
bool is_relay_msg = (buffer[0] == 12 || buffer[0] == 13);
|
||||
uint32_t required_size = is_relay_msg ? 2 : 4;
|
||||
if(total_sz < required_size)
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
std::copy(buffer, buffer + required_size, header_data);
|
||||
buffer += required_size;
|
||||
total_sz -= required_size;
|
||||
if(is_relay_message()) {
|
||||
if(total_sz < ipaddress_type::address_size * 2)
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
link_addr = buffer;
|
||||
peer_addr = buffer + ipaddress_type::address_size;
|
||||
buffer += ipaddress_type::address_size * 2;
|
||||
@@ -62,14 +61,14 @@ DHCPv6::DHCPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
options_size = total_sz;
|
||||
while(total_sz) {
|
||||
if(total_sz < sizeof(uint16_t) * 2)
|
||||
throw std::runtime_error(opt_err_msg);
|
||||
throw malformed_packet();
|
||||
|
||||
const uint16_t opt = Endian::be_to_host(*(const uint16_t*)buffer);
|
||||
const uint16_t data_size = Endian::be_to_host(
|
||||
*(const uint16_t*)(buffer + sizeof(uint16_t))
|
||||
);
|
||||
if(total_sz - sizeof(uint16_t) * 2 < data_size)
|
||||
throw std::runtime_error(opt_err_msg);
|
||||
throw malformed_packet();
|
||||
buffer += sizeof(uint16_t) * 2;
|
||||
add_option(
|
||||
option(opt, buffer, buffer + data_size)
|
||||
|
||||
12
src/dns.cpp
12
src/dns.cpp
@@ -35,6 +35,8 @@
|
||||
#include "dns.h"
|
||||
#include "ip_address.h"
|
||||
#include "ipv6_address.h"
|
||||
#include "exceptions.h"
|
||||
#include "rawpdu.h"
|
||||
|
||||
using std::string;
|
||||
using std::list;
|
||||
@@ -47,7 +49,7 @@ DNS::DNS() : extra_size(0) {
|
||||
|
||||
DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : extra_size(0) {
|
||||
if(total_sz < sizeof(dnshdr))
|
||||
throw std::runtime_error("Not enough size for a DNS header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&dns, buffer, sizeof(dnshdr));
|
||||
const uint8_t *end(buffer + total_sz);
|
||||
uint16_t nquestions(questions_count());
|
||||
@@ -59,7 +61,7 @@ DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : extra_size(0) {
|
||||
ptr++;
|
||||
Query query;
|
||||
if((ptr + (sizeof(uint16_t) * 2)) >= end)
|
||||
throw std::runtime_error("Not enough size for a given query.");
|
||||
throw malformed_packet();
|
||||
query.dname(string(buffer, ptr));
|
||||
ptr++;
|
||||
const uint16_t *opt_ptr = reinterpret_cast<const uint16_t*>(ptr);
|
||||
@@ -73,6 +75,8 @@ DNS::DNS(const uint8_t *buffer, uint32_t total_sz) : extra_size(0) {
|
||||
buffer = build_resource_list(ans, buffer, total_sz, answers_count());
|
||||
buffer = build_resource_list(arity, buffer, total_sz, authority_count());
|
||||
build_resource_list(addit, buffer, total_sz, additional_count());
|
||||
if(total_sz)
|
||||
inner_pdu(new RawPDU(buffer, total_sz));
|
||||
}
|
||||
|
||||
const uint8_t *DNS::build_resource_list(ResourcesType &lst, const uint8_t *ptr, uint32_t &sz, uint16_t nrecs) {
|
||||
@@ -81,7 +85,7 @@ const uint8_t *DNS::build_resource_list(ResourcesType &lst, const uint8_t *ptr,
|
||||
for(uint16_t i(0); i < nrecs; ++i) {
|
||||
const uint8_t *this_opt_start(ptr);
|
||||
if(ptr + sizeof(uint16_t) > ptr_end)
|
||||
throw std::runtime_error("Not enough size for a given resource.");
|
||||
throw malformed_packet();
|
||||
lst.push_back(DNSResourceRecord(ptr, ptr_end - ptr));
|
||||
ptr += lst.back().size();
|
||||
extra_size += ptr - this_opt_start;
|
||||
@@ -386,7 +390,7 @@ void DNS::compose_name(const uint8_t *ptr, uint32_t sz, std::string &out) const
|
||||
// We need at least a suffix or a suffix index to compose
|
||||
// the domain name
|
||||
if(it == suffixes.end() && suff_it == suffix_indices.end())
|
||||
throw std::runtime_error("Malformed DNS packet");
|
||||
throw malformed_packet();
|
||||
bool first(true);
|
||||
do {
|
||||
if(it != suffixes.end()) {
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <typeinfo>
|
||||
#include "dns_record.h"
|
||||
#include "endianness.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
bool contains_dname(uint16_t type) {
|
||||
@@ -65,17 +66,17 @@ DNSResourceRecord::DNSResourceRecord(const uint8_t *buffer, uint32_t size)
|
||||
while(str_end < buffer_end && *str_end)
|
||||
str_end++;
|
||||
if(str_end == buffer_end)
|
||||
throw std::runtime_error("Not enough size for a resource domain name.");
|
||||
throw malformed_packet();
|
||||
//str_end++;
|
||||
tmp_impl.reset(new NamedDNSRRImpl(buffer, str_end));
|
||||
buffer = ++str_end;
|
||||
}
|
||||
if(buffer + sizeof(info_) > buffer_end)
|
||||
throw std::runtime_error("Not enough size for a resource info.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&info_, buffer, sizeof(info_));
|
||||
buffer += sizeof(info_);
|
||||
if(buffer + sizeof(uint16_t) > buffer_end)
|
||||
throw std::runtime_error("Not enough size for resource data size.");
|
||||
throw malformed_packet();
|
||||
|
||||
// Store the option size.
|
||||
data.resize(
|
||||
@@ -83,7 +84,7 @@ DNSResourceRecord::DNSResourceRecord(const uint8_t *buffer, uint32_t size)
|
||||
);
|
||||
buffer += sizeof(uint16_t);
|
||||
if(buffer + data.size() > buffer_end)
|
||||
throw std::runtime_error("Not enough size for resource data");
|
||||
throw malformed_packet();
|
||||
if(contains_dname(info_.type) || data.size() != sizeof(uint32_t))
|
||||
std::copy(buffer, buffer + data.size(), data.begin());
|
||||
else if(data.size() == sizeof(uint32_t))
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <cassert>
|
||||
#include "dot1q.h"
|
||||
#include "internals.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -45,7 +46,7 @@ Dot1Q::Dot1Q(const uint8_t *buffer, uint32_t total_sz)
|
||||
: _append_padding()
|
||||
{
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for a Dot1Q header");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "dot3.h"
|
||||
#include "packet_sender.h"
|
||||
#include "llc.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
const Dot3::address_type Dot3::BROADCAST("ff:ff:ff:ff:ff:ff");
|
||||
@@ -64,7 +65,7 @@ Dot3::Dot3(const NetworkInterface& iface,
|
||||
Dot3::Dot3(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(ethhdr))
|
||||
throw std::runtime_error("Not enough size for an ethernetII header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_eth, buffer, sizeof(ethhdr));
|
||||
buffer += sizeof(ethhdr);
|
||||
total_sz -= sizeof(ethhdr);
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "eapol.h"
|
||||
#include "dot11.h"
|
||||
#include "rsn_information.h"
|
||||
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
EAPOL::EAPOL(uint8_t packet_type, EAPOLTYPE type)
|
||||
@@ -47,13 +47,13 @@ EAPOL::EAPOL(uint8_t packet_type, EAPOLTYPE type)
|
||||
EAPOL::EAPOL(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an EAPOL header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
}
|
||||
|
||||
EAPOL *EAPOL::from_bytes(const uint8_t *buffer, uint32_t total_sz) {
|
||||
if(total_sz < sizeof(eapolhdr))
|
||||
throw std::runtime_error("Not enough size for an EAPOL header in the buffer.");
|
||||
throw malformed_packet();
|
||||
const eapolhdr *ptr = (const eapolhdr*)buffer;
|
||||
switch(ptr->type) {
|
||||
case RC4:
|
||||
@@ -86,8 +86,6 @@ void EAPOL::type(uint8_t new_type) {
|
||||
void EAPOL::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *) {
|
||||
uint32_t sz = header_size();
|
||||
assert(total_sz >= sz);
|
||||
//if(!_header.length)
|
||||
// length(sz - sizeof(_header.version) - sizeof(_header.length) - sizeof(_header.type));
|
||||
std::memcpy(buffer, &_header, sizeof(_header));
|
||||
write_body(buffer + sizeof(_header), total_sz - sizeof(_header));
|
||||
}
|
||||
@@ -106,7 +104,7 @@ RC4EAPOL::RC4EAPOL(const uint8_t *buffer, uint32_t total_sz)
|
||||
buffer += sizeof(eapolhdr);
|
||||
total_sz -= sizeof(eapolhdr);
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an EAPOL header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
@@ -171,7 +169,7 @@ RSNEAPOL::RSNEAPOL(const uint8_t *buffer, uint32_t total_sz)
|
||||
buffer += sizeof(eapolhdr);
|
||||
total_sz -= sizeof(eapolhdr);
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an EAPOL header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "arp.h"
|
||||
#include "constants.h"
|
||||
#include "internals.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
const EthernetII::address_type EthernetII::BROADCAST("ff:ff:ff:ff:ff:ff");
|
||||
@@ -69,7 +70,7 @@ EthernetII::EthernetII(const NetworkInterface& iface,
|
||||
EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(ethhdr))
|
||||
throw std::runtime_error("Not enough size for an ethernetII header in the buffer.");
|
||||
throw malformed_packet();
|
||||
memcpy(&_eth, buffer, sizeof(ethhdr));
|
||||
buffer += sizeof(ethhdr);
|
||||
total_sz -= sizeof(ethhdr);
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "icmp.h"
|
||||
#include "rawpdu.h"
|
||||
#include "utils.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
Tins::ICMP::ICMP(Flags flag)
|
||||
{
|
||||
@@ -47,7 +48,7 @@ Tins::ICMP::ICMP(Flags flag)
|
||||
Tins::ICMP::ICMP(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(icmphdr))
|
||||
throw std::runtime_error("Not enough size for an ICMP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_icmp, buffer, sizeof(icmphdr));
|
||||
total_sz -= sizeof(icmphdr);
|
||||
if(total_sz)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "rawpdu.h"
|
||||
#include "utils.h"
|
||||
#include "constants.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -48,27 +49,27 @@ ICMPv6::ICMPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
: _options_size(), reach_time(0), retrans_timer(0)
|
||||
{
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an ICMPv6 header");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
if(has_target_addr()) {
|
||||
if(total_sz < ipaddress_type::address_size)
|
||||
throw std::runtime_error("Not enough size for the target address");
|
||||
throw malformed_packet();
|
||||
target_addr(buffer);
|
||||
buffer += ipaddress_type::address_size;
|
||||
total_sz -= ipaddress_type::address_size;
|
||||
}
|
||||
if(has_dest_addr()) {
|
||||
if(total_sz < ipaddress_type::address_size)
|
||||
throw std::runtime_error("Not enough size for the destination address");
|
||||
throw malformed_packet();
|
||||
dest_addr(buffer);
|
||||
buffer += ipaddress_type::address_size;
|
||||
total_sz -= ipaddress_type::address_size;
|
||||
}
|
||||
if(type() == ROUTER_ADVERT) {
|
||||
if(total_sz < sizeof(uint32_t) * 2)
|
||||
throw std::runtime_error("Not enough size for router advert fields");
|
||||
throw malformed_packet();
|
||||
const uint32_t *ptr_32 = (const uint32_t*)buffer;
|
||||
reach_time = *ptr_32++;
|
||||
retrans_timer = *ptr_32++;
|
||||
@@ -85,9 +86,15 @@ ICMPv6::ICMPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
void ICMPv6::parse_options(const uint8_t *&buffer, uint32_t &total_sz) {
|
||||
while(total_sz > 0) {
|
||||
if(total_sz < 8 || (static_cast<uint32_t>(buffer[1]) * 8) > total_sz || buffer[1] < 1)
|
||||
throw std::runtime_error("Not enough size for options");
|
||||
throw malformed_packet();
|
||||
// size(option) = option_size - identifier_size - length_identifier_size
|
||||
add_option(option(buffer[0], static_cast<uint32_t>(buffer[1]) * 8 - sizeof(uint8_t) * 2, buffer + 2));
|
||||
add_option(
|
||||
option(
|
||||
buffer[0],
|
||||
static_cast<uint32_t>(buffer[1]) * 8 - sizeof(uint8_t) * 2,
|
||||
buffer + 2
|
||||
)
|
||||
);
|
||||
total_sz -= buffer[1] * 8;
|
||||
buffer += buffer[1] * 8;
|
||||
}
|
||||
|
||||
12
src/ip.cpp
12
src/ip.cpp
@@ -49,6 +49,7 @@
|
||||
#include "packet_sender.h"
|
||||
#include "constants.h"
|
||||
#include "network_interface.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
using std::list;
|
||||
|
||||
@@ -66,18 +67,17 @@ IP::IP(address_type ip_dst, address_type ip_src, PDU *child)
|
||||
|
||||
IP::IP(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
const char *msg = "Not enough size for an IP header in the buffer.";
|
||||
if(total_sz < sizeof(iphdr))
|
||||
throw std::runtime_error(msg);
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_ip, buffer, sizeof(iphdr));
|
||||
|
||||
/* Options... */
|
||||
/* Establish beginning and ending of the options */
|
||||
const uint8_t* ptr_buffer = buffer + sizeof(iphdr);
|
||||
if(total_sz < head_len() * sizeof(uint32_t))
|
||||
throw std::runtime_error(msg);
|
||||
throw malformed_packet();
|
||||
if(head_len() * sizeof(uint32_t) < sizeof(iphdr))
|
||||
throw std::runtime_error("Malformed head len field");
|
||||
throw malformed_packet();
|
||||
buffer += head_len() * sizeof(uint32_t);
|
||||
|
||||
_options_size = 0;
|
||||
@@ -91,13 +91,13 @@ IP::IP(const uint8_t *buffer, uint32_t total_sz)
|
||||
if(opt_type.number > NOOP) {
|
||||
/* Multibyte options with length as second byte */
|
||||
if(ptr_buffer == buffer || *ptr_buffer == 0)
|
||||
throw std::runtime_error(msg);
|
||||
throw malformed_packet();
|
||||
|
||||
const uint8_t data_size = *ptr_buffer - 2;
|
||||
if(data_size > 0) {
|
||||
ptr_buffer++;
|
||||
if(buffer - ptr_buffer < data_size)
|
||||
throw std::runtime_error(msg);
|
||||
throw malformed_packet();
|
||||
_ip_options.push_back(option(opt_type, ptr_buffer, ptr_buffer + data_size));
|
||||
}
|
||||
else
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "icmp.h"
|
||||
#include "icmpv6.h"
|
||||
#include "rawpdu.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -60,7 +61,7 @@ IPv6::IPv6(address_type ip_dst, address_type ip_src, PDU *child)
|
||||
IPv6::IPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
: headers_size(0) {
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size for an IPv6 PDU");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
@@ -68,13 +69,13 @@ IPv6::IPv6(const uint8_t *buffer, uint32_t total_sz)
|
||||
while(total_sz) {
|
||||
if(is_extension_header(current_header)) {
|
||||
if(total_sz < 8)
|
||||
throw header_size_error();
|
||||
throw malformed_packet();
|
||||
// every ext header is at least 8 bytes long
|
||||
// minus one, from the next_header field.
|
||||
uint32_t size = static_cast<uint32_t>(buffer[1]) + 8;
|
||||
// -1 -> next header identifier
|
||||
if(total_sz < size)
|
||||
throw header_size_error();
|
||||
throw malformed_packet();
|
||||
// minus one, from the size field
|
||||
add_ext_header(
|
||||
ext_header(buffer[0], size - sizeof(uint8_t)*2, buffer + 2)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "llc.h"
|
||||
#include "stp.h"
|
||||
#include "rawpdu.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
using std::list;
|
||||
|
||||
@@ -62,14 +63,14 @@ LLC::LLC(uint8_t dsap, uint8_t ssap, PDU *child)
|
||||
LLC::LLC(const uint8_t *buffer, uint32_t total_sz) {
|
||||
// header + 1 info byte
|
||||
if(total_sz < sizeof(_header) + 1)
|
||||
throw std::runtime_error("Not enough size for a LLC header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
information_field_length = 0;
|
||||
if ((buffer[0] & 0x03) == LLC::UNNUMBERED) {
|
||||
if(total_sz < sizeof(un_control_field))
|
||||
throw std::runtime_error("Not enough size for a LLC header in the buffer.");
|
||||
throw malformed_packet();
|
||||
type(LLC::UNNUMBERED);
|
||||
std::memcpy(&control_field.unnumbered, buffer, sizeof(un_control_field));
|
||||
buffer += sizeof(un_control_field);
|
||||
@@ -78,7 +79,7 @@ LLC::LLC(const uint8_t *buffer, uint32_t total_sz) {
|
||||
}
|
||||
else {
|
||||
if(total_sz < sizeof(info_control_field))
|
||||
throw std::runtime_error("Not enough size for a LLC header in the buffer.");
|
||||
throw malformed_packet();
|
||||
type((Format)(buffer[0] & 0x03));
|
||||
control_field_length = 2;
|
||||
std::memcpy(&control_field.info, buffer, sizeof(info_control_field));
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "ip.h"
|
||||
#include "llc.h"
|
||||
#include "rawpdu.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
#if !defined(PF_LLC)
|
||||
// compilation fix, nasty but at least works on BSD
|
||||
@@ -65,7 +66,7 @@ Loopback::Loopback(const NetworkInterface &iface, PDU *inner_pdu)
|
||||
Loopback::Loopback(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(_family))
|
||||
throw std::runtime_error("Not enough size for a loopback PDU");
|
||||
throw malformed_packet();
|
||||
_family = *reinterpret_cast<const uint32_t*>(buffer);
|
||||
buffer += sizeof(uint32_t);
|
||||
total_sz -= sizeof(uint32_t);
|
||||
|
||||
@@ -39,13 +39,13 @@ PDU::PDU(PDU *next_pdu) : _inner_pdu(next_pdu) {
|
||||
}
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
PDU::PDU(PDU &&rhs)
|
||||
PDU::PDU(PDU &&rhs) noexcept
|
||||
: _inner_pdu(0)
|
||||
{
|
||||
std::swap(_inner_pdu, rhs._inner_pdu);
|
||||
}
|
||||
|
||||
PDU& PDU::operator=(PDU &&rhs) {
|
||||
PDU& PDU::operator=(PDU &&rhs) noexcept {
|
||||
std::swap(_inner_pdu, rhs._inner_pdu);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#endif
|
||||
#include <cstring>
|
||||
#include "pppoe.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -45,22 +46,21 @@ PPPoE::PPPoE()
|
||||
PPPoE::PPPoE(const uint8_t *buffer, uint32_t total_sz)
|
||||
: _tags_size()
|
||||
{
|
||||
const char *err_msg = "Not enough size for a PPPoE";
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
const uint8_t *end = buffer + total_sz;
|
||||
while(buffer < end) {
|
||||
if(buffer + sizeof(uint32_t) * 2 > end)
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
uint16_t opt_type = *(const uint16_t*)buffer;
|
||||
uint16_t opt_len = *(const uint16_t*)(buffer + sizeof(uint16_t));
|
||||
buffer += sizeof(uint16_t) * 2;
|
||||
total_sz -= sizeof(uint16_t) * 2;
|
||||
if(Endian::be_to_host(opt_len) > total_sz)
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
add_tag(
|
||||
tag(
|
||||
static_cast<TagTypes>(opt_type),
|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
#include "dot11.h"
|
||||
#include "utils.h"
|
||||
#include "packet_sender.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
void check_size(uint32_t total_sz, size_t field_size) {
|
||||
static const std::string msg("Not enough size for an RadioTap header in the buffer.");
|
||||
if(total_sz < field_size)
|
||||
throw std::runtime_error(msg);
|
||||
throw malformed_packet();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
||||
@@ -29,12 +29,13 @@
|
||||
|
||||
#include <stdexcept>
|
||||
#include "rsn_information.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
template<typename T>
|
||||
void check_size(uint32_t total_sz, const char* err_msg) {
|
||||
void check_size(uint32_t total_sz) {
|
||||
if(total_sz < sizeof(T))
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
}
|
||||
|
||||
RSNInformation::RSNInformation() : _version(1), _capabilities(0) {
|
||||
@@ -50,9 +51,8 @@ RSNInformation::RSNInformation(const uint8_t *buffer, uint32_t total_sz) {
|
||||
}
|
||||
|
||||
void RSNInformation::init(const uint8_t *buffer, uint32_t total_sz) {
|
||||
const char *err_msg = "Malformed RSN information structure";
|
||||
if(total_sz <= sizeof(uint16_t) * 2 + sizeof(uint32_t))
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
version(Endian::le_to_host(*(uint16_t*)buffer));
|
||||
buffer += sizeof(uint16_t);
|
||||
total_sz -= sizeof(uint16_t);
|
||||
@@ -66,25 +66,25 @@ void RSNInformation::init(const uint8_t *buffer, uint32_t total_sz) {
|
||||
total_sz -= sizeof(uint16_t);
|
||||
|
||||
if(count * sizeof(uint32_t) > total_sz)
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
total_sz -= count * sizeof(uint32_t);
|
||||
while(count--) {
|
||||
add_pairwise_cypher((RSNInformation::CypherSuites)*(uint32_t*)buffer);
|
||||
buffer += sizeof(uint32_t);
|
||||
}
|
||||
check_size<uint16_t>(total_sz, err_msg);
|
||||
check_size<uint16_t>(total_sz);
|
||||
|
||||
count = *(uint16_t*)buffer;
|
||||
buffer += sizeof(uint16_t);
|
||||
total_sz -= sizeof(uint16_t);
|
||||
if(count * sizeof(uint32_t) > total_sz)
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
total_sz -= count * sizeof(uint32_t);
|
||||
while(count--) {
|
||||
add_akm_cypher((RSNInformation::AKMSuites)*(uint32_t*)buffer);
|
||||
buffer += sizeof(uint32_t);
|
||||
}
|
||||
check_size<uint16_t>(total_sz, err_msg);
|
||||
check_size<uint16_t>(total_sz);
|
||||
|
||||
capabilities(Endian::le_to_host(*(uint16_t*)buffer));
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <cstring>
|
||||
#include "sll.h"
|
||||
#include "internals.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
SLL::SLL() : _header() {
|
||||
@@ -38,9 +39,8 @@ SLL::SLL() : _header() {
|
||||
}
|
||||
|
||||
SLL::SLL(const uint8_t *buffer, uint32_t total_sz) {
|
||||
const char *err_msg = "Not enough size for a SLL header";
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error(err_msg);
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer, sizeof(_header));
|
||||
buffer += sizeof(_header);
|
||||
total_sz -= sizeof(_header);
|
||||
|
||||
14
src/snap.cpp
14
src/snap.cpp
@@ -39,6 +39,7 @@
|
||||
#include "ip.h"
|
||||
#include "eapol.h"
|
||||
#include "internals.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
|
||||
Tins::SNAP::SNAP(PDU *child) : PDU(child)
|
||||
@@ -51,22 +52,11 @@ Tins::SNAP::SNAP(PDU *child) : PDU(child)
|
||||
Tins::SNAP::SNAP(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(_snap))
|
||||
throw std::runtime_error("Not enough size for a SNAP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_snap, buffer, sizeof(_snap));
|
||||
buffer += sizeof(_snap);
|
||||
total_sz -= sizeof(_snap);
|
||||
if(total_sz) {
|
||||
/*switch(eth_type()) {
|
||||
case Tins::Constants::Ethernet::IP:
|
||||
inner_pdu(new Tins::IP(buffer, total_sz));
|
||||
break;
|
||||
case Tins::Constants::Ethernet::ARP:
|
||||
inner_pdu(new Tins::ARP(buffer, total_sz));
|
||||
break;
|
||||
case Tins::Constants::Ethernet::EAPOL:
|
||||
inner_pdu(Tins::EAPOL::from_bytes(buffer, total_sz));
|
||||
break;
|
||||
};*/
|
||||
inner_pdu(
|
||||
Internals::pdu_from_flag(
|
||||
(Constants::Ethernet::e)eth_type(),
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include "stp.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -42,7 +43,7 @@ STP::STP()
|
||||
STP::STP(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(_header))
|
||||
throw std::runtime_error("Not enough size.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_header, buffer ,sizeof(_header));
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "constants.h"
|
||||
#include "rawpdu.h"
|
||||
#include "utils.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
|
||||
@@ -53,7 +54,7 @@ TCP::TCP(uint16_t dport, uint16_t sport)
|
||||
TCP::TCP(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(tcphdr))
|
||||
throw std::runtime_error("Not enough size for an TCP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_tcp, buffer, sizeof(tcphdr));
|
||||
buffer += sizeof(tcphdr);
|
||||
total_sz -= sizeof(tcphdr);
|
||||
@@ -67,7 +68,7 @@ TCP::TCP(const uint8_t *buffer, uint32_t total_sz)
|
||||
while(index < header_end) {
|
||||
for(unsigned i(0); i < 2; ++i) {
|
||||
if(index == header_end)
|
||||
throw std::runtime_error("Not enough size for a TCP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
args[i] = buffer[index++];
|
||||
// NOP and EOL contain no length field
|
||||
if(args[0] == NOP || args[0] == EOL)
|
||||
@@ -78,7 +79,7 @@ TCP::TCP(const uint8_t *buffer, uint32_t total_sz)
|
||||
// Not enough size for this option
|
||||
args[1] -= (sizeof(uint8_t) << 1);
|
||||
if(header_end - index < args[1])
|
||||
throw std::runtime_error("Not enough size for a TCP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
if(args[1])
|
||||
add_option(option((OptionTypes)args[0], buffer + index, buffer + index + args[1]));
|
||||
else
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "utils.h"
|
||||
#include "ip.h"
|
||||
#include "rawpdu.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace Tins {
|
||||
UDP::UDP(uint16_t dport, uint16_t sport, PDU *child)
|
||||
@@ -49,7 +50,7 @@ UDP::UDP(uint16_t dport, uint16_t sport, PDU *child)
|
||||
UDP::UDP(const uint8_t *buffer, uint32_t total_sz)
|
||||
{
|
||||
if(total_sz < sizeof(udphdr))
|
||||
throw std::runtime_error("Not enough size for an UDP header in the buffer.");
|
||||
throw malformed_packet();
|
||||
std::memcpy(&_udp, buffer, sizeof(udphdr));
|
||||
total_sz -= sizeof(udphdr);
|
||||
if(total_sz)
|
||||
|
||||
Reference in New Issue
Block a user