libmnl  1.0.3
libmnl.h
00001 #ifndef _LIBMNL_H_
00002 #define _LIBMNL_H_
00003 
00004 #ifdef __cplusplus
00005 #       include <cstdio>
00006 #       include <cstdint>
00007 #else
00008 #       include <stdbool.h> /* not in C++ */
00009 #       include <stdio.h>
00010 #       include <stdint.h>
00011 #endif
00012 #include <unistd.h>
00013 #include <sys/socket.h> /* for sa_family_t */
00014 #include <linux/netlink.h>
00015 
00016 #ifdef __cplusplus
00017 extern "C" {
00018 #endif
00019 
00020 /*
00021  * Netlink socket API
00022  */
00023 
00024 #define MNL_SOCKET_AUTOPID      0
00025 #define MNL_SOCKET_BUFFER_SIZE (getpagesize() < 8192L ? getpagesize() : 8192L)
00026 
00027 struct mnl_socket;
00028 
00029 extern struct mnl_socket *mnl_socket_open(int type);
00030 extern int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid);
00031 extern int mnl_socket_close(struct mnl_socket *nl);
00032 extern int mnl_socket_get_fd(const struct mnl_socket *nl);
00033 extern unsigned int mnl_socket_get_portid(const struct mnl_socket *nl);
00034 extern ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz);
00035 extern ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz);
00036 extern int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len);
00037 extern int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len);
00038 
00039 /*
00040  * Netlink message API
00041  */
00042 
00043 #define MNL_ALIGNTO             4
00044 #define MNL_ALIGN(len)          (((len)+MNL_ALIGNTO-1) & ~(MNL_ALIGNTO-1))
00045 #define MNL_NLMSG_HDRLEN        MNL_ALIGN(sizeof(struct nlmsghdr))
00046 
00047 extern size_t mnl_nlmsg_size(size_t len);
00048 extern size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh);
00049 
00050 /* Netlink message header builder */
00051 extern struct nlmsghdr *mnl_nlmsg_put_header(void *buf);
00052 extern void *mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size);
00053 
00054 /* Netlink message iterators */
00055 extern bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len);
00056 extern struct nlmsghdr *mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len);
00057 
00058 /* Netlink sequence tracking */
00059 extern bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq);
00060 
00061 /* Netlink portID checking */
00062 extern bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid);
00063 
00064 /* Netlink message getters */
00065 extern void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh);
00066 extern void *mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset);
00067 extern void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh);
00068 
00069 /* Netlink message printer */
00070 extern void mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen, size_t extra_header_size);
00071 
00072 /* Message batch helpers */
00073 struct mnl_nlmsg_batch;
00074 extern struct mnl_nlmsg_batch *mnl_nlmsg_batch_start(void *buf, size_t bufsiz);
00075 extern bool mnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b);
00076 extern void mnl_nlmsg_batch_stop(struct mnl_nlmsg_batch *b);
00077 extern size_t mnl_nlmsg_batch_size(struct mnl_nlmsg_batch *b);
00078 extern void mnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b);
00079 extern void *mnl_nlmsg_batch_head(struct mnl_nlmsg_batch *b);
00080 extern void *mnl_nlmsg_batch_current(struct mnl_nlmsg_batch *b);
00081 extern bool mnl_nlmsg_batch_is_empty(struct mnl_nlmsg_batch *b);
00082 
00083 /*
00084  * Netlink attributes API
00085  */
00086 #define MNL_ATTR_HDRLEN MNL_ALIGN(sizeof(struct nlattr))
00087 
00088 /* TLV attribute getters */
00089 extern uint16_t mnl_attr_get_type(const struct nlattr *attr);
00090 extern uint16_t mnl_attr_get_len(const struct nlattr *attr);
00091 extern uint16_t mnl_attr_get_payload_len(const struct nlattr *attr);
00092 extern void *mnl_attr_get_payload(const struct nlattr *attr);
00093 extern uint8_t mnl_attr_get_u8(const struct nlattr *attr);
00094 extern uint16_t mnl_attr_get_u16(const struct nlattr *attr);
00095 extern uint32_t mnl_attr_get_u32(const struct nlattr *attr);
00096 extern uint64_t mnl_attr_get_u64(const struct nlattr *attr);
00097 extern const char *mnl_attr_get_str(const struct nlattr *attr);
00098 
00099 /* TLV attribute putters */
00100 extern void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data);
00101 extern void mnl_attr_put_u8(struct nlmsghdr *nlh, uint16_t type, uint8_t data);
00102 extern void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data);
00103 extern void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data);
00104 extern void mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type, uint64_t data);
00105 extern void mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type, const char *data);
00106 extern void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data);
00107 
00108 /* TLV attribute putters with buffer boundary checkings */
00109 extern bool mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, size_t len, const void *data);
00110 extern bool mnl_attr_put_u8_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint8_t data);
00111 extern bool mnl_attr_put_u16_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint16_t data);
00112 extern bool mnl_attr_put_u32_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint32_t data);
00113 extern bool mnl_attr_put_u64_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint64_t data);
00114 extern bool mnl_attr_put_str_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, const char *data);
00115 extern bool mnl_attr_put_strz_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, const char *data);
00116 
00117 /* TLV attribute nesting */
00118 extern struct nlattr *mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type);
00119 extern struct nlattr *mnl_attr_nest_start_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type);
00120 extern void mnl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *start);
00121 extern void mnl_attr_nest_cancel(struct nlmsghdr *nlh, struct nlattr *start);
00122 
00123 /* TLV validation */
00124 extern int mnl_attr_type_valid(const struct nlattr *attr, uint16_t maxtype);
00125 
00126 enum mnl_attr_data_type {
00127         MNL_TYPE_UNSPEC,
00128         MNL_TYPE_U8,
00129         MNL_TYPE_U16,
00130         MNL_TYPE_U32,
00131         MNL_TYPE_U64,
00132         MNL_TYPE_STRING,
00133         MNL_TYPE_FLAG,
00134         MNL_TYPE_MSECS,
00135         MNL_TYPE_NESTED,
00136         MNL_TYPE_NESTED_COMPAT,
00137         MNL_TYPE_NUL_STRING,
00138         MNL_TYPE_BINARY,
00139         MNL_TYPE_MAX,
00140 };
00141 
00142 extern int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type);
00143 extern int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t len);
00144 
00145 /* TLV iterators */
00146 extern bool mnl_attr_ok(const struct nlattr *attr, int len);
00147 extern struct nlattr *mnl_attr_next(const struct nlattr *attr);
00148 
00149 #define mnl_attr_for_each(attr, nlh, offset) \
00150         for ((attr) = mnl_nlmsg_get_payload_offset((nlh), (offset)); \
00151              mnl_attr_ok((attr), (char *)mnl_nlmsg_get_payload_tail(nlh) - (char *)(attr)); \
00152              (attr) = mnl_attr_next(attr))
00153 
00154 #define mnl_attr_for_each_nested(attr, nest) \
00155         for ((attr) = mnl_attr_get_payload(nest); \
00156              mnl_attr_ok((attr), (char *)mnl_attr_get_payload(nest) + mnl_attr_get_payload_len(nest) - (char *)(attr)); \
00157              (attr) = mnl_attr_next(attr))
00158 
00159 #define mnl_attr_for_each_payload(payload, payload_size) \
00160         for ((attr) = (payload); \
00161              mnl_attr_ok((attr), (char *)(payload) + payload_size - (char *)(attr)); \
00162              (attr) = mnl_attr_next(attr))
00163 
00164 /* TLV callback-based attribute parsers */
00165 typedef int (*mnl_attr_cb_t)(const struct nlattr *attr, void *data);
00166 
00167 extern int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data);
00168 extern int mnl_attr_parse_nested(const struct nlattr *attr, mnl_attr_cb_t cb, void *data);
00169 extern int mnl_attr_parse_payload(const void *payload, size_t payload_len, mnl_attr_cb_t cb, void *data);
00170 
00171 /*
00172  * callback API
00173  */
00174 #define MNL_CB_ERROR            -1
00175 #define MNL_CB_STOP              0
00176 #define MNL_CB_OK                1
00177 
00178 typedef int (*mnl_cb_t)(const struct nlmsghdr *nlh, void *data);
00179 
00180 extern int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq,
00181                       unsigned int portid, mnl_cb_t cb_data, void *data);
00182 
00183 extern int mnl_cb_run2(const void *buf, size_t numbytes, unsigned int seq,
00184                        unsigned int portid, mnl_cb_t cb_data, void *data,
00185                        mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len);
00186 
00187 /*
00188  * other declarations
00189  */
00190 
00191 #ifndef SOL_NETLINK
00192 #define SOL_NETLINK     270
00193 #endif
00194 
00195 #ifndef MNL_ARRAY_SIZE
00196 #define MNL_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
00197 #endif
00198 
00199 #ifdef __cplusplus
00200 } /* extern "C" */
00201 #endif
00202 
00203 #endif