~ubuntu-branches/ubuntu/oneiric/libnl3/oneiric

« back to all changes in this revision

Viewing changes to lib/netfilter/queue_msg_obj.c

  • Committer: Bazaar Package Importer
  • Author(s): Heiko Stuebner
  • Date: 2011-05-21 19:25:13 UTC
  • Revision ID: james.westby@ubuntu.com-20110521192513-1ieyu9w9kym4bt16
Tags: upstream-3.0
ImportĀ upstreamĀ versionĀ 3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lib/netfilter/queue_msg_obj.c        Netfilter Queue Message Object
 
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) 2007, 2008 Patrick McHardy <kaber@trash.net>
 
10
 */
 
11
 
 
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>
 
17
 
 
18
/** @cond SKIP */
 
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)
 
33
/** @endcond */
 
34
 
 
35
static void nfnl_queue_msg_free_data(struct nl_object *c)
 
36
{
 
37
        struct nfnl_queue_msg *msg = (struct nfnl_queue_msg *) c;
 
38
 
 
39
        if (msg == NULL)
 
40
                return;
 
41
 
 
42
        free(msg->queue_msg_payload);
 
43
}
 
44
 
 
45
static int nfnl_queue_msg_clone(struct nl_object *_dst, struct nl_object *_src)
 
46
{
 
47
        struct nfnl_queue_msg *dst = (struct nfnl_queue_msg *) _dst;
 
48
        struct nfnl_queue_msg *src = (struct nfnl_queue_msg *) _src;
 
49
        int err;
 
50
 
 
51
        if (src->queue_msg_payload) {
 
52
                err = nfnl_queue_msg_set_payload(dst, src->queue_msg_payload,
 
53
                                                 src->queue_msg_payload_len);
 
54
                if (err < 0)
 
55
                        goto errout;
 
56
        }
 
57
 
 
58
        return 0;
 
59
errout:
 
60
        return err;
 
61
}
 
62
 
 
63
static void nfnl_queue_msg_dump(struct nl_object *a, struct nl_dump_params *p)
 
64
{
 
65
        struct nfnl_queue_msg *msg = (struct nfnl_queue_msg *) a;
 
66
        struct nl_cache *link_cache;
 
67
        char buf[64];
 
68
 
 
69
        link_cache = nl_cache_mngt_require("route/link");
 
70
 
 
71
        nl_new_line(p);
 
72
 
 
73
        if (msg->ce_mask & QUEUE_MSG_ATTR_GROUP)
 
74
                nl_dump(p, "GROUP=%u ", msg->queue_msg_group);
 
75
 
 
76
        if (msg->ce_mask & QUEUE_MSG_ATTR_INDEV) {
 
77
                if (link_cache)
 
78
                        nl_dump(p, "IN=%s ",
 
79
                                rtnl_link_i2name(link_cache,
 
80
                                                 msg->queue_msg_indev,
 
81
                                                 buf, sizeof(buf)));
 
82
                else
 
83
                        nl_dump(p, "IN=%d ", msg->queue_msg_indev);
 
84
        }
 
85
 
 
86
        if (msg->ce_mask & QUEUE_MSG_ATTR_PHYSINDEV) {
 
87
                if (link_cache)
 
88
                        nl_dump(p, "PHYSIN=%s ",
 
89
                                rtnl_link_i2name(link_cache,
 
90
                                                 msg->queue_msg_physindev,
 
91
                                                 buf, sizeof(buf)));
 
92
                else
 
93
                        nl_dump(p, "IN=%d ", msg->queue_msg_physindev);
 
94
        }
 
95
 
 
96
        if (msg->ce_mask & QUEUE_MSG_ATTR_OUTDEV) {
 
97
                if (link_cache)
 
98
                        nl_dump(p, "OUT=%s ",
 
99
                                rtnl_link_i2name(link_cache,
 
100
                                                 msg->queue_msg_outdev,
 
101
                                                 buf, sizeof(buf)));
 
102
                else
 
103
                        nl_dump(p, "OUT=%d ", msg->queue_msg_outdev);
 
104
        }
 
105
 
 
106
        if (msg->ce_mask & QUEUE_MSG_ATTR_PHYSOUTDEV) {
 
107
                if (link_cache)
 
108
                        nl_dump(p, "PHYSOUT=%s ",
 
109
                                rtnl_link_i2name(link_cache,
 
110
                                                 msg->queue_msg_physoutdev,
 
111
                                                 buf, sizeof(buf)));
 
112
                else
 
113
                        nl_dump(p, "PHYSOUT=%d ", msg->queue_msg_physoutdev);
 
114
        }
 
115
 
 
116
        if (msg->ce_mask & QUEUE_MSG_ATTR_HWADDR) {
 
117
                int i;
 
118
 
 
119
                nl_dump(p, "MAC");
 
120
                for (i = 0; i < msg->queue_msg_hwaddr_len; i++)
 
121
                        nl_dump(p, "%c%02x", i?':':'=',
 
122
                                msg->queue_msg_hwaddr[i]);
 
123
                nl_dump(p, " ");
 
124
        }
 
125
 
 
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)));
 
