main.cpp 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #include "hardware_address.h"
  2. #include "link.h"
  3. #include "vector.h"
  4. #include <cassert>
  5. #include <cstdlib>
  6. #include <iostream>
  7. #include <libmnl/libmnl.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. void mnl_recv_run_cb_all(const mnl_socket *nl, void *buf, size_t bufsiz,
  13. mnl_cb_t cb_data, void *data) {
  14. unsigned int nlpid = mnl_socket_get_portid(nl);
  15. ssize_t numbytes = mnl_socket_recvfrom(nl, buf, bufsiz);
  16. while (numbytes > 0) {
  17. if (mnl_cb_run(buf, numbytes, 0, nlpid, cb_data, data) <= MNL_CB_STOP) {
  18. break;
  19. }
  20. numbytes = mnl_socket_recvfrom(nl, buf, bufsiz);
  21. }
  22. assert(numbytes != -1);
  23. }
  24. static int link_cb(const nlmsghdr *nlh, void *data) {
  25. vector<Link> *links = (vector<Link> *)data;
  26. links->emplace_back();
  27. mnl_attr_parse(nlh, sizeof(ifinfomsg), Link::mnl_attr_cb, &links->back());
  28. return MNL_CB_OK;
  29. }
  30. void mnl_read_links(const mnl_socket *nl, vector<Link> *links) {
  31. uint8_t msgbuf[MNL_SOCKET_BUFFER_SIZE];
  32. nlmsghdr *nlh = mnl_nlmsg_put_header(msgbuf);
  33. nlh->nlmsg_type = RTM_GETLINK;
  34. nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
  35. mnl_nlmsg_put_extra_header(nlh, sizeof(rtgenmsg));
  36. assert(mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) > 0);
  37. mnl_recv_run_cb_all(nl, msgbuf, sizeof(msgbuf), link_cb, links);
  38. }
  39. int main(int argc, char *argv[]) {
  40. mnl_socket *nl = mnl_socket_open(NETLINK_ROUTE);
  41. assert(nl);
  42. assert(mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) == 0);
  43. vector<Link> links;
  44. mnl_read_links(nl, &links);
  45. links.write_yaml(std::cout);
  46. std::cout << std::endl;
  47. mnl_socket_close(nl);
  48. return EXIT_SUCCESS;
  49. }