nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 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-2008 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 | * @defgroup nfnl Netfilter Netlink |
||
16 | * |
||
17 | * @par Message Format |
||
18 | * @code |
||
19 | * <------- NLMSG_ALIGN(hlen) ------> <---- NLMSG_ALIGN(len) ---> |
||
20 | * +----------------------------+- - -+- - - - - - - - - - -+- - -+ |
||
21 | * | Header | Pad | Payload | Pad | |
||
22 | * | struct nlmsghdr | | | | |
||
23 | * +----------------------------+- - -+- - - - - - - - - - -+- - -+ |
||
24 | * @endcode |
||
25 | * @code |
||
26 | * <-------- NFNL_HDRLEN ---------> |
||
27 | * +--------------------------+- - -+------------+ |
||
28 | * | Netfilter Netlink Header | Pad | Attributes | |
||
29 | * | struct nfgenmsg | | | |
||
30 | * +--------------------------+- - -+------------+ |
||
31 | * nfnlmsg_attrdata(nfg, hdrlen)-----^ |
||
32 | * @endcode |
||
33 | * |
||
34 | * @par 1) Creating a new netfilter netlink message |
||
35 | * @code |
||
36 | * struct nl_msg *msg; |
||
37 | * |
||
38 | * // Create a new empty netlink message |
||
39 | * msg = nlmsg_alloc(); |
||
40 | * |
||
41 | * // Append the netlink and netfilter netlink message header |
||
42 | * hdr = nfnlmsg_put(msg, PID, SEQ, SUBSYS, TYPE, NLM_F_ECHO, |
||
43 | * FAMILY, RES_ID); |
||
44 | * |
||
45 | * // Append the attributes. |
||
46 | * nla_put_u32(msg, 1, 0x10); |
||
47 | * |
||
48 | * // Message is ready to be sent. |
||
49 | * nl_send_auto_complete(sk, msg); |
||
50 | * |
||
51 | * // All done? Free the message. |
||
52 | * nlmsg_free(msg); |
||
53 | * @endcode |
||
54 | * |
||
55 | * @par 2) Sending of trivial messages |
||
56 | * @code |
||
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); |
||
60 | * @endcode |
||
61 | * @{ |
||
62 | */ |
||
63 | |||
64 | #include <netlink-local.h> |
||
65 | #include <netlink/netlink.h> |
||
66 | #include <netlink/netfilter/nfnl.h> |
||
67 | |||
68 | /** |
||
69 | * @name Socket Creating |
||
70 | * @{ |
||
71 | */ |
||
72 | |||
73 | /** |
||
74 | * Create and connect netfilter netlink socket. |
||
75 | * @arg sk Netlink socket. |
||
76 | * |
||
77 | * Creates a NETLINK_NETFILTER netlink socket, binds the socket and |
||
78 | * issues a connection attempt. |
||
79 | * |
||
80 | * @see nl_connect() |
||
81 | * |
||
82 | * @return 0 on success or a negative error code. |
||
83 | */ |
||
84 | int nfnl_connect(struct nl_sock *sk) |
||
85 | { |
||
86 | return nl_connect(sk, NETLINK_NETFILTER); |
||
87 | } |
||
88 | |||
89 | /** @} */ |
||
90 | |||
91 | /** |
||
92 | * @name Sending |
||
93 | * @{ |
||
94 | */ |
||
95 | |||
96 | /** |
||
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 |
||
104 | * |
||
105 | * @return Newly allocated netlink message or NULL. |
||
106 | */ |
||
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) |
||
109 | { |
||
110 | struct nfgenmsg hdr = { |
||
111 | .nfgen_family = family, |
||
112 | .version = NFNETLINK_V0, |
||
113 | .res_id = htons(res_id), |
||
114 | }; |
||
115 | |||
116 | return nl_send_simple(sk, NFNLMSG_TYPE(subsys_id, type), flags, |
||
117 | &hdr, sizeof(hdr)); |
||
118 | } |
||
119 | |||
120 | /** @} */ |
||
121 | |||
122 | /** |
||
123 | * @name Message Parsing |
||
124 | * @{ |
||
125 | */ |
||
126 | |||
127 | /** |
||
128 | * Get netfilter subsystem id from message |
||
129 | * @arg nlh netlink messsage header |
||
130 | */ |
||
131 | uint8_t nfnlmsg_subsys(struct nlmsghdr *nlh) |
||
132 | { |
||
133 | return NFNL_SUBSYS_ID(nlh->nlmsg_type); |
||
134 | } |
||
135 | |||
136 | /** |
||
137 | * Get netfilter message type from message |
||
138 | * @arg nlh netlink messsage header |
||
139 | */ |
||
140 | uint8_t nfnlmsg_subtype(struct nlmsghdr *nlh) |
||
141 | { |
||
142 | return NFNL_MSG_TYPE(nlh->nlmsg_type); |
||
143 | } |
||
144 | |||
145 | /** |
||
146 | * Get netfilter family from message |
||
147 | * @arg nlh netlink messsage header |
||
148 | */ |
||
149 | uint8_t nfnlmsg_family(struct nlmsghdr *nlh) |
||
150 | { |
||
151 | struct nfgenmsg *nfg = nlmsg_data(nlh); |
||
152 | |||
153 | return nfg->nfgen_family; |
||
154 | } |
||
155 | |||
156 | /** |
||
157 | * Get netfilter resource id from message |
||
158 | * @arg nlh netlink messsage header |
||
159 | */ |
||
160 | uint16_t nfnlmsg_res_id(struct nlmsghdr *nlh) |
||
161 | { |
||
162 | struct nfgenmsg *nfg = nlmsg_data(nlh); |
||
163 | |||
164 | return ntohs(nfg->res_id); |
||
165 | } |
||
166 | |||
167 | /** @} */ |
||
168 | |||
169 | /** |
||
170 | * @name Message Building |
||
171 | * @{ |
||
172 | */ |
||
173 | |||
174 | static int nfnlmsg_append(struct nl_msg *msg, uint8_t family, uint16_t res_id) |
||
175 | { |
||
176 | struct nfgenmsg *nfg; |
||
177 | |||
178 | nfg = nlmsg_reserve(msg, sizeof(*nfg), NLMSG_ALIGNTO); |
||
179 | if (nfg == NULL) |
||
180 | return -NLE_NOMEM; |
||
181 | |||
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); |
||
187 | return 0; |
||
188 | } |
||
189 | |||
190 | /** |
||
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 |
||
197 | * |
||
198 | * @return Newly allocated netlink message or NULL. |
||
199 | */ |
||
200 | struct nl_msg *nfnlmsg_alloc_simple(uint8_t subsys_id, uint8_t type, int flags, |
||
201 | uint8_t family, uint16_t res_id) |
||
202 | { |
||
203 | struct nl_msg *msg; |
||
204 | |||
205 | msg = nlmsg_alloc_simple(NFNLMSG_TYPE(subsys_id, type), flags); |
||
206 | if (msg == NULL) |
||
207 | return NULL; |
||
208 | |||
209 | if (nfnlmsg_append(msg, family, res_id) < 0) |
||
210 | goto nla_put_failure; |
||
211 | |||
212 | return msg; |
||
213 | |||
214 | nla_put_failure: |
||
215 | nlmsg_free(msg); |
||
216 | return NULL; |
||
217 | } |
||
218 | |||
219 | /** |
||
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 |
||
229 | */ |
||
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, |
||
232 | uint16_t res_id) |
||
233 | { |
||
234 | struct nlmsghdr *nlh; |
||
235 | |||
236 | nlh = nlmsg_put(msg, pid, seq, NFNLMSG_TYPE(subsys_id, type), 0, flags); |
||
237 | if (nlh == NULL) |
||
238 | return -NLE_MSGSIZE; |
||
239 | |||
240 | return nfnlmsg_append(msg, family, res_id); |
||
241 | } |
||
242 | |||
243 | /** @} */ |
||
244 | |||
245 | /** @} */ |