address.h 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #ifndef _IPYML_ADDRESS_H
  2. #define _IPYML_ADDRESS_H
  3. #include "inet6_address.h"
  4. #include "inet_address.h"
  5. #include "yaml.h"
  6. #include <bits/socket.h> // AF_*
  7. #include <libmnl/libmnl.h> // mnl_attr_get_type
  8. #include <linux/if_addr.h> // struct ifaddrmsg
  9. #include <linux/netlink.h> // struct nlattr
  10. #include <ostream> // std::ostream
  11. class Address : public YamlObject {
  12. unsigned char family;
  13. union {
  14. InetAddress inet_addr;
  15. Inet6Address inet6_addr;
  16. };
  17. public:
  18. Address() : family(AF_UNSPEC) {}
  19. Address &operator=(const ifaddrmsg *msg) {
  20. family = msg->ifa_family;
  21. assert(family == AF_INET || family == AF_INET6);
  22. return *this;
  23. }
  24. // typedef int (*mnl_attr_cb_t)(const struct nlattr *attr, void *data);
  25. static int mnl_attr_cb(const nlattr *attr, void *data) {
  26. Address *addr = (Address *)data;
  27. assert(addr->family != AF_UNSPEC);
  28. // /usr/include/linux/if_addr.h
  29. switch (mnl_attr_get_type(attr)) {
  30. case IFA_ADDRESS:
  31. if (addr->family == AF_INET) {
  32. addr->inet_addr = attr;
  33. } else if (addr->family == AF_INET6) {
  34. addr->inet6_addr = attr;
  35. }
  36. break;
  37. }
  38. }
  39. void write_yaml(std::ostream &stream,
  40. const yaml_indent_level_t indent_level = 0) const {
  41. // const std::string indent(indent_level, ' ');
  42. if (family == AF_INET) {
  43. inet_addr.write_yaml(stream, indent_level + 2);
  44. } else if (family == AF_INET6) {
  45. inet6_addr.write_yaml(stream, indent_level + 2);
  46. }
  47. }
  48. };
  49. #endif