129
 
 
130
        if (msg->ce_mask & QUEUE_MSG_ATTR_HWPROTO)
 
131
                nl_dump(p, "HWPROTO=%s ",
 
132
                        nl_ether_proto2str(ntohs(msg->queue_msg_hwproto),
 
133
                                           buf, sizeof(buf)));
 
134
 
 
135
        if (msg->ce_mask & QUEUE_MSG_ATTR_HOOK)
 
136
                nl_dump(p, "HOOK=%s ",
 
137
                        nfnl_inet_hook2str(msg->queue_msg_hook,
 
138
                                           buf, sizeof(buf)));
 
139
 
 
140
        if (msg->ce_mask & QUEUE_MSG_ATTR_MARK)
 
141
                nl_dump(p, "MARK=%d ", msg->queue_msg_mark);
 
142
 
 
143
        if (msg->ce_mask & QUEUE_MSG_ATTR_PAYLOAD)
 
144
                nl_dump(p, "PAYLOADLEN=%d ", msg->queue_msg_payload_len);
 
145
 
 
146
        if (msg->ce_mask & QUEUE_MSG_ATTR_PACKETID)
 
147
                nl_dump(p, "PACKETID=%u ", msg->queue_msg_packetid);
 
148
 
 
149
        if (msg->ce_mask & QUEUE_MSG_ATTR_VERDICT)
 
150
                nl_dump(p, "VERDICT=%s ",
 
151
                        nfnl_verdict2str(msg->queue_msg_verdict,
 
152
                                         buf, sizeof(buf)));
 
153
 
 
154
        nl_dump(p, "\n");
 
155
}
 
156
 
 
157
/**
 
158
 * @name Allocation/Freeing
 
159
 * @{
 
160
 */
 
161
 
 
162
struct nfnl_queue_msg *nfnl_queue_msg_alloc(void)
 
163
{
 
164
        return (struct nfnl_queue_msg *) nl_object_alloc(&queue_msg_obj_ops);
 
165
}
 
166
 
 
167
void nfnl_queue_msg_get(struct nfnl_queue_msg *msg)
 
168
{
 
169
        nl_object_get((struct nl_object *) msg);
 
170
}
 
171
 
 
172
void nfnl_queue_msg_put(struct nfnl_queue_msg *msg)
 
173
{
 
174
        nl_object_put((struct nl_object *) msg);
 
175
}
 
176
 
 
177
/** @} */
 
178
 
 
179
/**
 
180
 * @name Attributes
 
181
 * @{
 
182
 */
 
183
 
 
184
void nfnl_queue_msg_set_group(struct nfnl_queue_msg *msg, uint16_t group)
 
185
{
 
186
        msg->queue_msg_group = group;
 
187
        msg->ce_mask |= QUEUE_MSG_ATTR_GROUP;
 
188
}
 
189
 
 
190
int nfnl_queue_msg_test_group(const struct nfnl_queue_msg *msg)
 
191
{
 
192
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_GROUP);
 
193
}
 
