1 /* Shared library add-on to iptables to add connection limit support. */
9 #include <linux/netfilter_ipv4/ip_conntrack.h>
10 #include <linux/netfilter_ipv4/ipt_connlimit.h>
12 /* Function which prints out usage message. */
17 "connlimit v%s options:\n"
18 "[!] --connlimit-above n match if the number of existing tcp connections is (not) above n\n"
19 " --connlimit-mask n group hosts using mask\n"
20 "\n", IPTABLES_VERSION
);
23 static struct option opts
[] = {
24 { "connlimit-above", 1, 0, '1' },
25 { "connlimit-mask", 1, 0, '2' },
29 static void connlimit_init(struct ipt_entry_match
*match
, unsigned int *nfc
)
31 struct ipt_connlimit_info
*info
= (void *)match
->data
;
32 info
->mask
= htonl(0xFFFFFFFF);
35 /* Function which parses command options; returns true if it
38 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
39 const struct ipt_entry
*entry
,
40 unsigned int *nfcache
,
41 struct ipt_entry_match
**match
)
43 struct ipt_connlimit_info
*info
= (struct ipt_connlimit_info
*)(*match
)->data
;
48 exit_error(PARAMETER_PROBLEM
,
49 "--connlimit-above and/or --connlimit-mask may "
50 "only be given once");
54 check_inverse(optarg
, &invert
, &optind
, 0);
55 info
->limit
= strtoul(argv
[optind
-1], NULL
, 0);
56 info
->inverse
= invert
;
60 i
= strtoul(argv
[optind
-1], &err
, 0);
61 if (i
> 32 || *err
!= '\0')
62 exit_error(PARAMETER_PROBLEM
,
63 "--connlimit-mask must be between 0 and 32");
67 info
->mask
= htonl(0xFFFFFFFF << (32 - i
));
79 static void final_check(unsigned int flags
)
82 exit_error(PARAMETER_PROBLEM
,
83 "You must specify \"--connlimit-above\"");
87 count_bits(u_int32_t mask
)
89 unsigned int bits
= 0;
91 for (mask
= ~ntohl(mask
); mask
!= 0; mask
>>= 1)
97 /* Prints out the matchinfo. */
99 print(const struct ipt_ip
*ip
,
100 const struct ipt_entry_match
*match
,
103 struct ipt_connlimit_info
*info
= (struct ipt_connlimit_info
*)match
->data
;
105 printf("#conn/%d %s %d ", count_bits(info
->mask
),
106 info
->inverse
? "<=" : ">", info
->limit
);
109 /* Saves the matchinfo in parsable form to stdout. */
110 static void save(const struct ipt_ip
*ip
, const struct ipt_entry_match
*match
)
112 struct ipt_connlimit_info
*info
= (struct ipt_connlimit_info
*)match
->data
;
114 printf("%s--connlimit-above %u --connlimit-mask %u ",
115 info
->inverse
? "! " : "", info
->limit
,
116 count_bits(info
->mask
));
119 static struct iptables_match connlimit
= {
121 .version
= IPTABLES_VERSION
,
122 .size
= IPT_ALIGN(sizeof(struct ipt_connlimit_info
)),
123 .userspacesize
= offsetof(struct ipt_connlimit_info
,data
),
125 .init
= connlimit_init
,
127 .final_check
= final_check
,
135 register_match(&connlimit
);