libxt_NFQUEUE.c revision d09b6d591ca7d7d7575cb6aa20384c9830f777ab
1/* 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 <stdbool.h> 9#include <stdio.h> 10#include <string.h> 11#include <stdlib.h> 12#include <getopt.h> 13 14#include <xtables.h> 15#include <linux/netfilter/x_tables.h> 16#include <linux/netfilter/xt_NFQUEUE.h> 17 18static void NFQUEUE_help(void) 19{ 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 27static 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 34static const struct option NFQUEUE_opts[] = { 35 {.name = "queue-num", .has_arg = true, .val = 'F'}, 36 {.name = "queue-balance", .has_arg = true, .val = 'B'}, 37 XT_GETOPT_TABLEEND, 38}; 39 40static void exit_badqueue(const char *s) 41{ 42 xtables_error(PARAMETER_PROBLEM, "Invalid queue number `%s'\n", s); 43} 44 45static void 46parse_num(const char *s, struct xt_NFQ_info *tinfo) 47{ 48 unsigned int num; 49 50 if (!xtables_strtoui(s, NULL, &num, 0, UINT16_MAX)) 51 exit_badqueue(s); 52 53 tinfo->queuenum = num; 54} 55 56static int 57NFQUEUE_parse(int c, char **argv, int invert, unsigned int *flags, 58 const void *entry, struct xt_entry_target **target) 59{ 60 struct xt_NFQ_info *tinfo 61 = (struct xt_NFQ_info *)(*target)->data; 62 63 switch (c) { 64 case 'F': 65 if (*flags) 66 xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: " 67 "Only use --queue-num ONCE!"); 68 parse_num(optarg, tinfo); 69 break; 70 case 'B': 71 xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: " 72 "--queue-balance not supported (kernel too old?)"); 73 } 74 75 return 1; 76} 77 78static int 79NFQUEUE_parse_v1(int c, char **argv, int invert, unsigned int *flags, 80 const void *entry, struct xt_entry_target **target) 81{ 82 struct xt_NFQ_info_v1 *info = (void *)(*target)->data; 83 char *colon; 84 unsigned int firstqueue, lastqueue; 85 86 switch (c) { 87 case 'F': /* fallthrough */ 88 case 'B': 89 if (*flags) 90 xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: " 91 "Only use --queue-num ONCE!"); 92 93 if (!xtables_strtoui(optarg, &colon, &firstqueue, 0, UINT16_MAX)) 94 exit_badqueue(optarg); 95 96 info->queuenum = firstqueue; 97 98 if (c == 'F') { 99 if (*colon) 100 exit_badqueue(optarg); 101 break; 102 } 103 104 if (*colon != ':') 105 xtables_error(PARAMETER_PROBLEM, "Bad range \"%s\"", optarg); 106 107 if (!xtables_strtoui(colon + 1, NULL, &lastqueue, 1, UINT16_MAX)) 108 exit_badqueue(optarg); 109 110 if (firstqueue >= lastqueue) 111 xtables_error(PARAMETER_PROBLEM, "%u should be less than %u", 112 firstqueue, lastqueue); 113 info->queues_total = lastqueue - firstqueue + 1; 114 break; 115 } 116 117 return 1; 118} 119 120static void NFQUEUE_print(const void *ip, 121 const struct xt_entry_target *target, int numeric) 122{ 123 const struct xt_NFQ_info *tinfo = 124 (const struct xt_NFQ_info *)target->data; 125 printf("NFQUEUE num %u", tinfo->queuenum); 126} 127 128static void NFQUEUE_print_v1(const void *ip, 129 const struct xt_entry_target *target, int numeric) 130{ 131 const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data; 132 unsigned int last = tinfo->queues_total; 133 134 if (last > 1) { 135 last += tinfo->queuenum - 1; 136 printf("NFQUEUE balance %u:%u", tinfo->queuenum, last); 137 } else { 138 printf("NFQUEUE num %u", tinfo->queuenum); 139 } 140} 141 142static void NFQUEUE_save(const void *ip, const struct xt_entry_target *target) 143{ 144 const struct xt_NFQ_info *tinfo = 145 (const struct xt_NFQ_info *)target->data; 146 147 printf("--queue-num %u ", tinfo->queuenum); 148} 149 150static void NFQUEUE_save_v1(const void *ip, const struct xt_entry_target *target) 151{ 152 const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data; 153 unsigned int last = tinfo->queues_total; 154 155 if (last > 1) { 156 last += tinfo->queuenum - 1; 157 printf("--queue-balance %u:%u ", tinfo->queuenum, last); 158 } else { 159 printf("--queue-num %u ", tinfo->queuenum); 160 } 161} 162 163static void NFQUEUE_init_v1(struct xt_entry_target *t) 164{ 165 struct xt_NFQ_info_v1 *tinfo = (void *)t->data; 166 tinfo->queues_total = 1; 167} 168 169static struct xtables_target nfqueue_target = { 170 .family = NFPROTO_UNSPEC, 171 .name = "NFQUEUE", 172 .version = XTABLES_VERSION, 173 .size = XT_ALIGN(sizeof(struct xt_NFQ_info)), 174 .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info)), 175 .help = NFQUEUE_help, 176 .parse = NFQUEUE_parse, 177 .print = NFQUEUE_print, 178 .save = NFQUEUE_save, 179 .extra_opts = NFQUEUE_opts 180}; 181 182static struct xtables_target nfqueue_target_v1 = { 183 .family = NFPROTO_UNSPEC, 184 .revision = 1, 185 .name = "NFQUEUE", 186 .version = XTABLES_VERSION, 187 .size = XT_ALIGN(sizeof(struct xt_NFQ_info_v1)), 188 .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info_v1)), 189 .help = NFQUEUE_help_v1, 190 .init = NFQUEUE_init_v1, 191 .parse = NFQUEUE_parse_v1, 192 .print = NFQUEUE_print_v1, 193 .save = NFQUEUE_save_v1, 194 .extra_opts = NFQUEUE_opts, 195}; 196 197void _init(void) 198{ 199 xtables_register_target(&nfqueue_target); 200 xtables_register_target(&nfqueue_target_v1); 201} 202