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 /* Function which parses command options; returns true if it
32 parse(int c, char **argv, int invert, unsigned int *flags,
33 const struct ipt_entry *entry,
34 unsigned int *nfcache,
35 struct ipt_entry_match **match)
37 struct ipt_connlimit_info *info = (struct ipt_connlimit_info*)(*match)->data;
40 if (0 == (*flags & 2)) {
41 /* set default mask unless we've already seen a mask option */
42 info->mask = htonl(0xFFFFFFFF);
47 check_inverse(optarg, &invert, &optind, 0);
48 info->limit = atoi(argv[optind-1]);
49 info->inverse = invert;
54 i = atoi(argv[optind-1]);
55 if ((i < 0) || (i > 32))
56 exit_error(PARAMETER_PROBLEM,
57 "--connlimit-mask must be between 0 and 32");
62 info->mask = htonl(0xFFFFFFFF << (32 - i));
74 static void final_check(unsigned int flags)
77 exit_error(PARAMETER_PROBLEM, "You must specify `--connlimit-above'");
81 count_bits(u_int32_t mask)
85 for (bits = 0, i = 31; i >= 0; i--) {
86 if (mask & htonl((u_int32_t)1 << i)) {
95 /* Prints out the matchinfo. */
97 print(const struct ipt_ip *ip,
98 const struct ipt_entry_match *match,
101 struct ipt_connlimit_info *info = (struct ipt_connlimit_info*)match->data;
103 printf("#conn/%d %s %d ", count_bits(info->mask),
104 info->inverse ? "<" : ">", info->limit);
107 /* Saves the matchinfo in parsable form to stdout. */
108 static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
110 struct ipt_connlimit_info *info = (struct ipt_connlimit_info*)match->data;
112 printf("%s--connlimit-above %d ",info->inverse ? "! " : "",info->limit);
113 printf("--connlimit-mask %d ",count_bits(info->mask));
116 static struct iptables_match connlimit = {
118 .version = IPTABLES_VERSION,
119 .size = IPT_ALIGN(sizeof(struct ipt_connlimit_info)),
120 .userspacesize = offsetof(struct ipt_connlimit_info,data),
123 .final_check = final_check,
131 register_match(&connlimit);