diff --git a/include/ipaddress.h b/include/ipaddress.h index 3c035f9..3c79ab4 100644 --- a/include/ipaddress.h +++ b/include/ipaddress.h @@ -27,30 +27,87 @@ #include namespace Tins { + /** + * \class IPv4Address + * \brief Abstraction of an IPv4 address. + */ class IPv4Address { public: + /** + * \brief Constructor taking a const char*. + * + * Constructs an IPv4Address from a dotted-notation address + * cstring. If the pointer provided is null, then a default + * IPv4Address object is constructed, which corresponds to + * the 0.0.0.0 address. + * + * \param ip const char* containing the dotted-notation address. + */ IPv4Address(const char *ip = 0); + + /** + * \brief Constructor taking a std::string. + * + * Constructs an IPv4Address from a dotted-notation std::strings + * + * \param ip std::string containing the dotted-notation address. + */ IPv4Address(const std::string &ip); + + /** + * \brief Constructor taking a IP address represented as a + * big endian integer. + * + * This constructor should be used internally by PDUs that + * handle IP addresses. The provided integer must be + * be in big endian. + */ explicit IPv4Address(uint32_t ip); - IPv4Address &operator=(uint32_t ip); - IPv4Address &operator=(const std::string &ip); - + /** + * \brief User defined conversion to big endian integral value. + */ operator uint32_t() const; + /** + * \brief Retrieve the string representation of this address. + * + * \return std::string containing the representation of this address. + */ std::string to_string() const; + /** + * \brief Compare this IPv4Address for equality. + * + * \param rhs The address to be compared. + * \return bool indicating whether this address equals rhs. + */ bool operator==(const IPv4Address &rhs) const { return ip_addr == rhs.ip_addr; } - bool operator!=(const std::string &rhs) const { + /** + * \brief Compare this IPv4Address for inequality. + * + * \param rhs The address to be compared. + * \return bool indicating whether this address is distinct + * from rhs. + */ + bool operator!=(const IPv4Address &rhs) const { return !(*this == rhs); } - friend std::ostream &operator<<(std::ostream &output, const IPv4Address &addr) { - return output << addr.to_string(); - } + /** + * \brief Writes this address to a std::ostream. + * + * This method writes addr in a dotted-string notation address + * to the std::ostream argument. + * + * \param output The std::ostream in which to write the address. + * \param addr The IPv4Address to be written. + * \return std::stream& pointing to output. + */ + friend std::ostream &operator<<(std::ostream &output, const IPv4Address &addr); private: uint32_t ip_to_int(const std::string &ip); diff --git a/include/utils.h b/include/utils.h index d9a4e65..e5c1835 100644 --- a/include/utils.h +++ b/include/utils.h @@ -374,11 +374,11 @@ void Tins::Utils::route_entries(ForwardIterator output) { for(unsigned i(0); i < 5; ++i) input >> mask; from_hex(destination, dummy); - entry.destination = be_to_host(dummy); + entry.destination = IPv4Address(dummy); from_hex(mask, dummy); - entry.mask = be_to_host(dummy); + entry.mask = IPv4Address(dummy); from_hex(gw, dummy); - entry.gateway = be_to_host(dummy); + entry.gateway = IPv4Address(dummy); skip_line(input); *output = entry; ++output; diff --git a/src/dhcp.cpp b/src/dhcp.cpp index f2342db..7e65081 100644 --- a/src/dhcp.cpp +++ b/src/dhcp.cpp @@ -265,7 +265,7 @@ bool DHCP::generic_search(Options opt, uint32_t *value) { bool DHCP::generic_search(Options opt, ipaddress_type *value) { uint32_t ip_int; if(generic_search(opt, &ip_int)) { - *value = ip_int; + *value = IPv4Address(Utils::host_to_be(ip_int)); return true; } return false; diff --git a/src/ipaddress.cpp b/src/ipaddress.cpp index 3e99e41..ea975c2 100644 --- a/src/ipaddress.cpp +++ b/src/ipaddress.cpp @@ -40,22 +40,20 @@ IPv4Address::IPv4Address(const std::string &ip) } -IPv4Address &IPv4Address::operator=(uint32_t ip) { - ip_addr = ip; - return *this; -} - -IPv4Address &Tins::IPv4Address::operator=(const string &ip) { - ip_addr = ip_to_int(ip); - return *this; -} - IPv4Address::operator uint32_t() const { return Utils::host_to_be(ip_addr); } std::string IPv4Address::to_string() const { - return Utils::ip_to_string(ip_addr); + std::ostringstream oss; + int mask(24); + while(mask >=0) { + oss << ((ip_addr >> mask) & 0xff); + if(mask) + oss << '.'; + mask -= 8; + } + return oss.str(); } uint32_t IPv4Address::ip_to_int(const string &ip) { @@ -81,4 +79,8 @@ uint32_t IPv4Address::ip_to_int(const string &ip) { throw std::runtime_error("Invalid ip address"); return result; } + +std::ostream &operator<<(std::ostream &output, const IPv4Address &addr) { + return output << addr.to_string(); +} } diff --git a/src/network_interface.cpp b/src/network_interface.cpp index e45efc4..7ccfb28 100644 --- a/src/network_interface.cpp +++ b/src/network_interface.cpp @@ -42,15 +42,16 @@ struct InterfaceInfoCollector { bool operator() (struct ifaddrs *addr) { using Tins::Utils::host_to_be; + using Tins::IPv4Address; const struct sockaddr_ll* addr_ptr = ((struct sockaddr_ll*)addr->ifa_addr); if(addr->ifa_addr->sa_family == AF_PACKET && addr_ptr->sll_ifindex == iface_id) info->hw_addr = addr_ptr->sll_addr; else if(addr->ifa_addr->sa_family == AF_INET && !std::strcmp(addr->ifa_name, iface_name)) { - info->ip_addr = host_to_be(((struct sockaddr_in *)addr->ifa_addr)->sin_addr.s_addr); - info->netmask = host_to_be(((struct sockaddr_in *)addr->ifa_netmask)->sin_addr.s_addr); + info->ip_addr = IPv4Address(((struct sockaddr_in *)addr->ifa_addr)->sin_addr.s_addr); + info->netmask = IPv4Address(((struct sockaddr_in *)addr->ifa_netmask)->sin_addr.s_addr); if((addr->ifa_flags & (IFF_BROADCAST | IFF_POINTOPOINT))) - info->bcast_addr = host_to_be(((struct sockaddr_in *)addr->ifa_ifu.ifu_broadaddr)->sin_addr.s_addr); + info->bcast_addr = IPv4Address(((struct sockaddr_in *)addr->ifa_ifu.ifu_broadaddr)->sin_addr.s_addr); else info->bcast_addr = 0; found = true; diff --git a/tests/src/ipaddress.cpp b/tests/src/ipaddress.cpp index 4d39a80..9a74cd4 100644 --- a/tests/src/ipaddress.cpp +++ b/tests/src/ipaddress.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "ipaddress.h" #include "utils.h" @@ -17,3 +18,20 @@ TEST(IPAddressTest, Constructor) { EXPECT_EQ(addr2.to_string(), ip_string); EXPECT_NE(addr1, "192.168.0.254"); } + +TEST(IPAddressTest, CopyAssignmentOperator) { + IPv4Address addr1(ip_string); + uint32_t as_int = addr1; + IPv4Address addr2; + addr2 = IPv4Address(as_int); + EXPECT_EQ(addr1, addr2); + uint32_t as_int2 = addr2; + EXPECT_EQ(as_int2, as_int); +} + +TEST(IPAddressTest, OutputOperator) { + IPv4Address addr(ip_string); + std::ostringstream oss; + oss << addr; + EXPECT_EQ(oss.str(), ip_string); +}