libxt_NFQUEUE.c revision 32b8e61e4e5bd405d9ad07bf9468498dfbb19f9e
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 default: 74 return 0; 75 } 76 77 return 1; 78} 79 80static int 81NFQUEUE_parse_v1(int c, char **argv, int invert, unsigned int *flags, 82 const void *entry, struct xt_entry_target **target) 83{ 84 struct xt_NFQ_info_v1 *info = (void *)(*target)->data; 85 char *colon; 86 unsigned int firstqueue, lastqueue; 87 88 switch (c) { 89 case 'F': /* fallthrough */ 90 case 'B': 91 if (*flags) 92 xtables_error(PARAMETER_PROBLEM, "NFQUEUE target: " 93 "Only use --queue-num ONCE!"); 94 95 if (!xtables_strtoui(optarg, &colon, &firstqueue, 0, UINT16_MAX)) 96 exit_badqueue(optarg); 97 98 info->queuenum = firstqueue; 99 100 if (c == 'F') { 101 if (*colon) 102 exit_badqueue(optarg); 103 break; 104 } 105 106 if (*colon != ':') 107 xtables_error(PARAMETER_PROBLEM, "Bad range \"%s\"", optarg); 108 109 if (!xtables_strtoui(colon + 1, NULL, &lastqueue, 1, UINT16_MAX)) 110 exit_badqueue(optarg); 111 112 if (firstqueue >= lastqueue) 113 xtables_error(PARAMETER_PROBLEM, "%u should be less than %u", 114 firstqueue, lastqueue); 115 info->queues_total = lastqueue - firstqueue + 1; 116 break; 117 default: 118 return 0; 119 } 120 121 return 1; 122} 123 124static void NFQUEUE_print(const void *ip, 125 const struct xt_entry_target *target, int numeric) 126{ 127 const struct xt_NFQ_info *tinfo = 128 (const struct xt_NFQ_info *)target->data; 129 printf("NFQUEUE num %u", tinfo->queuenum); 130} 131 132static void NFQUEUE_print_v1(const void *ip, 133 const struct xt_entry_target *target, int numeric) 134{ 135 const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data; 136 unsigned int last = tinfo->queues_total; 137 138 if (last > 1) { 139 last += tinfo->queuenum - 1; 140 printf("NFQUEUE balance %u:%u", tinfo->queuenum, last); 141 } else { 142 printf("NFQUEUE num %u", tinfo->queuenum); 143 } 144} 145 146static void NFQUEUE_save(const void *ip, const struct xt_entry_target *target) 147{ 148 const struct xt_NFQ_info *tinfo = 149 (const struct xt_NFQ_info *)target->data; 150 151 printf("--queue-num %u ", tinfo->queuenum); 152} 153 154static void NFQUEUE_save_v1(const void *ip, const struct xt_entry_target *target) 155{ 156 const struct xt_NFQ_info_v1 *tinfo = (const void *)target->data; 157 unsigned int last = tinfo->queues_total; 158 159 if (last > 1) { 160 last += tinfo->queuenum - 1; 161 printf("--queue-balance %u:%u ", tinfo->queuenum, last); 162 } else { 163 printf("--queue-num %u ", tinfo->queuenum); 164 } 165} 166 167static void NFQUEUE_init_v1(struct xt_entry_target *t) 168{ 169 struct xt_NFQ_info_v1 *tinfo = (void *)t->data; 170 tinfo->queues_total = 1; 171} 172 173static struct xtables_target nfqueue_target = { 174 .family = NFPROTO_UNSPEC, 175 .name = "NFQUEUE", 176 .version = XTABLES_VERSION, 177 .size = XT_ALIGN(sizeof(struct xt_NFQ_info)), 178 .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info)), 179 .help = NFQUEUE_help, 180 .parse = NFQUEUE_parse, 181 .print = NFQUEUE_print, 182 .save = NFQUEUE_save, 183 .extra_opts = NFQUEUE_opts 184}; 185 186static struct xtables_target nfqueue_target_v1 = { 187 .family = NFPROTO_UNSPEC, 188 .revision = 1, 189 .name = "NFQUEUE", 190 .version = XTABLES_VERSION, 191 .size = XT_ALIGN(sizeof(struct xt_NFQ_info_v1)), 192 .userspacesize = XT_ALIGN(sizeof(struct xt_NFQ_info_v1)), 193 .help = NFQUEUE_help_v1, 194 .init = NFQUEUE_init_v1, 195 .parse = NFQUEUE_parse_v1, 196 .print = NFQUEUE_print_v1, 197 .save = NFQUEUE_save_v1, 198 .extra_opts = NFQUEUE_opts, 199}; 200 201void _init(void) 202{ 203 xtables_register_target(&nfqueue_target); 204 xtables_register_target(&nfqueue_target_v1); 205} 206