194
 
 
195
uint16_t nfnl_queue_msg_get_group(const struct nfnl_queue_msg *msg)
 
196
{
 
197
        return msg->queue_msg_group;
 
198
}
 
199
 
 
200
/**
 
201
* Set the protocol family
 
202
* @arg msg         NF queue message
 
203
* @arg family      AF_XXX  address family  example: AF_INET, AF_UNIX, etc
 
204
*/
 
205
void nfnl_queue_msg_set_family(struct nfnl_queue_msg *msg, uint8_t family)
 
206
{
 
207
        msg->queue_msg_family = family;
 
208
        msg->ce_mask |= QUEUE_MSG_ATTR_FAMILY;
 
209
}
 
210
 
 
211
int nfnl_queue_msg_test_family(const struct nfnl_queue_msg *msg)
 
212
{
 
213
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_FAMILY);
 
214
}
 
215
 
 
216
uint8_t nfnl_queue_msg_get_family(const struct nfnl_queue_msg *msg)
 
217
{
 
218
        if (msg->ce_mask & QUEUE_MSG_ATTR_FAMILY)
 
219
                return msg->queue_msg_family;
 
220
        else
 
221
                return AF_UNSPEC;
 
222
}
 
223
 
 
224
void nfnl_queue_msg_set_packetid(struct nfnl_queue_msg *msg, uint32_t packetid)
 
225
{
 
226
        msg->queue_msg_packetid = packetid;
 
227
        msg->ce_mask |= QUEUE_MSG_ATTR_PACKETID;
 
228
}
 
229
 
 
230
int nfnl_queue_msg_test_packetid(const struct nfnl_queue_msg *msg)
 
231
{
 
232
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_PACKETID);
 
233
}
 
234
 
 
235
uint32_t nfnl_queue_msg_get_packetid(const struct nfnl_queue_msg *msg)
 
236
{
 
237
        return msg->queue_msg_packetid;
 
238
}
 
239
 
 
240
void nfnl_queue_msg_set_hwproto(struct nfnl_queue_msg *msg, uint16_t hwproto)
 
241
{
 
242
        msg->queue_msg_hwproto = hwproto;
 
243
        msg->ce_mask |= QUEUE_MSG_ATTR_HWPROTO;
 
244
}
 
245
 
 
246
int nfnl_queue_msg_test_hwproto(const struct nfnl_queue_msg *msg)
 
247
{
 
248
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_HWPROTO);
 
249
}
 
250
 
 
251
uint16_t nfnl_queue_msg_get_hwproto(const struct nfnl_queue_msg *msg)
 
252
{
 
253
        return msg->queue_msg_hwproto;
 
254
}
 
255
 
 
256
void nfnl_queue_msg_set_hook(struct nfnl_queue_msg *msg, uint8_t hook)
 
257
{
 
258
        msg->queue_msg_hook = hook;
 
259
        msg->ce_mask |= QUEUE_MSG_ATTR_HOOK;
 
260
}
 
261
 
 
262
int nfnl_queue_msg_test_hook(const struct nfnl_queue_msg *msg)
 
263
{
 
264
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_HOOK);
 
265
}
 
266
 
 
267
uint8_t nfnl_queue_msg_get_hook(const struct nfnl_queue_msg *msg)
 
268
{
 
269
        return msg->queue_msg_hook;
 
270
}
 
271
 
 
272
void nfnl_queue_msg_set_mark(struct nfnl_queue_msg *msg, uint32_t mark)
 
273
{
 
274
        msg->queue_msg_mark = mark;
 
275
        msg->ce_mask |= QUEUE_MSG_ATTR_MARK;
 
276
}
 
277
 
 
278
int nfnl_queue_msg_test_mark(const struct nfnl_queue_msg *msg)
 
279
{
 
280
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_MARK);
 
281
}
 
282
 
 
283
uint32_t nfnl_queue_msg_get_mark(const struct nfnl_queue_msg *msg)
 
284
{
 
285
        return msg->queue_msg_mark;
 
286
}
 
