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 
71 EXPORT_SYMBOL
72 void 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 
90 EXPORT_SYMBOL
91 void nfq_nlmsg_verdict_put_mark(struct nlmsghdr *nlh, uint32_t mark)
92 {
93  mnl_attr_put_u32(nlh, NFQA_MARK, htonl(mark));
94 }
95 
96 EXPORT_SYMBOL
130 void 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 
165 EXPORT_SYMBOL
166 void 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 
181 EXPORT_SYMBOL
182 void 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 
196 EXPORT_SYMBOL
197 void 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 
211 static 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 
268 EXPORT_SYMBOL
269 int 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 
282 EXPORT_SYMBOL
283 struct 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_cmd(struct nlmsghdr *nlh, uint16_t pf, uint8_t cmd)
Definition: nlmsg.c:166
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
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_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