1 /* Shared library add-on to iptables to add recent matching support. */
9 #include <linux/netfilter_ipv4/ipt_recent.h>
11 /* Function which prints out usage message. */
16 "recent v%s options:\n"
17 "[!] --set Add source address to list, always matches.\n"
18 "[!] --rcheck Match if source address in list.\n"
19 "[!] --update Match if source address in list, also update last-seen time.\n"
20 "[!] --remove Match if source address in list, also removes that address from list.\n"
21 " --seconds seconds For check and update commands above.\n"
22 " Specifies that the match will only occur if source address last seen within\n"
23 " the last 'seconds' seconds.\n"
24 " --hitcount hits For check and update commands above.\n"
25 " Specifies that the match will only occur if source address seen hits times.\n"
26 " May be used in conjunction with the seconds option.\n"
27 " --rttl For check and update commands above.\n"
28 " Specifies that the match will only occur if the source address and the TTL\n"
29 " match between this packet and the one which was set.\n"
30 " Useful if you have problems with people spoofing their source address in order\n"
31 " to DoS you via this module.\n"
32 " --name name Name of the recent list to be used. DEFAULT used if none given.\n"
33 " --rsource Save the source address of each packet in the recent list table (default).\n"
34 " --rdest Save the destination address of each packet in the recent list table.\n"
40 static struct option opts[] = {
42 { "rcheck", 0, 0, 202 },
43 { "update", 0, 0, 203 },
44 { "seconds", 1, 0, 204 },
45 { "hitcount", 1, 0, 205 },
46 { "remove",0, 0, 206 },
48 { "name", 1, 0, 208 },
49 { "rsource", 0, 0, 209 },
50 { "rdest", 0, 0, 210 },
54 /* Initialize the match. */
56 init(struct ipt_entry_match *match, unsigned int *nfcache)
58 struct ipt_recent_info *info = (struct ipt_recent_info *)(match)->data;
60 *nfcache |= NFC_UNKNOWN;
62 strncpy(info->name, "DEFAULT", 200);
63 info->side = IPT_RECENT_SOURCE;
66 /* Function which parses command options; returns true if it
69 parse(int c, char **argv, int invert, unsigned int *flags,
70 const struct ipt_entry *entry,
71 unsigned int *nfcache,
72 struct ipt_entry_match **match)
74 struct ipt_recent_info *info = (struct ipt_recent_info *)(*match)->data;
78 exit_error(PARAMETER_PROBLEM,
79 "recent: only one of `--set', `--check' "
80 "`--update' or `--remove' may be set");
81 check_inverse(optarg, &invert, &optind, 0);
82 info->check_set |= IPT_RECENT_SET;
90 exit_error(PARAMETER_PROBLEM,
91 "recent: only one of `--set', `--check' "
92 "`--update' or `--remove' may be set");
93 check_inverse(optarg, &invert, &optind, 0);
94 info->check_set |= IPT_RECENT_CHECK;
102 exit_error(PARAMETER_PROBLEM,
103 "recent: only one of `--set', `--check' "
104 "`--update' or `--remove' may be set");
105 check_inverse(optarg, &invert, &optind, 0);
106 info->check_set |= IPT_RECENT_UPDATE;
114 exit_error(PARAMETER_PROBLEM,
115 "recent: only one of `--set', `--check' "
116 "`--update' or `--remove' may be set");
117 check_inverse(optarg, &invert, &optind, 0);
118 info->check_set |= IPT_RECENT_REMOVE;
125 info->seconds = atoi(optarg);
129 info->hit_count = atoi(optarg);
133 info->check_set |= IPT_RECENT_TTL;
137 strncpy(info->name, optarg, 200);
141 info->side = IPT_RECENT_SOURCE;
145 info->side = IPT_RECENT_DEST;
155 /* Final check; must have specified a specific option. */
157 final_check(unsigned int flags)
161 exit_error(PARAMETER_PROBLEM,
162 "recent: you must specify one of `--set', `--check' "
163 "`--update' or `--remove'");
166 /* Prints out the matchinfo. */
168 print(const struct ipt_ip *ip,
169 const struct ipt_entry_match *match,
172 struct ipt_recent_info *info = (struct ipt_recent_info *)match->data;
174 if (info->invert) fputc('!', stdout);
177 if(info->check_set & IPT_RECENT_SET) printf("SET ");
178 if(info->check_set & IPT_RECENT_CHECK) printf("CHECK ");
179 if(info->check_set & IPT_RECENT_UPDATE) printf("UPDATE ");
180 if(info->check_set & IPT_RECENT_REMOVE) printf("REMOVE ");
181 if(info->seconds) printf("seconds: %d ", info->seconds);
182 if(info->hit_count) printf("hit_count: %d ", info->hit_count);
183 if(info->check_set & IPT_RECENT_TTL) printf("TTL-Match ");
184 if(info->name) printf("name: %s ", info->name);
185 if(info->side == IPT_RECENT_SOURCE) printf("side: source ");
186 if(info->side == IPT_RECENT_DEST) printf("side: dest");
189 /* Saves the union ipt_matchinfo in parsable form to stdout. */
191 save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
193 struct ipt_recent_info *info = (struct ipt_recent_info *)match;
195 if (info->invert) fputc('!', stdout);
198 if(info->check_set & IPT_RECENT_SET) printf("SET ");
199 if(info->check_set & IPT_RECENT_CHECK) printf("CHECK ");
200 if(info->check_set & IPT_RECENT_UPDATE) printf("UPDATE ");
201 if(info->check_set & IPT_RECENT_REMOVE) printf("REMOVE ");
202 if(info->seconds) printf("seconds: %d ",info->seconds);
203 if(info->hit_count) printf("hit_count: %d ",info->hit_count);
204 if(info->check_set & IPT_RECENT_TTL) printf("TTL-Match ");
205 if(info->name) printf("name: %s ",info->name);
206 if(info->side == IPT_RECENT_SOURCE) printf("side: source ");
207 if(info->side == IPT_RECENT_DEST) printf("side: dest");
211 struct iptables_match recent
215 IPT_ALIGN(sizeof(struct ipt_recent_info)),
216 IPT_ALIGN(sizeof(struct ipt_recent_info)),
228 register_match(&recent);