Merge "platform: Added ipv6 field to onu device_stats"
diff --git a/cmds/device_stats.proto b/cmds/device_stats.proto
index 30a344e..4f47b5e 100644
--- a/cmds/device_stats.proto
+++ b/cmds/device_stats.proto
@@ -17,5 +17,8 @@
// Device serial number.
optional string serial = 5;
+
+ // Public ipv6 address of onu
+ optional string ipv6 = 6;
};
diff --git a/cmds/statcatcher.cc b/cmds/statcatcher.cc
index 64db2b6..bfd7033 100644
--- a/cmds/statcatcher.cc
+++ b/cmds/statcatcher.cc
@@ -142,7 +142,8 @@
"onu_acs_contacted": %s,
"onu_acs_contact_time": "%lld",
"onu_uptime": %lld,
-"onu_serial": "%s"
+"onu_serial": "%s",
+"onu_ipv6": "%s"
})";
FILE *f = fopen(tmp_file.c_str(), "w");
if (!f) {
@@ -155,7 +156,8 @@
status.acs_contacted() ? "true" : "false",
status.acs_contact_time(),
status.uptime(),
- status.serial().c_str());
+ status.serial().c_str(),
+ status.ipv6().c_str());
fclose(f);
if (rename(tmp_file.c_str(), stat_file.c_str()) != 0) {
diff --git a/cmds/statpitcher.cc b/cmds/statpitcher.cc
index 412be5d..990666d 100644
--- a/cmds/statpitcher.cc
+++ b/cmds/statpitcher.cc
@@ -16,8 +16,10 @@
#include <fstream>
#include <iostream>
+#include <sstream>
#include <string>
#include <vector>
+#include <memory>
#include "device_stats.pb.h"
@@ -91,6 +93,71 @@
return static_cast<int64_t>(up);
}
+std::string IPAddress() {
+ std::ifstream infile;
+ infile.open("/proc/net/if_inet6");
+
+ if (!infile.good()) {
+ perror("error reading ipv6 from file");
+ exit(1);
+ }
+
+ std::string line;
+ int found = 0;
+ while (!infile.eof()) {
+ getline(infile, line);
+ // Want Ipv6 address on man interface
+ if (line.find("man") == std::string::npos) {
+ continue;
+ }
+ // Avoid local ipv6
+ if (line.substr(0, 4) == "0100" || // Discard prefix RFC 6666
+ line.substr(0, 2) == "fc" || // Unique local addresses
+ line.substr(0, 2) == "fd" ||
+ line.substr(0, 4) == "fe80" || // Link-local addresses
+ line.substr(0, 4) == "fec0") { // Old, deprecated local address range
+ continue;
+ }
+ found = 1;
+ break;
+ }
+
+ infile.close();
+ if (!found || line.size() < 32) {
+ perror("ipv6 address on man not found in file");
+ return "::1";
+ }
+
+ // Add colons
+ std::stringstream ipv6;
+ line = line.substr(0, 32);
+ for (unsigned int i = 0; i < line.size(); i++) {
+ if (i != 0 && i % 4 == 0) {
+ ipv6 << ':';
+ }
+ ipv6 << line[i];
+ }
+
+ // Format canonically
+ struct in6_addr ipv6_struct;
+ if (!inet_pton(AF_INET6, ipv6.str().c_str(), &ipv6_struct)) {
+ std::string errmsg = "unable to parse ipv6 address to inet_pton: " +
+ ipv6.str();
+ perror(errmsg.c_str());
+ exit(1);
+ }
+ char address[INET6_ADDRSTRLEN];
+ if (!inet_ntop(AF_INET6, &ipv6_struct, address, INET6_ADDRSTRLEN)) {
+ std::string errmsg = "unable to parse ipv6 address from inet_pton struct "
+ "created from: " + ipv6.str();
+ perror(errmsg.c_str());
+ exit(1);
+ }
+
+ std::string result(address);
+ return result;
+}
+
void MakePacket(std::vector<uint8_t>* pkt) {
devstatus::Status status;
@@ -101,6 +168,7 @@
status.set_acs_contact_time(acs_contact_time);
status.set_uptime(Uptime());
status.set_serial(serial_number);
+ status.set_ipv6(IPAddress());
pkt->resize(status.ByteSize());
status.SerializeToArray(&(*pkt)[0], status.ByteSize());