summaryrefslogtreecommitdiff
path: root/include/libmnl/libmnl.h
blob: 259ddc291ea23bf4ce710c253877e34c4cb9c440 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#ifndef _LIBMNL_H_
#define _LIBMNL_H_

#include <stdint.h>
#include <sys/socket.h> /* for sa_family_t */
#include <linux/netlink.h>

/*
 * generic netlink socket API
 */

#define MNL_SOCKET_AUTOPID	0

struct mnl_socket;

extern struct mnl_socket *mnl_socket_open(int type);
extern int mnl_socket_bind(struct mnl_socket *nl, int groups, int pid);
extern int mnl_socket_close(struct mnl_socket *nl);
extern int mnl_socket_get_fd(const struct mnl_socket *nl);
extern unsigned int mnl_socket_get_portid(const struct mnl_socket *nl);
extern int mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz);
extern int mnl_socket_sendmsg(const struct mnl_socket *nl, const struct msghdr *msg, int flags);
extern int mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz);
extern int mnl_socket_recvmsg(const struct mnl_socket *nl, struct msghdr *msg, int flags);
extern int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len);
extern int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len);

/*
 * generic netlink message API
 */

#define MNL_ALIGNTO		4
#define MNL_ALIGN(len)		(((len)+MNL_ALIGNTO-1) & ~(MNL_ALIGNTO-1))
#define MNL_NLMSG_HDRLEN	MNL_ALIGN(sizeof(struct nlmsghdr))

extern size_t mnl_nlmsg_size(int len);
extern size_t mnl_nlmsg_total_size(int len);
extern size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh);

/* Netlink message header builder */
extern struct nlmsghdr *mnl_nlmsg_put_header(void *buf);
extern void *mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, int size);

/* Netlink message iterators */
extern int mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len);
extern struct nlmsghdr *mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len);

/* Netlink sequence tracking */
extern int mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq);

/* Netlink portID checking */
int mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid);

/* Netlink message getters */
extern void *mnl_nlmsg_get_payload(const struct nlmsghdr *nlh);
extern void *mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, int offset);
extern void *mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh);

/* Netlink dump message */
extern void mnl_nlmsg_print(const struct nlmsghdr *nlh);

/*
 * generic netlink attributes API
 */
#define MNL_ATTR_HDRLEN	MNL_ALIGN(sizeof(struct nlattr))

/* TLV attribute getters */
extern uint16_t mnl_attr_get_type(const struct nlattr *attr);
extern uint16_t mnl_attr_get_len(const struct nlattr *attr);
extern uint16_t mnl_attr_get_payload_len(const struct nlattr *attr);
extern void *mnl_attr_get_payload(const struct nlattr *attr);
extern uint8_t mnl_attr_get_u8(const struct nlattr *attr);
extern uint16_t mnl_attr_get_u16(const struct nlattr *attr);
extern uint32_t mnl_attr_get_u32(const struct nlattr *attr);
extern uint64_t mnl_attr_get_u64(const struct nlattr *attr);
extern const char *mnl_attr_get_str(const struct nlattr *attr);

/* TLV attribute putters */
extern void mnl_attr_put(struct nlmsghdr *nlh, int type, size_t len, const void *data);
extern void mnl_attr_put_u8(struct nlmsghdr *nlh, int type, uint8_t data);
extern void mnl_attr_put_u16(struct nlmsghdr *nlh, int type, uint16_t data);
extern void mnl_attr_put_u32(struct nlmsghdr *nlh, int type, uint32_t data);
extern void mnl_attr_put_u64(struct nlmsghdr *nlh, int type, uint64_t data);
extern void mnl_attr_put_str(struct nlmsghdr *nlh, int type, const void *data);
extern void mnl_attr_put_str_null(struct nlmsghdr *nlh, int type, const void *data);

/* TLV validation */
extern int mnl_attr_type_valid(const struct nlattr *attr, int maxtype);

enum mnl_attr_data_type {
	MNL_TYPE_UNSPEC,
	MNL_TYPE_U8,
	MNL_TYPE_U16,
	MNL_TYPE_U32,
	MNL_TYPE_U64,
	MNL_TYPE_STRING,
	MNL_TYPE_FLAG,
	MNL_TYPE_MSECS,
	MNL_TYPE_NESTED,
	MNL_TYPE_NESTED_COMPAT,
	MNL_TYPE_NUL_STRING,
	MNL_TYPE_BINARY,
	MNL_TYPE_MAX,
};

extern int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type);
extern int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, int minlen);

/* TLV iterators */
extern int mnl_attr_ok(const struct nlattr *attr, int len);
extern struct nlattr *mnl_attr_next(const struct nlattr *attr, int *len);

#define mnl_attr_for_each(attr, nlh, offset)			\
	int __len__ = mnl_nlmsg_get_payload_len(nlh);		\
	for (attr = mnl_nlmsg_get_payload_offset(nlh, offset);	\
	     mnl_attr_ok(attr, __len__);			\
	     attr = mnl_attr_next(attr, &(__len__)))

#define mnl_attr_for_each_nested(attr, nest)			\
	int __len__ = mnl_attr_get_len(nest);			\
	for (attr = mnl_attr_get_payload(nest);			\
	     mnl_attr_ok(attr, __len__);			\
	     attr = mnl_attr_next(attr, &(__len__)))

/* TLV callback-based attribute parsers */
typedef int (*mnl_attr_cb_t)(const struct nlattr *attr, void *data);

extern int mnl_attr_parse(const struct nlmsghdr *nlh, int offset, mnl_attr_cb_t cb, void *data);
extern int mnl_attr_parse_nested(const struct nlattr *attr, mnl_attr_cb_t cb, void *data);

/*
 * callback API
 */
#define MNL_CB_ERROR		-1
#define MNL_CB_STOP		 0
#define MNL_CB_OK		 1

typedef int (*mnl_cb_t)(const struct nlmsghdr *nlh, void *data);

extern int mnl_cb_run(const char *buf, int numbytes, unsigned int seq,
		      unsigned int portid, mnl_cb_t cb_data, void *data);

extern int mnl_cb_run2(const char *buf, int numbytes, unsigned int seq,
		       unsigned int portid, mnl_cb_t cb_data, void *data,
		       mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len);

/*
 * other declarations
 */

#ifndef SOL_NETLINK
#define SOL_NETLINK	270
#endif

#endif