1
0
mirror of https://github.com/mfontanini/libtins synced 2026-01-23 02:35:57 +01:00

Documented and fixed some bugs in IPv4Address.

This commit is contained in:
Matias Fontanini
2012-08-27 11:57:14 -03:00
parent da8c77c77e
commit e1a84be0cb
6 changed files with 103 additions and 25 deletions

View File

@@ -27,30 +27,87 @@
#include <stdint.h>
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 <b>must</b> 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);

View File

@@ -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;

View File

@@ -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;

View File

@@ -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();
}
}

View File

@@ -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;

View File

@@ -1,6 +1,7 @@
#include <gtest/gtest.h>
#include <cstring>
#include <string>
#include <sstream>
#include <stdint.h>
#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);
}