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