2 * lib/netfilter/nfnl.c Netfilter 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>
10 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
11 * Copyright (c) 2007 Secure Computing Corporation
15 * @defgroup nfnl Netfilter Netlink
19 * <------- NLMSG_ALIGN(hlen) ------> <---- NLMSG_ALIGN(len) --->
20 * +----------------------------+- - -+- - - - - - - - - - -+- - -+
21 * | Header | Pad | Payload | Pad |
22 * | struct nlmsghdr | | | |
23 * +----------------------------+- - -+- - - - - - - - - - -+- - -+
26 * <-------- NFNL_HDRLEN --------->
27 * +--------------------------+- - -+------------+
28 * | Netfilter Netlink Header | Pad | Attributes |
29 * | struct nfgenmsg | | |
30 * +--------------------------+- - -+------------+
31 * nfnlmsg_attrdata(nfg, hdrlen)-----^
34 * @par 1) Creating a new netfilter netlink message
38 * // Create a new empty netlink message
39 * msg = nlmsg_alloc();
41 * // Append the netlink and netfilter netlink message header
42 * hdr = nfnlmsg_put(msg, PID, SEQ, SUBSYS, TYPE, NLM_F_ECHO,
45 * // Append the attributes.
46 * nla_put_u32(msg, 1, 0x10);
48 * // Message is ready to be sent.
49 * nl_send_auto_complete(sk, msg);
51 * // All done? Free the message.
55 * @par 2) Sending of trivial messages
57 * // For trivial messages not requiring any subsys specific header or
58 * // attributes, nfnl_send_simple() may be used to send messages directly.
59 * nfnl_send_simple(sk, SUBSYS, TYPE, 0, FAMILY, RES_ID);
64 #include <netlink-local.h>
65 #include <netlink/netlink.h>
66 #include <netlink/netfilter/nfnl.h>
69 * @name Socket Creating
74 * Create and connect netfilter netlink socket.
75 * @arg sk Netlink socket.
77 * Creates a NETLINK_NETFILTER netlink socket, binds the socket and
78 * issues a connection attempt.
82 * @return 0 on success or a negative error code.
84 int nfnl_connect(struct nl_sock *sk)
86 return nl_connect(sk, NETLINK_NETFILTER);
97 * Send trivial netfilter netlink message
98 * @arg sk Netlink socket.
99 * @arg subsys_id nfnetlink subsystem
100 * @arg type nfnetlink message type
101 * @arg flags message flags
102 * @arg family nfnetlink address family
103 * @arg res_id nfnetlink resource id
105 * @return Newly allocated netlink message or NULL.
107 int nfnl_send_simple(struct nl_sock *sk, uint8_t subsys_id, uint8_t type,
108 int flags, uint8_t family, uint16_t res_id)
110 struct nfgenmsg hdr = {
111 .nfgen_family = family,
112 .version = NFNETLINK_V0,
113 .res_id = htons(res_id),
116 return nl_send_simple(sk, NFNLMSG_TYPE(subsys_id, type), flags,
123 * @name Message Parsing
128 * Get netfilter subsystem id from message
129 * @arg nlh netlink messsage header
131 uint8_t nfnlmsg_subsys(struct nlmsghdr *nlh)
133 return NFNL_SUBSYS_ID(nlh->nlmsg_type);
137 * Get netfilter message type from message
138 * @arg nlh netlink messsage header
140 uint8_t nfnlmsg_subtype(struct nlmsghdr *nlh)
142 return NFNL_MSG_TYPE(nlh->nlmsg_type);
146 * Get netfilter family from message
147 * @arg nlh netlink messsage header
149 uint8_t nfnlmsg_family(struct nlmsghdr *nlh)
151 struct nfgenmsg *nfg = nlmsg_data(nlh);
153 return nfg->nfgen_family;
157 * Get netfilter resource id from message
158 * @arg nlh netlink messsage header
160 uint16_t nfnlmsg_res_id(struct nlmsghdr *nlh)
162 struct nfgenmsg *nfg = nlmsg_data(nlh);
164 return ntohs(nfg->res_id);
170 * @name Message Building
174 static int nfnlmsg_append(struct nl_msg *msg, uint8_t family, uint16_t res_id)
176 struct nfgenmsg *nfg;
178 nfg = nlmsg_reserve(msg, sizeof(*nfg), NLMSG_ALIGNTO);
182 nfg->nfgen_family = family;
183 nfg->version = NFNETLINK_V0;
184 nfg->res_id = htons(res_id);
185 NL_DBG(2, "msg %p: Added nfnetlink header family=%d res_id=%d\n",
186 msg, family, res_id);
191 * Allocate a new netfilter netlink message
192 * @arg subsys_id nfnetlink subsystem
193 * @arg type nfnetlink message type
194 * @arg flags message flags
195 * @arg family nfnetlink address family
196 * @arg res_id nfnetlink resource id
198 * @return Newly allocated netlink message or NULL.
200 struct nl_msg *nfnlmsg_alloc_simple(uint8_t subsys_id, uint8_t type, int flags,
201 uint8_t family, uint16_t res_id)
205 msg = nlmsg_alloc_simple(NFNLMSG_TYPE(subsys_id, type), flags);
209 if (nfnlmsg_append(msg, family, res_id) < 0)
210 goto nla_put_failure;
220 * Add netlink and netfilter netlink headers to netlink message
221 * @arg msg netlink message
222 * @arg pid netlink process id
223 * @arg seq sequence number of message
224 * @arg subsys_id nfnetlink subsystem
225 * @arg type nfnetlink message type
226 * @arg flags message flags
227 * @arg family nfnetlink address family
228 * @arg res_id nfnetlink resource id
230 int nfnlmsg_put(struct nl_msg *msg, uint32_t pid, uint32_t seq,
231 uint8_t subsys_id, uint8_t type, int flags, uint8_t family,
234 struct nlmsghdr *nlh;
236 nlh = nlmsg_put(msg, pid, seq, NFNLMSG_TYPE(subsys_id, type), 0, flags);
240 return nfnlmsg_append(msg, family, res_id);