You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
7.9 KiB

2 years ago
  1. #ifndef _LIBMNL_H_
  2. #define _LIBMNL_H_
  3. #include <stdbool.h>
  4. #include <stdio.h>
  5. #include <stdint.h>
  6. #include <unistd.h>
  7. #include <sys/socket.h> /* for sa_family_t */
  8. #include <linux/netlink.h>
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif
  12. /*
  13. * Netlink socket API
  14. */
  15. #define MNL_SOCKET_AUTOPID 0
  16. #define MNL_SOCKET_BUFFER_SIZE (sysconf(_SC_PAGESIZE) < 8192L ? sysconf(_SC_PAGESIZE) : 8192L)
  17. #define MNL_SOCKET_DUMP_SIZE 32768
  18. struct mnl_socket;
  19. extern struct mnl_socket *mnl_socket_open(int bus);
  20. extern struct mnl_socket *mnl_socket_open2(int bus, int flags);
  21. extern struct mnl_socket *mnl_socket_fdopen(int fd);
  22. extern int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid);
  23. extern int mnl_socket_close(struct mnl_socket *nl);
  24. extern int mnl_socket_get_fd(const struct mnl_socket *nl);
  25. extern unsigned int mnl_socket_get_portid(const struct mnl_socket *nl);
  26. extern ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz);
  27. extern ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz);
  28. extern int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len);
  29. extern int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len);
  30. /*
  31. * Netlink message API
  32. */
  33. #define MNL_ALIGNTO 4
  34. #define MNL_ALIGN(len) (((len)+MNL_ALIGNTO-1) & ~(MNL_ALIGNTO-1))
  35. #define MNL_NLMSG_HDRLEN MNL_ALIGN(sizeof(struct nlmsghdr))
  36. extern size_t mnl_nlmsg_size(size_t len);
  37. extern size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh);
  38. /* Netlink message header builder */
  39. extern struct nlmsghdr *mnl_nlmsg_put_header(void *buf);
  40. extern void *mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size);
  41. /* Netlink message iterators */
  42. extern bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len);
  43. extern struct nlmsghdr *mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len);
  44. /* Netlink sequence tracking */
  45. extern bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq);
  46. /* Netlink portID checking */
  47. extern bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid);
  48. /* Netlink message getters */
  49. extern void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh);
  50. extern void *mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset);
  51. extern void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh);
  52. /* Netlink message printer */
  53. extern void mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen, size_t extra_header_size);
  54. /* Message batch helpers */
  55. struct mnl_nlmsg_batch;
  56. extern struct mnl_nlmsg_batch *mnl_nlmsg_batch_start(void *buf, size_t bufsiz);
  57. extern bool mnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b);
  58. extern void mnl_nlmsg_batch_stop(struct mnl_nlmsg_batch *b);
  59. extern size_t mnl_nlmsg_batch_size(struct mnl_nlmsg_batch *b);
  60. extern void mnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b);
  61. extern void *mnl_nlmsg_batch_head(struct mnl_nlmsg_batch *b);
  62. extern void *mnl_nlmsg_batch_current(struct mnl_nlmsg_batch *b);
  63. extern bool mnl_nlmsg_batch_is_empty(struct mnl_nlmsg_batch *b);
  64. /*
  65. * Netlink attributes API
  66. */
  67. #define MNL_ATTR_HDRLEN MNL_ALIGN(sizeof(struct nlattr))
  68. /* TLV attribute getters */
  69. extern uint16_t mnl_attr_get_type(const struct nlattr *attr);
  70. extern uint16_t mnl_attr_get_len(const struct nlattr *attr);
  71. extern uint16_t mnl_attr_get_payload_len(const struct nlattr *attr);
  72. extern void *mnl_attr_get_payload(const struct nlattr *attr);
  73. extern uint8_t mnl_attr_get_u8(const struct nlattr *attr);
  74. extern uint16_t mnl_attr_get_u16(const struct nlattr *attr);
  75. extern uint32_t mnl_attr_get_u32(const struct nlattr *attr);
  76. extern uint64_t mnl_attr_get_u64(const struct nlattr *attr);
  77. extern const char *mnl_attr_get_str(const struct nlattr *attr);
  78. /* TLV attribute putters */
  79. extern void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data);
  80. extern void mnl_attr_put_u8(struct nlmsghdr *nlh, uint16_t type, uint8_t data);
  81. extern void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data);
  82. extern void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data);
  83. extern void mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type, uint64_t data);
  84. extern void mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type, const char *data);
  85. extern void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data);
  86. /* TLV attribute putters with buffer boundary checkings */
  87. extern bool mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, size_t len, const void *data);
  88. extern bool mnl_attr_put_u8_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint8_t data);
  89. extern bool mnl_attr_put_u16_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint16_t data);
  90. extern bool mnl_attr_put_u32_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint32_t data);
  91. extern bool mnl_attr_put_u64_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint64_t data);
  92. extern bool mnl_attr_put_str_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, const char *data);
  93. extern bool mnl_attr_put_strz_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, const char *data);
  94. /* TLV attribute nesting */
  95. extern struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type);
  96. extern struct nlattr *mnl_attr_nest_start_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type);
  97. extern void mnl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *start);
  98. extern void mnl_attr_nest_cancel(struct nlmsghdr *nlh, struct nlattr *start);
  99. /* TLV validation */
  100. extern int mnl_attr_type_valid(const struct nlattr *attr, uint16_t maxtype);
  101. enum mnl_attr_data_type {
  102. MNL_TYPE_UNSPEC,
  103. MNL_TYPE_U8,
  104. MNL_TYPE_U16,
  105. MNL_TYPE_U32,
  106. MNL_TYPE_U64,
  107. MNL_TYPE_STRING,
  108. MNL_TYPE_FLAG,
  109. MNL_TYPE_MSECS,
  110. MNL_TYPE_NESTED,
  111. MNL_TYPE_NESTED_COMPAT,
  112. MNL_TYPE_NUL_STRING,
  113. MNL_TYPE_BINARY,
  114. MNL_TYPE_MAX,
  115. };
  116. extern int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type);
  117. extern int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t len);
  118. /* TLV iterators */
  119. extern bool mnl_attr_ok(const struct nlattr *attr, int len);
  120. extern struct nlattr *mnl_attr_next(const struct nlattr *attr);
  121. #define mnl_attr_for_each(attr, nlh, offset) \
  122. for ((attr) = mnl_nlmsg_get_payload_offset((nlh), (offset)); \
  123. mnl_attr_ok((attr), (char *)mnl_nlmsg_get_payload_tail(nlh) - (char *)(attr)); \
  124. (attr) = mnl_attr_next(attr))
  125. #define mnl_attr_for_each_nested(attr, nest) \
  126. for ((attr) = mnl_attr_get_payload(nest); \
  127. mnl_attr_ok((attr), (char *)mnl_attr_get_payload(nest) + mnl_attr_get_payload_len(nest) - (char *)(attr)); \
  128. (attr) = mnl_attr_next(attr))
  129. #define mnl_attr_for_each_payload(payload, payload_size) \
  130. for ((attr) = (payload); \
  131. mnl_attr_ok((attr), (char *)(payload) + payload_size - (char *)(attr)); \
  132. (attr) = mnl_attr_next(attr))
  133. /* TLV callback-based attribute parsers */
  134. typedef int (*mnl_attr_cb_t)(const struct nlattr *attr, void *data);
  135. extern int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data);
  136. extern int mnl_attr_parse_nested(const struct nlattr *attr, mnl_attr_cb_t cb, void *data);
  137. extern int mnl_attr_parse_payload(const void *payload, size_t payload_len, mnl_attr_cb_t cb, void *data);
  138. /*
  139. * callback API
  140. */
  141. #define MNL_CB_ERROR -1
  142. #define MNL_CB_STOP 0
  143. #define MNL_CB_OK 1
  144. typedef int (*mnl_cb_t)(const struct nlmsghdr *nlh, void *data);
  145. extern int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq,
  146. unsigned int portid, mnl_cb_t cb_data, void *data);
  147. extern int mnl_cb_run2(const void *buf, size_t numbytes, unsigned int seq,
  148. unsigned int portid, mnl_cb_t cb_data, void *data,
  149. const mnl_cb_t *cb_ctl_array,
  150. unsigned int cb_ctl_array_len);
  151. /*
  152. * other declarations
  153. */
  154. #ifndef SOL_NETLINK
  155. #define SOL_NETLINK 270
  156. #endif
  157. #ifndef MNL_ARRAY_SIZE
  158. #define MNL_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
  159. #endif
  160. #ifdef __cplusplus
  161. } /* extern "C" */
  162. #endif
  163. #endif