From 3fd1b3d37d07dbb5c3db7803ea21bce10e29ba1d Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Thu, 18 Apr 2013 00:12:20 -0300 Subject: [PATCH] Added malformed_packet exception. Every class except Dot11* use it. --- Makefile.am | 3 ++- Makefile.in | 3 ++- include/arp.h | 10 ++++++++-- include/bootp.h | 7 +++++-- include/dhcp.h | 8 ++++++-- include/dhcpv6.h | 9 ++++++--- include/dns.h | 6 +++++- include/dns_record.h | 4 ++++ include/dot1q.h | 11 ++++++++--- include/dot3.h | 8 ++++++-- include/eapol.h | 20 +++++++++++++++++--- include/ethernetII.h | 10 ++++++++-- include/icmp.h | 9 +++++++-- include/icmpv6.h | 8 ++++++-- include/ip.h | 10 +++++++--- include/ipv6.h | 19 +++++-------------- include/llc.h | 8 ++++++-- include/loopback.h | 9 ++++++++- include/pdu.h | 4 ++-- include/pdu_option.h | 11 +---------- include/pppoe.h | 3 +++ include/radiotap.h | 6 +++++- include/rsn_information.h | 5 ++++- include/sll.h | 11 ++++++++--- include/snap.h | 10 ++++++++-- include/stp.h | 8 +++++--- include/tcp.h | 11 ++++++++--- include/udp.h | 9 +++++++-- src/arp.cpp | 3 ++- src/bootp.cpp | 3 ++- src/dhcp.cpp | 11 +++++++---- src/dhcpv6.cpp | 13 ++++++------- src/dns.cpp | 12 ++++++++---- src/dns_record.cpp | 9 +++++---- src/dot1q.cpp | 3 ++- src/dot3.cpp | 3 ++- src/eapol.cpp | 12 +++++------- src/ethernetII.cpp | 3 ++- src/icmp.cpp | 3 ++- src/icmpv6.cpp | 19 +++++++++++++------ src/ip.cpp | 12 ++++++------ src/ipv6.cpp | 7 ++++--- src/llc.cpp | 7 ++++--- src/loopback.cpp | 3 ++- src/pdu.cpp | 4 ++-- src/pppoe.cpp | 8 ++++---- src/radiotap.cpp | 4 ++-- src/rsn_information.cpp | 16 ++++++++-------- src/sll.cpp | 4 ++-- src/snap.cpp | 14 ++------------ src/stp.cpp | 3 ++- src/tcp.cpp | 7 ++++--- src/udp.cpp | 3 ++- 53 files changed, 267 insertions(+), 159 deletions(-) diff --git a/Makefile.am b/Makefile.am index 6b07a6a..4e7a82b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/Makefile.in b/Makefile.in index e2cccd4..4e9dab9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 \ diff --git a/include/arp.h b/include/arp.h index 1ac6eb8..499cd2c 100644 --- a/include/arp.h +++ b/include/arp.h @@ -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. */ diff --git a/include/bootp.h b/include/bootp.h index 63ff0f3..55f4a43 100644 --- a/include/bootp.h +++ b/include/bootp.h @@ -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. diff --git a/include/dhcp.h b/include/dhcp.h index c3ec791..b0da952 100644 --- a/include/dhcp.h +++ b/include/dhcp.h @@ -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. diff --git a/include/dhcpv6.h b/include/dhcpv6.h index b7264e6..5fc5db8 100644 --- a/include/dhcpv6.h +++ b/include/dhcpv6.h @@ -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. */ diff --git a/include/dns.h b/include/dns.h index c870fb9..3e23326 100644 --- a/include/dns.h +++ b/include/dns.h @@ -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. diff --git a/include/dns_record.h b/include/dns_record.h index 79bf17e..f64aea5 100644 --- a/include/dns_record.h +++ b/include/dns_record.h @@ -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. */ diff --git a/include/dot1q.h b/include/dot1q.h index 1b8c21f..46dd0bd 100644 --- a/include/dot1q.h +++ b/include/dot1q.h @@ -48,9 +48,14 @@ 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 - * one. + * \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. diff --git a/include/dot3.h b/include/dot3.h index 7800c73..73d44a1 100644 --- a/include/dot3.h +++ b/include/dot3.h @@ -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. */ diff --git a/include/eapol.h b/include/eapol.h index a12e95f..bf9b555 100644 --- a/include/eapol.h +++ b/include/eapol.h @@ -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. */ diff --git a/include/ethernetII.h b/include/ethernetII.h index b602b1e..0281419 100644 --- a/include/ethernetII.h +++ b/include/ethernetII.h @@ -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. diff --git a/include/icmp.h b/include/icmp.h index bdc994f..5b6ecd6 100644 --- a/include/icmp.h +++ b/include/icmp.h @@ -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. */ diff --git a/include/icmpv6.h b/include/icmpv6.h index a3d8c49..06ef028 100644 --- a/include/icmpv6.h +++ b/include/icmpv6.h @@ -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. diff --git a/include/ip.h b/include/ip.h index 0907317..36ffe99 100644 --- a/include/ip.h +++ b/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. */ diff --git a/include/ipv6.h b/include/ipv6.h index e90404b..8de6397 100644 --- a/include/ipv6.h +++ b/include/ipv6.h @@ -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. diff --git a/include/llc.h b/include/llc.h index 4297460..baf056f 100644 --- a/include/llc.h +++ b/include/llc.h @@ -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. */ diff --git a/include/loopback.h b/include/loopback.h index 384c8f6..06fd1b7 100644 --- a/include/loopback.h +++ b/include/loopback.h @@ -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. diff --git a/include/pdu.h b/include/pdu.h index 55530e2..9f7f78e 100644 --- a/include/pdu.h +++ b/include/pdu.h @@ -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 /** diff --git a/include/pdu_option.h b/include/pdu_option.h index 5e43879..4c6f95f 100644 --- a/include/pdu_option.h +++ b/include/pdu_option.h @@ -33,18 +33,9 @@ #include #include #include +#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. diff --git a/include/pppoe.h b/include/pppoe.h index fa5f7bf..780daac 100644 --- a/include/pppoe.h +++ b/include/pppoe.h @@ -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. */ diff --git a/include/radiotap.h b/include/radiotap.h index 9786091..c9799cf 100644 --- a/include/radiotap.h +++ b/include/radiotap.h @@ -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. */ diff --git a/include/rsn_information.h b/include/rsn_information.h index eb7c80d..4bd1d33 100644 --- a/include/rsn_information.h +++ b/include/rsn_information.h @@ -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. diff --git a/include/sll.h b/include/sll.h index 47af8d2..5ba7ede 100644 --- a/include/sll.h +++ b/include/sll.h @@ -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. */ diff --git a/include/snap.h b/include/snap.h index 6d3d162..0ea2871 100644 --- a/include/snap.h +++ b/include/snap.h @@ -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. */ diff --git a/include/stp.h b/include/stp.h index b9371e6..fb11094 100644 --- a/include/stp.h +++ b/include/stp.h @@ -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. */ diff --git a/include/tcp.h b/include/tcp.h index 2b4a1fc..3794a73 100644 --- a/include/tcp.h +++ b/include/tcp.h @@ -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. */ diff --git a/include/udp.h b/include/udp.h index 6afd89b..ff46536 100644 --- a/include/udp.h +++ b/include/udp.h @@ -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. */ diff --git a/src/arp.cpp b/src/arp.cpp index 5d22715..8a97b7e 100644 --- a/src/arp.cpp +++ b/src/arp.cpp @@ -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) diff --git a/src/bootp.cpp b/src/bootp.cpp index 8e5357c..f66972a 100644 --- a/src/bootp.cpp +++ b/src/bootp.cpp @@ -31,6 +31,7 @@ #include #include #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); diff --git a/src/dhcp.cpp b/src/dhcp.cpp index 083fd05..2fd8ccf 100644 --- a/src/dhcp.cpp +++ b/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(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]; } diff --git a/src/dhcpv6.cpp b/src/dhcpv6.cpp index a8ff12f..bf63944 100644 --- a/src/dhcpv6.cpp +++ b/src/dhcpv6.cpp @@ -30,6 +30,7 @@ #include #include #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) diff --git a/src/dns.cpp b/src/dns.cpp index 3d49f48..892cd9f 100644 --- a/src/dns.cpp +++ b/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(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()) { diff --git a/src/dns_record.cpp b/src/dns_record.cpp index f563713..59dac33 100644 --- a/src/dns_record.cpp +++ b/src/dns_record.cpp @@ -33,6 +33,7 @@ #include #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)) diff --git a/src/dot1q.cpp b/src/dot1q.cpp index 34945fd..bf867a3 100644 --- a/src/dot1q.cpp +++ b/src/dot1q.cpp @@ -32,6 +32,7 @@ #include #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); diff --git a/src/dot3.cpp b/src/dot3.cpp index b6d1269..a9bce2b 100644 --- a/src/dot3.cpp +++ b/src/dot3.cpp @@ -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); diff --git a/src/eapol.cpp b/src/eapol.cpp index aad283c..9474077 100644 --- a/src/eapol.cpp +++ b/src/eapol.cpp @@ -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); diff --git a/src/ethernetII.cpp b/src/ethernetII.cpp index ee0d418..de06b91 100644 --- a/src/ethernetII.cpp +++ b/src/ethernetII.cpp @@ -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); diff --git a/src/icmp.cpp b/src/icmp.cpp index 4a38945..fcfa047 100644 --- a/src/icmp.cpp +++ b/src/icmp.cpp @@ -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) diff --git a/src/icmpv6.cpp b/src/icmpv6.cpp index ba763de..0d7451e 100644 --- a/src/icmpv6.cpp +++ b/src/icmpv6.cpp @@ -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(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(buffer[1]) * 8 - sizeof(uint8_t) * 2, buffer + 2)); + add_option( + option( + buffer[0], + static_cast(buffer[1]) * 8 - sizeof(uint8_t) * 2, + buffer + 2 + ) + ); total_sz -= buffer[1] * 8; buffer += buffer[1] * 8; } diff --git a/src/ip.cpp b/src/ip.cpp index 173242d..0af9f37 100644 --- a/src/ip.cpp +++ b/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 diff --git a/src/ipv6.cpp b/src/ipv6.cpp index bf2531f..7c72af8 100644 --- a/src/ipv6.cpp +++ b/src/ipv6.cpp @@ -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(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) diff --git a/src/llc.cpp b/src/llc.cpp index c3e56bc..284974c 100644 --- a/src/llc.cpp +++ b/src/llc.cpp @@ -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)); diff --git a/src/loopback.cpp b/src/loopback.cpp index 1ffa842..147dd6f 100644 --- a/src/loopback.cpp +++ b/src/loopback.cpp @@ -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(buffer); buffer += sizeof(uint32_t); total_sz -= sizeof(uint32_t); diff --git a/src/pdu.cpp b/src/pdu.cpp index f639e66..aea6e4a 100644 --- a/src/pdu.cpp +++ b/src/pdu.cpp @@ -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; } diff --git a/src/pppoe.cpp b/src/pppoe.cpp index d3e0adb..6aee175 100644 --- a/src/pppoe.cpp +++ b/src/pppoe.cpp @@ -32,6 +32,7 @@ #endif #include #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(opt_type), diff --git a/src/radiotap.cpp b/src/radiotap.cpp index 517479f..bbf60f0 100644 --- a/src/radiotap.cpp +++ b/src/radiotap.cpp @@ -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 diff --git a/src/rsn_information.cpp b/src/rsn_information.cpp index a441518..3197c27 100644 --- a/src/rsn_information.cpp +++ b/src/rsn_information.cpp @@ -29,12 +29,13 @@ #include #include "rsn_information.h" +#include "exceptions.h" namespace Tins { template -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(total_sz, err_msg); + check_size(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(total_sz, err_msg); + check_size(total_sz); capabilities(Endian::le_to_host(*(uint16_t*)buffer)); } diff --git a/src/sll.cpp b/src/sll.cpp index 2cf402e..9dd6301 100644 --- a/src/sll.cpp +++ b/src/sll.cpp @@ -31,6 +31,7 @@ #include #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); diff --git a/src/snap.cpp b/src/snap.cpp index 96be43e..05a93a5 100644 --- a/src/snap.cpp +++ b/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(), diff --git a/src/stp.cpp b/src/stp.cpp index 2612718..dbea5d3 100644 --- a/src/stp.cpp +++ b/src/stp.cpp @@ -30,6 +30,7 @@ #include #include #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)); } diff --git a/src/tcp.cpp b/src/tcp.cpp index f5a65b3..b58fb3c 100644 --- a/src/tcp.cpp +++ b/src/tcp.cpp @@ -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 diff --git a/src/udp.cpp b/src/udp.cpp index 7b7549d..f7f81f0 100644 --- a/src/udp.cpp +++ b/src/udp.cpp @@ -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)