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