Permalink
Browse files

Add an InterfacePicker which has a main and fallback choice. Also add…

… a ToString method to Interface.
  • Loading branch information...
peternewman committed Aug 17, 2018
1 parent 3fe92ac commit b0cd317d052ebc78e7375cd7bdd566d56957eedd
@@ -117,7 +117,7 @@ Interface& Interface::operator=(const Interface &other) {
}


bool Interface::operator==(const Interface &other) {
bool Interface::operator==(const Interface &other) const {
return (name == other.name &&
ip_address == other.ip_address &&
subnet_mask == other.subnet_mask &&
@@ -127,6 +127,19 @@ bool Interface::operator==(const Interface &other) {
}


string Interface::ToString(const string &separator) const {
std::ostringstream str;
str << name << separator
<< "index: " << index << separator
<< "ip: " << ip_address << separator
<< "bcast: " << bcast_address << separator
<< "subnet: " << subnet_mask << separator
<< "type: " << type << separator
<< "hw_addr: " << hw_address;
return str.str();
}


/**
* Create a new interface builder
*/
@@ -228,8 +241,9 @@ Interface InterfaceBuilder::Construct() {
bool InterfaceBuilder::SetAddress(const string &str,
IPV4Address *target) {
IPV4Address tmp_address;
if (!IPV4Address::FromString(str, &tmp_address))
if (!IPV4Address::FromString(str, &tmp_address)) {
return false;
}
*target = tmp_address;
return true;
}
@@ -44,7 +44,7 @@ using std::vector;
* @param iface, the interface to populate
* @param ip_or_name the IP address or interface name of the local interface
* we'd prefer to use.
* @param options a Options struct configuring ChooseInterface
* @param options an Options struct configuring ChooseInterface
* @return true if we found an interface, false otherwise
*/
// TODO(Simon): Change these to callback based code to reduce duplication.
@@ -95,11 +95,38 @@ bool InterfacePicker::ChooseInterface(
}


/*
* Select an interface to use
* @param iface, the interface to populate
* @param ip_or_name the IP address or interface name of the local interface
* we'd prefer to use.
* @param default_ip_or_name the IP address or interface name of the local
* interface we'd prefer to fall back to if ip_or_name isn't found.
* @param options an Options struct configuring ChooseInterface
* @return true if we found an interface, false otherwise
*/
// TODO(Simon): Change these to callback based code to reduce duplication.
bool InterfacePicker::ChooseInterface(
Interface *iface,
const string &ip_or_name,
const string &default_ip_or_name,
const Options &options) const {
Options specific_options = options;
specific_options.specific_only = true;
// Need to force strict mode in the options here, so we only get a real match
if (!ip_or_name.empty() && ChooseInterface(iface, ip_or_name, specific_options)) {
return true;
} else {
return ChooseInterface(iface, default_ip_or_name, options);
}
}


/*
* Select an interface to use by index
* @param iface, the interface to populate
* @param index the index of the local interface we'd prefer to use.
* @param options a Options struct configuring ChooseInterface
* @param options an Options struct configuring ChooseInterface
* @return true if we found an interface, false otherwise
*/
// TODO(Simon): Change these to callback based code to reduce duplication.
@@ -75,13 +75,7 @@ void InterfacePickerTest::testGetInterfaces() {
vector<Interface>::iterator iter;
cout << endl;
for (iter = interfaces.begin(); iter != interfaces.end(); ++iter) {
cout << iter->name << endl;
cout << " index: " << iter->index << endl;
cout << " ip: " << iter->ip_address << endl;
cout << " bcast: " << iter->bcast_address << endl;
cout << " subnet: " << iter->subnet_mask << endl;
cout << " type: " << iter->type << endl;
cout << " hw_addr: " << iter->hw_address << endl;
cout << iter->ToString("\n ") << endl;
cout << endl;
cout << "---------------" << endl;
}
@@ -121,6 +115,11 @@ void InterfacePickerTest::testChooseInterface() {
// no interfaces
Interface iface;
OLA_ASSERT_FALSE(picker.ChooseInterface(&iface, ""));
// no interfaces, with default
OLA_ASSERT_FALSE(picker.ChooseInterface(&iface, "", ""));
OLA_ASSERT_FALSE(picker.ChooseInterface(&iface, "", "foo"));
OLA_ASSERT_FALSE(picker.ChooseInterface(&iface, "foo", ""));
OLA_ASSERT_FALSE(picker.ChooseInterface(&iface, "foo", "bar"));
// no interfaces, by index
OLA_ASSERT_FALSE(picker.ChooseInterface(&iface, 0));

@@ -133,7 +132,10 @@ void InterfacePickerTest::testChooseInterface() {

FakeInterfacePicker picker2(interfaces);
OLA_ASSERT_TRUE(picker2.ChooseInterface(&iface, "192.168.1.1"));
OLA_ASSERT_TRUE(iface1 == iface);
OLA_ASSERT_EQ(iface1, iface);
iface = Interface();
OLA_ASSERT_TRUE(picker2.ChooseInterface(&iface, "192.168.1.1", "172.16.0.1"));
OLA_ASSERT_EQ(iface1, iface);

// check that preferred works
Interface iface2;
@@ -144,24 +146,59 @@ void InterfacePickerTest::testChooseInterface() {

FakeInterfacePicker picker3(interfaces);
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "192.168.1.1"));
OLA_ASSERT_TRUE(iface2 == iface);
OLA_ASSERT_EQ(iface2, iface);
iface = Interface();
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "192.168.1.1", ""));
OLA_ASSERT_EQ(iface2, iface);
iface = Interface();
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "", "192.168.1.1"));
OLA_ASSERT_EQ(iface2, iface);
iface = Interface();
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "192.168.1.1", "foo"));
OLA_ASSERT_EQ(iface2, iface);

