1/* 2 Shared library add-on to iptables to add match support for the fuzzy match. 3 4 This file is distributed under the terms of the GNU General Public 5 License (GPL). Copies of the GPL can be obtained from: 6 ftp://prep.ai.mit.edu/pub/gnu/GPL 7 82002-08-07 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Initial version. 92003-06-09 Hime Aguiar e Oliveira Jr. <hime@engineer.com> : Bug corrections in 10the save function , thanks to information given by Jean-Francois Patenaude . 11 12*/ 13 14#include <stdio.h> 15#include <netdb.h> 16#include <string.h> 17#include <stdlib.h> 18#include <syslog.h> 19#include <getopt.h> 20#include <iptables.h> 21#include <linux/netfilter_ipv4/ip_tables.h> 22#include <linux/netfilter_ipv4/ipt_fuzzy.h> 23 24 25static void 26help(void) 27{ 28 printf( 29"fuzzy v%s options:\n" 30" --lower-limit number (in packets per second)\n" 31" --upper-limit number\n" 32,IPTABLES_VERSION); 33}; 34 35static struct option opts[] = { 36 { "lower-limit", 1 , 0 , '1' } , 37 { "upper-limit", 1 , 0 , '2' } , 38 { 0 } 39}; 40 41/* Initialize data structures */ 42static void 43init(struct ipt_entry_match *m, unsigned int *nfcache) 44{ 45 struct ipt_fuzzy_info *presentinfo = (struct ipt_fuzzy_info *)(m)->data; 46 47 /* 48 * Default rates ( I'll improve this very soon with something based 49 * on real statistics of the running machine ) . 50 */ 51 52 presentinfo->minimum_rate = 1000; 53 presentinfo->maximum_rate = 2000; 54} 55 56#define IPT_FUZZY_OPT_MINIMUM 0x01 57#define IPT_FUZZY_OPT_MAXIMUM 0x02 58 59static int 60parse(int c, char **argv, int invert, unsigned int *flags, 61 const struct ipt_entry *entry, 62 unsigned int *nfcache, 63 struct ipt_entry_match **match) 64{ 65 66struct ipt_fuzzy_info *fuzzyinfo = (struct ipt_fuzzy_info *)(*match)->data; 67 68 u_int32_t num; 69 70 switch (c) { 71 72 case '1': 73 74 if (invert) 75 exit_error(PARAMETER_PROBLEM,"Can't specify ! --lower-limit"); 76 77 if (*flags & IPT_FUZZY_OPT_MINIMUM) 78 exit_error(PARAMETER_PROBLEM,"Can't specify --lower-limit twice"); 79 80 if (string_to_number(optarg,1,MAXFUZZYRATE,&num) == -1 || num < 1) 81 exit_error(PARAMETER_PROBLEM,"BAD --lower-limit"); 82 83 fuzzyinfo->minimum_rate = num ; 84 85 *flags |= IPT_FUZZY_OPT_MINIMUM; 86 87 break; 88 89 case '2': 90 91 if (invert) 92 exit_error(PARAMETER_PROBLEM,"Can't specify ! --upper-limit"); 93 94 if (*flags & IPT_FUZZY_OPT_MAXIMUM) 95 exit_error(PARAMETER_PROBLEM,"Can't specify --upper-limit twice"); 96 97 if (string_to_number(optarg,1,MAXFUZZYRATE,&num) == -1 || num < 1) 98 exit_error(PARAMETER_PROBLEM,"BAD --upper-limit"); 99 100 fuzzyinfo->maximum_rate = num ; 101 102 *flags |= IPT_FUZZY_OPT_MAXIMUM; 103 104 break ; 105 106 default: 107 return 0; 108 } 109 return 1; 110} 111 112static void final_check(unsigned int flags) 113{ 114} 115 116static void 117print(const struct ipt_ip *ip, 118 const struct ipt_entry_match *match, 119 int numeric) 120{ 121 const struct ipt_fuzzy_info *fuzzyinfo 122 = (const struct ipt_fuzzy_info *)match->data; 123 124 printf(" fuzzy: lower limit = %u pps - upper limit = %u pps ",fuzzyinfo->minimum_rate,fuzzyinfo->maximum_rate); 125 126} 127 128/* Saves the union ipt_targinfo in parsable form to stdout. */ 129static void 130save(const struct ipt_ip *ip, const struct ipt_entry_match *match) 131{ 132 const struct ipt_fuzzy_info *fuzzyinfo 133 = (const struct ipt_fuzzy_info *)match->data; 134 135 printf("--lower-limit %u ",fuzzyinfo->minimum_rate); 136 printf("--upper-limit %u ",fuzzyinfo->maximum_rate); 137 138} 139 140static struct iptables_match fuzzy_match = { 141 .next = NULL, 142 .name = "fuzzy", 143 .version = IPTABLES_VERSION, 144 .size = IPT_ALIGN(sizeof(struct ipt_fuzzy_info)), 145 .userspacesize = IPT_ALIGN(sizeof(struct ipt_fuzzy_info)), 146 .help = &help, 147 .init = &init, 148 .parse = &parse, 149 .final_check = &final_check, 150 .print = &print, 151 .save = &save, 152 .extra_opts = opts 153}; 154 155void _init(void) 156{ 157 register_match(&fuzzy_match); 158} 159