2 #include <linux/ethtool.h> 3 #include <linux/sockios.h> 29 ethtool_stats_buf_(NULL),
31 rx_crc_error_index_(-1),
32 rx_frame_error_index_(-1),
33 rx_align_error_index_(-1)
51 sock_ = socket(AF_INET, SOCK_DGRAM, 0);
54 ROS_WARN(
"Cannot get control socket for ioctls : %s", strerror(errno));
62 memset(&ifr, 0,
sizeof(ifr));
63 strncpy(ifr.ifr_name,
interface_.c_str(),
sizeof(ifr.ifr_name));
66 struct ethtool_drvinfo drvinfo;
67 drvinfo.cmd = ETHTOOL_GDRVINFO;
68 ifr.ifr_data = (caddr_t)&drvinfo;
69 int result = ioctl(
sock_, SIOCETHTOOL, &ifr);
72 ROS_WARN(
"Cannot get driver information for %s : %s",
interface_.c_str(), strerror(errno));
82 unsigned strings_len =
sizeof(ethtool_gstrings) +
n_stats_ * ETH_GSTRING_LEN;
83 char *strings_buf =
new char[ strings_len ];
84 memset(strings_buf, 0, strings_len);
85 ethtool_gstrings* strings = (ethtool_gstrings*) strings_buf;
87 strings->cmd = ETHTOOL_GSTRINGS;
88 strings->string_set = ETH_SS_STATS;
90 ifr.ifr_data = (caddr_t) strings;
91 result = ioctl(
sock_, SIOCETHTOOL, &ifr);
94 ROS_WARN(
"Cannot get statistics strings for %s : %s",
interface_.c_str(), strerror(errno));
103 char s[ETH_GSTRING_LEN+1];
104 strncpy(s, (
const char*) &strings->data[i * ETH_GSTRING_LEN], ETH_GSTRING_LEN);
105 s[ETH_GSTRING_LEN] =
'\0';
108 const char *stat_name = (
const char*) &strings->data[i * ETH_GSTRING_LEN];
109 if (strncmp(
"rx_errors", stat_name, ETH_GSTRING_LEN) == 0)
113 else if (strncmp(
"rx_crc_errors", stat_name, ETH_GSTRING_LEN) == 0)
117 else if (strncmp(
"rx_frame_errors", stat_name, ETH_GSTRING_LEN) == 0)
121 else if (strncmp(
"rx_align_errors", stat_name, ETH_GSTRING_LEN) == 0)
130 unsigned ethtool_stats_buf_len =
sizeof(
struct ethtool_stats) + n_stats_ *
sizeof(uint64_t);
136 ROS_WARN(
"Error collecting intial ethernet interface statistics");
138 ethtool_stats_buf_ = NULL;
146 memset(&ifr, 0,
sizeof(ifr));
147 strncpy(ifr.ifr_name,
interface_.c_str(),
sizeof(ifr.ifr_name));
149 if (ioctl(
sock_, SIOCGIFFLAGS, &ifr) < 0) {
150 ROS_WARN(
"Cannot get interface flags for %s: %s",
interface_.c_str(), strerror(errno));
154 state.
up_ = bool(ifr.ifr_flags & IFF_UP);
155 state.
running_ = bool(ifr.ifr_flags & IFF_RUNNING);
166 memset(&ifr, 0,
sizeof(ifr));
167 strncpy(ifr.ifr_name,
interface_.c_str(),
sizeof(ifr.ifr_name));
170 stats->cmd = ETHTOOL_GSTATS;
172 ifr.ifr_data = (caddr_t) stats;
173 if (ioctl(
sock_, SIOCETHTOOL, &ifr) < 0)
175 ROS_WARN(
"Cannot get NIC stats information for %s : %s",
interface_.c_str(), strerror(errno));
221 d.
addf(
"Interface State",
"%s UP, %s RUNNING", state.
up_?
"":
"NOT", state.
running_?
"":
"NOT");
226 d.
add(
"Iface State",
"ERROR");
237 d.
add(
"RX Errors",
"N/A");
242 d.
add(
"RX CRC Errors",
"N/A");
247 d.
add(
"RX Frame Errors",
"N/A");
252 d.
add(
"RX Align Errors",
"N/A");
unsigned lost_link_count_
Number of time master link went down.
int sock_
network socket for making ioctl requests
InterfaceState last_state_
bool getInterfaceState(InterfaceState &state)
Get state (up,running) of interface.
void initialize(const std::string &interface)
std::string interface_
name of network interface (for example : eth0)
int rx_frame_error_index_
int rx_align_error_index_
void addf(const std::string &key, const char *format,...)
unsigned n_stats_
Number of stats available from ethtool ioctl.
char * ethtool_stats_buf_
buffer for NIC statistic values
EthtoolStats orig_stats_
Orignal statistics counts when initialize() was called.
void mergeSummary(unsigned char lvl, const std::string s)
void add(const std::string &key, const T &val)
void publishDiagnostics(diagnostic_updater::DiagnosticStatusWrapper &d)
Collect and append ethernet interface diagnostics.
bool getEthtoolStats(EthtoolStats &stats)
Get ethtool stats from interface.