287
 
 
288
void nfnl_queue_msg_set_timestamp(struct nfnl_queue_msg *msg,
 
289
                                  struct timeval *tv)
 
290
{
 
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;
 
294
}
 
295
 
 
296
int nfnl_queue_msg_test_timestamp(const struct nfnl_queue_msg *msg)
 
297
{
 
298
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_TIMESTAMP);
 
299
}
 
300
 
 
301
const struct timeval *nfnl_queue_msg_get_timestamp(const struct nfnl_queue_msg *msg)
 
302
{
 
303
        if (!(msg->ce_mask & QUEUE_MSG_ATTR_TIMESTAMP))
 
304
                return NULL;
 
305
        return &msg->queue_msg_timestamp;
 
306
}
 
307
 
 
308
void nfnl_queue_msg_set_indev(struct nfnl_queue_msg *msg, uint32_t indev)
 
309
{
 
310
        msg->queue_msg_indev = indev;
 
311
        msg->ce_mask |= QUEUE_MSG_ATTR_INDEV;
 
312
}
 
313
 
 
314
int nfnl_queue_msg_test_indev(const struct nfnl_queue_msg *msg)
 
315
{
 
316
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_INDEV);
 
317
}
 
318
 
 
319
uint32_t nfnl_queue_msg_get_indev(const struct nfnl_queue_msg *msg)
 
320
{
 
321
        return msg->queue_msg_indev;
 
322
}
 
323
 
 
324
void nfnl_queue_msg_set_outdev(struct nfnl_queue_msg *msg, uint32_t outdev)
 
325
{
 
326
        msg->queue_msg_outdev = outdev;
 
327
        msg->ce_mask |= QUEUE_MSG_ATTR_OUTDEV;
 
328
}
 
329
 
 
330
int nfnl_queue_msg_test_outdev(const struct nfnl_queue_msg *msg)
 
331
{
 
332
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_OUTDEV);
 
333
}
 
334
 
 
335
uint32_t nfnl_queue_msg_get_outdev(const struct nfnl_queue_msg *msg)
 
336
{
 
337
        return msg->queue_msg_outdev;
 
338
}
 
339
 
 
340
void nfnl_queue_msg_set_physindev(struct nfnl_queue_msg *msg,
 
341
                                  uint32_t physindev)
 
342
{
 
343
        msg->queue_msg_physindev = physindev;
 
344
        msg->ce_mask |= QUEUE_MSG_ATTR_PHYSINDEV;
 
345
}
 
346
 
 
347
int nfnl_queue_msg_test_physindev(const struct nfnl_queue_msg *msg)
 
348
{
 
349
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_PHYSINDEV);
 
350
}
 
351
 
 
352
uint32_t nfnl_queue_msg_get_physindev(const struct nfnl_queue_msg *msg)
 
353
{
 
354
        return msg->queue_msg_physindev;
 
355
}
 
356
 
 
357
void nfnl_queue_msg_set_physoutdev(struct nfnl_queue_msg *msg,
 
358
                                   uint32_t physoutdev)
 
359
{
 
360
        msg->queue_msg_physoutdev = physoutdev;
 
361
        msg->ce_mask |= QUEUE_MSG_ATTR_PHYSOUTDEV;
 
362
}
 
363
 
 
364
int nfnl_queue_msg_test_physoutdev(const struct nfnl_queue_msg *msg)
 
365
{
 
366
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_PHYSOUTDEV);
 
367
}
 
368
 
 
369
uint32_t nfnl_queue_msg_get_physoutdev(const struct nfnl_queue_msg *msg)
 
370
{
 
371
        return msg->queue_msg_physoutdev;
 
372
}
 
373
 
 
374
void nfnl_queue_msg_set_hwaddr(struct nfnl_queue_msg *msg, uint8_t *hwaddr,
 
375
                               int len)
 
376
{
 
377
        if (len > sizeof(msg->queue_msg_hwaddr))
 
378
                len = sizeof(msg->queue_msg_hwaddr);
 
379
 
 
380
        msg->queue_msg_hwaddr_len = len;
 
381
        memcpy(msg->queue_msg_hwaddr, hwaddr, len);
 
382
        msg->ce_mask |= QUEUE_MSG_ATTR_HWADDR;
 
383
}
 
