2 * lib/genl/genl.c Generic Netlink
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation version 2.1
9 * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
13 * @defgroup genl Generic Netlink
17 * <------- NLMSG_ALIGN(hlen) ------> <---- NLMSG_ALIGN(len) --->
18 * +----------------------------+- - -+- - - - - - - - - - -+- - -+
19 * | Header | Pad | Payload | Pad |
20 * | struct nlmsghdr | | | |
21 * +----------------------------+- - -+- - - - - - - - - - -+- - -+
24 * <-------- GENL_HDRLEN -------> <--- hdrlen -->
25 * <------- genlmsg_len(ghdr) ------>
26 * +------------------------+- - -+---------------+- - -+------------+
27 * | Generic Netlink Header | Pad | Family Header | Pad | Attributes |
28 * | struct genlmsghdr | | | | |
29 * +------------------------+- - -+---------------+- - -+------------+
30 * genlmsg_data(ghdr)--------------^ ^
31 * genlmsg_attrdata(ghdr, hdrlen)-------------------------
36 * #include <netlink/netlink.h>
37 * #include <netlink/genl/genl.h>
38 * #include <netlink/genl/ctrl.h>
40 * struct nl_sock *sock;
44 * // Allocate a new netlink socket
45 * sock = nl_socket_alloc();
47 * // Connect to generic netlink socket on kernel side
50 * // Ask kernel to resolve family name to family id
51 * family = genl_ctrl_resolve(sock, "generic_netlink_family_name");
53 * // Construct a generic netlink by allocating a new message, fill in
54 * // the header and append a simple integer attribute.
55 * msg = nlmsg_alloc();
56 * genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_ECHO,
57 * CMD_FOO_GET, FOO_VERSION);
58 * nla_put_u32(msg, ATTR_FOO, 123);
60 * // Send message over netlink socket
61 * nl_send_auto_complete(sock, msg);
66 * // Prepare socket to receive the answer by specifying the callback
67 * // function to be called for valid messages.
68 * nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, parse_cb, NULL);
70 * // Wait for the answer and receive it
71 * nl_recvmsgs_default(sock);
73 * static int parse_cb(struct nl_msg *msg, void *arg)
75 * struct nlmsghdr *nlh = nlmsg_hdr(msg);
76 * struct nlattr *attrs[ATTR_MAX+1];
78 * // Validate message and parse attributes
79 * genlmsg_parse(nlh, 0, attrs, ATTR_MAX, policy);
81 * if (attrs[ATTR_FOO]) {
82 * uint32_t value = nla_get_u32(attrs[ATTR_FOO]);
92 #include <netlink-generic.h>
93 #include <netlink/netlink.h>
94 #include <netlink/genl/genl.h>
95 #include <netlink/utils.h>
98 * @name Socket Creating
102 int genl_connect(struct nl_sock
*sk
)
104 return nl_connect(sk
, NETLINK_GENERIC
);
115 * Send trivial generic netlink message
116 * @arg sk Netlink socket.
117 * @arg family Generic netlink family
119 * @arg version Version
120 * @arg flags Additional netlink message flags.
122 * Fills out a routing netlink request message and sends it out
123 * using nl_send_simple().
125 * @return 0 on success or a negative error code.
127 int genl_send_simple(struct nl_sock
*sk
, int family
, int cmd
,
128 int version
, int flags
)
130 struct genlmsghdr hdr
= {
135 return nl_send_simple(sk
, family
, flags
, &hdr
, sizeof(hdr
));
142 * @name Message Parsing
146 int genlmsg_valid_hdr(struct nlmsghdr
*nlh
, int hdrlen
)
148 struct genlmsghdr
*ghdr
;
150 if (!nlmsg_valid_hdr(nlh
, GENL_HDRLEN
))
153 ghdr
= nlmsg_data(nlh
);
154 if (genlmsg_len(ghdr
) < NLMSG_ALIGN(hdrlen
))
160 int genlmsg_validate(struct nlmsghdr
*nlh
, int hdrlen
, int maxtype
,
161 struct nla_policy
*policy
)
163 struct genlmsghdr
*ghdr
;
165 if (!genlmsg_valid_hdr(nlh
, hdrlen
))
166 return -NLE_MSG_TOOSHORT
;
168 ghdr
= nlmsg_data(nlh
);
169 return nla_validate(genlmsg_attrdata(ghdr
, hdrlen
),
170 genlmsg_attrlen(ghdr
, hdrlen
), maxtype
, policy
);
173 int genlmsg_parse(struct nlmsghdr
*nlh
, int hdrlen
, struct nlattr
*tb
[],
174 int maxtype
, struct nla_policy
*policy
)
176 struct genlmsghdr
*ghdr
;
178 if (!genlmsg_valid_hdr(nlh
, hdrlen
))
179 return -NLE_MSG_TOOSHORT
;
181 ghdr
= nlmsg_data(nlh
);
182 return nla_parse(tb
, maxtype
, genlmsg_attrdata(ghdr
, hdrlen
),
183 genlmsg_attrlen(ghdr
, hdrlen
), policy
);
187 * Get head of message payload
188 * @arg gnlh genetlink messsage header
190 void *genlmsg_data(const struct genlmsghdr
*gnlh
)
192 return ((unsigned char *) gnlh
+ GENL_HDRLEN
);
196 * Get lenght of message payload
197 * @arg gnlh genetlink message header
199 int genlmsg_len(const struct genlmsghdr
*gnlh
)
201 struct nlmsghdr
*nlh
= (struct nlmsghdr
*)((unsigned char *)gnlh
-
203 return (nlh
->nlmsg_len
- GENL_HDRLEN
- NLMSG_HDRLEN
);
207 * Get head of attribute data
208 * @arg gnlh generic netlink message header
209 * @arg hdrlen length of family specific header
211 struct nlattr
*genlmsg_attrdata(const struct genlmsghdr
*gnlh
, int hdrlen
)
213 return genlmsg_data(gnlh
) + NLMSG_ALIGN(hdrlen
);
217 * Get length of attribute data
218 * @arg gnlh generic netlink message header
219 * @arg hdrlen length of family specific header
221 int genlmsg_attrlen(const struct genlmsghdr
*gnlh
, int hdrlen
)
223 return genlmsg_len(gnlh
) - NLMSG_ALIGN(hdrlen
);
229 * @name Message Building
234 * Add generic netlink header to netlink message
235 * @arg msg netlink message
236 * @arg pid netlink process id or NL_AUTO_PID
237 * @arg seq sequence number of message or NL_AUTO_SEQ
238 * @arg family generic netlink family
239 * @arg hdrlen length of user specific header
240 * @arg flags message flags
241 * @arg cmd generic netlink command
242 * @arg version protocol version
244 * Returns pointer to user specific header.
246 void *genlmsg_put(struct nl_msg
*msg
, uint32_t pid
, uint32_t seq
, int family
,
247 int hdrlen
, int flags
, uint8_t cmd
, uint8_t version
)
249 struct nlmsghdr
*nlh
;
250 struct genlmsghdr hdr
= {
255 nlh
= nlmsg_put(msg
, pid
, seq
, family
, GENL_HDRLEN
+ hdrlen
, flags
);
259 memcpy(nlmsg_data(nlh
), &hdr
, sizeof(hdr
));
260 NL_DBG(2, "msg %p: Added generic netlink header cmd=%d version=%d\n",
263 return nlmsg_data(nlh
) + GENL_HDRLEN
;
This page took 0.070301 seconds and 5 git commands to generate.