libnetfilter_queue 1.0.5
nlmsg.c
1/*
2 * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 */
9#include <arpa/inet.h>
10#include <time.h>
11#include <endian.h>
12#include <stdlib.h>
13#include <string.h>
14
15#include <libmnl/libmnl.h>
16
17#ifndef __aligned_be64
18#define __aligned_be64 __be64 __attribute__((aligned(8)))
19#define __aligned_le64 __le64 __attribute__((aligned(8)))
20#endif
21
22#include <linux/netfilter/nfnetlink_queue.h>
23
24#include <libnetfilter_queue/libnetfilter_queue.h>
25
26#include "internal.h"
27
71EXPORT_SYMBOL
72void nfq_nlmsg_verdict_put(struct nlmsghdr *nlh, int id, int verdict)
73{
74 struct nfqnl_msg_verdict_hdr vh = {
75 .verdict = htonl(verdict),
76 .id = htonl(id),
77 };
78 mnl_attr_put(nlh, NFQA_VERDICT_HDR, sizeof(vh), &vh);
79}
80
90EXPORT_SYMBOL
91void nfq_nlmsg_verdict_put_mark(struct nlmsghdr *nlh, uint32_t mark)
92{
93 mnl_attr_put_u32(nlh, NFQA_MARK, htonl(mark));
94}
95
96EXPORT_SYMBOL
130void nfq_nlmsg_verdict_put_pkt(struct nlmsghdr *nlh, const void *pkt,
131 uint32_t plen)
132{
133 mnl_attr_put(nlh, NFQA_PAYLOAD, plen, pkt);
134}
135
165EXPORT_SYMBOL
166void nfq_nlmsg_cfg_put_cmd(struct nlmsghdr *nlh, uint16_t pf, uint8_t cmd)
167{
168 struct nfqnl_msg_config_cmd command = {
169 .command = cmd,
170 .pf = htons(pf),
171 };
172 mnl_attr_put(nlh, NFQA_CFG_CMD, sizeof(command), &command);
173}
174
181EXPORT_SYMBOL
182void nfq_nlmsg_cfg_put_params(struct nlmsghdr *nlh, uint8_t mode, int range)
183{
184 struct nfqnl_msg_config_params params = {
185 .copy_range = htonl(range),
186 .copy_mode = mode,
187 };
188 mnl_attr_put(nlh, NFQA_CFG_PARAMS, sizeof(params), &params);
189}
190
196EXPORT_SYMBOL
197void nfq_nlmsg_cfg_put_qmaxlen(struct nlmsghdr *nlh, uint32_t queue_maxlen)
198{
199 mnl_attr_put_u32(nlh, NFQA_CFG_QUEUE_MAXLEN, htonl(queue_maxlen));
200}
201
211static int nfq_pkt_parse_attr_cb(const struct nlattr *attr, void *data)
212{
213 const struct nlattr **tb = data;
214 int type = mnl_attr_get_type(attr);
215
216 /* skip unsupported attribute in user-space */
217 if (mnl_attr_type_valid(attr, NFQA_MAX) < 0)
218 return MNL_CB_OK;
219
220 switch(type) {
221 case NFQA_MARK:
222 case NFQA_IFINDEX_INDEV:
223 case NFQA_IFINDEX_OUTDEV:
224 case NFQA_IFINDEX_PHYSINDEV:
225 case NFQA_IFINDEX_PHYSOUTDEV:
226 case NFQA_CAP_LEN:
227 case NFQA_SKB_INFO:
228 case NFQA_SECCTX:
229 case NFQA_UID:
230 case NFQA_GID:
231 case NFQA_CT_INFO:
232 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0)
233 return MNL_CB_ERROR;
234 break;
235 case NFQA_TIMESTAMP:
236 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
237 sizeof(struct nfqnl_msg_packet_timestamp)) < 0) {
238 return MNL_CB_ERROR;
239 }
240 break;
241 case NFQA_HWADDR:
242 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
243 sizeof(struct nfqnl_msg_packet_hw)) < 0) {
244 return MNL_CB_ERROR;
245 }
246 break;
247 case NFQA_PACKET_HDR:
248 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
249 sizeof(struct nfqnl_msg_packet_hdr)) < 0) {
250 return MNL_CB_ERROR;
251 }
252 break;
253 case NFQA_PAYLOAD:
254 case NFQA_CT:
255 case NFQA_EXP:
256 break;
257 }
258 tb[type] = attr;
259 return MNL_CB_OK;
260}
261
268EXPORT_SYMBOL
269int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)
270{
271 return mnl_attr_parse(nlh, sizeof(struct nfgenmsg),
272 nfq_pkt_parse_attr_cb, attr);
273}
274
282EXPORT_SYMBOL
283struct nlmsghdr *nfq_nlmsg_put(char *buf, int type, uint32_t queue_num)
284{
285 struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
286 nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | type;
287 nlh->nlmsg_flags = NLM_F_REQUEST;
288
289 struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
290 nfg->nfgen_family = AF_UNSPEC;
291 nfg->version = NFNETLINK_V0;
292 nfg->res_id = htons(queue_num);
293
294 return nlh;
295}
296
void nfq_nlmsg_cfg_put_params(struct nlmsghdr *nlh, uint8_t mode, int range)
Definition nlmsg.c:182
void nfq_nlmsg_cfg_put_qmaxlen(struct nlmsghdr *nlh, uint32_t queue_maxlen)
Definition nlmsg.c:197
void nfq_nlmsg_cfg_put_cmd(struct nlmsghdr *nlh, uint16_t pf, uint8_t cmd)
Definition nlmsg.c:166
void nfq_nlmsg_verdict_put_mark(struct nlmsghdr *nlh, uint32_t mark)
Definition nlmsg.c:91
void nfq_nlmsg_verdict_put_pkt(struct nlmsghdr *nlh, const void *pkt, uint32_t plen)
Definition nlmsg.c:130
void nfq_nlmsg_verdict_put(struct nlmsghdr *nlh, int id, int verdict)
Definition nlmsg.c:72
struct nlmsghdr * nfq_nlmsg_put(char *buf, int type, uint32_t queue_num)
Definition nlmsg.c:283
int nfq_nlmsg_parse(const struct nlmsghdr *nlh, struct nlattr **attr)
Definition nlmsg.c:269