// an invalid address should fallback to default
iface = Interface();
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "foo", "192.168.1.1"));
OLA_ASSERT_EQ(iface2, iface);

// a valid address should ignore the default
iface = Interface();
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "192.168.1.1", "10.0.0.1"));
OLA_ASSERT_EQ(iface2, iface);

// now check for iface name
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "eth0"));
OLA_ASSERT_TRUE(iface1 == iface);
OLA_ASSERT_EQ(iface1, iface);

OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "eth1"));
OLA_ASSERT_TRUE(iface2 == iface);
OLA_ASSERT_EQ(iface2, iface);

// an invalid or empty address should fallback to default
iface = Interface();
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "", "eth1"));
OLA_ASSERT_EQ(iface2, iface);
iface = Interface();
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "foo", "eth1"));
OLA_ASSERT_EQ(iface2, iface);

// a valid address should ignore the default
iface = Interface();
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "eth1", "eth0"));
OLA_ASSERT_EQ(iface2, iface);

// a invalid address should return the first one
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "foo"));
OLA_ASSERT_TRUE(iface1 == iface);
OLA_ASSERT_EQ(iface1, iface);
iface = Interface();
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, "foo", "bar"));
OLA_ASSERT_EQ(iface1, iface);

// now check by iface index
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, 2));
OLA_ASSERT_TRUE(iface2 == iface);
OLA_ASSERT_EQ(iface2, iface);

// an invalid index should return the first one
OLA_ASSERT_TRUE(picker3.ChooseInterface(&iface, 3));
OLA_ASSERT_TRUE(iface1 == iface);
OLA_ASSERT_EQ(iface1, iface);
}
@@ -153,7 +153,7 @@ class IPV4Address {
* @brief Write the string representation of this IPV4Address to an
* ostream.
* @param out the ostream to write to.
* @param address to address to write.
* @param address the address to write.
*/
friend std::ostream& operator<<(std::ostream &out,
const IPV4Address &address) {
@@ -47,7 +47,25 @@ class Interface {
uint16_t type = ARP_VOID_TYPE);
Interface(const Interface &other);
Interface& operator=(const Interface &other);
bool operator==(const Interface &other);
bool operator==(const Interface &other) const;

/**
* @brief Convert the Interface to a string.
* @param separator the separator to use between items, defaults to ", ".
* @returns the string representation of this Interface.
*/
std::string ToString(const std::string &separator = ", ") const;

/**
* @brief Write the string representation of this Interface to an
* ostream.
* @param out the ostream to write to.
* @param iface the iface to write.
*/
friend std::ostream& operator<<(std::ostream &out,
const Interface &iface) {
return out << iface.ToString();
}

std::string name;
IPV4Address ip_address;
@@ -81,6 +81,11 @@ class InterfacePicker {
Interface *iface,
const std::string &ip_or_name,
const Options &options = Options()) const;
bool ChooseInterface(
Interface *iface,
const std::string &ip_or_name,
const std::string &default_ip_or_name,
const Options &options = Options()) const;
bool ChooseInterface(
Interface *iface,
int32_t index,

0 comments on commit b0cd317

Please sign in to comment.