main.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. #include "hardware_address.h"
  2. #include "link.h"
  3. #include "vector.h"
  4. #include <assert.h>
  5. #include <iostream>
  6. #include <libmnl/libmnl.h>
  7. #include <linux/if_link.h>
  8. #include <linux/netlink.h>
  9. #include <linux/rtnetlink.h>
  10. #include <string>
  11. // https://netfilter.org/projects/libmnl/doxygen/html/modules.html
  12. static int link_attr_cb(const nlattr *attr, void *data) {
  13. Link *link = (Link *)data;
  14. // /usr/include/linux/if_link.h
  15. switch (mnl_attr_get_type(attr)) {
  16. case IFLA_ADDRESS:
  17. link->hwaddr = attr;
  18. break;
  19. case IFLA_BROADCAST:
  20. link->broadcast = attr;
  21. break;
  22. case IFLA_IFNAME:
  23. link->ifname = mnl_attr_get_str(attr);
  24. break;
  25. }
  26. return MNL_CB_OK;
  27. }
  28. static int link_cb(const nlmsghdr *nlh, void *data) {
  29. vector<Link> *links = (vector<Link> *)data;
  30. links->emplace_back();
  31. mnl_attr_parse(nlh, sizeof(ifinfomsg), link_attr_cb, &links->back());
  32. return MNL_CB_OK;
  33. }
  34. int main(int argc, char *argv[]) {
  35. mnl_socket *nl = mnl_socket_open(NETLINK_ROUTE);
  36. assert(nl);
  37. assert(mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) == 0);
  38. unsigned int nlpid = mnl_socket_get_portid(nl);
  39. uint8_t msgbuf[MNL_SOCKET_BUFFER_SIZE];
  40. nlmsghdr *nlh = mnl_nlmsg_put_header(msgbuf);
  41. nlh->nlmsg_type = RTM_GETLINK;
  42. nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
  43. nlh->nlmsg_seq = 0;
  44. mnl_nlmsg_put_extra_header(nlh, sizeof(rtgenmsg));
  45. assert(mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) > 0);
  46. vector<Link> links;
  47. size_t numbytes = mnl_socket_recvfrom(nl, msgbuf, sizeof(msgbuf));
  48. while (numbytes > 0) {
  49. if (mnl_cb_run(msgbuf, numbytes, nlh->nlmsg_seq, nlpid, link_cb, &links) <=
  50. MNL_CB_STOP) {
  51. break;
  52. } else {
  53. numbytes = mnl_socket_recvfrom(nl, msgbuf, sizeof(msgbuf));
  54. }
  55. }
  56. assert(numbytes != -1);
  57. links.write_yaml(std::cout);
  58. std::cout << std::endl;
  59. mnl_socket_close(nl);
  60. return EXIT_SUCCESS;
  61. }