2
* lib/netfilter/queue_msg_obj.c Netfilter Queue Message Object
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) 2007, 2008 Patrick McHardy <kaber@trash.net>
12
#include <netlink-local.h>
13
#include <netlink/netfilter/nfnl.h>
14
#include <netlink/netfilter/netfilter.h>
15
#include <netlink/netfilter/queue_msg.h>
16
#include <linux/netfilter.h>
19
#define QUEUE_MSG_ATTR_GROUP (1UL << 0)
20
#define QUEUE_MSG_ATTR_FAMILY (1UL << 1)
21
#define QUEUE_MSG_ATTR_PACKETID (1UL << 2)
22
#define QUEUE_MSG_ATTR_HWPROTO (1UL << 3)
23
#define QUEUE_MSG_ATTR_HOOK (1UL << 4)
24
#define QUEUE_MSG_ATTR_MARK (1UL << 5)
25
#define QUEUE_MSG_ATTR_TIMESTAMP (1UL << 6)
26
#define QUEUE_MSG_ATTR_INDEV (1UL << 7)
27
#define QUEUE_MSG_ATTR_OUTDEV (1UL << 8)
28
#define QUEUE_MSG_ATTR_PHYSINDEV (1UL << 9)
29
#define QUEUE_MSG_ATTR_PHYSOUTDEV (1UL << 10)
30
#define QUEUE_MSG_ATTR_HWADDR (1UL << 11)
31
#define QUEUE_MSG_ATTR_PAYLOAD (1UL << 12)
32
#define QUEUE_MSG_ATTR_VERDICT (1UL << 13)
35
static void nfnl_queue_msg_free_data(struct nl_object *c)
37
struct nfnl_queue_msg *msg = (struct nfnl_queue_msg *) c;
42
free(msg->queue_msg_payload);
45
static int nfnl_queue_msg_clone(struct nl_object *_dst, struct nl_object *_src)
47
struct nfnl_queue_msg *dst = (struct nfnl_queue_msg *) _dst;
48
struct nfnl_queue_msg *src = (struct nfnl_queue_msg *) _src;
51
if (src->queue_msg_payload) {
52
err = nfnl_queue_msg_set_payload(dst, src->queue_msg_payload,
53
src->queue_msg_payload_len);
63
static void nfnl_queue_msg_dump(struct nl_object *a, struct nl_dump_params *p)
65
struct nfnl_queue_msg *msg = (struct nfnl_queue_msg *) a;
66
struct nl_cache *link_cache;
69
link_cache = nl_cache_mngt_require("route/link");
73
if (msg->ce_mask & QUEUE_MSG_ATTR_GROUP)
74
nl_dump(p, "GROUP=%u ", msg->queue_msg_group);
76
if (msg->ce_mask & QUEUE_MSG_ATTR_INDEV) {
79
rtnl_link_i2name(link_cache,
83
nl_dump(p, "IN=%d ", msg->queue_msg_indev);
86
if (msg->ce_mask & QUEUE_MSG_ATTR_PHYSINDEV) {
88
nl_dump(p, "PHYSIN=%s ",
89
rtnl_link_i2name(link_cache,
90
msg->queue_msg_physindev,
93
nl_dump(p, "IN=%d ", msg->queue_msg_physindev);
96
if (msg->ce_mask & QUEUE_MSG_ATTR_OUTDEV) {
99
rtnl_link_i2name(link_cache,
100
msg->queue_msg_outdev,
103
nl_dump(p, "OUT=%d ", msg->queue_msg_outdev);
106
if (msg->ce_mask & QUEUE_MSG_ATTR_PHYSOUTDEV) {
108
nl_dump(p, "PHYSOUT=%s ",
109
rtnl_link_i2name(link_cache,
110
msg->queue_msg_physoutdev,
113
nl_dump(p, "PHYSOUT=%d ", msg->queue_msg_physoutdev);
116
if (msg->ce_mask & QUEUE_MSG_ATTR_HWADDR) {
120
for (i = 0; i < msg->queue_msg_hwaddr_len; i++)
121
nl_dump(p, "%c%02x", i?':':'=',
122
msg->queue_msg_hwaddr[i]);
126
if (msg->ce_mask & QUEUE_MSG_ATTR_FAMILY)
127
nl_dump(p, "FAMILY=%s ",
128
nl_af2str(msg->queue_msg_family, buf, sizeof(buf)));
130
if (msg->ce_mask & QUEUE_MSG_ATTR_HWPROTO)
131
nl_dump(p, "HWPROTO=%s ",
132
nl_ether_proto2str(ntohs(msg->queue_msg_hwproto),
135
if (msg->ce_mask & QUEUE_MSG_ATTR_HOOK)
136
nl_dump(p, "HOOK=%s ",
137
nfnl_inet_hook2str(msg->queue_msg_hook,
140
if (msg->ce_mask & QUEUE_MSG_ATTR_MARK)
141
nl_dump(p, "MARK=%d ", msg->queue_msg_mark);
143
if (msg->ce_mask & QUEUE_MSG_ATTR_PAYLOAD)
144
nl_dump(p, "PAYLOADLEN=%d ", msg->queue_msg_payload_len);
146
if (msg->ce_mask & QUEUE_MSG_ATTR_PACKETID)
147
nl_dump(p, "PACKETID=%u ", msg->queue_msg_packetid);
149
if (msg->ce_mask & QUEUE_MSG_ATTR_VERDICT)
150
nl_dump(p, "VERDICT=%s ",
151
nfnl_verdict2str(msg->queue_msg_verdict,
158
* @name Allocation/Freeing
162
struct nfnl_queue_msg *nfnl_queue_msg_alloc(void)
164
return (struct nfnl_queue_msg *) nl_object_alloc(&queue_msg_obj_ops);
167
void nfnl_queue_msg_get(struct nfnl_queue_msg *msg)
169
nl_object_get((struct nl_object *) msg);
172
void nfnl_queue_msg_put(struct nfnl_queue_msg *msg)
174
nl_object_put((struct nl_object *) msg);
184
void nfnl_queue_msg_set_group(struct nfnl_queue_msg *msg, uint16_t group)
186
msg->queue_msg_group = group;
187
msg->ce_mask |= QUEUE_MSG_ATTR_GROUP;
190
int nfnl_queue_msg_test_group(const struct nfnl_queue_msg *msg)
192
return !!(msg->ce_mask & QUEUE_MSG_ATTR_GROUP);
195
uint16_t nfnl_queue_msg_get_group(const struct nfnl_queue_msg *msg)
197
return msg->queue_msg_group;
201
* Set the protocol family
202
* @arg msg NF queue message
203
* @arg family AF_XXX address family example: AF_INET, AF_UNIX, etc
205
void nfnl_queue_msg_set_family(struct nfnl_queue_msg *msg, uint8_t family)
207
msg->queue_msg_family = family;
208
msg->ce_mask |= QUEUE_MSG_ATTR_FAMILY;
211
int nfnl_queue_msg_test_family(const struct nfnl_queue_msg *msg)
213
return !!(msg->ce_mask & QUEUE_MSG_ATTR_FAMILY);
216
uint8_t nfnl_queue_msg_get_family(const struct nfnl_queue_msg *msg)
218
if (msg->ce_mask & QUEUE_MSG_ATTR_FAMILY)
219
return msg->queue_msg_family;
224
void nfnl_queue_msg_set_packetid(struct nfnl_queue_msg *msg, uint32_t packetid)
226
msg->queue_msg_packetid = packetid;
227
msg->ce_mask |= QUEUE_MSG_ATTR_PACKETID;
230
int nfnl_queue_msg_test_packetid(const struct nfnl_queue_msg *msg)
232
return !!(msg->ce_mask & QUEUE_MSG_ATTR_PACKETID);
235
uint32_t nfnl_queue_msg_get_packetid(const struct nfnl_queue_msg *msg)
237
return msg->queue_msg_packetid;
240
void nfnl_queue_msg_set_hwproto(struct nfnl_queue_msg *msg, uint16_t hwproto)
242
msg->queue_msg_hwproto = hwproto;
243
msg->ce_mask |= QUEUE_MSG_ATTR_HWPROTO;
246
int nfnl_queue_msg_test_hwproto(const struct nfnl_queue_msg *msg)
248
return !!(msg->ce_mask & QUEUE_MSG_ATTR_HWPROTO);
251
uint16_t nfnl_queue_msg_get_hwproto(const struct nfnl_queue_msg *msg)
253
return msg->queue_msg_hwproto;
256
void nfnl_queue_msg_set_hook(struct nfnl_queue_msg *msg, uint8_t hook)
258
msg->queue_msg_hook = hook;
259
msg->ce_mask |= QUEUE_MSG_ATTR_HOOK;
262
int nfnl_queue_msg_test_hook(const struct nfnl_queue_msg *msg)
264
return !!(msg->ce_mask & QUEUE_MSG_ATTR_HOOK);
267
uint8_t nfnl_queue_msg_get_hook(const struct nfnl_queue_msg *msg)
269
return msg->queue_msg_hook;
272
void nfnl_queue_msg_set_mark(struct nfnl_queue_msg *msg, uint32_t mark)
274
msg->queue_msg_mark = mark;
275
msg->ce_mask |= QUEUE_MSG_ATTR_MARK;
278
int nfnl_queue_msg_test_mark(const struct nfnl_queue_msg *msg)
280
return !!(msg->ce_mask & QUEUE_MSG_ATTR_MARK);
283
uint32_t nfnl_queue_msg_get_mark(const struct nfnl_queue_msg *msg)
285
return msg->queue_msg_mark;
288
void nfnl_queue_msg_set_timestamp(struct nfnl_queue_msg *msg,
291
msg->queue_msg_timestamp.tv_sec = tv->tv_sec;
292
msg->queue_msg_timestamp.tv_usec = tv->tv_usec;
293
msg->ce_mask |= QUEUE_MSG_ATTR_TIMESTAMP;
296
int nfnl_queue_msg_test_timestamp(const struct nfnl_queue_msg *msg)
298
return !!(msg->ce_mask & QUEUE_MSG_ATTR_TIMESTAMP);
301
const struct timeval *nfnl_queue_msg_get_timestamp(const struct nfnl_queue_msg *msg)
303
if (!(msg->ce_mask & QUEUE_MSG_ATTR_TIMESTAMP))
305
return &msg->queue_msg_timestamp;
308
void nfnl_queue_msg_set_indev(struct nfnl_queue_msg *msg, uint32_t indev)
310
msg->queue_msg_indev = indev;
311
msg->ce_mask |= QUEUE_MSG_ATTR_INDEV;
314
int nfnl_queue_msg_test_indev(const struct nfnl_queue_msg *msg)
316
return !!(msg->ce_mask & QUEUE_MSG_ATTR_INDEV);
319
uint32_t nfnl_queue_msg_get_indev(const struct nfnl_queue_msg *msg)
321
return msg->queue_msg_indev;
324
void nfnl_queue_msg_set_outdev(struct nfnl_queue_msg *msg, uint32_t outdev)
326
msg->queue_msg_outdev = outdev;
327
msg->ce_mask |= QUEUE_MSG_ATTR_OUTDEV;
330
int nfnl_queue_msg_test_outdev(const struct nfnl_queue_msg *msg)
332
return !!(msg->ce_mask & QUEUE_MSG_ATTR_OUTDEV);
335
uint32_t nfnl_queue_msg_get_outdev(const struct nfnl_queue_msg *msg)
337
return msg->queue_msg_outdev;
340
void nfnl_queue_msg_set_physindev(struct nfnl_queue_msg *msg,
343
msg->queue_msg_physindev = physindev;
344
msg->ce_mask |= QUEUE_MSG_ATTR_PHYSINDEV;
347
int nfnl_queue_msg_test_physindev(const struct nfnl_queue_msg *msg)
349
return !!(msg->ce_mask & QUEUE_MSG_ATTR_PHYSINDEV);
352
uint32_t nfnl_queue_msg_get_physindev(const struct nfnl_queue_msg *msg)
354
return msg->queue_msg_physindev;
357
void nfnl_queue_msg_set_physoutdev(struct nfnl_queue_msg *msg,
360
msg->queue_msg_physoutdev = physoutdev;
361
msg->ce_mask |= QUEUE_MSG_ATTR_PHYSOUTDEV;
364
int nfnl_queue_msg_test_physoutdev(const struct nfnl_queue_msg *msg)
366
return !!(msg->ce_mask & QUEUE_MSG_ATTR_PHYSOUTDEV);
369
uint32_t nfnl_queue_msg_get_physoutdev(const struct nfnl_queue_msg *msg)
371
return msg->queue_msg_physoutdev;
374
void nfnl_queue_msg_set_hwaddr(struct nfnl_queue_msg *msg, uint8_t *hwaddr,
377
if (len > sizeof(msg->queue_msg_hwaddr))
378
len = sizeof(msg->queue_msg_hwaddr);
380
msg->queue_msg_hwaddr_len = len;
381
memcpy(msg->queue_msg_hwaddr, hwaddr, len);
382
msg->ce_mask |= QUEUE_MSG_ATTR_HWADDR;
385
int nfnl_queue_msg_test_hwaddr(const struct nfnl_queue_msg *msg)
387
return !!(msg->ce_mask & QUEUE_MSG_ATTR_HWADDR);
390
const uint8_t *nfnl_queue_msg_get_hwaddr(const struct nfnl_queue_msg *msg,
393
if (!(msg->ce_mask & QUEUE_MSG_ATTR_HWADDR)) {
398
*len = msg->queue_msg_hwaddr_len;
399
return msg->queue_msg_hwaddr;
402
int nfnl_queue_msg_set_payload(struct nfnl_queue_msg *msg, uint8_t *payload,
405
free(msg->queue_msg_payload);
406
msg->queue_msg_payload = malloc(len);
407
if (!msg->queue_msg_payload)
410
memcpy(msg->queue_msg_payload, payload, len);
411
msg->queue_msg_payload_len = len;
412
msg->ce_mask |= QUEUE_MSG_ATTR_PAYLOAD;
416
int nfnl_queue_msg_test_payload(const struct nfnl_queue_msg *msg)
418
return !!(msg->ce_mask & QUEUE_MSG_ATTR_PAYLOAD);
421
const void *nfnl_queue_msg_get_payload(const struct nfnl_queue_msg *msg, int *len)
423
if (!(msg->ce_mask & QUEUE_MSG_ATTR_PAYLOAD)) {
428
*len = msg->queue_msg_payload_len;
429
return msg->queue_msg_payload;
433
* Return the number of items matching a filter in the cache
435
* @arg verdict NF_DROP, NF_ACCEPT, NF_REPEAT, etc
437
void nfnl_queue_msg_set_verdict(struct nfnl_queue_msg *msg,
438
unsigned int verdict)
440
msg->queue_msg_verdict = verdict;
441
msg->ce_mask |= QUEUE_MSG_ATTR_VERDICT;
444
int nfnl_queue_msg_test_verdict(const struct nfnl_queue_msg *msg)
446
return !!(msg->ce_mask & QUEUE_MSG_ATTR_VERDICT);
449
unsigned int nfnl_queue_msg_get_verdict(const struct nfnl_queue_msg *msg)
451
return msg->queue_msg_verdict;
454
static const struct trans_tbl nfnl_queue_msg_attrs[] = {
455
__ADD(QUEUE_MSG_ATTR_GROUP, group)
456
__ADD(QUEUE_MSG_ATTR_FAMILY, family)
457
__ADD(QUEUE_MSG_ATTR_PACKETID, packetid)
458
__ADD(QUEUE_MSG_ATTR_HWPROTO, hwproto)
459
__ADD(QUEUE_MSG_ATTR_HOOK, hook)
460
__ADD(QUEUE_MSG_ATTR_MARK, mark)
461
__ADD(QUEUE_MSG_ATTR_TIMESTAMP, timestamp)
462
__ADD(QUEUE_MSG_ATTR_INDEV, indev)
463
__ADD(QUEUE_MSG_ATTR_OUTDEV, outdev)
464
__ADD(QUEUE_MSG_ATTR_PHYSINDEV, physindev)
465
__ADD(QUEUE_MSG_ATTR_PHYSOUTDEV, physoutdev)
466
__ADD(QUEUE_MSG_ATTR_HWADDR, hwaddr)
467
__ADD(QUEUE_MSG_ATTR_PAYLOAD, payload)
468
__ADD(QUEUE_MSG_ATTR_VERDICT, verdict)
471
static char *nfnl_queue_msg_attrs2str(int attrs, char *buf, size_t len)
473
return __flags2str(attrs, buf, len, nfnl_queue_msg_attrs,
474
ARRAY_SIZE(nfnl_queue_msg_attrs));
479
struct nl_object_ops queue_msg_obj_ops = {
480
.oo_name = "netfilter/queuemsg",
481
.oo_size = sizeof(struct nfnl_queue_msg),
482
.oo_free_data = nfnl_queue_msg_free_data,
483
.oo_clone = nfnl_queue_msg_clone,
485
[NL_DUMP_LINE] = nfnl_queue_msg_dump,
486
[NL_DUMP_DETAILS] = nfnl_queue_msg_dump,
487
[NL_DUMP_STATS] = nfnl_queue_msg_dump,
489
.oo_attrs2str = nfnl_queue_msg_attrs2str,