libnl 1.1.4
nfnl.c
1/*
2 * lib/netfilter/nfnl.c Netfilter Netlink
3 *
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
7 * of the License.
8 *
9 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
10 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
11 * Copyright (c) 2007 Secure Computing Corporation
12 */
13
14/**
15 * @ingroup nlfam
16 * @defgroup nfnl Netfilter Netlink
17 *
18 * @par Message Format
19 * @code
20 * <------- NLMSG_ALIGN(hlen) ------> <---- NLMSG_ALIGN(len) --->
21 * +----------------------------+- - -+- - - - - - - - - - -+- - -+
22 * | Header | Pad | Payload | Pad |
23 * | struct nlmsghdr | | | |
24 * +----------------------------+- - -+- - - - - - - - - - -+- - -+
25 * @endcode
26 * @code
27 * <-------- NFNL_HDRLEN --------->
28 * +--------------------------+- - -+------------+
29 * | Netfilter Netlink Header | Pad | Attributes |
30 * | struct nfgenmsg | | |
31 * +--------------------------+- - -+------------+
32 * nfnlmsg_attrdata(nfg, hdrlen)-----^
33 * @endcode
34 *
35 * @par 1) Creating a new netfilter netlink message
36 * @code
37 * struct nl_msg *msg;
38 *
39 * // Create a new empty netlink message
40 * msg = nlmsg_alloc();
41 *
42 * // Append the netlink and netfilter netlink message header
43 * hdr = nfnlmsg_put(msg, PID, SEQ, SUBSYS, TYPE, NLM_F_ECHO,
44 * FAMILY, RES_ID);
45 *
46 * // Append the attributes.
47 * nla_put_u32(msg, 1, 0x10);
48 *
49 * // Message is ready to be sent.
50 * nl_send_auto_complete(nl_handle, msg);
51 *
52 * // All done? Free the message.
53 * nlmsg_free(msg);
54 * @endcode
55 *
56 * @par 2) Sending of trivial messages
57 * @code
58 * // For trivial messages not requiring any subsys specific header or
59 * // attributes, nfnl_send_simple() may be used to send messages directly.
60 * nfnl_send_simple(nl_handle, SUBSYS, TYPE, 0, FAMILY, RES_ID);
61 * @endcode
62 * @{
63 */
64
65#include <netlink-local.h>
66#include <netlink/netlink.h>
67#include <netlink/netfilter/nfnl.h>
68
69/**
70 * @name Socket Creating
71 * @{
72 */
73
74/**
75 * Create and connect netfilter netlink socket.
76 * @arg handle Netlink handle.
77 *
78 * Creates a NETLINK_NETFILTER netlink socket, binds the socket and
79 * issues a connection attempt.
80 *
81 * @see nl_connect()
82 *
83 * @return 0 on success or a negative error code.
84 */
85int nfnl_connect(struct nl_handle *handle)
86{
87 return nl_connect(handle, NETLINK_NETFILTER);
88}
89
90/** @} */
91
92/**
93 * @name Sending
94 * @{
95 */
96
97/**
98 * Send trivial netfilter netlink message
99 * @arg handle Netlink handle.
100 * @arg subsys_id nfnetlink subsystem
101 * @arg type nfnetlink message type
102 * @arg flags message flags
103 * @arg family nfnetlink address family
104 * @arg res_id nfnetlink resource id
105 *
106 * @return Newly allocated netlink message or NULL.
107 */
108int nfnl_send_simple(struct nl_handle *handle, uint8_t subsys_id, uint8_t type,
109 int flags, uint8_t family, uint16_t res_id)
110{
111 struct nfgenmsg hdr = {
112 .nfgen_family = family,
113 .version = NFNETLINK_V0,
114 .res_id = htons(res_id),
115 };
116
117 return nl_send_simple(handle, NFNLMSG_TYPE(subsys_id, type), flags,
118 &hdr, sizeof(hdr));
119}
120
121/** @} */
122
123/**
124 * @name Message Parsing
125 * @{
126 */
127
128/**
129 * Get netfilter subsystem id from message
130 * @arg nlh netlink messsage header
131 */
132uint8_t nfnlmsg_subsys(struct nlmsghdr *nlh)
133{
134 return NFNL_SUBSYS_ID(nlh->nlmsg_type);
135}
136
137/**
138 * Get netfilter message type from message
139 * @arg nlh netlink messsage header
140 */
141uint8_t nfnlmsg_subtype(struct nlmsghdr *nlh)
142{
143 return NFNL_MSG_TYPE(nlh->nlmsg_type);
144}
145
146/**
147 * Get netfilter family from message
148 * @arg nlh netlink messsage header
149 */
150uint8_t nfnlmsg_family(struct nlmsghdr *nlh)
151{
152 struct nfgenmsg *nfg = nlmsg_data(nlh);
153
154 return nfg->nfgen_family;
155}
156
157/**
158 * Get netfilter resource id from message
159 * @arg nlh netlink messsage header
160 */
161uint16_t nfnlmsg_res_id(struct nlmsghdr *nlh)
162{
163 struct nfgenmsg *nfg = nlmsg_data(nlh);
164
165 return ntohs(nfg->res_id);
166}
167
168/** @} */
169
170/**
171 * @name Message Building
172 * @{
173 */
174
175static int nfnlmsg_append(struct nl_msg *msg, uint8_t family, uint16_t res_id)
176{
177 struct nfgenmsg *nfg;
178
179 nfg = nlmsg_reserve(msg, sizeof(*nfg), NLMSG_ALIGNTO);
180 if (nfg == NULL)
181 return nl_errno(ENOMEM);
182
183 nfg->nfgen_family = family;
184 nfg->version = NFNETLINK_V0;
185 nfg->res_id = htons(res_id);
186 NL_DBG(2, "msg %p: Added nfnetlink header family=%d res_id=%d\n",
187 msg, family, res_id);
188 return 0;
189}
190
191/**
192 * Allocate a new netfilter netlink message
193 * @arg subsys_id nfnetlink subsystem
194 * @arg type nfnetlink message type
195 * @arg flags message flags
196 * @arg family nfnetlink address family
197 * @arg res_id nfnetlink resource id
198 *
199 * @return Newly allocated netlink message or NULL.
200 */
201struct nl_msg *nfnlmsg_alloc_simple(uint8_t subsys_id, uint8_t type, int flags,
202 uint8_t family, uint16_t res_id)
203{
204 struct nl_msg *msg;
205
206 msg = nlmsg_alloc_simple(NFNLMSG_TYPE(subsys_id, type), flags);
207 if (msg == NULL)
208 return NULL;
209
210 if (nfnlmsg_append(msg, family, res_id) < 0)
211 goto nla_put_failure;
212
213 return msg;
214
215nla_put_failure:
216 nlmsg_free(msg);
217 return NULL;
218}
219
220/**
221 * Add netlink and netfilter netlink headers to netlink message
222 * @arg msg netlink message
223 * @arg pid netlink process id
224 * @arg seq sequence number of message
225 * @arg subsys_id nfnetlink subsystem
226 * @arg type nfnetlink message type
227 * @arg flags message flags
228 * @arg family nfnetlink address family
229 * @arg res_id nfnetlink resource id
230 */
231int nfnlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq,
232 uint8_t subsys_id, uint8_t type, int flags, uint8_t family,
233 uint16_t res_id)
234{
235 struct nlmsghdr *nlh;
236
237 nlh = nlmsg_put(msg, pid, seq, NFNLMSG_TYPE(subsys_id, type), 0, flags);
238 if (nlh == NULL)
239 return nl_get_errno();
240
241 return nfnlmsg_append(msg, family, res_id);
242}
243
244/** @} */
245
246/** @} */
struct nl_msg * nlmsg_alloc_simple(int nlmsgtype, int flags)
Allocate a new netlink message.
Definition: msg.c:448
void nlmsg_free(struct nl_msg *n)
Free a netlink message.
Definition: msg.c:656
void * nlmsg_data(const struct nlmsghdr *nlh)
head of message payload
Definition: msg.c:218
void * nlmsg_reserve(struct nl_msg *n, size_t len, int pad)
Reserve room for additional data in a netlink message.
Definition: msg.c:512
struct nlmsghdr * nlmsg_put(struct nl_msg *n, uint32_t pid, uint32_t seq, int type, int payload, int flags)
Add a netlink message header to a netlink message.
Definition: msg.c:610
int nfnl_send_simple(struct nl_handle *handle, uint8_t subsys_id, uint8_t type, int flags, uint8_t family, uint16_t res_id)
Send trivial netfilter netlink message.
Definition: nfnl.c:108
uint16_t nfnlmsg_res_id(struct nlmsghdr *nlh)
Get netfilter resource id from message.
Definition: nfnl.c:161
uint8_t nfnlmsg_subsys(struct nlmsghdr *nlh)
Get netfilter subsystem id from message.
Definition: nfnl.c:132
uint8_t nfnlmsg_family(struct nlmsghdr *nlh)
Get netfilter family from message.
Definition: nfnl.c:150
int nfnlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq, uint8_t subsys_id, uint8_t type, int flags, uint8_t family, uint16_t res_id)
Add netlink and netfilter netlink headers to netlink message.
Definition: nfnl.c:231
int nfnl_connect(struct nl_handle *handle)
Create and connect netfilter netlink socket.
Definition: nfnl.c:85
uint8_t nfnlmsg_subtype(struct nlmsghdr *nlh)
Get netfilter message type from message.
Definition: nfnl.c:141
struct nl_msg * nfnlmsg_alloc_simple(uint8_t subsys_id, uint8_t type, int flags, uint8_t family, uint16_t res_id)
Allocate a new netfilter netlink message.
Definition: nfnl.c:201
int nl_connect(struct nl_handle *handle, int protocol)
Create and connect netlink socket.
Definition: nl.c:191
int nl_send_simple(struct nl_handle *handle, int type, int flags, void *buf, size_t size)
Send simple netlink message using nl_send_auto_complete()
Definition: nl.c:410
Netlink message header.
uint16_t nlmsg_type
Message type (content type)