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