xref: /aosp_15_r20/external/libnl/lib/genl/genl.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker  * Copyright (c) 2003-2012 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker  */
5*4dc78e53SAndroid Build Coastguard Worker 
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker  * @defgroup genl Generic Netlink Library (libnl-genl)
8*4dc78e53SAndroid Build Coastguard Worker  *
9*4dc78e53SAndroid Build Coastguard Worker  * @{
10*4dc78e53SAndroid Build Coastguard Worker  */
11*4dc78e53SAndroid Build Coastguard Worker 
12*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
13*4dc78e53SAndroid Build Coastguard Worker 
14*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
15*4dc78e53SAndroid Build Coastguard Worker #include <netlink/genl/genl.h>
16*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
17*4dc78e53SAndroid Build Coastguard Worker 
18*4dc78e53SAndroid Build Coastguard Worker #include "nl-genl.h"
19*4dc78e53SAndroid Build Coastguard Worker #include "nl-aux-core/nl-core.h"
20*4dc78e53SAndroid Build Coastguard Worker 
21*4dc78e53SAndroid Build Coastguard Worker /**
22*4dc78e53SAndroid Build Coastguard Worker  * @name Generic Netlink Socket
23*4dc78e53SAndroid Build Coastguard Worker  * @{
24*4dc78e53SAndroid Build Coastguard Worker  */
25*4dc78e53SAndroid Build Coastguard Worker 
26*4dc78e53SAndroid Build Coastguard Worker /**
27*4dc78e53SAndroid Build Coastguard Worker  * Connect a Generic Netlink socket
28*4dc78e53SAndroid Build Coastguard Worker  * @arg sk		Unconnected Netlink socket
29*4dc78e53SAndroid Build Coastguard Worker  *
30*4dc78e53SAndroid Build Coastguard Worker  * This function expects a struct nl_socket object previously allocated via
31*4dc78e53SAndroid Build Coastguard Worker  * nl_socket_alloc(). It calls nl_connect() to create the local socket file
32*4dc78e53SAndroid Build Coastguard Worker  * descriptor and binds the socket to the \c NETLINK_GENERIC Netlink protocol.
33*4dc78e53SAndroid Build Coastguard Worker  *
34*4dc78e53SAndroid Build Coastguard Worker  * Using this function is equivalent to:
35*4dc78e53SAndroid Build Coastguard Worker  * @code
36*4dc78e53SAndroid Build Coastguard Worker  * nl_connect(sk, NETLINK_GENERIC);
37*4dc78e53SAndroid Build Coastguard Worker  * @endcode
38*4dc78e53SAndroid Build Coastguard Worker  *
39*4dc78e53SAndroid Build Coastguard Worker  * @see nl_connect()
40*4dc78e53SAndroid Build Coastguard Worker  *
41*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
42*4dc78e53SAndroid Build Coastguard Worker  */
genl_connect(struct nl_sock * sk)43*4dc78e53SAndroid Build Coastguard Worker int genl_connect(struct nl_sock *sk)
44*4dc78e53SAndroid Build Coastguard Worker {
45*4dc78e53SAndroid Build Coastguard Worker 	return nl_connect(sk, NETLINK_GENERIC);
46*4dc78e53SAndroid Build Coastguard Worker }
47*4dc78e53SAndroid Build Coastguard Worker 
48*4dc78e53SAndroid Build Coastguard Worker /** @} */
49*4dc78e53SAndroid Build Coastguard Worker 
50*4dc78e53SAndroid Build Coastguard Worker /**
51*4dc78e53SAndroid Build Coastguard Worker  * @name Sending Data
52*4dc78e53SAndroid Build Coastguard Worker  * @{
53*4dc78e53SAndroid Build Coastguard Worker  */
54*4dc78e53SAndroid Build Coastguard Worker 
55*4dc78e53SAndroid Build Coastguard Worker /**
56*4dc78e53SAndroid Build Coastguard Worker  * Send a Generic Netlink message consisting only of a header
57*4dc78e53SAndroid Build Coastguard Worker  * @arg sk		Generic Netlink socket
58*4dc78e53SAndroid Build Coastguard Worker  * @arg family		Numeric family identifier
59*4dc78e53SAndroid Build Coastguard Worker  * @arg cmd		Numeric command identifier
60*4dc78e53SAndroid Build Coastguard Worker  * @arg version		Interface version
61*4dc78e53SAndroid Build Coastguard Worker  * @arg flags		Additional Netlink message flags (optional)
62*4dc78e53SAndroid Build Coastguard Worker  *
63*4dc78e53SAndroid Build Coastguard Worker  * This function is a shortcut for sending a Generic Netlink message without
64*4dc78e53SAndroid Build Coastguard Worker  * any message payload. The message will only consist of the Netlink and
65*4dc78e53SAndroid Build Coastguard Worker  * Generic Netlink headers. The header is constructed based on the specified
66*4dc78e53SAndroid Build Coastguard Worker  * parameters and passed on to nl_send_simple() to send it on the specified
67*4dc78e53SAndroid Build Coastguard Worker  * socket.
68*4dc78e53SAndroid Build Coastguard Worker  *
69*4dc78e53SAndroid Build Coastguard Worker  * @par Example:
70*4dc78e53SAndroid Build Coastguard Worker  * @code
71*4dc78e53SAndroid Build Coastguard Worker  * #include <netlink/genl/genl.h>
72*4dc78e53SAndroid Build Coastguard Worker  * #include <linux/genetlink.h>
73*4dc78e53SAndroid Build Coastguard Worker  *
74*4dc78e53SAndroid Build Coastguard Worker  * err = genl_send_simple(sk, GENL_ID_CTRL, CTRL_CMD_GETFAMILY, CTRL_VERSION,
75*4dc78e53SAndroid Build Coastguard Worker  *                        NLM_F_DUMP);
76*4dc78e53SAndroid Build Coastguard Worker  * @endcode
77*4dc78e53SAndroid Build Coastguard Worker  *
78*4dc78e53SAndroid Build Coastguard Worker  * @see nl_send_simple()
79*4dc78e53SAndroid Build Coastguard Worker  *
80*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code. Due to a bug, this function
81*4dc78e53SAndroid Build Coastguard Worker  * returns the number of bytes sent. Treat any non-negative number as success.
82*4dc78e53SAndroid Build Coastguard Worker  */
genl_send_simple(struct nl_sock * sk,int family,int cmd,int version,int flags)83*4dc78e53SAndroid Build Coastguard Worker int genl_send_simple(struct nl_sock *sk, int family, int cmd,
84*4dc78e53SAndroid Build Coastguard Worker 		     int version, int flags)
85*4dc78e53SAndroid Build Coastguard Worker {
86*4dc78e53SAndroid Build Coastguard Worker 	struct genlmsghdr hdr = {
87*4dc78e53SAndroid Build Coastguard Worker 		.cmd = cmd,
88*4dc78e53SAndroid Build Coastguard Worker 		.version = version,
89*4dc78e53SAndroid Build Coastguard Worker 	};
90*4dc78e53SAndroid Build Coastguard Worker 
91*4dc78e53SAndroid Build Coastguard Worker 	return nl_send_simple(sk, family, flags, &hdr, sizeof(hdr));
92*4dc78e53SAndroid Build Coastguard Worker }
93*4dc78e53SAndroid Build Coastguard Worker 
94*4dc78e53SAndroid Build Coastguard Worker /** @} */
95*4dc78e53SAndroid Build Coastguard Worker 
96*4dc78e53SAndroid Build Coastguard Worker /**
97*4dc78e53SAndroid Build Coastguard Worker  * @name Message Parsing
98*4dc78e53SAndroid Build Coastguard Worker  * @{
99*4dc78e53SAndroid Build Coastguard Worker  */
100*4dc78e53SAndroid Build Coastguard Worker 
101*4dc78e53SAndroid Build Coastguard Worker /**
102*4dc78e53SAndroid Build Coastguard Worker  * Validate Generic Netlink message headers
103*4dc78e53SAndroid Build Coastguard Worker  * @arg nlh		Pointer to Netlink message header
104*4dc78e53SAndroid Build Coastguard Worker  * @arg hdrlen		Length of user header
105*4dc78e53SAndroid Build Coastguard Worker  *
106*4dc78e53SAndroid Build Coastguard Worker  * Verifies the integrity of the Netlink and Generic Netlink headers by
107*4dc78e53SAndroid Build Coastguard Worker  * enforcing the following requirements:
108*4dc78e53SAndroid Build Coastguard Worker  *  - Valid Netlink message header (nlmsg_valid_hdr())
109*4dc78e53SAndroid Build Coastguard Worker  *  - Presence of a complete Generic Netlink header
110*4dc78e53SAndroid Build Coastguard Worker  *  - At least \c hdrlen bytes of payload included after the generic
111*4dc78e53SAndroid Build Coastguard Worker  *    netlink header.
112*4dc78e53SAndroid Build Coastguard Worker  *
113*4dc78e53SAndroid Build Coastguard Worker  * @return A positive integer (true) if the headers are valid or
114*4dc78e53SAndroid Build Coastguard Worker  *         0 (false) if not.
115*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_valid_hdr(struct nlmsghdr * nlh,int hdrlen)116*4dc78e53SAndroid Build Coastguard Worker int genlmsg_valid_hdr(struct nlmsghdr *nlh, int hdrlen)
117*4dc78e53SAndroid Build Coastguard Worker {
118*4dc78e53SAndroid Build Coastguard Worker 	struct genlmsghdr *ghdr;
119*4dc78e53SAndroid Build Coastguard Worker 	int l;
120*4dc78e53SAndroid Build Coastguard Worker 
121*4dc78e53SAndroid Build Coastguard Worker 	if (!nlmsg_valid_hdr(nlh, GENL_HDRLEN))
122*4dc78e53SAndroid Build Coastguard Worker 		return 0;
123*4dc78e53SAndroid Build Coastguard Worker 
124*4dc78e53SAndroid Build Coastguard Worker 	ghdr = nlmsg_data(nlh);
125*4dc78e53SAndroid Build Coastguard Worker 	l = genlmsg_len(ghdr);
126*4dc78e53SAndroid Build Coastguard Worker 	if (l < 0 || ((unsigned)l) < NLMSG_ALIGN(hdrlen))
127*4dc78e53SAndroid Build Coastguard Worker 		return 0;
128*4dc78e53SAndroid Build Coastguard Worker 
129*4dc78e53SAndroid Build Coastguard Worker 	return 1;
130*4dc78e53SAndroid Build Coastguard Worker }
131*4dc78e53SAndroid Build Coastguard Worker 
132*4dc78e53SAndroid Build Coastguard Worker /**
133*4dc78e53SAndroid Build Coastguard Worker  * Validate Generic Netlink message including attributes
134*4dc78e53SAndroid Build Coastguard Worker  * @arg nlh		Pointer to Netlink message header
135*4dc78e53SAndroid Build Coastguard Worker  * @arg hdrlen		Length of user header
136*4dc78e53SAndroid Build Coastguard Worker  * @arg maxtype		Maximum attribtue id expected
137*4dc78e53SAndroid Build Coastguard Worker  * @arg policy		Attribute validation policy
138*4dc78e53SAndroid Build Coastguard Worker  *
139*4dc78e53SAndroid Build Coastguard Worker  * Verifies the validity of the Netlink and Generic Netlink headers using
140*4dc78e53SAndroid Build Coastguard Worker  * genlmsg_valid_hdr() and calls nla_validate() on the message payload to
141*4dc78e53SAndroid Build Coastguard Worker  * verify the integrity of eventual attributes.
142*4dc78e53SAndroid Build Coastguard Worker  *
143*4dc78e53SAndroid Build Coastguard Worker  * @note You may call genlmsg_parse() directly to perform validation and
144*4dc78e53SAndroid Build Coastguard Worker  *       parsing in a single step.
145*4dc78e53SAndroid Build Coastguard Worker  *
146*4dc78e53SAndroid Build Coastguard Worker  * @see genlmsg_valid_hdr()
147*4dc78e53SAndroid Build Coastguard Worker  * @see nla_validate()
148*4dc78e53SAndroid Build Coastguard Worker  * @see genlmsg_parse()
149*4dc78e53SAndroid Build Coastguard Worker  *
150*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
151*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_validate(struct nlmsghdr * nlh,int hdrlen,int maxtype,const struct nla_policy * policy)152*4dc78e53SAndroid Build Coastguard Worker int genlmsg_validate(struct nlmsghdr *nlh, int hdrlen, int maxtype,
153*4dc78e53SAndroid Build Coastguard Worker 		     const struct nla_policy *policy)
154*4dc78e53SAndroid Build Coastguard Worker {
155*4dc78e53SAndroid Build Coastguard Worker 	struct genlmsghdr *ghdr;
156*4dc78e53SAndroid Build Coastguard Worker 
157*4dc78e53SAndroid Build Coastguard Worker 	if (!genlmsg_valid_hdr(nlh, hdrlen))
158*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MSG_TOOSHORT;
159*4dc78e53SAndroid Build Coastguard Worker 
160*4dc78e53SAndroid Build Coastguard Worker 	ghdr = nlmsg_data(nlh);
161*4dc78e53SAndroid Build Coastguard Worker 	return nla_validate(genlmsg_attrdata(ghdr, hdrlen),
162*4dc78e53SAndroid Build Coastguard Worker 			    genlmsg_attrlen(ghdr, hdrlen), maxtype, policy);
163*4dc78e53SAndroid Build Coastguard Worker }
164*4dc78e53SAndroid Build Coastguard Worker 
165*4dc78e53SAndroid Build Coastguard Worker /**
166*4dc78e53SAndroid Build Coastguard Worker  * Parse Generic Netlink message including attributes
167*4dc78e53SAndroid Build Coastguard Worker  * @arg nlh		Pointer to Netlink message header
168*4dc78e53SAndroid Build Coastguard Worker  * @arg hdrlen		Length of user header
169*4dc78e53SAndroid Build Coastguard Worker  * @arg tb		Array to store parsed attributes
170*4dc78e53SAndroid Build Coastguard Worker  * @arg maxtype		Maximum attribute id expected
171*4dc78e53SAndroid Build Coastguard Worker  * @arg policy		Attribute validation policy
172*4dc78e53SAndroid Build Coastguard Worker  *
173*4dc78e53SAndroid Build Coastguard Worker  * Verifies the validity of the Netlink and Generic Netlink headers using
174*4dc78e53SAndroid Build Coastguard Worker  * genlmsg_valid_hdr() and calls nla_parse() on the message payload to
175*4dc78e53SAndroid Build Coastguard Worker  * parse eventual attributes.
176*4dc78e53SAndroid Build Coastguard Worker  *
177*4dc78e53SAndroid Build Coastguard Worker  * @par Example:
178*4dc78e53SAndroid Build Coastguard Worker  * @code
179*4dc78e53SAndroid Build Coastguard Worker  * struct nlattr *attrs[MY_TYPE_MAX+1];
180*4dc78e53SAndroid Build Coastguard Worker  *
181*4dc78e53SAndroid Build Coastguard Worker  * if ((err = genlmsg_parse(nlmsg_hdr(msg), sizeof(struct my_hdr), attrs,
182*4dc78e53SAndroid Build Coastguard Worker  *                          MY_TYPE_MAX, attr_policy)) < 0)
183*4dc78e53SAndroid Build Coastguard Worker  * 	// ERROR
184*4dc78e53SAndroid Build Coastguard Worker  * @endcode
185*4dc78e53SAndroid Build Coastguard Worker  *
186*4dc78e53SAndroid Build Coastguard Worker  * @see genlmsg_valid_hdr()
187*4dc78e53SAndroid Build Coastguard Worker  * @see genlmsg_validate()
188*4dc78e53SAndroid Build Coastguard Worker  * @see nla_parse()
189*4dc78e53SAndroid Build Coastguard Worker  *
190*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
191*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_parse(struct nlmsghdr * nlh,int hdrlen,struct nlattr * tb[],int maxtype,const struct nla_policy * policy)192*4dc78e53SAndroid Build Coastguard Worker int genlmsg_parse(struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[],
193*4dc78e53SAndroid Build Coastguard Worker 		  int maxtype, const struct nla_policy *policy)
194*4dc78e53SAndroid Build Coastguard Worker {
195*4dc78e53SAndroid Build Coastguard Worker 	struct genlmsghdr *ghdr;
196*4dc78e53SAndroid Build Coastguard Worker 
197*4dc78e53SAndroid Build Coastguard Worker 	if (!genlmsg_valid_hdr(nlh, hdrlen))
198*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MSG_TOOSHORT;
199*4dc78e53SAndroid Build Coastguard Worker 
200*4dc78e53SAndroid Build Coastguard Worker 	ghdr = nlmsg_data(nlh);
201*4dc78e53SAndroid Build Coastguard Worker 	return nla_parse(tb, maxtype, genlmsg_attrdata(ghdr, hdrlen),
202*4dc78e53SAndroid Build Coastguard Worker 			 genlmsg_attrlen(ghdr, hdrlen), policy);
203*4dc78e53SAndroid Build Coastguard Worker }
204*4dc78e53SAndroid Build Coastguard Worker 
205*4dc78e53SAndroid Build Coastguard Worker /**
206*4dc78e53SAndroid Build Coastguard Worker  * Return pointer to Generic Netlink header
207*4dc78e53SAndroid Build Coastguard Worker  * @arg nlh		Netlink message header
208*4dc78e53SAndroid Build Coastguard Worker  *
209*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to Generic Netlink message header
210*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_hdr(struct nlmsghdr * nlh)211*4dc78e53SAndroid Build Coastguard Worker struct genlmsghdr *genlmsg_hdr(struct nlmsghdr *nlh)
212*4dc78e53SAndroid Build Coastguard Worker {
213*4dc78e53SAndroid Build Coastguard Worker 	return nlmsg_data(nlh);
214*4dc78e53SAndroid Build Coastguard Worker }
215*4dc78e53SAndroid Build Coastguard Worker 
216*4dc78e53SAndroid Build Coastguard Worker /**
217*4dc78e53SAndroid Build Coastguard Worker  * Return length of message payload including user header
218*4dc78e53SAndroid Build Coastguard Worker  * @arg gnlh		Generic Netlink message header
219*4dc78e53SAndroid Build Coastguard Worker  *
220*4dc78e53SAndroid Build Coastguard Worker  * @see genlmsg_data()
221*4dc78e53SAndroid Build Coastguard Worker  *
222*4dc78e53SAndroid Build Coastguard Worker  * @return Length of user payload including an eventual user header in
223*4dc78e53SAndroid Build Coastguard Worker  *         number of bytes.
224*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_len(const struct genlmsghdr * gnlh)225*4dc78e53SAndroid Build Coastguard Worker int genlmsg_len(const struct genlmsghdr *gnlh)
226*4dc78e53SAndroid Build Coastguard Worker {
227*4dc78e53SAndroid Build Coastguard Worker 	const struct nlmsghdr *nlh;
228*4dc78e53SAndroid Build Coastguard Worker 
229*4dc78e53SAndroid Build Coastguard Worker 	nlh = (const struct nlmsghdr *)((const unsigned char *) gnlh - NLMSG_HDRLEN);
230*4dc78e53SAndroid Build Coastguard Worker 	return (nlh->nlmsg_len - GENL_HDRLEN - NLMSG_HDRLEN);
231*4dc78e53SAndroid Build Coastguard Worker }
232*4dc78e53SAndroid Build Coastguard Worker 
233*4dc78e53SAndroid Build Coastguard Worker 
234*4dc78e53SAndroid Build Coastguard Worker /**
235*4dc78e53SAndroid Build Coastguard Worker  * Return pointer to user header
236*4dc78e53SAndroid Build Coastguard Worker  * @arg gnlh		Generic Netlink message header
237*4dc78e53SAndroid Build Coastguard Worker  *
238*4dc78e53SAndroid Build Coastguard Worker  * Calculates the pointer to the user header based on the pointer to
239*4dc78e53SAndroid Build Coastguard Worker  * the Generic Netlink message header.
240*4dc78e53SAndroid Build Coastguard Worker  *
241*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to the user header
242*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_user_hdr(const struct genlmsghdr * gnlh)243*4dc78e53SAndroid Build Coastguard Worker void *genlmsg_user_hdr(const struct genlmsghdr *gnlh)
244*4dc78e53SAndroid Build Coastguard Worker {
245*4dc78e53SAndroid Build Coastguard Worker 	return genlmsg_data(gnlh);
246*4dc78e53SAndroid Build Coastguard Worker }
247*4dc78e53SAndroid Build Coastguard Worker 
248*4dc78e53SAndroid Build Coastguard Worker /**
249*4dc78e53SAndroid Build Coastguard Worker  * Return pointer to user data
250*4dc78e53SAndroid Build Coastguard Worker  * @arg gnlh		Generic netlink message header
251*4dc78e53SAndroid Build Coastguard Worker  * @arg hdrlen		Length of user header
252*4dc78e53SAndroid Build Coastguard Worker  *
253*4dc78e53SAndroid Build Coastguard Worker  * Calculates the pointer to the user data based on the pointer to
254*4dc78e53SAndroid Build Coastguard Worker  * the Generic Netlink message header.
255*4dc78e53SAndroid Build Coastguard Worker  *
256*4dc78e53SAndroid Build Coastguard Worker  * @see genlmsg_user_datalen()
257*4dc78e53SAndroid Build Coastguard Worker  *
258*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to the user data
259*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_user_data(const struct genlmsghdr * gnlh,const int hdrlen)260*4dc78e53SAndroid Build Coastguard Worker void *genlmsg_user_data(const struct genlmsghdr *gnlh, const int hdrlen)
261*4dc78e53SAndroid Build Coastguard Worker {
262*4dc78e53SAndroid Build Coastguard Worker 	return (char *) genlmsg_user_hdr(gnlh) + NLMSG_ALIGN(hdrlen);
263*4dc78e53SAndroid Build Coastguard Worker }
264*4dc78e53SAndroid Build Coastguard Worker 
265*4dc78e53SAndroid Build Coastguard Worker /**
266*4dc78e53SAndroid Build Coastguard Worker  * Return length of user data
267*4dc78e53SAndroid Build Coastguard Worker  * @arg gnlh		Generic Netlink message header
268*4dc78e53SAndroid Build Coastguard Worker  * @arg hdrlen		Length of user header
269*4dc78e53SAndroid Build Coastguard Worker  *
270*4dc78e53SAndroid Build Coastguard Worker  * @see genlmsg_user_data()
271*4dc78e53SAndroid Build Coastguard Worker  *
272*4dc78e53SAndroid Build Coastguard Worker  * @return Length of user data in bytes
273*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_user_datalen(const struct genlmsghdr * gnlh,const int hdrlen)274*4dc78e53SAndroid Build Coastguard Worker int genlmsg_user_datalen(const struct genlmsghdr *gnlh, const int hdrlen)
275*4dc78e53SAndroid Build Coastguard Worker {
276*4dc78e53SAndroid Build Coastguard Worker 	return genlmsg_len(gnlh) - NLMSG_ALIGN(hdrlen);
277*4dc78e53SAndroid Build Coastguard Worker }
278*4dc78e53SAndroid Build Coastguard Worker 
279*4dc78e53SAndroid Build Coastguard Worker /**
280*4dc78e53SAndroid Build Coastguard Worker  * Return pointer to message attributes
281*4dc78e53SAndroid Build Coastguard Worker  * @arg gnlh		Generic Netlink message header
282*4dc78e53SAndroid Build Coastguard Worker  * @arg hdrlen		Length of user header
283*4dc78e53SAndroid Build Coastguard Worker  *
284*4dc78e53SAndroid Build Coastguard Worker  * @see genlmsg_attrlen()
285*4dc78e53SAndroid Build Coastguard Worker  *
286*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to the start of the message's attributes section.
287*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_attrdata(const struct genlmsghdr * gnlh,int hdrlen)288*4dc78e53SAndroid Build Coastguard Worker struct nlattr *genlmsg_attrdata(const struct genlmsghdr *gnlh, int hdrlen)
289*4dc78e53SAndroid Build Coastguard Worker {
290*4dc78e53SAndroid Build Coastguard Worker 	return genlmsg_user_data(gnlh, hdrlen);
291*4dc78e53SAndroid Build Coastguard Worker }
292*4dc78e53SAndroid Build Coastguard Worker 
293*4dc78e53SAndroid Build Coastguard Worker /**
294*4dc78e53SAndroid Build Coastguard Worker  * Return length of message attributes
295*4dc78e53SAndroid Build Coastguard Worker  * @arg gnlh		Generic Netlink message header
296*4dc78e53SAndroid Build Coastguard Worker  * @arg hdrlen		Length of user header
297*4dc78e53SAndroid Build Coastguard Worker  *
298*4dc78e53SAndroid Build Coastguard Worker  * @see genlmsg_attrdata()
299*4dc78e53SAndroid Build Coastguard Worker  *
300*4dc78e53SAndroid Build Coastguard Worker  * @return Length of the message section containing attributes in number
301*4dc78e53SAndroid Build Coastguard Worker  *         of bytes.
302*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_attrlen(const struct genlmsghdr * gnlh,int hdrlen)303*4dc78e53SAndroid Build Coastguard Worker int genlmsg_attrlen(const struct genlmsghdr *gnlh, int hdrlen)
304*4dc78e53SAndroid Build Coastguard Worker {
305*4dc78e53SAndroid Build Coastguard Worker 	return genlmsg_len(gnlh) - NLMSG_ALIGN(hdrlen);
306*4dc78e53SAndroid Build Coastguard Worker }
307*4dc78e53SAndroid Build Coastguard Worker 
308*4dc78e53SAndroid Build Coastguard Worker /** @} */
309*4dc78e53SAndroid Build Coastguard Worker 
310*4dc78e53SAndroid Build Coastguard Worker /**
311*4dc78e53SAndroid Build Coastguard Worker  * @name Message Construction
312*4dc78e53SAndroid Build Coastguard Worker  * @{
313*4dc78e53SAndroid Build Coastguard Worker  */
314*4dc78e53SAndroid Build Coastguard Worker 
315*4dc78e53SAndroid Build Coastguard Worker /**
316*4dc78e53SAndroid Build Coastguard Worker  * Add Generic Netlink headers to Netlink message
317*4dc78e53SAndroid Build Coastguard Worker  * @arg msg		Netlink message object
318*4dc78e53SAndroid Build Coastguard Worker  * @arg port		Netlink port or NL_AUTO_PORT
319*4dc78e53SAndroid Build Coastguard Worker  * @arg seq		Sequence number of message or NL_AUTO_SEQ
320*4dc78e53SAndroid Build Coastguard Worker  * @arg family		Numeric family identifier
321*4dc78e53SAndroid Build Coastguard Worker  * @arg hdrlen		Length of user header
322*4dc78e53SAndroid Build Coastguard Worker  * @arg flags		Additional Netlink message flags (optional)
323*4dc78e53SAndroid Build Coastguard Worker  * @arg cmd		Numeric command identifier
324*4dc78e53SAndroid Build Coastguard Worker  * @arg version		Interface version
325*4dc78e53SAndroid Build Coastguard Worker  *
326*4dc78e53SAndroid Build Coastguard Worker  * Calls nlmsg_put() on the specified message object to reserve space for
327*4dc78e53SAndroid Build Coastguard Worker  * the Netlink header, the Generic Netlink header, and a user header of
328*4dc78e53SAndroid Build Coastguard Worker  * specified length. Fills out the header fields with the specified
329*4dc78e53SAndroid Build Coastguard Worker  * parameters.
330*4dc78e53SAndroid Build Coastguard Worker  *
331*4dc78e53SAndroid Build Coastguard Worker  * @par Example:
332*4dc78e53SAndroid Build Coastguard Worker  * @code
333*4dc78e53SAndroid Build Coastguard Worker  * struct nl_msg *msg;
334*4dc78e53SAndroid Build Coastguard Worker  * struct my_hdr *user_hdr;
335*4dc78e53SAndroid Build Coastguard Worker  *
336*4dc78e53SAndroid Build Coastguard Worker  * if (!(msg = nlmsg_alloc()))
337*4dc78e53SAndroid Build Coastguard Worker  * 	// ERROR
338*4dc78e53SAndroid Build Coastguard Worker  *
339*4dc78e53SAndroid Build Coastguard Worker  * user_hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, family_id,
340*4dc78e53SAndroid Build Coastguard Worker  *                        sizeof(struct my_hdr), 0, MY_CMD_FOO, 0);
341*4dc78e53SAndroid Build Coastguard Worker  * if (!user_hdr)
342*4dc78e53SAndroid Build Coastguard Worker  * 	// ERROR
343*4dc78e53SAndroid Build Coastguard Worker  * @endcode
344*4dc78e53SAndroid Build Coastguard Worker  *
345*4dc78e53SAndroid Build Coastguard Worker  * @see nlmsg_put()
346*4dc78e53SAndroid Build Coastguard Worker  *
347*4dc78e53SAndroid Build Coastguard Worker  * Returns Pointer to user header or NULL if an error occurred.
348*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_put(struct nl_msg * msg,uint32_t port,uint32_t seq,int family,int hdrlen,int flags,uint8_t cmd,uint8_t version)349*4dc78e53SAndroid Build Coastguard Worker void *genlmsg_put(struct nl_msg *msg, uint32_t port, uint32_t seq, int family,
350*4dc78e53SAndroid Build Coastguard Worker 		  int hdrlen, int flags, uint8_t cmd, uint8_t version)
351*4dc78e53SAndroid Build Coastguard Worker {
352*4dc78e53SAndroid Build Coastguard Worker 	struct nlmsghdr *nlh;
353*4dc78e53SAndroid Build Coastguard Worker 	struct genlmsghdr hdr = {
354*4dc78e53SAndroid Build Coastguard Worker 		.cmd = cmd,
355*4dc78e53SAndroid Build Coastguard Worker 		.version = version,
356*4dc78e53SAndroid Build Coastguard Worker 	};
357*4dc78e53SAndroid Build Coastguard Worker 
358*4dc78e53SAndroid Build Coastguard Worker 	nlh = nlmsg_put(msg, port, seq, family, GENL_HDRLEN + hdrlen, flags);
359*4dc78e53SAndroid Build Coastguard Worker 	if (nlh == NULL)
360*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
361*4dc78e53SAndroid Build Coastguard Worker 
362*4dc78e53SAndroid Build Coastguard Worker 	memcpy(nlmsg_data(nlh), &hdr, sizeof(hdr));
363*4dc78e53SAndroid Build Coastguard Worker 	NL_DBG(2, "msg %p: Added generic netlink header cmd=%d version=%d\n",
364*4dc78e53SAndroid Build Coastguard Worker 	       msg, cmd, version);
365*4dc78e53SAndroid Build Coastguard Worker 
366*4dc78e53SAndroid Build Coastguard Worker 	return (char *) nlmsg_data(nlh) + GENL_HDRLEN;
367*4dc78e53SAndroid Build Coastguard Worker }
368*4dc78e53SAndroid Build Coastguard Worker 
369*4dc78e53SAndroid Build Coastguard Worker /** @} */
370*4dc78e53SAndroid Build Coastguard Worker 
371*4dc78e53SAndroid Build Coastguard Worker /**
372*4dc78e53SAndroid Build Coastguard Worker  * @name Deprecated
373*4dc78e53SAndroid Build Coastguard Worker  * @{
374*4dc78e53SAndroid Build Coastguard Worker  */
375*4dc78e53SAndroid Build Coastguard Worker 
376*4dc78e53SAndroid Build Coastguard Worker /**
377*4dc78e53SAndroid Build Coastguard Worker  * Return pointer to message payload
378*4dc78e53SAndroid Build Coastguard Worker  * @arg gnlh		Generic Netlink message header
379*4dc78e53SAndroid Build Coastguard Worker  *
380*4dc78e53SAndroid Build Coastguard Worker  * @deprecated This function has been deprecated due to inability to specify
381*4dc78e53SAndroid Build Coastguard Worker  *             the length of the user header. Use genlmsg_user_hdr()
382*4dc78e53SAndroid Build Coastguard Worker  *             respectively genlmsg_user_data().
383*4dc78e53SAndroid Build Coastguard Worker  *
384*4dc78e53SAndroid Build Coastguard Worker  * @return Pointer to payload section
385*4dc78e53SAndroid Build Coastguard Worker  */
genlmsg_data(const struct genlmsghdr * gnlh)386*4dc78e53SAndroid Build Coastguard Worker void *genlmsg_data(const struct genlmsghdr *gnlh)
387*4dc78e53SAndroid Build Coastguard Worker {
388*4dc78e53SAndroid Build Coastguard Worker 	return ((unsigned char *) gnlh + GENL_HDRLEN);
389*4dc78e53SAndroid Build Coastguard Worker }
390*4dc78e53SAndroid Build Coastguard Worker 
391*4dc78e53SAndroid Build Coastguard Worker /** @} */
392*4dc78e53SAndroid Build Coastguard Worker /** @} */
393