link.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #include "link.h"
  2. #include <libmnl/libmnl.h> // mnl_attr_*
  3. #include <linux/if_link.h> // IFLA_*
  4. #include <string> // std::string
  5. // https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/ip/iplink.c
  6. Link::Link(const ifinfomsg *msg) {
  7. /*
  8. struct ifinfomsg {
  9. unsigned char ifi_family; // AF_UNSPEC
  10. unsigned short ifi_type; // Device type
  11. int ifi_index; // Interface index
  12. unsigned int ifi_flags; // Device flags
  13. unsigned int ifi_change; // change mask
  14. };
  15. see /usr/include/net/if_arp.h for ifi_type:
  16. > #define ARPHRD_ETHER 1
  17. > #define ARPHRD_LOOPBACK 772
  18. > #define ARPHRD_SIT 776
  19. */
  20. index = msg->ifi_index;
  21. }
  22. int Link::mnl_attr_cb(const nlattr *attr, void *data) {
  23. Link *link = (Link *)data;
  24. // https://netfilter.org/projects/libmnl/doxygen/html/group__attr.html
  25. // /usr/include/linux/if_link.h
  26. switch (mnl_attr_get_type(attr)) {
  27. case IFLA_ADDRESS:
  28. link->address = attr;
  29. break;
  30. case IFLA_BROADCAST:
  31. link->broadcast = attr;
  32. break;
  33. case IFLA_IFNAME:
  34. assert(mnl_attr_validate(attr, MNL_TYPE_STRING) == 0);
  35. link->ifname = mnl_attr_get_str(attr);
  36. break;
  37. case IFLA_MTU:
  38. assert(mnl_attr_validate(attr, MNL_TYPE_U32) == 0);
  39. link->mtu = mnl_attr_get_u32(attr);
  40. break;
  41. case IFLA_OPERSTATE:
  42. link->operstate = attr;
  43. break;
  44. }
  45. return MNL_CB_OK;
  46. }
  47. void Link::write_yaml(std::ostream &stream,
  48. const yaml_indent_level_t indent_level) const {
  49. const std::string indent(indent_level, ' ');
  50. stream << "ifname: " + ifname + "\n";
  51. // stream << indent << "index: " << index << "\n";
  52. if (address.specified()) {
  53. stream << indent << "address: ";
  54. address.write_yaml(stream);
  55. }
  56. if (broadcast.specified()) {
  57. stream << indent << "broadcast: ";
  58. broadcast.write_yaml(stream);
  59. }
  60. stream << indent << "mtu: " << mtu << "\n";
  61. stream << indent << "operstate: ";
  62. operstate.write_yaml(stream);
  63. stream << indent << "addresses: ";
  64. addresses.write_yaml(stream, indent_level + 2);
  65. }