node_state_interfaces_linux.cpp 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include "diagnostic/node_state_interfaces_linux.hpp"
  2. #include <ifaddrs.h>
  3. #include <net/if.h>
  4. #include <netinet/in.h>
  5. #include <arpa/inet.h>
  6. #include <sys/ioctl.h>
  7. #include <unistd.h>
  8. #include <cstring>
  9. #include <vector>
  10. void addNodeStateInterfacesJson(nlohmann::json& j) {
  11. try {
  12. std::vector<nlohmann::json> interfaces_json;
  13. struct ifreq ifr;
  14. struct ifconf ifc;
  15. char buf[1024];
  16. char stringBuffer[128];
  17. int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
  18. ifc.ifc_len = sizeof(buf);
  19. ifc.ifc_buf = buf;
  20. ioctl(sock, SIOCGIFCONF, &ifc);
  21. struct ifreq *it = ifc.ifc_req;
  22. const struct ifreq * const end = it + (ifc.ifc_len / sizeof(struct ifreq));
  23. for(; it != end; ++it) {
  24. strcpy(ifr.ifr_name, it->ifr_name);
  25. if(ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
  26. if (!(ifr.ifr_flags & IFF_LOOPBACK)) { // skip loopback
  27. nlohmann::json iface_json;
  28. iface_json["name"] = ifr.ifr_name;
  29. if (ioctl(sock, SIOCGIFMTU, &ifr) == 0) {
  30. iface_json["mtu"] = ifr.ifr_mtu;
  31. }
  32. if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
  33. unsigned char mac_addr[6];
  34. memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, 6);
  35. char macStr[18];
  36. sprintf(macStr, "%02x:%02x:%02x:%02x:%02x:%02x",
  37. mac_addr[0],
  38. mac_addr[1],
  39. mac_addr[2],
  40. mac_addr[3],
  41. mac_addr[4],
  42. mac_addr[5]);
  43. iface_json["mac"] = macStr;
  44. }
  45. std::vector<std::string> addresses;
  46. struct ifaddrs *ifap, *ifa;
  47. void *addr;
  48. getifaddrs(&ifap);
  49. for(ifa = ifap; ifa; ifa = ifa->ifa_next) {
  50. if(strcmp(ifr.ifr_name, ifa->ifa_name) == 0 && ifa->ifa_addr != NULL) {
  51. if(ifa->ifa_addr->sa_family == AF_INET) {
  52. struct sockaddr_in *ipv4 = (struct sockaddr_in*)ifa->ifa_addr;
  53. addr = &ipv4->sin_addr;
  54. } else if (ifa->ifa_addr->sa_family == AF_INET6) {
  55. struct sockaddr_in6 *ipv6 = (struct sockaddr_in6*)ifa->ifa_addr;
  56. addr = &ipv6->sin6_addr;
  57. } else {
  58. continue;
  59. }
  60. inet_ntop(ifa->ifa_addr->sa_family, addr, stringBuffer, sizeof(stringBuffer));
  61. addresses.push_back(stringBuffer);
  62. }
  63. }
  64. iface_json["addresses"] = addresses;
  65. interfaces_json.push_back(iface_json);
  66. }
  67. }
  68. }
  69. close(sock);
  70. j["network_interfaces"] = interfaces_json;
  71. } catch (const std::exception& e) {
  72. j["network_interfaces"] = std::string("Exception: ") + e.what();
  73. } catch (...) {
  74. j["network_interfaces"] = "Unknown error retrieving interfaces";
  75. }
  76. }