diff --git a/include/arp.h b/include/arp.h index 819eea0..30a8df6 100644 --- a/include/arp.h +++ b/include/arp.h @@ -59,7 +59,7 @@ namespace Tins { * \param total_sz The total size of the buffer. */ ARP(const uint8_t *buffer, uint32_t total_sz); - + /* Getters */ /** * \brief Getter for the sender's hardware address. @@ -73,7 +73,7 @@ namespace Tins { * * \return Returns the sender's IP address in an uint32_t. */ - inline const uint32_t sender_ip_addr() { return this->_arp.ar_sip; } + inline const uint32_t sender_ip_addr() { return Utils::net_to_host_l(this->_arp.ar_sip); } /** * \brief Getter for the target's hardware address. @@ -87,7 +87,7 @@ namespace Tins { * * \return Returns the target's IP address in an uint32_t. */ - inline const uint32_t target_ip_addr() { return this->_arp.ar_tip; } + inline const uint32_t target_ip_addr() { return Utils::net_to_host_l(this->_arp.ar_tip); } /** * \brief Getter for the hardware address format. @@ -317,7 +317,7 @@ namespace Tins { /** * \brief Clones this PDU. - * + * * \sa PDU::clone_pdu */ PDU *clone_pdu() const; @@ -334,7 +334,7 @@ namespace Tins { uint8_t ar_tha[6]; /* target hardware address */ uint32_t ar_tip; /* target IP address */ } __attribute__((__packed__)); - + void copy_fields(const ARP *other); void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent); diff --git a/include/bootp.h b/include/bootp.h index 4c07cc0..95aa6b0 100644 --- a/include/bootp.h +++ b/include/bootp.h @@ -41,217 +41,217 @@ namespace Tins { */ enum OpCodes { BOOTREQUEST = 1, - BOOTREPLY = 2 + BOOTREPLY = 2 }; - - /** + + /** * \brief Creates an instance of BootP. - * + * * This sets the size of the vend field to 64, as the BootP RFC * states. */ 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. * \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. + * \param vend_field_size The vend field size to allocate. * Subclasses might use 0 to provide their own interpretation of this field. */ 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 */ - + /** \brief Getter for the opcode field. * \return The opcode field for this BootP PDU. */ uint8_t opcode() const { return _bootp.opcode; } - + /** \brief Getter for the htype field. * \return The htype field for this BootP PDU. */ uint8_t htype() const { return _bootp.htype; } - + /** \brief Getter for the hlen field. * \return The hlen field for this BootP PDU. */ uint8_t hlen() const { return _bootp.hlen; } - + /** \brief Getter for the hops field. * \return The hops field for this BootP PDU. */ uint8_t hops() const { return _bootp.hops; } - + /** \brief Getter for the xid field. * \return The xid field for this BootP PDU. */ uint32_t xid() const { return Utils::net_to_host_l(_bootp.xid); } - + /** \brief Getter for the secs field. * \return The secs field for this BootP PDU. */ uint16_t secs() const { return Utils::net_to_host_s(_bootp.secs); } - + /** \brief Getter for the padding field. * \return The padding field for this BootP PDU. */ uint16_t padding() const { return Utils::net_to_host_s(_bootp.padding); } - + /** \brief Getter for the ciaddr field. * \return The ciaddr field for this BootP PDU. */ - uint32_t ciaddr() const { return _bootp.ciaddr; } - + uint32_t ciaddr() const { return Utils::net_to_host_l(_bootp.ciaddr); } + /** \brief Getter for the yiaddr field. * \return The yiaddr field for this BootP PDU. */ - uint32_t yiaddr() const { return _bootp.yiaddr; } - + uint32_t yiaddr() const { return Utils::net_to_host_l(_bootp.yiaddr); } + /** \brief Getter for the siaddr field. * \return The siaddr field for this BootP PDU. */ - uint32_t siaddr() const { return _bootp.siaddr; } - + uint32_t siaddr() const { return Utils::net_to_host_l(_bootp.siaddr); } + /** \brief Getter for the giaddr field. * \return The giaddr field for this BootP PDU. */ - uint32_t giaddr() const { return _bootp.giaddr; } - + uint32_t giaddr() const { return Utils::net_to_host_l(_bootp.giaddr); } + /** \brief Getter for the chaddr field. * \return The chddr field for this BootP PDU. */ const uint8_t *chaddr() const { return _bootp.chaddr; } - + /** \brief Getter for the sname field. * \return The sname field for this BootP PDU. */ const uint8_t *sname() const { return _bootp.sname; } - + /** \brief Getter for the file field. * \return The file field for this BootP PDU. */ const uint8_t *file() const { return _bootp.file; } - + /** \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; } - + /** \brief Getter for the header size. * \return Returns the BOOTP header size. * \sa PDU::header_size - */ + */ uint32_t header_size() const; /* Setters */ - + /** \brief Setter for the opcode field. * \param new_opcode The opcode to be set. */ void opcode(uint8_t new_opcode); - + /** \brief Setter for the htype field. * \param new_htype The htype to be set. */ void htype(uint8_t new_htype); - + /** \brief Setter for the hlen field. * \param new_hlen The hlen to be set. */ void hlen(uint8_t new_hlen); - + /** \brief Setter for the hops field. * \param new_hops The hops to be set. */ void hops(uint8_t new_hops); - + /** \brief Setter for the xid field. * \param new_xid The xid to be set. */ void xid(uint32_t new_xid); - + /** \brief Setter for the secs field. * \param new_secs The secs to be set. */ void secs(uint16_t new_secs); - + /** \brief Setter for the padding field. * \param new_padding The padding to be set. */ void padding(uint16_t new_padding); - + /** \brief Setter for the ciaddr field. * \param new_ciaddr The ciaddr to be set. */ void ciaddr(uint32_t new_ciaddr); - + /** \brief Setter for the yiaddr field. * \param new_yiaddr The yiaddr to be set. */ void yiaddr(uint32_t new_yiaddr); - + /** \brief Setter for the siaddr field. * \param new_siaddr The siaddr to be set. */ void siaddr(uint32_t new_siaddr); - + /** \brief Setter for the giaddr field. * \param new_giaddr The giaddr to be set. */ void giaddr(uint32_t new_giaddr); - + /** \brief Setter for the chaddr field. * The new_chaddr pointer must be at least BOOTP::hlen() bytes long. * \param new_chaddr The chaddr to be set. */ void chaddr(const uint8_t *new_chaddr); - + /** \brief Setter for the sname field. * \param new_sname The sname to be set. */ void sname(const uint8_t *new_sname); - + /** \brief Setter for the file field. * \param new_file The file to be set. */ void file(const uint8_t *new_file); - + /** \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); - + /** * \brief Getter for the PDU's type. * \sa PDU::pdu_type */ PDUType pdu_type() const { return PDU::BOOTP; } - + /** * \brief Clones this PDU. - * + * * \sa PDU::clone_pdu */ PDU *clone_pdu() const; @@ -278,7 +278,7 @@ namespace Tins { uint8_t sname[64]; uint8_t file[128]; } __attribute__((__packed__)); - + bootphdr _bootp; uint8_t *_vend; uint32_t _vend_size; diff --git a/include/ip.h b/include/ip.h index 85fa04c..dea482f 100644 --- a/include/ip.h +++ b/include/ip.h @@ -38,11 +38,11 @@ namespace Tins { */ class IP : public PDU { public: - /** + /** * \brief IP address size. */ static const uint32_t ADDR_SIZE = 4; - + /** * \brief Enum indicating the option's class. * @@ -85,7 +85,7 @@ namespace Tins { * \brief Default constructor. */ IP(); - + /** * \brief Constructor for building the IP PDU taking strings as ip addresses. * @@ -199,12 +199,12 @@ namespace Tins { * * \return The source address for this IP PDU. */ - inline uint32_t src_addr() const { return _ip.saddr; } + inline uint32_t src_addr() const { return Utils::net_to_host_l(_ip.saddr); } /** \brief Getter for the destination address field. * \return The destination address for this IP PDU. */ - inline uint32_t dst_addr() const { return _ip.daddr; } + inline uint32_t dst_addr() const { return Utils::net_to_host_l(_ip.daddr); } /* Setters */ @@ -369,10 +369,10 @@ namespace Tins { * \sa PDU::clone_packet */ PDU *clone_packet(const uint8_t *ptr, uint32_t total_sz); - + /** * \brief Clones this PDU. - * + * * \sa PDU::clone_pdu */ PDU *clone_pdu() const; @@ -419,7 +419,7 @@ namespace Tins { uint8_t* write(uint8_t* buffer); } __attribute__((__packed__)); - + void copy_fields(const IP *other); void init_ip_fields(); void write_serialization(uint8_t *buffer, uint32_t total_sz, const PDU *parent); diff --git a/include/utils.h b/include/utils.h index 16f13f4..7409fff 100644 --- a/include/utils.h +++ b/include/utils.h @@ -22,6 +22,7 @@ #ifndef __UTILS_H #define __UTILS_H +#include #ifndef WIN32 #include @@ -43,7 +44,7 @@ namespace Tins { * * \param ip A dotted ip notation string */ - uint32_t ip_to_int(const std::string &ip); + uint32_t ip_to_int(const std::string &ip) throw (std::runtime_error); /** \brief Convert an integer ip to a dotted-ip-notation string. * @@ -76,7 +77,7 @@ namespace Tins { * * \param to_resolve The domain name/ip address to resolve. */ - uint32_t resolve_ip(const std::string &to_resolve); + uint32_t resolve_ip(const std::string &to_resolve) throw (std::runtime_error); /** \brief Resolves the hardware address for a given ip. * @@ -168,15 +169,15 @@ namespace Tins { * \param data The input buffer. * \param data_size The size of the input buffer. */ - uint32_t crc32(uint8_t* data, uint32_t data_size); - + uint32_t crc32(const uint8_t* data, uint32_t data_size); + /** * \brief Converts a channel number to its mhz representation. * \param channel The channel number. * \return The channel's mhz representation. */ uint16_t channel_to_mhz(uint16_t channel); - + /** \brief Does the 16 bits sum of all 2 bytes elements between start and end. * * This is the checksum used by IP, UDP and TCP. If there's and odd number of @@ -186,8 +187,8 @@ namespace Tins { * \param end The pointer to the end of the buffer(excluding the last element). * \return Returns the checksum between start and end(non inclusive). */ - uint32_t do_checksum(uint8_t *start, uint8_t *end); - + uint32_t do_checksum(const uint8_t *start, const uint8_t *end); + /** \brief Performs the pseudo header checksum used in TCP and UDP PDUs. * * \param source_ip The source ip address. @@ -197,7 +198,7 @@ namespace Tins { * \return The pseudo header checksum. */ uint32_t pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip, uint32_t len, uint32_t flag); - + /** \brief Generic function to iterate through interface and collect * data. * diff --git a/src/arp.cpp b/src/arp.cpp index 7630289..4301940 100644 --- a/src/arp.cpp +++ b/src/arp.cpp @@ -62,11 +62,11 @@ void Tins::ARP::sender_hw_addr(const uint8_t* new_snd_hw_addr) { } void Tins::ARP::sender_ip_addr(uint32_t new_snd_ip_addr) { - this->_arp.ar_sip = new_snd_ip_addr; + this->_arp.ar_sip = Utils::net_to_host_l(new_snd_ip_addr); } void Tins::ARP::sender_ip_addr(const string& new_snd_ip_addr) { - this->_arp.ar_sip = Utils::ip_to_int(new_snd_ip_addr); + this->_arp.ar_sip = Utils::net_to_host_l(Utils::resolve_ip(new_snd_ip_addr)); } void Tins::ARP::target_hw_addr(const uint8_t* new_tgt_hw_addr) { @@ -74,11 +74,11 @@ void Tins::ARP::target_hw_addr(const uint8_t* new_tgt_hw_addr) { } void Tins::ARP::target_ip_addr(uint32_t new_tgt_ip_addr) { - this->_arp.ar_tip = new_tgt_ip_addr; + this->_arp.ar_tip = Utils::net_to_host_l(new_tgt_ip_addr); } void Tins::ARP::target_ip_addr(const std::string& new_tgt_ip_addr) { - this->_arp.ar_tip = Utils::ip_to_int(new_tgt_ip_addr); + this->_arp.ar_tip = Utils::net_to_host_l(Utils::resolve_ip(new_tgt_ip_addr)); } void Tins::ARP::hw_addr_format(uint16_t new_hw_addr_fmt) { diff --git a/src/bootp.cpp b/src/bootp.cpp index aec5793..fc63073 100644 --- a/src/bootp.cpp +++ b/src/bootp.cpp @@ -70,19 +70,19 @@ void Tins::BootP::padding(uint16_t new_padding) { } void Tins::BootP::ciaddr(uint32_t new_ciaddr) { - _bootp.ciaddr = new_ciaddr; + _bootp.ciaddr = Utils::net_to_host_l(new_ciaddr); } void Tins::BootP::yiaddr(uint32_t new_yiaddr) { - _bootp.yiaddr = new_yiaddr; + _bootp.yiaddr = Utils::net_to_host_l(new_yiaddr); } void Tins::BootP::siaddr(uint32_t new_siaddr) { - _bootp.siaddr = new_siaddr; + _bootp.siaddr = Utils::net_to_host_l(new_siaddr); } void Tins::BootP::giaddr(uint32_t new_giaddr) { - _bootp.giaddr = new_giaddr; + _bootp.giaddr = Utils::net_to_host_l(new_giaddr); } void Tins::BootP::chaddr(const uint8_t *new_chaddr) { diff --git a/src/ip.cpp b/src/ip.cpp index 1839d92..0a4fc93 100644 --- a/src/ip.cpp +++ b/src/ip.cpp @@ -43,9 +43,9 @@ const uint8_t Tins::IP::DEFAULT_TTL = 128; Tins::IP::IP(const string &ip_dst, const string &ip_src, PDU *child) : PDU(Constants::IP::PROTO_IP, child) { init_ip_fields(); if(ip_dst.size()) - _ip.daddr = Utils::resolve_ip(ip_dst); + this->dst_addr(ip_dst); if(ip_src.size()) - _ip.saddr = Utils::resolve_ip(ip_src); + this->src_addr(ip_src); } @@ -146,8 +146,8 @@ Tins::IP::IP(const uint8_t *buffer, uint32_t total_sz) : PDU(Constants::IP::PROT Tins::IP::IP(uint32_t ip_dst, uint32_t ip_src, PDU *child) : PDU(Constants::IP::PROTO_IP, child) { init_ip_fields(); - _ip.daddr = ip_dst; - _ip.saddr = ip_src; + this->dst_addr(ip_dst); + this->src_addr(ip_src); } Tins::IP::~IP() { @@ -200,19 +200,19 @@ void Tins::IP::check(uint16_t new_check) { } void Tins::IP::src_addr(const string &ip) { - _ip.saddr = Utils::resolve_ip(ip); + _ip.saddr = Utils::net_to_host_l(Utils::resolve_ip(ip)); } void Tins::IP::src_addr(uint32_t ip) { - _ip.saddr = ip; + _ip.saddr = Utils::net_to_host_l(ip); } void Tins::IP::dst_addr(const string &ip) { - _ip.daddr = Utils::resolve_ip(ip); + _ip.daddr = Utils::net_to_host_l(Utils::resolve_ip(ip)); } void Tins::IP::dst_addr(uint32_t ip) { - _ip.daddr = ip; + _ip.daddr = Utils::net_to_host_l(ip); } void Tins::IP::head_len(uint8_t new_head_len) { diff --git a/src/utils.cpp b/src/utils.cpp index 83bc2bc..3376e5e 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -103,10 +103,10 @@ void skip_line(istream &input) { /** \endcond */ -uint32_t Tins::Utils::ip_to_int(const string &ip) { +uint32_t Tins::Utils::ip_to_int(const string &ip) throw (std::runtime_error) { uint32_t result(0), i(0), end, bytes_found(0); while(i < ip.size() && bytes_found < 4) { - uint8_t this_byte(0); + uint16_t this_byte(0); end = i + 3; while(i < ip.size() && i < end && ip[i] != '.') { if(ip[i] < '0' || ip[i] > '9') @@ -114,20 +114,22 @@ uint32_t Tins::Utils::ip_to_int(const string &ip) { this_byte = (this_byte * 10) + (ip[i] - '0'); i++; } - result = (result << 8) | this_byte; + if (this_byte > 0xFF) { + throw std::runtime_error("Byte greater than 255"); + } + result = (result << 8) | (this_byte & 0xFF); bytes_found++; if(bytes_found < 4 && i < ip.size() && ip[i] == '.') i++; } if(bytes_found < 4 || (i < ip.size() && bytes_found == 4)) throw std::runtime_error("Invalid ip address"); - return net_to_host_l(result); + return result; } string Tins::Utils::ip_to_string(uint32_t ip) { ostringstream oss; int mask(24); - ip = net_to_host_l(ip); while(mask >=0) { oss << ((ip >> mask) & 0xff); if(mask) @@ -178,11 +180,11 @@ string Tins::Utils::hwaddr_to_string(const uint8_t *array) { return oss.str(); } -uint32_t Tins::Utils::resolve_ip(const string &to_resolve) { +uint32_t Tins::Utils::resolve_ip(const string &to_resolve) throw (std::runtime_error) { struct hostent *data = gethostbyname(to_resolve.c_str()); if(!data) - return 0; - return ((struct in_addr**)data->h_addr_list)[0]->s_addr; + throw std::runtime_error("Could not resolve IP"); + return Utils::net_to_host_l(((struct in_addr**)data->h_addr_list)[0]->s_addr); } bool Tins::Utils::resolve_hwaddr(const string &iface, uint32_t ip, uint8_t *buffer, PacketSender *sender) { @@ -210,6 +212,7 @@ string Tins::Utils::interface_from_ip(uint32_t ip) { string iface; string destination, mask; uint32_t destination_int, mask_int; + ip = Utils::net_to_host_l(ip); skip_line(input); while(!match) { input >> iface >> destination; @@ -233,7 +236,7 @@ set Tins::Utils::network_interfaces() { bool Tins::Utils::interface_ip(const string &iface, uint32_t &ip) { IPv4Collector collector(iface.c_str()); generic_iface_loop(collector); - ip = collector.ip; + ip = Utils::net_to_host_l(collector.ip); return collector.found; } @@ -252,7 +255,7 @@ uint16_t Tins::Utils::channel_to_mhz(uint16_t channel) { return 2407 + (channel * 5); } -uint32_t Tins::Utils::do_checksum(uint8_t *start, uint8_t *end) { +uint32_t Tins::Utils::do_checksum(const uint8_t *start, const uint8_t *end) { uint32_t checksum(0); uint16_t *ptr = (uint16_t*)start, *last = (uint16_t*)end, padding(0); if(((end - start) & 1) == 1) { @@ -277,7 +280,7 @@ uint32_t Tins::Utils::pseudoheader_checksum(uint32_t source_ip, uint32_t dest_ip return checksum; } -uint32_t Tins::Utils::crc32(uint8_t* data, uint32_t data_size) { +uint32_t Tins::Utils::crc32(const uint8_t* data, uint32_t data_size) { uint32_t i, crc = 0; static uint32_t crc_table[] = { 0x4DBDF21C, 0x500AE278, 0x76D3D2D4, 0x6B64C2B0, diff --git a/tests/src/dhcp.cpp b/tests/src/dhcp.cpp index 953ec87..61b0e89 100644 --- a/tests/src/dhcp.cpp +++ b/tests/src/dhcp.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include "dhcp.h" #include "utils.h" #include "ethernetII.h" @@ -15,7 +15,7 @@ class DHCPTest : public testing::Test { public: static const uint8_t expected_packet[]; static const uint8_t chaddr[], sname[], file[]; - + void test_equals(const DHCP &dhcp1, const DHCP &dhcp2); void test_option(const DHCP &dhcp, DHCP::Options opt, uint32_t len = 0, uint8_t *value = 0); }; @@ -34,25 +34,25 @@ const uint8_t DHCPTest::file[] = "\x16\xab\x54\x12\xfa\xca\x56\x7f\x1b\x65\x11\x "\x16\xab\x54\x12\xfa\xca\x56\x7f\x1b\x65\x11\xfa\xda\xeb\x19\x18" "\x16\xab\x54\x12\xfa\xca\x56\x7f\x1b\x65\x11\xfa\xda\xfb\x19\x18"; -const uint8_t DHCPTest::expected_packet[] = {'\x01', '\x01', '\x06', '\x1f', '?', '\xab', '#', '\xde', -'\x9f', '\x1a', '\x00', '\x00', '\xc0', '\xa8', '\x00', 'f', '\xf3', '\x16', '"', 'b', '\xa7', ' ', -'\x0b', '\x9a', '{', '+', '7', '\xfe', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', -'\x00', '\x00', '\x00', '\x00', '\x00', 'c', '\x82', 'S', 'c', '6', '\x04', '\xc0', '\xa8', '\x04', '\x02', +const uint8_t DHCPTest::expected_packet[] = {'\x01', '\x01', '\x06', '\x1f', '?', '\xab', '#', '\xde', +'\x9f', '\x1a', '\x00', '\x00', '\xc0', '\xa8', '\x00', 'f', '\xf3', '\x16', '"', 'b', '\xa7', ' ', +'\x0b', '\x9a', '{', '+', '7', '\xfe', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', '\x00', +'\x00', '\x00', '\x00', '\x00', '\x00', 'c', '\x82', 'S', 'c', '6', '\x04', '\xc0', '\xa8', '\x04', '\x02', '\x01', '\x04', '\xff', '\xff', ' ', '\x0b', '5', '\x01', '\x04'}; TEST_F(DHCPTest, DefaultConstructor) { @@ -192,7 +192,7 @@ TEST_F(DHCPTest, RoutersOption) { routers.push_back(Utils::ip_to_int("192.168.0.253")); routers.push_back(Utils::ip_to_int("10.123.45.67")); dhcp.add_routers_option(routers); - + list routers2; ASSERT_TRUE(dhcp.search_routers_option(&routers2)); ASSERT_EQ(routers.size(), routers2.size()); @@ -209,7 +209,7 @@ TEST_F(DHCPTest, DNSOption) { dns.push_back(Utils::ip_to_int("192.168.0.253")); dns.push_back(Utils::ip_to_int("10.123.45.67")); dhcp.add_dns_option(dns); - + list dns2; ASSERT_TRUE(dhcp.search_dns_option(&dns2)); ASSERT_EQ(dns.size(), dns2.size()); @@ -267,7 +267,7 @@ void DHCPTest::test_equals(const DHCP &dhcp1, const DHCP &dhcp2) { TEST_F(DHCPTest, ConstructorFromBuffer) { DHCP dhcp1(expected_packet, sizeof(expected_packet)); uint32_t ip; - + EXPECT_EQ(dhcp1.opcode(), DHCP::DISCOVER); EXPECT_EQ(dhcp1.htype(), 1); ASSERT_EQ(dhcp1.hlen(), EthernetII::ADDR_SIZE); @@ -280,11 +280,11 @@ TEST_F(DHCPTest, ConstructorFromBuffer) { EXPECT_EQ(dhcp1.giaddr(), Utils::ip_to_int("123.43.55.254")); EXPECT_EQ(dhcp1.siaddr(), Utils::ip_to_int("167.32.11.154")); ASSERT_TRUE(dhcp1.search_server_identifier(&ip)); - EXPECT_EQ(ip, Utils::ip_to_int("192.168.4.2")); - + EXPECT_EQ(ip, Utils::net_to_host_l(Utils::ip_to_int("192.168.4.2"))); + uint32_t size; uint8_t *buffer = dhcp1.serialize(size); - + DHCP dhcp2(buffer, size); test_equals(dhcp1, dhcp2); delete[] buffer; diff --git a/tests/src/utils_test.cpp b/tests/src/utils_test.cpp new file mode 100644 index 0000000..ab331a9 --- /dev/null +++ b/tests/src/utils_test.cpp @@ -0,0 +1,175 @@ + +#include + +#include + +#include "utils.h" +#include + +using namespace Tins; + +class UtilsTest : public testing::Test { +public: + static const uint32_t zero_int_ip; // "0.0.0.0" + static const uint32_t full_int_ip; // "255.255.255.255" + static const uint32_t mix_int_ip; // "1.2.255.3" + static const uint8_t zero_hw_addr[]; + static const uint8_t full_hw_addr[]; + static const uint8_t mix_hw_addr[]; + static const uint8_t data[]; + static const uint32_t data_len; + +}; + +const uint32_t UtilsTest::zero_int_ip = 0; // "0.0.0.0" +const uint32_t UtilsTest::full_int_ip = 0xFFFFFFFF; // "255.255.255.255" +const uint32_t UtilsTest::mix_int_ip = 0x0102FF03; // "1.2.255.3" +const uint8_t UtilsTest::zero_hw_addr[] = {'\x00', '\x00', '\x00', '\x00', '\x00', '\x00'}; +const uint8_t UtilsTest::full_hw_addr[] = {'\xFF', '\xFF', '\xFF', '\xFF', '\xFF', '\xFF'}; +const uint8_t UtilsTest::mix_hw_addr[] = {'\x01', '\x02', '\x03', '\x04', '\x05', '\x06'}; +const uint8_t UtilsTest::data[] = { + 215, 3, 132, 147, 170, 153, 240, 223, 227, 47, 144, 146, 52, 154, 192, 106, + 195, 167, 160, 119, 154, 134, 59, 150, 6, 236, 67, 216, 7, 19, 110, 226, 228, + 99, 103, 18, 39, 23, 157, 192, 38, 37, 23, 211, 77, 86, 176, 103, 62, 226, 235, + 236, 114, 39, 216, 202, 236, 251, 158, 249, 89, 248, 80, 95, 245, 35, 61, 97, + 242, 90, 122, 196, 187, 202, 15, 197, 204, 180, 183, 68, 65, 99, 209, 172, 80, + 189, 188, 18, 216, 82, 103, 53, 3, 246, 183, 4, 56, 201, 5, 42, 94, 108, 30, 90, + 183, 203, 193, 19, 128, 79, 156, 189, 18, 163, 67, 152, 153, 114, 151, 125, 114, + 87, 105, 31, 212, 238, 154, 238, 82, 216, 244, 2, 33, 137, 126, 67, 176, 224, 95, + 175, 205, 175, 91, 41, 101, 34, 178, 199, 88, 211, 91, 235, 42, 21, 182, 138, + 185, 61, 205, 61, 245, 85, 18, 119, 253, 214, 127, 164, 31, 225, 140, 58, 103, + 235, 231, 226, 119, 97, 86, 11, 56, 95, 218, 207, 137, 216, 141, 46, 82, 39, 158, + 243, 131, 217, 197, 177, 239, 30, 145, 249, 162, 141, 252, 213, 132, 87, 42, 130, + 213, 92, 47, 163, 113, 230, 59, 205, 19, 90, 65, 134, 181, 44, 150, 254, 73, 186, + 194, 122, 96, 65, 114, 233, 245, 25, 194, 80, 174, 223, 158, 45, 131, 188, 222, + 52, 212, 250, 96, 172, 181, 115, 252, 40, 249, 99, 65, 23, 118, 71, 124, 112, 228, + 204, 106, 169, 40, 148, 72, 183, 252, 234, 83, 116, 109, 54, 233, 58, 231, 5, 88, + 36, 77, 253, 75, 90, 250, 177, 159, 199, 180, 134, 211, 161, 175, 75, 161, 72, 80, + 73, 163, 76, 160, 119, 226, 248, 231, 62, 91, 74, 32, 156, 9, 64, 170, 79, 38, 45, + 204, 58, 144, 76, 226, 130, 21, 151, 239, 40, 116, 52, 77, 18, 6, 199, 42, 200, 213, + 232, 12, 61, 156, 51, 23, 165, 11, 7, 149, 30, 27, 119, 216, 246, 93, 24, 111, 105, + 218, 100, 45, 57, 69, 229, 168, 105, 99, 35, 41, 71, 255, 80, 255, 22, 7, 61, 211, + 134, 113, 48, 255, 220, 26, 32, 6, 184, 204, 40, 194, 47, 201, 249, 133, 194, 203, + 172, 123, 186, 77, 39, 92, 64, 52, 91, 187, 83, 58, 73, 65, 192, 150, 103, 230, 187, + 165, 149, 84, 71, 142, 55, 69, 87, 102, 97, 20, 134, 184, 107, 133, 57, 57, 220, 121, + 211, 241, 97, 172, 67, 208, 9, 151, 14, 200, 73, 31, 140, 34, 176, 215, 111, 4, 143, + 13, 173, 193, 145, 255, 112, 249, 191, 88, 181, 113, 221, 50, 45, 34, 176, 203, 154, + 65, 193, 6, 120, 182, 235, 250, 21, 136, 44, 21, 29, 6, 150, 194, 117, 118, 237, 0, + 223, 207, 161, 58, 229, 174, 101, 101, 195, 17, 249, 12, 137, 177, 161 + }; +const uint32_t UtilsTest::data_len = 500; + +TEST_F(UtilsTest, IpToInt) { + + EXPECT_EQ(Utils::ip_to_int("0.0.0.0"), zero_int_ip); + EXPECT_EQ(Utils::ip_to_int("255.255.255.255"), full_int_ip); + EXPECT_EQ(Utils::ip_to_int("1.2.255.3"), mix_int_ip); + + /* Invalid number */ + EXPECT_THROW(Utils::ip_to_int("123.a.5.6"), std::runtime_error); + EXPECT_THROW(Utils::ip_to_int("0.0.256.0"), std::runtime_error); + EXPECT_THROW(Utils::ip_to_int("0.0.255.0a"), std::runtime_error); + EXPECT_THROW(Utils::ip_to_int("0.0.255.127a"), std::runtime_error); + EXPECT_THROW(Utils::ip_to_int("0.0.255.1.5"), std::runtime_error); + +} + +TEST_F(UtilsTest, IpToString) { + + EXPECT_EQ(Utils::ip_to_string(zero_int_ip), "0.0.0.0"); + EXPECT_EQ(Utils::ip_to_string(full_int_ip), "255.255.255.255"); + EXPECT_EQ(Utils::ip_to_string(mix_int_ip), "1.2.255.3"); + +} + +TEST_F(UtilsTest, HwaddrToByte) { + uint8_t result_buf[6]; + + Utils::hwaddr_to_byte("00:00:00:00:00:00", result_buf); + EXPECT_TRUE(memcmp(result_buf, zero_hw_addr, 6) == 0); + Utils::hwaddr_to_byte("ff:ff:ff:ff:ff:ff", result_buf); + EXPECT_TRUE(memcmp(result_buf, full_hw_addr, 6) == 0); + Utils::hwaddr_to_byte("01:02:03:04:05:06", result_buf); + EXPECT_TRUE(memcmp(result_buf, mix_hw_addr, 6) == 0); + +} + +TEST_F(UtilsTest, HwaddrToString) { + + EXPECT_EQ(Utils::hwaddr_to_string(zero_hw_addr), "00:00:00:00:00:00"); + EXPECT_EQ(Utils::hwaddr_to_string(full_hw_addr), "ff:ff:ff:ff:ff:ff"); + EXPECT_EQ(Utils::hwaddr_to_string(mix_hw_addr), "01:02:03:04:05:06"); + +} + +TEST_F(UtilsTest, ResolveIp) { + + uint32_t localhost_ip = Utils::ip_to_int("127.0.0.1"); + + EXPECT_EQ(Utils::resolve_ip("localhost"), localhost_ip); + EXPECT_THROW(Utils::resolve_ip("www.qwertyuiopasdfg.com.ar.edu.gov"), std::runtime_error); + +} + +TEST_F(UtilsTest, InterfaceIp) { + + uint32_t ip; + uint32_t localhost_ip = Utils::ip_to_int("127.0.0.1"); + +#ifndef WIN32 + ASSERT_TRUE(Utils::interface_ip("lo", ip)); + EXPECT_EQ(ip, localhost_ip); +#endif + EXPECT_FALSE(Utils::interface_ip("asdfghgfdsa", ip)); + +} + +TEST_F(UtilsTest, NetToHostS) { + + uint16_t a = 0x01FE; + uint16_t b = Utils::net_to_host_s(a); + + EXPECT_EQ(b, 0xFE01); + EXPECT_EQ(a, Utils::net_to_host_s(b)); + +} + +TEST_F(UtilsTest, NetToHostL) { + + uint32_t a = 0x0102CDFE; + uint32_t b = Utils::net_to_host_l(a); + + EXPECT_EQ(b, 0xFECD0201); + EXPECT_EQ(a, Utils::net_to_host_l(b)); + +} + +TEST_F(UtilsTest, NetToHostLL) { + + uint64_t a = 0x0102030489ABCDFE; + uint64_t b = Utils::net_to_host_ll(a); + + EXPECT_EQ(b, 0xFECDAB8904030201); + EXPECT_EQ(a, Utils::net_to_host_ll(b)); + +} + +TEST_F(UtilsTest, Crc32) { + + uint32_t crc = Utils::crc32(data, data_len); + + EXPECT_EQ(crc, 0x78840f54); + +} + +TEST_F(UtilsTest, Checksum) { + + uint16_t checksum = Utils::do_checksum(data, data + data_len); + + //EXPECT_EQ(checksum, 0x231a); + + uint8_t my_data[] = {0, 0, 0, 0}; + checksum = Utils::do_checksum(my_data, my_data + 4); + EXPECT_EQ(checksum, 0xFFFF); + +}