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