384
 
 
385
int nfnl_queue_msg_test_hwaddr(const struct nfnl_queue_msg *msg)
 
386
{
 
387
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_HWADDR);
 
388
}
 
389
 
 
390
const uint8_t *nfnl_queue_msg_get_hwaddr(const struct nfnl_queue_msg *msg,
 
391
                                         int *len)
 
392
{
 
393
        if (!(msg->ce_mask & QUEUE_MSG_ATTR_HWADDR)) {
 
394
                *len = 0;
 
395
                return NULL;
 
396
        }
 
397
 
 
398
        *len = msg->queue_msg_hwaddr_len;
 
399
        return msg->queue_msg_hwaddr;
 
400
}
 
401
 
 
402
int nfnl_queue_msg_set_payload(struct nfnl_queue_msg *msg, uint8_t *payload,
 
403
                               int len)
 
404
{
 
405
        free(msg->queue_msg_payload);
 
406
        msg->queue_msg_payload = malloc(len);
 
407
        if (!msg->queue_msg_payload)
 
408
                return -NLE_NOMEM;
 
409
 
 
410
        memcpy(msg->queue_msg_payload, payload, len);
 
411
        msg->queue_msg_payload_len = len;
 
412
        msg->ce_mask |= QUEUE_MSG_ATTR_PAYLOAD;
 
413
        return 0;
 
414
}
 
415
 
 
416
int nfnl_queue_msg_test_payload(const struct nfnl_queue_msg *msg)
 
417
{
 
418
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_PAYLOAD);
 
419
}
 
420
 
 
421
const void *nfnl_queue_msg_get_payload(const struct nfnl_queue_msg *msg, int *len)
 
422
{
 
423
        if (!(msg->ce_mask & QUEUE_MSG_ATTR_PAYLOAD)) {
 
424
                *len = 0;
 
425
                return NULL;
 
426
        }
 
427
 
 
428
        *len = msg->queue_msg_payload_len;
 
429
        return msg->queue_msg_payload;
 
430
}
 
431
 
 
432
/**
 
433
* Return the number of items matching a filter in the cache
 
434
* @arg msg        queue msg
 
435
* @arg verdict    NF_DROP, NF_ACCEPT, NF_REPEAT, etc
 
436
*/
 
437
void nfnl_queue_msg_set_verdict(struct nfnl_queue_msg *msg,
 
438
                                unsigned int verdict)
 
439
{
 
440
        msg->queue_msg_verdict = verdict;
 
441
        msg->ce_mask |= QUEUE_MSG_ATTR_VERDICT;
 
442
}
 
443
 
 
444
int nfnl_queue_msg_test_verdict(const struct nfnl_queue_msg *msg)
 
445
{
 
446
        return !!(msg->ce_mask & QUEUE_MSG_ATTR_VERDICT);
 
447
}
 
448
 
 
449
unsigned int nfnl_queue_msg_get_verdict(const struct nfnl_queue_msg *msg)
 
450
{
 
451
        return msg->queue_msg_verdict;
 
452
}
 
453
 
 
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)
 
469
};
 
470
 
 
471
static char *nfnl_queue_msg_attrs2str(int attrs, char *buf, size_t len)
 
472
{
 
473
        return __flags2str(attrs, buf, len, nfnl_queue_msg_attrs,
 
474
                           ARRAY_SIZE(nfnl_queue_msg_attrs));
 
475
}
 
476
 
 
477
/** @} */
 
478
 
 
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,
 
484
        .oo_dump = {
 
485
            [NL_DUMP_LINE]      = nfnl_queue_msg_dump,
 
486
            [NL_DUMP_DETAILS]   = nfnl_queue_msg_dump,
 
487
            [NL_DUMP_STATS]     = nfnl_queue_msg_dump,
 
488
        },
 
489
        .oo_attrs2str           = nfnl_queue_msg_attrs2str,
 
490
};
 
491
 
 
492
/** @} */