From da8c77c77e454ac899a86e4e9d972c80fd52d778 Mon Sep 17 00:00:00 2001 From: Matias Fontanini Date: Mon, 27 Aug 2012 00:16:56 -0300 Subject: [PATCH] RAII'd some code. Everything(hopefully) uses IPv4Address now. --- include/arp.h | 28 +++++++----- include/bootp.h | 72 +++++++++++++++---------------- include/dhcp.h | 42 +++++++++--------- include/dot11.h | 15 ++++--- include/ip.h | 39 +++++++++-------- include/ipaddress.h | 9 +--- include/network_interface.h | 8 +--- include/utils.h | 2 +- src/arp.cpp | 14 +++--- src/bootp.cpp | 58 ++++++------------------- src/dhcp.cpp | 86 +++++++++++-------------------------- src/dot11.cpp | 27 ++++-------- src/ethernetII.cpp | 2 + src/ip.cpp | 17 +++++--- src/ipaddress.cpp | 11 +++-- src/network_interface.cpp | 8 +++- src/utils.cpp | 4 +- tests/src/arp.cpp | 2 +- tests/src/ip.cpp | 26 +++++------ tests/src/ipaddress.cpp | 3 +- 20 files changed, 206 insertions(+), 267 deletions(-) diff --git a/include/arp.h b/include/arp.h index 8e04135..3ef368e 100644 --- a/include/arp.h +++ b/include/arp.h @@ -39,7 +39,15 @@ namespace Tins { */ class ARP : public PDU { public: + /** + * The type of the hardware address. + */ typedef HWAddress<6> hwaddress_type; + + /** + * The type of the IP address. + */ + typedef IPv4Address ipaddress_type; /** * \brief This PDU's flag. @@ -60,8 +68,8 @@ namespace Tins { * ARP requests and replies can be constructed easily using * ARP::make_arp_request/reply static functions. */ - ARP(IPv4Address target_ip = IPv4Address(), - IPv4Address sender_ip = IPv4Address(), + ARP(ipaddress_type target_ip = ipaddress_type(), + ipaddress_type sender_ip = ipaddress_type(), const hwaddress_type &target_hw = hwaddress_type(), const hwaddress_type &sender_hw = hwaddress_type()); @@ -86,7 +94,7 @@ namespace Tins { * * \return Returns the sender's IP address in an uint32_t. */ - IPv4Address sender_ip_addr() const { return Utils::be_to_host(_arp.ar_sip); } + ipaddress_type sender_ip_addr() const { return ipaddress_type(_arp.ar_sip); } /** * \brief Getter for the target's hardware address. @@ -100,7 +108,7 @@ namespace Tins { * * \return Returns the target's IP address in an uint32_t. */ - IPv4Address target_ip_addr() const { return Utils::be_to_host(_arp.ar_tip); } + ipaddress_type target_ip_addr() const { return ipaddress_type(_arp.ar_tip); } /** * \brief Getter for the hardware address format. @@ -156,7 +164,7 @@ namespace Tins { * * \param new_snd_ip_addr IPv4Address containing the new sender's IP address. */ - void sender_ip_addr(IPv4Address new_snd_ip_addr); + void sender_ip_addr(ipaddress_type new_snd_ip_addr); /** * \brief Setter for the target's hardware address. @@ -170,7 +178,7 @@ namespace Tins { * * \param new_tgt_ip_addr IPv4Address containing the new target's IP address. */ - void target_ip_addr(IPv4Address new_tgt_ip_addr); + void target_ip_addr(ipaddress_type new_tgt_ip_addr); /** * \brief Setter for the hardware address format. @@ -225,8 +233,8 @@ namespace Tins { * \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address. * \return Returns a PDU* to the new Layer 2 PDU containing the ARP Request. */ - static PDU* make_arp_request(const NetworkInterface& iface, IPv4Address target, - IPv4Address sender, const hwaddress_type &hw_snd = hwaddress_type()); + static PDU* make_arp_request(const NetworkInterface& iface, ipaddress_type target, + ipaddress_type sender, const hwaddress_type &hw_snd = hwaddress_type()); /** * \brief Creates an ARP Reply within a Layer 2 PDU using uint32_t for target and sender. @@ -241,8 +249,8 @@ namespace Tins { * \param hw_snd uint8_t array of 6 bytes containing the sender's hardware address. * \return Returns a PDU* to the new Layer 2 PDU containing the ARP Replay. */ - static PDU* make_arp_reply(const NetworkInterface& iface, IPv4Address target, - IPv4Address sender, const hwaddress_type &hw_tgt = hwaddress_type(), + static PDU* make_arp_reply(const NetworkInterface& iface, ipaddress_type target, + ipaddress_type sender, const hwaddress_type &hw_tgt = hwaddress_type(), const hwaddress_type &hw_snd = hwaddress_type()); /** \brief Check wether ptr points to a valid response for this PDU. diff --git a/include/bootp.h b/include/bootp.h index aade259..1834cfb 100644 --- a/include/bootp.h +++ b/include/bootp.h @@ -24,6 +24,7 @@ #include #include +#include #include "pdu.h" #include "utils.h" #include "ipaddress.h" @@ -37,7 +38,21 @@ namespace Tins { */ class BootP : public PDU { public: + /** + * The type of the IP addresses. + */ + typedef IPv4Address ipaddress_type; + + /** + * The type of the chaddr field. + */ typedef HWAddress<16> chaddr_type; + + /** + * The type of the vend field. + */ + typedef std::vector vend_type; + /** * \brief This PDU's flag. */ @@ -69,23 +84,6 @@ namespace Tins { */ BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size = 64); - /** - * \brief Copy constructor. - */ - BootP(const BootP &other); - - /** - * \brief Copy assignment operator. - */ - BootP &operator= (const BootP &other); - - /** - * \brief BootP destructor. - * - * This frees the memory allocated to hold the vend field. - */ - ~BootP(); - /* Getters */ /** @@ -133,25 +131,25 @@ namespace Tins { * \brief Getter for the ciaddr field. * \return The ciaddr field for this BootP PDU. */ - IPv4Address ciaddr() const { return Utils::be_to_host(_bootp.ciaddr); } + ipaddress_type ciaddr() const { return ipaddress_type(_bootp.ciaddr); } /** * \brief Getter for the yiaddr field. * \return The yiaddr field for this BootP PDU. */ - IPv4Address yiaddr() const { return Utils::be_to_host(_bootp.yiaddr); } + ipaddress_type yiaddr() const { return ipaddress_type(_bootp.yiaddr); } /** * \brief Getter for the siaddr field. * \return The siaddr field for this BootP PDU. */ - IPv4Address siaddr() const { return Utils::be_to_host(_bootp.siaddr); } + ipaddress_type siaddr() const { return ipaddress_type(_bootp.siaddr); } /** * \brief Getter for the giaddr field. * \return The giaddr field for this BootP PDU. */ - IPv4Address giaddr() const { return Utils::be_to_host(_bootp.giaddr); } + ipaddress_type giaddr() const { return ipaddress_type(_bootp.giaddr); } /** * \brief Getter for the chaddr field. @@ -175,12 +173,7 @@ namespace Tins { * \brief Getter for the vend field. * \return The vend field for this BootP PDU. */ - uint8_t *vend() { return _vend; } - - /** - * \brief Getter for the vend field. - */ - uint32_t vend_size() const { return _vend_size; } + const vend_type &vend() const { return _vend; } /** * \brief Getter for the header size. @@ -236,25 +229,25 @@ namespace Tins { * \brief Setter for the ciaddr field. * \param new_ciaddr The ciaddr to be set. */ - void ciaddr(IPv4Address new_ciaddr); + void ciaddr(ipaddress_type new_ciaddr); /** * \brief Setter for the yiaddr field. * \param new_yiaddr The yiaddr to be set. */ - void yiaddr(IPv4Address new_yiaddr); + void yiaddr(ipaddress_type new_yiaddr); /** * \brief Setter for the siaddr field. * \param new_siaddr The siaddr to be set. */ - void siaddr(IPv4Address new_siaddr); + void siaddr(ipaddress_type new_siaddr); /** * \brief Setter for the giaddr field. * \param new_giaddr The giaddr to be set. */ - void giaddr(IPv4Address new_giaddr); + void giaddr(ipaddress_type new_giaddr); /** * \brief Setter for the chaddr field. @@ -288,9 +281,8 @@ namespace Tins { /** * \brief Setter for the vend field. * \param new_vend The vend to be set. - * \param size The size of the new vend field. */ - void vend(uint8_t *new_vend, uint32_t size); + void vend(const vend_type &new_vend); /** * \brief Getter for the PDU's type. @@ -305,7 +297,16 @@ namespace Tins { return do_clone_pdu(); } protected: - void copy_bootp_fields(const BootP *other); + /** + * \brief Getter for the vend field. + * + * This getter can be used by subclasses to avoid copying the + * vend field around. + * + * \return The vend field for this BootP PDU. + */ + vend_type &vend() { return _vend; } + void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent); private: /** @@ -329,8 +330,7 @@ namespace Tins { } __attribute__((__packed__)); bootphdr _bootp; - uint8_t *_vend; - uint32_t _vend_size; + vend_type _vend; }; }; diff --git a/include/dhcp.h b/include/dhcp.h index 819c631..72674cc 100644 --- a/include/dhcp.h +++ b/include/dhcp.h @@ -40,12 +40,12 @@ namespace Tins { class DHCP : public BootP { public: /** - * \brief This PDU's flag. + * This PDU's flag. */ static const PDU::PDUType pdu_flag = PDU::DHCP; /** - * \brief DHCP flags. + * DHCP flags. */ enum Flags { DISCOVER = 1, @@ -147,7 +147,8 @@ namespace Tins { * \param len The length of the option's value in bytes. * \param val The option's value. */ - DHCPOption(uint8_t opt, uint8_t len, const uint8_t *val); + DHCPOption(uint8_t opt, uint8_t len = 0, const uint8_t *val = 0); + /** * \brief The option number. @@ -228,14 +229,14 @@ namespace Tins { * \param ip The ip of the server. * \return True if the option was added successfully. \sa DHCP::add_option */ - bool add_server_identifier(IPv4Address ip); + bool add_server_identifier(ipaddress_type ip); /** * \brief Searchs for a server identifier option. * \param value A pointer in which the option's value will be stored. * \return True if the option was found, false otherwise. */ - bool search_server_identifier(IPv4Address *value); + bool search_server_identifier(ipaddress_type *value); /** * \brief Adds an IP address lease time option. @@ -284,70 +285,70 @@ namespace Tins { * \param mask The subnet mask. * \return True if the option was added successfully. \sa DHCP::add_option */ - bool add_subnet_mask(IPv4Address mask); + bool add_subnet_mask(ipaddress_type mask); /** * \brief Searchs for a subnet mask option. * \param value A pointer in which the option's value will be stored. * \return True if the option was found, false otherwise. */ - bool search_subnet_mask(IPv4Address *value); + bool search_subnet_mask(ipaddress_type *value); /** * \brief Adds a routers option. * \param routers A list of ip addresses. * \return True if the option was added successfully. \sa DHCP::add_option */ - bool add_routers_option(const std::list &routers); + bool add_routers_option(const std::list &routers); /** * \brief Searchs for a routers option. * \param routers A pointer in which the option's value will be stored. * \return True if the option was found, false otherwise. */ - bool search_routers_option(std::list *routers); + bool search_routers_option(std::list *routers); /** * \brief Adds a domain name servers option. * \param dns A list of ip addresses. * \return True if the option was added successfully. \sa DHCP::add_option */ - bool add_dns_option(const std::list &dns); + bool add_dns_option(const std::list &dns); /** * \brief Searchs for a dns option. * \param dns A pointer in which the option's value will be stored. * \return True if the option was found, false otherwise. */ - bool search_dns_option(std::list *dns); + bool search_dns_option(std::list *dns); /** * \brief Adds a broadcast address option. * \param addr The broadcast address. * \return True if the option was added successfully. \sa DHCP::add_option */ - bool add_broadcast_option(IPv4Address addr); + bool add_broadcast_option(ipaddress_type addr); /** * \brief Searchs for a broadcast option. * \param value A pointer in which the option's value will be stored. * \return True if the option was found, false otherwise. */ - bool search_broadcast_option(IPv4Address *value); + bool search_broadcast_option(ipaddress_type *value); /** * \brief Adds a requested address option. * \param addr The requested address. * \return True if the option was added successfully. \sa DHCP::add_option */ - bool add_requested_ip_option(IPv4Address addr); + bool add_requested_ip_option(ipaddress_type addr); /** * \brief Searchs for a requested option. * \param value A pointer in which the option's value will be stored. * \return True if the option was found, false otherwise. */ - bool search_requested_ip_option(IPv4Address *value); + bool search_requested_ip_option(ipaddress_type *value); /** * \brief Adds a domain name option. @@ -389,8 +390,7 @@ namespace Tins { } private: static const uint32_t MAX_DHCP_SIZE; - - void copy_fields(const DHCP *other); + void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent); template @@ -403,14 +403,12 @@ namespace Tins { return false; } - bool generic_search(Options opt, std::list *container); - bool generic_search(Options opt, std::list *container); + bool generic_search(Options opt, std::list *container); bool generic_search(Options opt, std::string *str); bool generic_search(Options opt, uint32_t *value); - bool generic_search(Options opt, IPv4Address *value); + bool generic_search(Options opt, ipaddress_type *value); - uint8_t *serialize_list(const std::list &int_list, uint32_t &sz); - uint8_t *serialize_list(const std::list &ip_list, uint32_t &sz); + uint8_t *serialize_list(const std::list &ip_list, uint32_t &sz); options_type _options; uint32_t _size; diff --git a/include/dot11.h b/include/dot11.h index 50310cd..5934c5e 100644 --- a/include/dot11.h +++ b/include/dot11.h @@ -213,11 +213,6 @@ namespace Tins { */ Dot11(const uint8_t *buffer, uint32_t total_sz); - /** - * \brief Copy assignment operator. - */ - Dot11 &operator= (const Dot11 &other); - /** * \brief Getter for the protocol version. * @@ -448,11 +443,17 @@ namespace Tins { /** * \brief Allocates an Dot11 PDU from a buffer. + * + * This can be used somehow as a "virtual constructor". This + * method instantiates a subclass of Dot11 from the given buffer. + * The allocated class' type will be figured out from the + * information provided in the buffer. + * * \param buffer The buffer from which to take the PDU data. * \param total_sz The total size of the buffer. - * \return The allocated PDU. + * \return The allocated Dot11 PDU. */ - static PDU *from_bytes(const uint8_t *buffer, uint32_t total_sz); + static Dot11 *from_bytes(const uint8_t *buffer, uint32_t total_sz); protected: virtual uint32_t write_ext_header(uint8_t *buffer, uint32_t total_sz) { return 0; } virtual uint32_t write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) { return 0; } diff --git a/include/ip.h b/include/ip.h index e3da2a6..d1295d1 100644 --- a/include/ip.h +++ b/include/ip.h @@ -44,10 +44,15 @@ namespace Tins { class IP : public PDU { public: /** - * \brief This PDU's flag. + * his PDU's flag. */ static const PDU::PDUType pdu_flag = PDU::IP; + /** + * The type used to store addresses. + */ + typedef IPv4Address address_type; + /** * \brief IP address size. */ @@ -124,22 +129,20 @@ namespace Tins { }; /** - * \brief Default constructor. - * Sets the source and destination port to 0. - */ - IP(); - - /** - * \brief Constructor for building the IP PDU taking integer as ip addresses. + * \brief Constructor for building the IP PDU. * - * Constructor that builds an IP using strings as addresses. They - * can be hostnames or IPs. + * Both the destination and source IP address can be supplied. + * By default, those fields are initialized using the IP + * address 0.0.0.0. * * \param ip_dst The destination ip address(optional). * \param ip_src The source ip address(optional). - * \param child pointer to a PDU which will be set as the inner_pdu for the packet being constructed(optional). + * \param child pointer to a PDU which will be set as the inner_pdu + * for the packet being constructed(optional). */ - IP(IPv4Address ip_dst, IPv4Address ip_src = IPv4Address(), PDU *child = 0); + IP(address_type ip_dst = address_type(), + address_type ip_src = address_type(), + PDU *child = 0); /** * \brief Constructor which creates an IP object from a buffer and adds all identifiable @@ -212,13 +215,13 @@ namespace Tins { * * \return The source address for this IP PDU. */ - IPv4Address src_addr() const { return Utils::be_to_host(_ip.saddr); } + address_type src_addr() const { return address_type(_ip.saddr); } /** * \brief Getter for the destination address field. * \return The destination address for this IP PDU. */ - IPv4Address dst_addr() const { return Utils::be_to_host(_ip.daddr); } + address_type dst_addr() const { return address_type(_ip.daddr); } /** * \brief Getter for the version field. @@ -287,16 +290,16 @@ namespace Tins { /** * \brief Setter for the source address field. * - * \param ip The ip address in integer notation. + * \param ip The source address to be set. */ - void src_addr(IPv4Address ip); + void src_addr(address_type ip); /** * \brief Setter for the destination address field. * - * \param ip The ip address in integer notation. + * \param ip The destination address to be set. */ - void dst_addr(IPv4Address ip); + void dst_addr(address_type ip); /** * \brief Setter for the version field. diff --git a/include/ipaddress.h b/include/ipaddress.h index 1a4a1ad..3c035f9 100644 --- a/include/ipaddress.h +++ b/include/ipaddress.h @@ -29,14 +29,9 @@ namespace Tins { class IPv4Address { public: - IPv4Address(uint32_t ip = 0); + IPv4Address(const char *ip = 0); IPv4Address(const std::string &ip); - - template - IPv4Address(const char (&ip)[n]) - : ip_addr(ip_to_int(ip)) { - - } + explicit IPv4Address(uint32_t ip); IPv4Address &operator=(uint32_t ip); IPv4Address &operator=(const std::string &ip); diff --git a/include/network_interface.h b/include/network_interface.h index 86999ea..6238f4b 100644 --- a/include/network_interface.h +++ b/include/network_interface.h @@ -71,15 +71,11 @@ public: NetworkInterface(const std::string &name); /** - * \brief Constructor to allow implicit conversions from string - * literals. + * \brief Constructor from const char*. * * \param name The name of the interface this object will abstract. */ - template - NetworkInterface(const char (&name)[n]) { - iface_id = resolve_index(name); - } + NetworkInterface(const char *name); /** * \brief Constructs a NetworkInterface from an ip address. diff --git a/include/utils.h b/include/utils.h index 08467c1..d9a4e65 100644 --- a/include/utils.h +++ b/include/utils.h @@ -79,7 +79,7 @@ namespace Tins { * * \param ip A dotted ip notation string */ - uint32_t ip_to_int(const std::string &ip) throw (std::runtime_error); + uint32_t ip_to_int(const std::string &ip); /** * \brief Convert an integer ip to a dotted-ip-notation string. diff --git a/src/arp.cpp b/src/arp.cpp index a2fba58..0277e02 100644 --- a/src/arp.cpp +++ b/src/arp.cpp @@ -36,7 +36,7 @@ using std::runtime_error; namespace Tins { -ARP::ARP(IPv4Address target_ip, IPv4Address sender_ip, +ARP::ARP(ipaddress_type target_ip, ipaddress_type sender_ip, const hwaddress_type &target_hw, const hwaddress_type &sender_hw) : PDU(0x0608) { @@ -66,7 +66,7 @@ void ARP::sender_hw_addr(const hwaddress_type &new_snd_hw_addr) { std::copy(new_snd_hw_addr.begin(), new_snd_hw_addr.end(), _arp.ar_sha); } -void ARP::sender_ip_addr(IPv4Address new_snd_ip_addr) { +void ARP::sender_ip_addr(ipaddress_type new_snd_ip_addr) { this->_arp.ar_sip = new_snd_ip_addr; } @@ -74,7 +74,7 @@ void ARP::target_hw_addr(const hwaddress_type &new_tgt_hw_addr) { std::copy(new_tgt_hw_addr.begin(), new_tgt_hw_addr.end(), _arp.ar_tha); } -void ARP::target_ip_addr(IPv4Address new_tgt_ip_addr) { +void ARP::target_ip_addr(ipaddress_type new_tgt_ip_addr) { this->_arp.ar_tip = new_tgt_ip_addr; } @@ -128,8 +128,8 @@ PDU *ARP::clone_packet(const uint8_t *ptr, uint32_t total_sz) { return cloned; } -PDU* ARP::make_arp_request(const NetworkInterface& iface, IPv4Address target, - IPv4Address sender, const hwaddress_type &hw_snd) +PDU* ARP::make_arp_request(const NetworkInterface& iface, ipaddress_type target, + ipaddress_type sender, const hwaddress_type &hw_snd) { /* Create ARP packet and set its attributes */ ARP* arp = new ARP(); @@ -142,8 +142,8 @@ PDU* ARP::make_arp_request(const NetworkInterface& iface, IPv4Address target, return new EthernetII(iface, EthernetII::BROADCAST, hw_snd, arp); } -PDU* ARP::make_arp_reply(const NetworkInterface& iface, IPv4Address target, - IPv4Address sender, const hwaddress_type &hw_tgt, +PDU* ARP::make_arp_reply(const NetworkInterface& iface, ipaddress_type target, + ipaddress_type sender, const hwaddress_type &hw_tgt, const hwaddress_type &hw_snd) { /* Create ARP packet and set its attributes */ diff --git a/src/bootp.cpp b/src/bootp.cpp index 3e66f44..faaca56 100644 --- a/src/bootp.cpp +++ b/src/bootp.cpp @@ -25,43 +25,25 @@ #include "bootp.h" namespace Tins{ -BootP::BootP() : PDU(255), _vend_size(64) { - _vend = new uint8_t[64]; +BootP::BootP() +: PDU(255), _vend(64) { std::memset(&_bootp, 0, sizeof(bootphdr)); - std::memset(_vend, 0, 64); } BootP::BootP(const uint8_t *buffer, uint32_t total_sz, uint32_t vend_field_size) -: PDU(255), _vend(0), _vend_size(vend_field_size) +: PDU(255), _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."); std::memcpy(&_bootp, buffer, sizeof(bootphdr)); buffer += sizeof(bootphdr); total_sz -= sizeof(bootphdr); - if(_vend_size) { - _vend = new uint8_t[_vend_size]; - std::copy(buffer, buffer + _vend_size, _vend); - } + _vend.assign(buffer, buffer + vend_field_size); // Maybe RawPDU on what is left on the buffer?... } -BootP::BootP(const BootP &other) : PDU(other) { - copy_bootp_fields(&other); -} - -BootP &BootP::operator= (const BootP &other) { - copy_bootp_fields(&other); - copy_inner_pdu(other); - return *this; -} - -BootP::~BootP() { - delete[] _vend; -} - uint32_t BootP::header_size() const { - return sizeof(bootphdr) + _vend_size; + return sizeof(bootphdr) + _vend.size(); } void BootP::opcode(uint8_t new_opcode) { @@ -92,19 +74,19 @@ void BootP::padding(uint16_t new_padding) { _bootp.padding = Utils::host_to_be(new_padding); } -void BootP::ciaddr(IPv4Address new_ciaddr) { +void BootP::ciaddr(ipaddress_type new_ciaddr) { _bootp.ciaddr = new_ciaddr; } -void BootP::yiaddr(IPv4Address new_yiaddr) { +void BootP::yiaddr(ipaddress_type new_yiaddr) { _bootp.yiaddr = new_yiaddr; } -void BootP::siaddr(IPv4Address new_siaddr) { +void BootP::siaddr(ipaddress_type new_siaddr) { _bootp.siaddr = new_siaddr; } -void BootP::giaddr(IPv4Address new_giaddr) { +void BootP::giaddr(ipaddress_type new_giaddr) { _bootp.giaddr = new_giaddr; } @@ -116,27 +98,13 @@ void BootP::file(const uint8_t *new_file) { std::memcpy(_bootp.file, new_file, sizeof(_bootp.file)); } -void BootP::vend(uint8_t *new_vend, uint32_t size) { - delete[] _vend; - _vend_size = size; - _vend = new uint8_t[size]; - std::copy(new_vend, new_vend + size, _vend); +void BootP::vend(const vend_type &new_vend) { + _vend = new_vend; } void BootP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) { - assert(total_sz >= sizeof(bootphdr) + _vend_size); + assert(total_sz >= sizeof(bootphdr) + _vend.size()); std::memcpy(buffer, &_bootp, sizeof(bootphdr)); - std::copy(_vend, _vend + _vend_size, buffer + sizeof(bootphdr)); -} - -void BootP::copy_bootp_fields(const BootP *other) { - std::memcpy(&_bootp, &other->_bootp, sizeof(_bootp)); - _vend_size = other->_vend_size; - if(_vend_size) { - _vend = new uint8_t[_vend_size]; - std::memcpy(_vend, other->_vend, _vend_size); - } - else - _vend = 0; + std::copy(_vend.begin(), _vend.end(), buffer + sizeof(bootphdr)); } } diff --git a/src/dhcp.cpp b/src/dhcp.cpp index 0b0bce2..f2342db 100644 --- a/src/dhcp.cpp +++ b/src/dhcp.cpp @@ -44,8 +44,8 @@ DHCP::DHCP() : _size(sizeof(uint32_t)) { DHCP::DHCP(const uint8_t *buffer, uint32_t total_sz) : BootP(buffer, total_sz, 0), _size(sizeof(uint32_t)) { - buffer += BootP::header_size() - vend_size(); - total_sz -= BootP::header_size() - vend_size(); + buffer += BootP::header_size() - vend().size(); + total_sz -= BootP::header_size() - vend().size(); uint8_t args[2] = {0}; if(total_sz < sizeof(uint32_t) || *(uint32_t*)buffer != Utils::host_to_be(0x63825363)) throw std::runtime_error("Not enough size for a DHCP header in the buffer."); @@ -105,12 +105,12 @@ bool DHCP::search_type_option(uint8_t *value) { return generic_search(DHCP_MESSAGE_TYPE, value); } -bool DHCP::add_server_identifier(IPv4Address ip) { +bool DHCP::add_server_identifier(ipaddress_type ip) { uint32_t ip_int = ip; return add_option(DHCP_SERVER_IDENTIFIER, sizeof(uint32_t), (const uint8_t*)&ip_int); } -bool DHCP::search_server_identifier(IPv4Address *value) { +bool DHCP::search_server_identifier(ipaddress_type *value) { return generic_search(DHCP_SERVER_IDENTIFIER, value); } @@ -132,16 +132,16 @@ bool DHCP::search_renewal_time(uint32_t *value) { return generic_search(DHCP_RENEWAL_TIME, value); } -bool DHCP::add_subnet_mask(IPv4Address mask) { +bool DHCP::add_subnet_mask(ipaddress_type mask) { uint32_t mask_int = mask; return add_option(SUBNET_MASK, sizeof(uint32_t), (const uint8_t*)&mask_int); } -bool DHCP::search_subnet_mask(IPv4Address *value) { +bool DHCP::search_subnet_mask(ipaddress_type *value) { return generic_search(SUBNET_MASK, value); } -bool DHCP::add_routers_option(const list &routers) { +bool DHCP::add_routers_option(const list &routers) { uint32_t size; uint8_t *buffer = serialize_list(routers, size); bool ret = add_option(ROUTERS, size, buffer); @@ -149,11 +149,11 @@ bool DHCP::add_routers_option(const list &routers) { return ret; } -bool DHCP::search_routers_option(std::list *routers) { +bool DHCP::search_routers_option(std::list *routers) { return generic_search(ROUTERS, routers); } -bool DHCP::add_dns_option(const list &dns) { +bool DHCP::add_dns_option(const list &dns) { uint32_t size; uint8_t *buffer = serialize_list(dns, size); bool ret = add_option(DOMAIN_NAME_SERVERS, size, buffer); @@ -161,25 +161,25 @@ bool DHCP::add_dns_option(const list &dns) { return ret; } -bool DHCP::search_dns_option(std::list *dns) { +bool DHCP::search_dns_option(std::list *dns) { return generic_search(DOMAIN_NAME_SERVERS, dns); } -bool DHCP::add_broadcast_option(IPv4Address addr) { +bool DHCP::add_broadcast_option(ipaddress_type addr) { uint32_t int_addr = addr; return add_option(BROADCAST_ADDRESS, sizeof(uint32_t), (uint8_t*)&int_addr); } -bool DHCP::search_broadcast_option(IPv4Address *value) { +bool DHCP::search_broadcast_option(ipaddress_type *value) { return generic_search(BROADCAST_ADDRESS, value); } -bool DHCP::add_requested_ip_option(IPv4Address addr) { +bool DHCP::add_requested_ip_option(ipaddress_type addr) { uint32_t int_addr = addr; return add_option(DHCP_REQUESTED_ADDRESS, sizeof(uint32_t), (uint8_t*)&int_addr); } -bool DHCP::search_requested_ip_option(IPv4Address *value) { +bool DHCP::search_requested_ip_option(ipaddress_type *value) { return generic_search(DHCP_REQUESTED_ADDRESS, value); } @@ -200,59 +200,38 @@ bool DHCP::search_rebind_time(uint32_t *value) { return generic_search(DHCP_REBINDING_TIME, value); } -uint8_t *DHCP::serialize_list(const list &int_list, uint32_t &sz) { - uint8_t *buffer = new uint8_t[int_list.size() * sizeof(uint32_t)]; - uint32_t *ptr = (uint32_t*)buffer; - for(list::const_iterator it = int_list.begin(); it != int_list.end(); ++it) - *(ptr++) = Utils::host_to_be(*it); - sz = sizeof(uint32_t) * int_list.size(); - return buffer; -} - -uint8_t *DHCP::serialize_list(const list &ip_list, uint32_t &sz) { +uint8_t *DHCP::serialize_list(const list &ip_list, uint32_t &sz) { uint8_t *buffer = new uint8_t[ip_list.size() * sizeof(uint32_t)]; uint32_t *ptr = (uint32_t*)buffer; - for(list::const_iterator it = ip_list.begin(); it != ip_list.end(); ++it) - *(ptr++) = Utils::host_to_be(*it); + for(list::const_iterator it = ip_list.begin(); it != ip_list.end(); ++it) + *(ptr++) = *it; sz = sizeof(uint32_t) * ip_list.size(); return buffer; } - uint32_t DHCP::header_size() const { - return BootP::header_size() - vend_size() + _size; + return BootP::header_size() - vend().size() + _size; } void DHCP::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent) { assert(total_sz >= header_size()); - uint8_t *result = 0; if(_size) { - result = new uint8_t[_size]; - uint8_t *ptr = result + sizeof(uint32_t); + vend_type &result(BootP::vend()); + result.resize(_size); + uint8_t *ptr = &result[0] + sizeof(uint32_t); // Magic cookie - *((uint32_t*)result) = Utils::host_to_be(0x63825363); + *((uint32_t*)&result[0]) = Utils::host_to_be(0x63825363); for(options_type::const_iterator it = _options.begin(); it != _options.end(); ++it) { *(ptr++) = it->option; *(ptr++) = it->value.size(); std::copy(it->value.begin(), it->value.end(), ptr); ptr += it->value.size(); } - // End of options - //result[_size-1] = END; - vend(result, _size); } BootP::write_serialization(buffer, total_sz, parent); - delete[] result; } -void DHCP::copy_fields(const DHCP *other) { - BootP::copy_bootp_fields(other); - _size = other->_size; - for(options_type::const_iterator it = other->_options.begin(); it != other->_options.end(); ++it) - _options.push_back(*it); -} - -bool DHCP::generic_search(Options opt, std::list *container) { +bool DHCP::generic_search(Options opt, std::list *container) { const DHCPOption *option = search_option(opt); if(!option) return false; @@ -261,22 +240,7 @@ bool DHCP::generic_search(Options opt, std::list *container) { if((len % sizeof(uint32_t)) != 0) return false; while(len) { - container->push_back(Utils::host_to_be(*(ptr++))); - len -= sizeof(uint32_t); - } - return true; -} - -bool DHCP::generic_search(Options opt, std::list *container) { - const DHCPOption *option = search_option(opt); - if(!option) - return false; - const uint32_t *ptr = (const uint32_t*)&option->value[0]; - uint32_t len = option->value.size(); - if((len % sizeof(uint32_t)) != 0) - return false; - while(len) { - container->push_back(Utils::be_to_host(*(ptr++))); + container->push_back(ipaddress_type(*(ptr++))); len -= sizeof(uint32_t); } return true; @@ -298,7 +262,7 @@ bool DHCP::generic_search(Options opt, uint32_t *value) { return false; } -bool DHCP::generic_search(Options opt, IPv4Address *value) { +bool DHCP::generic_search(Options opt, ipaddress_type *value) { uint32_t ip_int; if(generic_search(opt, &ip_int)) { *value = ip_int; diff --git a/src/dot11.cpp b/src/dot11.cpp index bdb7427..69d692f 100644 --- a/src/dot11.cpp +++ b/src/dot11.cpp @@ -68,12 +68,6 @@ Dot11::Dot11(const uint8_t *buffer, uint32_t total_sz) std::memcpy(&_header, buffer, sizeof(_header)); } -Dot11 &Dot11::operator= (const Dot11 &other) { - copy_80211_fields(&other); - copy_inner_pdu(other); - return *this; -} - void Dot11::parse_tagged_parameters(const uint8_t *buffer, uint32_t total_sz) { if(total_sz > 0) { uint8_t opcode, length; @@ -175,8 +169,8 @@ bool Dot11::send(PacketSender* sender) { addr.sll_family = Utils::host_to_be(PF_PACKET); addr.sll_protocol = Utils::host_to_be(ETH_P_ALL); addr.sll_halen = 6; - addr.sll_ifindex = this->_iface.id(); - memcpy(&(addr.sll_addr), this->_header.addr1, 6); + addr.sll_ifindex = _iface.id(); + memcpy(&(addr.sll_addr), _header.addr1, 6); return sender->send_l2(this, (struct sockaddr*)&addr, (uint32_t)sizeof(addr)); } @@ -188,7 +182,7 @@ void Dot11::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *p buffer += sizeof(_header); total_sz -= sizeof(_header); - uint32_t written = this->write_ext_header(buffer, total_sz); + uint32_t written = write_ext_header(buffer, total_sz); buffer += written; total_sz -= written; @@ -203,12 +197,12 @@ void Dot11::write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *p } } -PDU *Dot11::from_bytes(const uint8_t *buffer, uint32_t total_sz) { +Dot11 *Dot11::from_bytes(const uint8_t *buffer, uint32_t total_sz) { // We only need the control field, the length of the PDU will depend on the flags set. if(total_sz < sizeof(ieee80211_header::control)) throw runtime_error("Not enough size for a IEEE 802.11 header in the buffer."); const ieee80211_header *hdr = (const ieee80211_header*)buffer; - PDU *ret = 0; + Dot11 *ret = 0; if(hdr->control.type == MANAGEMENT) { if(hdr->control.subtype == BEACON) ret = new Dot11Beacon(buffer, total_sz); @@ -228,11 +222,8 @@ PDU *Dot11::from_bytes(const uint8_t *buffer, uint32_t total_sz) { ret = new Dot11Deauthentication(buffer, total_sz); else if(hdr->control.subtype == PROBE_REQ) ret = new Dot11ProbeRequest(buffer, total_sz); - //else if(hdr->control.subtype == PROBE_RESP) - else + else if(hdr->control.subtype == PROBE_RESP) ret = new Dot11ProbeResponse(buffer, total_sz); - - } else if(hdr->control.type == DATA){ if(hdr->control.subtype <= 4) @@ -256,7 +247,7 @@ PDU *Dot11::from_bytes(const uint8_t *buffer, uint32_t total_sz) { else if(hdr->control.subtype == BLOCK_ACK_REQ) ret = new Dot11BlockAckRequest(buffer, total_sz); } - else + if(ret == 0) ret = new Dot11(buffer, total_sz); return ret; } @@ -1309,7 +1300,7 @@ uint32_t Dot11Data::write_ext_header(uint8_t *buffer, uint32_t total_sz) { memcpy(buffer, &_ext_header, sizeof(_ext_header)); buffer += sizeof(_ext_header); if (from_ds() && to_ds()) { - written += 6; + written += _addr4.size(); _addr4.copy(buffer); } return written; @@ -1348,7 +1339,7 @@ void Dot11QoSData::qos_control(uint16_t new_qos_control) { } uint32_t Dot11QoSData::header_size() const { - return Dot11::header_size() + sizeof(this->_qos_control); + return Dot11Data::header_size() + sizeof(this->_qos_control); } uint32_t Dot11QoSData::write_fixed_parameters(uint8_t *buffer, uint32_t total_sz) { diff --git a/src/ethernetII.cpp b/src/ethernetII.cpp index bf5d0ca..8e4622d 100644 --- a/src/ethernetII.cpp +++ b/src/ethernetII.cpp @@ -67,6 +67,8 @@ EthernetII::EthernetII(const uint8_t *buffer, uint32_t total_sz) case ETHERTYPE_ARP: next = new Tins::ARP(buffer, total_sz); break; + default: + next = new Tins::RawPDU(buffer, total_sz); // Other protos plz } inner_pdu(next); diff --git a/src/ip.cpp b/src/ip.cpp index 46a0227..b05f6d4 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -40,8 +40,9 @@ using namespace std; const uint8_t Tins::IP::DEFAULT_TTL = 128; -Tins::IP::IP(IPv4Address ip_dst, IPv4Address ip_src, PDU *child) : - PDU(Constants::IP::PROTO_IP, child) { +Tins::IP::IP(address_type ip_dst, address_type ip_src, PDU *child) +: PDU(Constants::IP::PROTO_IP, child) +{ init_ip_fields(); this->dst_addr(ip_dst); this->src_addr(ip_src); @@ -60,10 +61,12 @@ Tins::IP::IP(const uint8_t *buffer, uint32_t total_sz) const uint8_t* ptr_buffer = buffer + sizeof(iphdr); if(total_sz < head_len() * sizeof(uint32_t)) throw std::runtime_error(msg); + if(head_len() * sizeof(uint32_t) < sizeof(iphdr)) + throw std::runtime_error("Malformed head len field"); buffer += head_len() * sizeof(uint32_t); - this->_options_size = 0; - this->_padded_options_size = head_len() * sizeof(uint32_t) - sizeof(iphdr); + _options_size = 0; + _padded_options_size = head_len() * sizeof(uint32_t) - sizeof(iphdr); /* While the end of the options is not reached read an option */ while (ptr_buffer < buffer && (*ptr_buffer != 0)) { IPOption opt_to_add; @@ -165,12 +168,12 @@ void Tins::IP::check(uint16_t new_check) { } -void Tins::IP::src_addr(IPv4Address ip) { +void Tins::IP::src_addr(address_type ip) { _ip.saddr = ip; } -void Tins::IP::dst_addr(IPv4Address ip) { +void Tins::IP::dst_addr(address_type ip) { _ip.daddr = ip; } @@ -214,7 +217,7 @@ void Tins::IP::set_option(uint8_t copied, _ip_options.push_back(option); _options_size += 1 + (!option.optional_data.empty() ? (data_size) : 0); uint8_t padding = _options_size & 3; - _padded_options_size = padding? (_options_size - padding + 4) : _options_size; + _padded_options_size = padding ? (_options_size - padding + 4) : _options_size; } const Tins::IP::IPOption *Tins::IP::search_option(OptionClass opt_class, Option opt_number) const { diff --git a/src/ipaddress.cpp b/src/ipaddress.cpp index 2724eeb..3e99e41 100644 --- a/src/ipaddress.cpp +++ b/src/ipaddress.cpp @@ -26,12 +26,17 @@ using std::string; namespace Tins{ -IPv4Address::IPv4Address(uint32_t ip) : ip_addr(ip) { +IPv4Address::IPv4Address(uint32_t ip) +: ip_addr(Utils::be_to_host(ip)) { } +IPv4Address::IPv4Address(const char *ip) { + ip_addr = ip ? ip_to_int(ip) : 0; +} + IPv4Address::IPv4Address(const std::string &ip) -: ip_addr(Utils::ip_to_int(ip)) { +: ip_addr(ip_to_int(ip)) { } @@ -41,7 +46,7 @@ IPv4Address &IPv4Address::operator=(uint32_t ip) { } IPv4Address &Tins::IPv4Address::operator=(const string &ip) { - ip_addr = Utils::ip_to_int(ip); + ip_addr = ip_to_int(ip); return *this; } diff --git a/src/network_interface.cpp b/src/network_interface.cpp index 4f47db7..e45efc4 100644 --- a/src/network_interface.cpp +++ b/src/network_interface.cpp @@ -63,13 +63,17 @@ struct InterfaceInfoCollector { namespace Tins { // static NetworkInterface NetworkInterface::default_interface() { - return NetworkInterface(IPv4Address(0)); + return NetworkInterface(0); } NetworkInterface::NetworkInterface() : iface_id(0) { } - + +NetworkInterface::NetworkInterface(const char *name) { + iface_id = name ? resolve_index(name) : 0; +} + NetworkInterface::NetworkInterface(const std::string &name) { iface_id = resolve_index(name.c_str()); } diff --git a/src/utils.cpp b/src/utils.cpp index 05adedc..f710353 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -93,7 +93,7 @@ void Utils::Internals::skip_line(istream &input) { /** \endcond */ -uint32_t Utils::ip_to_int(const string &ip) throw (std::runtime_error) { +uint32_t Utils::ip_to_int(const string &ip) { uint32_t result(0), i(0), end, bytes_found(0); while(i < ip.size() && bytes_found < 4) { uint16_t this_byte(0); @@ -133,7 +133,7 @@ IPv4Address Utils::resolve_ip(const string &to_resolve) { struct hostent *data = gethostbyname(to_resolve.c_str()); if(!data) throw std::runtime_error("Could not resolve IP"); - return be_to_host(((struct in_addr**)data->h_addr_list)[0]->s_addr); + return IPv4Address(((struct in_addr**)data->h_addr_list)[0]->s_addr); } PDU *Utils::ping_address(IPv4Address ip, PacketSender *sender, IPv4Address ip_src) { diff --git a/tests/src/arp.cpp b/tests/src/arp.cpp index b24f9f1..d65b7ec 100644 --- a/tests/src/arp.cpp +++ b/tests/src/arp.cpp @@ -141,7 +141,7 @@ TEST_F(ARPTest, Opcode) { } TEST_F(ARPTest, Serialize) { - ARP arp1(0x1234, 0xa3f1, hw_addr1, hw_addr2); + ARP arp1("192.168.0.1", "192.168.0.100", hw_addr1, hw_addr2); PDU::serialization_type buffer = arp1.serialize(); diff --git a/tests/src/ip.cpp b/tests/src/ip.cpp index 27fe43a..8d3fc72 100644 --- a/tests/src/ip.cpp +++ b/tests/src/ip.cpp @@ -24,8 +24,8 @@ const uint8_t IPTest::expected_packet[] = { '(', '\x7f', '\x00', ' ', TEST_F(IPTest, DefaultConstructor) { IP ip; - EXPECT_EQ(ip.dst_addr(), IPv4Address()); - EXPECT_EQ(ip.src_addr(), IPv4Address()); + EXPECT_EQ(ip.dst_addr(), 0); + EXPECT_EQ(ip.src_addr(), 0); EXPECT_EQ(ip.version(), 4); EXPECT_EQ(ip.id(), 1); EXPECT_EQ(ip.pdu_type(), PDU::IP); @@ -53,9 +53,9 @@ TEST_F(IPTest, NestedCopy) { } TEST_F(IPTest, IPIntConstructor) { - IP ip(0x23abcdef, 0xff1443ab); - EXPECT_EQ(ip.dst_addr(), IPv4Address(0x23abcdef)); - EXPECT_EQ(ip.src_addr(), IPv4Address(0xff1443ab)); + IP ip("192.168.0.1", "192.168.0.100"); + EXPECT_EQ(ip.dst_addr(), "192.168.0.1"); + EXPECT_EQ(ip.src_addr(), "192.168.0.100"); EXPECT_EQ(ip.version(), 4); EXPECT_EQ(ip.id(), 1); } @@ -63,8 +63,8 @@ TEST_F(IPTest, IPIntConstructor) { TEST_F(IPTest, IPStringConstructor) { string ip1 = "154.33.200.55", ip2 = "192.10.11.52"; IP ip(ip1, ip2); - EXPECT_EQ(ip.dst_addr(), IPv4Address(ip1)); - EXPECT_EQ(ip.src_addr(), IPv4Address(ip2)); + EXPECT_EQ(ip.dst_addr(), ip1); + EXPECT_EQ(ip.src_addr(), ip2); EXPECT_EQ(ip.version(), 4); EXPECT_EQ(ip.id(), 1); } @@ -133,14 +133,14 @@ TEST_F(IPTest, DstIPString) { TEST_F(IPTest, SrcIPInt) { IP ip; - ip.src_addr(0x7f137ab3); - EXPECT_EQ(ip.src_addr(), IPv4Address(0x7f137ab3)); + ip.src_addr("192.155.32.10"); + EXPECT_EQ(ip.src_addr(), "192.155.32.10"); } TEST_F(IPTest, DstIPInt) { IP ip; - ip.dst_addr(0x7f137ab3); - EXPECT_EQ(ip.dst_addr(), IPv4Address(0x7f137ab3)); + ip.dst_addr("192.155.32.10"); + EXPECT_EQ(ip.dst_addr(), "192.155.32.10"); } TEST_F(IPTest, Version) { @@ -174,8 +174,8 @@ TEST_F(IPTest, ConstructorFromBuffer) { IP ip1(expected_packet, sizeof(expected_packet)); const uint8_t opt_sec[] = { 't', 'j', 'g', '\xab', 'w', '\xab', 'h', 'e', 'l' }; - EXPECT_EQ(ip1.dst_addr(), IPv4Address ("192.168.9.43")); - EXPECT_EQ(ip1.src_addr(), IPv4Address("84.52.254.5")); + EXPECT_EQ(ip1.dst_addr(), "192.168.9.43"); + EXPECT_EQ(ip1.src_addr(), "84.52.254.5"); EXPECT_EQ(ip1.id(), 0x7a); EXPECT_EQ(ip1.tos(), 0x7f); EXPECT_EQ(ip1.frag_off(), 0x43); diff --git a/tests/src/ipaddress.cpp b/tests/src/ipaddress.cpp index 5f6792c..4d39a80 100644 --- a/tests/src/ipaddress.cpp +++ b/tests/src/ipaddress.cpp @@ -11,8 +11,9 @@ std::string ip_string("192.168.0.225"); TEST(IPAddressTest, Constructor) { IPv4Address addr1(ip_string); - IPv4Address addr2(Utils::ip_to_int(ip_string)); + IPv4Address addr2(ip_string); EXPECT_EQ(addr2, addr1); EXPECT_EQ(addr1.to_string(), ip_string); EXPECT_EQ(addr2.to_string(), ip_string); + EXPECT_NE(addr1, "192.168.0.254"); }