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