1/* 2 3 bcount match (experimental) 4 Copyright (C) 2006 Jonathan Zarate 5 6 Licensed under GNU GPL v2 or later. 7 8*/ 9#include <stdio.h> 10#include <string.h> 11#include <stdlib.h> 12#include <getopt.h> 13 14#include <iptables.h> 15#include <linux/netfilter_ipv4/ipt_bcount.h> 16 17 18#undef IPTABLES_SAVE 19 20 21static void help(void) 22{ 23 printf( 24 "bcount match v0.00\n" 25 "[!] --range min:max (upper range of 0x0FFFFFFF or more means unlimited)\n" 26 ); 27} 28 29static void init(struct ipt_entry_match *match, unsigned int *nfcache) 30{ 31 struct ipt_bcount_match *info = (struct ipt_bcount_match *)match->data; 32 info->min = 0xFFFFFFFF; 33 info->max = 0x0FFFFFFF; 34 *nfcache |= NFC_UNKNOWN; 35} 36 37static struct option opts[] = { 38 { .name = "range", .has_arg = 1, .flag = 0, .val = '1' }, 39 { .name = NULL } 40}; 41 42static int parse(int c, char **argv, int invert, unsigned int *flags, 43 const struct ipt_entry *entry, unsigned int *nfcache, 44 struct ipt_entry_match **match) 45{ 46 char *p; 47 struct ipt_bcount_match *info; 48 49 if (c != '1') return 0; 50 51 info = (struct ipt_bcount_match *)(*match)->data; 52 53 *flags = 1; 54 check_inverse(optarg, &invert, &optind, 0); 55 if (invert) info->invert = 1; 56 57 info->min = strtoul(argv[optind - 1], &p, 0); 58 if (*p == '+') { 59 ++p; 60 } 61 else if ((*p == '-') || (*p == ':')) { 62 ++p; 63 if ((*p == 0) || (strcmp(p, "max") == 0)) { 64 info->max = 0x0FFFFFFF; 65 } 66 else { 67 info->max = strtoul(p, &p, 0); 68 if (info->max > 0x0FFFFFFF) info->max = 0x0FFFFFFF; 69 } 70 } 71 72 if ((*p != 0) || (info->min > info->max)) 73 exit_error(PARAMETER_PROBLEM, "Invalid range"); 74 return 1; 75} 76 77static void final_check(unsigned int flags) 78{ 79 if (!flags) { 80 exit_error(PARAMETER_PROBLEM, "Invalid range"); 81 } 82} 83 84static void print_match(const struct ipt_bcount_match *info) 85{ 86 if (info->min != 0xFFFFFFFF) { 87 if (info->invert) printf("! "); 88 printf("--range %u", info->min); 89 if (info->max == 0x0FFFFFFF) printf("+ "); 90 else printf(":%u ", info->max); 91 } 92} 93 94static void print(const struct ipt_ip *ip, const struct ipt_entry_match *match, int numeric) 95{ 96 printf("bcount "); 97 print_match((const struct ipt_bcount_match *)match->data); 98} 99 100static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match) 101{ 102#ifdef IPTABLES_SAVE 103 print_match((const struct ipt_bcount_match *)match->data); 104#endif 105} 106 107 108static struct iptables_match bcount_match = { 109 .name = "bcount", 110 .version = IPTABLES_VERSION, 111 .size = IPT_ALIGN(sizeof(struct ipt_bcount_match)), 112 .userspacesize = IPT_ALIGN(sizeof(struct ipt_bcount_match)), 113 .help = &help, 114 .init = &init, 115 .parse = &parse, 116 .final_check = &final_check, 117 .print = &print, 118 .save = &save, 119 .extra_opts = opts 120}; 121 122void _init(void) 123{ 124 register_match(&bcount_match); 125} 126