shill: DeviceInfo::GetAddress can be used now to lookup the device MAC address.
Also enhance ByteString with a HexEncode method used for logging.
BUG=chromium-os:19028
TEST=unit tests, tested on device
Change-Id: Ie64ebb0d009ce7fb3ed16948a7789ef721b56039
Reviewed-on: http://gerrit.chromium.org/gerrit/5766
Reviewed-by: Darin Petkov <petkov@chromium.org>
Tested-by: Darin Petkov <petkov@chromium.org>
diff --git a/byte_string.cc b/byte_string.cc
index 3c9db10..9976e0f 100644
--- a/byte_string.cc
+++ b/byte_string.cc
@@ -6,6 +6,10 @@
#include <netinet/in.h>
+#include <base/string_number_conversions.h>
+
+using std::string;
+
namespace shill {
// static
@@ -53,4 +57,8 @@
data_.insert(data_.end(), b.data_.begin(), b.data_.end());
}
+string ByteString::HexEncode() const {
+ return base::HexEncode(GetConstData(), GetLength());
+}
+
} // namespace shill
diff --git a/byte_string.h b/byte_string.h
index 0077ff0..22ac750 100644
--- a/byte_string.h
+++ b/byte_string.h
@@ -48,6 +48,7 @@
// Returns true on success
bool ConvertToNetUInt32(uint32 *val) const;
+ bool IsEmpty() const { return GetLength() == 0; }
bool IsZero() const;
bool Equals(const ByteString &b) const;
void Append(const ByteString &b);
@@ -55,6 +56,8 @@
data_.resize(size, 0);
}
+ std::string HexEncode() const;
+
private:
std::vector<unsigned char> data_;
// NO DISALLOW_COPY_AND_ASSIGN -- we assign ByteStrings in STL hashes
diff --git a/byte_string_unittest.cc b/byte_string_unittest.cc
index e8e6048..fb35c34 100644
--- a/byte_string_unittest.cc
+++ b/byte_string_unittest.cc
@@ -14,7 +14,9 @@
namespace {
const unsigned char kTest1[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
-const unsigned char kTest2[] = { 1, 2, 3, 4 };
+const unsigned char kTest2[] = { 1, 2, 3, 0xa };
+const char kTest2HexString[] = "0102030A";
+const unsigned int kTest2Uint32 = 0x0102030a;
const unsigned char kTest3[] = { 0, 0, 0, 0 };
const char kTest4[] = "Hello world";
} // namespace {}
@@ -26,6 +28,7 @@
uint32 val;
ByteString bs1(0);
+ EXPECT_TRUE(bs1.IsEmpty());
EXPECT_EQ(0, bs1.GetLength());
EXPECT_TRUE(bs1.GetData() == NULL);
EXPECT_FALSE(bs1.ConvertToNetUInt32(&val));
@@ -36,6 +39,8 @@
ByteString bs1(kTest1, sizeof(kTest1));
uint32 val;
+ EXPECT_FALSE(bs1.IsEmpty());
+
EXPECT_EQ(sizeof(kTest1), bs1.GetLength());
for (unsigned int i = 0; i < sizeof(kTest1); i++) {
EXPECT_EQ(bs1.GetData()[i], kTest1[i]);
@@ -77,19 +82,19 @@
}
TEST_F(ByteStringTest, UInt32) {
- ByteString bs1 = ByteString::CreateFromNetUInt32(0x1020304);
+ ByteString bs1 = ByteString::CreateFromNetUInt32(kTest2Uint32);
uint32 val;
EXPECT_EQ(4, bs1.GetLength());
EXPECT_TRUE(bs1.GetData() != NULL);
EXPECT_TRUE(bs1.ConvertToNetUInt32(&val));
- EXPECT_EQ(0x1020304, val);
+ EXPECT_EQ(kTest2Uint32, val);
EXPECT_FALSE(bs1.IsZero());
ByteString bs2(kTest2, sizeof(kTest2));
EXPECT_TRUE(bs1.Equals(bs2));
EXPECT_TRUE(bs2.ConvertToNetUInt32(&val));
- EXPECT_EQ(0x1020304, val);
+ EXPECT_EQ(kTest2Uint32, val);
ByteString bs3 = ByteString::CreateFromCPUUInt32(0x1020304);
EXPECT_EQ(4, bs1.GetLength());
@@ -122,4 +127,9 @@
EXPECT_EQ(0, memcmp(bs1.GetData(), kTest2, sizeof(kTest2) - 2));
}
+TEST_F(ByteStringTest, HexEncode) {
+ ByteString bs(kTest2, sizeof(kTest2));
+ EXPECT_EQ(kTest2HexString, bs.HexEncode());
+}
+
} // namespace shill
diff --git a/device_info.cc b/device_info.cc
index d6a680b..c6ba786 100644
--- a/device_info.cc
+++ b/device_info.cc
@@ -149,6 +149,11 @@
DeviceRefPtr device = GetDevice(dev_index);
if (!device.get()) {
+ if (msg.HasAttribute(IFLA_ADDRESS)) {
+ infos_[dev_index].address = msg.GetAttribute(IFLA_ADDRESS);
+ VLOG(2) << "link index " << dev_index << " address "
+ << infos_[dev_index].address.HexEncode();
+ }
if (!msg.HasAttribute(IFLA_IFNAME)) {
LOG(ERROR) << "Add Link message does not have IFLA_IFNAME!";
return;
@@ -195,13 +200,22 @@
RemoveInfo(msg.interface_index());
}
-DeviceRefPtr DeviceInfo::GetDevice(int interface_index) {
- Info *info = GetInfo(interface_index);
+DeviceRefPtr DeviceInfo::GetDevice(int interface_index) const {
+ const Info *info = GetInfo(interface_index);
return info ? info->device : NULL;
}
-bool DeviceInfo::GetFlags(int interface_index, unsigned int *flags) {
- Info *info = GetInfo(interface_index);
+bool DeviceInfo::GetAddress(int interface_index, ByteString *address) const {
+ const Info *info = GetInfo(interface_index);
+ if (!info) {
+ return false;
+ }
+ *address = info->address;
+ return true;
+}
+
+bool DeviceInfo::GetFlags(int interface_index, unsigned int *flags) const {
+ const Info *info = GetInfo(interface_index);
if (!info) {
return false;
}
@@ -209,8 +223,8 @@
return true;
}
-DeviceInfo::Info *DeviceInfo::GetInfo(int interface_index) {
- map<int, Info>::iterator iter = infos_.find(interface_index);
+const DeviceInfo::Info *DeviceInfo::GetInfo(int interface_index) const {
+ map<int, Info>::const_iterator iter = infos_.find(interface_index);
if (iter == infos_.end()) {
return NULL;
}
diff --git a/device_info.h b/device_info.h
index cb8c39e..3f94184 100644
--- a/device_info.h
+++ b/device_info.h
@@ -13,8 +13,8 @@
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
+#include "shill/byte_string.h"
#include "shill/device.h"
-
#include "shill/rtnl_listener.h"
namespace shill {
@@ -37,8 +37,9 @@
// messages, and registers it with the manager.
void RegisterDevice(const DeviceRefPtr &device);
- DeviceRefPtr GetDevice(int interface_index);
- bool GetFlags(int interface_index, unsigned int *flags);
+ DeviceRefPtr GetDevice(int interface_index) const;
+ bool GetAddress(int interface_index, ByteString *address) const;
+ bool GetFlags(int interface_index, unsigned int *flags) const;
private:
friend class DeviceInfoTest;
@@ -47,6 +48,7 @@
Info() : flags(0) {}
DeviceRefPtr device;
+ ByteString address;
unsigned int flags;
};
@@ -60,7 +62,7 @@
void DelLinkMsgHandler(const RTNLMessage &msg);
void LinkMsgHandler(const RTNLMessage &msg);
- Info *GetInfo(int interface_index);
+ const Info *GetInfo(int interface_index) const;
void RemoveInfo(int interface_index);
ControlInterface *control_interface_;
diff --git a/device_info_unittest.cc b/device_info_unittest.cc
index f0247b9..3e76418 100644
--- a/device_info_unittest.cc
+++ b/device_info_unittest.cc
@@ -52,6 +52,7 @@
protected:
static const int kTestDeviceIndex;
static const char kTestDeviceName[];
+ static const char kTestAddress[];
RTNLMessage *BuildMessage(RTNLMessage::MessageType type,
RTNLMessage::MessageMode mode);
@@ -66,6 +67,8 @@
const int DeviceInfoTest::kTestDeviceIndex = 123456;
const char DeviceInfoTest::kTestDeviceName[] = "test-device";
+const char DeviceInfoTest::kTestAddress[] = {
+ 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
RTNLMessage *DeviceInfoTest::BuildMessage(RTNLMessage::MessageType type,
RTNLMessage::MessageMode mode) {
@@ -86,12 +89,18 @@
scoped_ptr<RTNLMessage> message(BuildMessage(RTNLMessage::kMessageTypeLink,
RTNLMessage::kMessageModeAdd));
message->set_link_status(RTNLMessage::LinkStatus(0, IFF_LOWER_UP, 0));
+ ByteString test_address(kTestAddress, sizeof(kTestAddress));
+ message->SetAttribute(IFLA_ADDRESS, test_address);
EXPECT_FALSE(device_info_.GetDevice(kTestDeviceIndex).get());
SendMessageToDeviceInfo(*message);
EXPECT_TRUE(device_info_.GetDevice(kTestDeviceIndex).get());
unsigned int flags = 0;
EXPECT_TRUE(device_info_.GetFlags(kTestDeviceIndex, &flags));
EXPECT_EQ(IFF_LOWER_UP, flags);
+ ByteString address;
+ EXPECT_TRUE(device_info_.GetAddress(kTestDeviceIndex, &address));
+ EXPECT_FALSE(address.IsEmpty());
+ EXPECT_TRUE(test_address.Equals(address));
message.reset(BuildMessage(RTNLMessage::kMessageTypeLink,
RTNLMessage::kMessageModeAdd));