1 /* Shared library add-on to iptables to add recent matching support. */
9 #include <linux/netfilter_ipv6/ip6_tables.h>
10 #include <linux/netfilter/xt_recent.h>
12 #ifndef XTABLES_VERSION
13 #define XTABLES_VERSION IPTABLES_VERSION
17 #define xtables_target ip6tables_target
18 #define xtables_register_target register_target6
21 /* Need these in order to not fail when compiling against an older kernel. */
23 #define RECENT_NAME "ip6t_recent"
24 #endif /* RECENT_NAME */
27 #define RECENT_VER "unknown"
28 #endif /* RECENT_VER */
30 /* Options for this module */
31 static struct option opts
[] = {
32 { .name
= "set", .has_arg
= 0, .flag
= 0, .val
= 201 },
33 { .name
= "rcheck", .has_arg
= 0, .flag
= 0, .val
= 202 },
34 { .name
= "update", .has_arg
= 0, .flag
= 0, .val
= 203 },
35 { .name
= "seconds", .has_arg
= 1, .flag
= 0, .val
= 204 },
36 { .name
= "hitcount", .has_arg
= 1, .flag
= 0, .val
= 205 },
37 { .name
= "remove", .has_arg
= 0, .flag
= 0, .val
= 206 },
38 { .name
= "rttl", .has_arg
= 0, .flag
= 0, .val
= 207 },
39 { .name
= "name", .has_arg
= 1, .flag
= 0, .val
= 208 },
40 { .name
= "rsource", .has_arg
= 0, .flag
= 0, .val
= 209 },
41 { .name
= "rdest", .has_arg
= 0, .flag
= 0, .val
= 210 },
42 { .name
= 0, .has_arg
= 0, .flag
= 0, .val
= 0 }
45 /* Function which prints out usage message. */
50 "recent v%s options:\n"
51 "[!] --set Add source address to list, always matches.\n"
52 "[!] --rcheck Match if source address in list.\n"
53 "[!] --update Match if source address in list, also update last-seen time.\n"
54 "[!] --remove Match if source address in list, also removes that address from list.\n"
55 " --seconds seconds For check and update commands above.\n"
56 " Specifies that the match will only occur if source address last seen within\n"
57 " the last 'seconds' seconds.\n"
58 " --hitcount hits For check and update commands above.\n"
59 " Specifies that the match will only occur if source address seen hits times.\n"
60 " May be used in conjunction with the seconds option.\n"
61 " --rttl For check and update commands above.\n"
62 " Specifies that the match will only occur if the source address and the TTL\n"
63 " match between this packet and the one which was set.\n"
64 " Useful if you have problems with people spoofing their source address in order\n"
65 " to DoS you via this module.\n"
66 " --name name Name of the recent list to be used. DEFAULT used if none given.\n"
67 " --rsource Match/Save the source address of each packet in the recent list table (default).\n"
68 " --rdest Match/Save the destination address of each packet in the recent list table.\n"
69 RECENT_NAME
" " RECENT_VER
": Stephen Frost <sfrost@snowman.net>. http://snowman.net/projects/ipt_recent/\n"
75 /* Initialize the match. */
77 init(struct ip6t_entry_match
*match
, unsigned int *nfcache
)
79 struct xt_recent_mtinfo
*info
= (struct xt_recent_mtinfo
*)(match
)->data
;
82 strncpy(info
->name
,"DEFAULT",XT_RECENT_NAME_LEN
);
83 /* eventhough XT_RECENT_NAME_LEN is currently defined as 200,
84 * better be safe, than sorry */
85 info
->name
[XT_RECENT_NAME_LEN
-1] = '\0';
86 info
->side
= XT_RECENT_SOURCE
;
89 /* Function which parses command options; returns true if it
92 parse(int c
, char **argv
, int invert
, unsigned int *flags
,
93 const struct ip6t_entry
*entry
,
94 unsigned int *nfcache
,
95 struct ip6t_entry_match
**match
)
97 struct xt_recent_mtinfo
*info
= (struct xt_recent_mtinfo
*)(*match
)->data
;
100 if (*flags
) exit_error(PARAMETER_PROBLEM
,
101 "recent: only one of `--set', `--rcheck' "
102 "`--update' or `--remove' may be set");
103 check_inverse(optarg
, &invert
, &optind
, 0);
104 info
->check_set
|= XT_RECENT_SET
;
105 if (invert
) info
->invert
= 1;
110 if (*flags
) exit_error(PARAMETER_PROBLEM
,
111 "recent: only one of `--set', `--rcheck' "
112 "`--update' or `--remove' may be set");
113 check_inverse(optarg
, &invert
, &optind
, 0);
114 info
->check_set
|= XT_RECENT_CHECK
;
115 if(invert
) info
->invert
= 1;
120 if (*flags
) exit_error(PARAMETER_PROBLEM
,
121 "recent: only one of `--set', `--rcheck' "
122 "`--update' or `--remove' may be set");
123 check_inverse(optarg
, &invert
, &optind
, 0);
124 info
->check_set
|= XT_RECENT_UPDATE
;
125 if (invert
) info
->invert
= 1;
130 if (*flags
) exit_error(PARAMETER_PROBLEM
,
131 "recent: only one of `--set', `--rcheck' "
132 "`--update' or `--remove' may be set");
133 check_inverse(optarg
, &invert
, &optind
, 0);
134 info
->check_set
|= XT_RECENT_REMOVE
;
135 if (invert
) info
->invert
= 1;
140 info
->seconds
= atoi(optarg
);
144 info
->hit_count
= atoi(optarg
);
148 info
->check_set
|= XT_RECENT_TTL
;
152 strncpy(info
->name
,optarg
,XT_RECENT_NAME_LEN
);
153 info
->name
[XT_RECENT_NAME_LEN
-1] = '\0';
157 info
->side
= XT_RECENT_SOURCE
;
161 info
->side
= XT_RECENT_DEST
;
171 /* Final check; must have specified a specific option. */
173 final_check(unsigned int flags
)
176 exit_error(PARAMETER_PROBLEM
,
177 "recent: you must specify one of `--set', `--rcheck' "
178 "`--update' or `--remove'");
181 /* Prints out the matchinfo. */
183 print(const struct ip6t_ip6
*ip
,
184 const struct ip6t_entry_match
*match
,
187 struct xt_recent_mtinfo
*info
= (struct xt_recent_mtinfo
*)match
->data
;
193 if(info
->check_set
& XT_RECENT_SET
) printf("SET ");
194 if(info
->check_set
& XT_RECENT_CHECK
) printf("CHECK ");
195 if(info
->check_set
& XT_RECENT_UPDATE
) printf("UPDATE ");
196 if(info
->check_set
& XT_RECENT_REMOVE
) printf("REMOVE ");
197 if(info
->seconds
) printf("seconds: %d ",info
->seconds
);
198 if(info
->hit_count
) printf("hit_count: %d ",info
->hit_count
);
199 if(info
->check_set
& XT_RECENT_TTL
) printf("TTL-Match ");
200 if(info
->name
) printf("name: %s ",info
->name
);
201 if(info
->side
== XT_RECENT_SOURCE
) printf("side: source ");
202 if(info
->side
== XT_RECENT_DEST
) printf("side: dest");
205 /* Saves the union ip6t_matchinfo in parsable form to stdout. */
207 save(const struct ip6t_ip6
*ip
, const struct ip6t_entry_match
*match
)
209 struct xt_recent_mtinfo
*info
= (struct xt_recent_mtinfo
*)match
->data
;
214 if(info
->check_set
& XT_RECENT_SET
) printf("--set ");
215 if(info
->check_set
& XT_RECENT_CHECK
) printf("--rcheck ");
216 if(info
->check_set
& XT_RECENT_UPDATE
) printf("--update ");
217 if(info
->check_set
& XT_RECENT_REMOVE
) printf("--remove ");
218 if(info
->seconds
) printf("--seconds %d ",info
->seconds
);
219 if(info
->hit_count
) printf("--hitcount %d ",info
->hit_count
);
220 if(info
->check_set
& XT_RECENT_TTL
) printf("--rttl ");
221 if(info
->name
) printf("--name %s ",info
->name
);
222 if(info
->side
== XT_RECENT_SOURCE
) printf("--rsource ");
223 if(info
->side
== XT_RECENT_DEST
) printf("--rdest ");
226 /* Structure for iptables to use to communicate with module */
227 static struct ip6tables_match recent
= {
230 .version
= XTABLES_VERSION
,
231 .size
= IP6T_ALIGN(sizeof(struct xt_recent_mtinfo
)),
232 .userspacesize
= IP6T_ALIGN(sizeof(struct xt_recent_mtinfo
)),
236 .final_check
= &final_check
,
244 register_match6(&recent
);