blob: a86c88a3cdade0f21b46eec33579521fc9cccaf8 [file] [log] [blame]
Harald Weltedaa1ef32005-07-19 21:44:58 +00001/* Shared library add-on to iptables for NFQ
2 *
3 * (C) 2005 by Harald Welte <laforge@netfilter.org>
4 *
5 * This program is distributed under the terms of GNU GPL v2, 1991
6 *
7 */
8#include <stdio.h>
Yasuyuki KOZAKAIa2e89cc2007-07-24 07:29:36 +00009#include <xtables.h>
Yasuyuki KOZAKAIa2e89cc2007-07-24 07:29:36 +000010#include <linux/netfilter/xt_NFQUEUE.h>
Harald Weltedaa1ef32005-07-19 21:44:58 +000011
Jan Engelhardt478be252011-03-06 17:54:50 +010012enum {
13 O_QUEUE_NUM = 0,
14 O_QUEUE_BALANCE,
15 O_QUEUE_BYPASS,
16};
17
Jan Engelhardt932e6482007-10-04 16:27:30 +000018static void NFQUEUE_help(void)
Harald Weltedaa1ef32005-07-19 21:44:58 +000019{
20 printf(
21"NFQUEUE target options\n"
22" --queue-num value Send packet to QUEUE number <value>.\n"
23" Valid queue numbers are 0-65535\n"
24);
25}
26
Florian Westphal4282d892009-08-20 16:39:05 +020027static void NFQUEUE_help_v1(void)
28{
29 NFQUEUE_help();
30 printf(
31" --queue-balance first:last Balance flows between queues <value> to <value>.\n");
32}
33
Florian Westphal6924b492011-01-20 11:27:42 +010034static void NFQUEUE_help_v2(void)
35{
36 NFQUEUE_help_v1();
37 printf(
38" --queue-bypass Bypass Queueing if no queue instance exists.\n");
39}
40
Jan Engelhardt478be252011-03-06 17:54:50 +010041#define s struct xt_NFQ_info
42static const struct xt_option_entry NFQUEUE_opts[] = {
43 {.name = "queue-num", .id = O_QUEUE_NUM, .type = XTTYPE_UINT16,
44 .flags = XTOPT_PUT, XTOPT_POINTER(s, queuenum)},
45 {.name = "queue-balance", .id = O_QUEUE_BALANCE,
46 .type = XTTYPE_UINT16RC},
47 {.name = "queue-bypass", .id = O_QUEUE_BYPASS, .type = XTTYPE_NONE},
48 XTOPT_TABLEEND,
Harald Weltedaa1ef32005-07-19 21:44:58 +000049};
Jan Engelhardt478be252011-03-06 17:54:50 +010050#undef s
Harald Weltedaa1ef32005-07-19 21:44:58 +000051
Jan Engelhardt478be252011-03-06 17:54:50 +010052static void NFQUEUE_parse(struct xt_option_call *cb)
Florian Westphal4282d892009-08-20 16:39:05 +020053{
Jan Engelhardt478be252011-03-06 17:54:50 +010054 xtables_option_parse(cb);
55 if (cb->entry->id == O_QUEUE_BALANCE)
Florian Westphal4282d892009-08-20 16:39:05 +020056 xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: "
57 "--queue-balance not supported (kernel too old?)");
Florian Westphal4282d892009-08-20 16:39:05 +020058}
59
Jan Engelhardt478be252011-03-06 17:54:50 +010060static void NFQUEUE_parse_v1(struct xt_option_call *cb)
Florian Westphal4282d892009-08-20 16:39:05 +020061{
Jan Engelhardt478be252011-03-06 17:54:50 +010062 struct xt_NFQ_info_v1 *info = cb->data;
63 const uint16_t *r = cb->val.u16_range;
Florian Westphal4282d892009-08-20 16:39:05 +020064
Jan Engelhardt478be252011-03-06 17:54:50 +010065 xtables_option_parse(cb);
66 switch (cb->entry->id) {
67 case O_QUEUE_BALANCE:
68 if (cb->nvals != 2)
69 xtables_error(PARAMETER_PROBLEM,
70 "Bad range \"%s\"", cb->arg);
71 if (r[0] >= r[1])
Florian Westphal4282d892009-08-20 16:39:05 +020072 xtables_error(PARAMETER_PROBLEM, "%u should be less than %u",
Jan Engelhardt478be252011-03-06 17:54:50 +010073 r[0], r[1]);
74 info->queuenum = r[0];
75 info->queues_total = r[1] - r[0] + 1;
Florian Westphal4282d892009-08-20 16:39:05 +020076 break;
Harald Weltedaa1ef32005-07-19 21:44:58 +000077 }
Harald Weltedaa1ef32005-07-19 21:44:58 +000078}
79
Jan Engelhardt478be252011-03-06 17:54:50 +010080static void NFQUEUE_parse_v2(struct xt_option_call *cb)
Florian Westphal6924b492011-01-20 11:27:42 +010081{
Jan Engelhardt478be252011-03-06 17:54:50 +010082 struct xt_NFQ_info_v2 *info = cb->data;
83
84 xtables_option_parse(cb);
85 switch (cb->entry->id) {
86 case O_QUEUE_BYPASS:
Florian Westphal6924b492011-01-20 11:27:42 +010087 info->bypass = 1;
Jan Engelhardt478be252011-03-06 17:54:50 +010088 break;
89 default:
90 NFQUEUE_parse_v1(cb);
91 break;
Florian Westphal6924b492011-01-20 11:27:42 +010092 }
Florian Westphal6924b492011-01-20 11:27:42 +010093}
94
Jan Engelhardt932e6482007-10-04 16:27:30 +000095static void NFQUEUE_print(const void *ip,
96 const struct xt_entry_target *target, int numeric)
Harald Weltedaa1ef32005-07-19 21:44:58 +000097{
Yasuyuki KOZAKAIa2e89cc2007-07-24 07:29:36 +000098 const struct xt_NFQ_info *tinfo =
99 (const struct xt_NFQ_info *)target->data;
Jan Engelhardt73866352010-12-18 02:04:59 +0100100 printf(" NFQUEUE num %u", tinfo->queuenum);
Harald Weltedaa1ef32005-07-19 21:44:58 +0000101}
102
Florian Westphal4282d892009-08-20 16:39:05 +0200103static void NFQUEUE_print_v1(const void *ip,
104 const struct xt_entry_target *target, int numeric)
105{
106 const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data;
107 unsigned int last = tinfo->queues_total;
108
109 if (last > 1) {
110 last += tinfo->queuenum - 1;
Jan Engelhardt73866352010-12-18 02:04:59 +0100111 printf(" NFQUEUE balance %u:%u", tinfo->queuenum, last);
Florian Westphal4282d892009-08-20 16:39:05 +0200112 } else {
Jan Engelhardt73866352010-12-18 02:04:59 +0100113 printf(" NFQUEUE num %u", tinfo->queuenum);
Florian Westphal4282d892009-08-20 16:39:05 +0200114 }
115}
116
Florian Westphal6924b492011-01-20 11:27:42 +0100117static void NFQUEUE_print_v2(const void *ip,
118 const struct xt_entry_target *target, int numeric)
119{
120 const struct xt_NFQ_info_v2 *info = (void *) target->data;
121
122 NFQUEUE_print_v1(ip, target, numeric);
123 if (info->bypass)
124 printf(" bypass");
125}
126
Jan Engelhardt932e6482007-10-04 16:27:30 +0000127static void NFQUEUE_save(const void *ip, const struct xt_entry_target *target)
Harald Weltedaa1ef32005-07-19 21:44:58 +0000128{
Yasuyuki KOZAKAIa2e89cc2007-07-24 07:29:36 +0000129 const struct xt_NFQ_info *tinfo =
130 (const struct xt_NFQ_info *)target->data;
Harald Weltedaa1ef32005-07-19 21:44:58 +0000131
Jan Engelhardt73866352010-12-18 02:04:59 +0100132 printf(" --queue-num %u", tinfo->queuenum);
Harald Weltedaa1ef32005-07-19 21:44:58 +0000133}
134
Florian Westphal4282d892009-08-20 16:39:05 +0200135static void NFQUEUE_save_v1(const void *ip, const struct xt_entry_target *target)
136{
137 const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data;
138 unsigned int last = tinfo->queues_total;
139
140 if (last > 1) {
141 last += tinfo->queuenum - 1;
Jan Engelhardt73866352010-12-18 02:04:59 +0100142 printf(" --queue-balance %u:%u", tinfo->queuenum, last);
Florian Westphal4282d892009-08-20 16:39:05 +0200143 } else {
Jan Engelhardt73866352010-12-18 02:04:59 +0100144 printf(" --queue-num %u", tinfo->queuenum);
Florian Westphal4282d892009-08-20 16:39:05 +0200145 }
146}
147
Florian Westphal6924b492011-01-20 11:27:42 +0100148static void NFQUEUE_save_v2(const void *ip, const struct xt_entry_target *target)
149{
150 const struct xt_NFQ_info_v2 *info = (void *) target->data;
151
152 NFQUEUE_save_v1(ip, target);
153
154 if (info->bypass)
155 printf("--queue-bypass ");
156}
157
Florian Westphal4282d892009-08-20 16:39:05 +0200158static void NFQUEUE_init_v1(struct xt_entry_target *t)
159{
160 struct xt_NFQ_info_v1 *tinfo = (void *)t->data;
161 tinfo->queues_total = 1;
162}
163
Florian Westphal6924b492011-01-20 11:27:42 +0100164static struct xtables_target nfqueue_targets[] = {
165{
Jan Engelhardtc5e85732009-06-12 20:55:44 +0200166 .family = NFPROTO_UNSPEC,
Harald Weltedaa1ef32005-07-19 21:44:58 +0000167 .name = "NFQUEUE",
Jan Engelhardt8b7c64d2008-04-15 11:48:25 +0200168 .version = XTABLES_VERSION,
Yasuyuki KOZAKAIa2e89cc2007-07-24 07:29:36 +0000169 .size = XT_ALIGN(sizeof(struct xt_NFQ_info)),
170 .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info)),
Jan Engelhardt932e6482007-10-04 16:27:30 +0000171 .help = NFQUEUE_help,
Jan Engelhardt932e6482007-10-04 16:27:30 +0000172 .print = NFQUEUE_print,
173 .save = NFQUEUE_save,
Jan Engelhardt478be252011-03-06 17:54:50 +0100174 .x6_parse = NFQUEUE_parse,
175 .x6_options = NFQUEUE_opts
Florian Westphal6924b492011-01-20 11:27:42 +0100176},{
Florian Westphal4282d892009-08-20 16:39:05 +0200177 .family = NFPROTO_UNSPEC,
178 .revision = 1,
179 .name = "NFQUEUE",
180 .version = XTABLES_VERSION,
181 .size = XT_ALIGN(sizeof(struct xt_NFQ_info_v1)),
182 .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info_v1)),
183 .help = NFQUEUE_help_v1,
184 .init = NFQUEUE_init_v1,
Florian Westphal4282d892009-08-20 16:39:05 +0200185 .print = NFQUEUE_print_v1,
186 .save = NFQUEUE_save_v1,
Jan Engelhardt478be252011-03-06 17:54:50 +0100187 .x6_parse = NFQUEUE_parse_v1,
188 .x6_options = NFQUEUE_opts,
Florian Westphal6924b492011-01-20 11:27:42 +0100189},{
190 .family = NFPROTO_UNSPEC,
191 .revision = 2,
192 .name = "NFQUEUE",
193 .version = XTABLES_VERSION,
194 .size = XT_ALIGN(sizeof(struct xt_NFQ_info_v2)),
195 .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info_v2)),
196 .help = NFQUEUE_help_v2,
197 .init = NFQUEUE_init_v1,
Florian Westphal6924b492011-01-20 11:27:42 +0100198 .print = NFQUEUE_print_v2,
199 .save = NFQUEUE_save_v2,
Jan Engelhardt478be252011-03-06 17:54:50 +0100200 .x6_parse = NFQUEUE_parse_v2,
201 .x6_options = NFQUEUE_opts,
Florian Westphal6924b492011-01-20 11:27:42 +0100202}
Florian Westphal4282d892009-08-20 16:39:05 +0200203};
204
Harald Weltedaa1ef32005-07-19 21:44:58 +0000205void _init(void)
206{
Florian Westphal6924b492011-01-20 11:27:42 +0100207 xtables_register_targets(nfqueue_targets, ARRAY_SIZE(nfqueue_targets));
Harald Weltedaa1ef32005-07-19 21:44:58 +0000208}