5 Copyright (C) 2006 Jonathan Zarate
7 Licensed under GNU GPL v2 or later.
15 #include <ip6tables.h>
16 #include <linux/netfilter_ipv6/ip6_tables.h>
17 #include <linux/netfilter_ipv4/ipt_web.h>
23 static void help(void)
26 "web match v0.01 (experimental)\n"
27 "Copyright (C) 2006 Jonathan Zarate\n"
29 "[!] --http (default) find an HTTP GET/POST request\n"
30 "[!] --host <text ...> find in host line\n"
31 "[!] --req <text ...> find in request\n"
32 "[!] --path <text ...> find in request path\n"
33 "[!] --query <text ...> find in request query\n"
34 "[!] --hore <text ...> find in host or request line\n"
37 " ^text begins with\n"
39 " ^text$ exact match\n");
42 static void init(struct ip6t_entry_match
*m
, unsigned int *nfcache
)
44 *nfcache
|= NFC_UNKNOWN
;
47 static struct option opts
[] = {
48 { .name
= "http", .has_arg
= 0, .flag
= 0, .val
= '1' },
49 { .name
= "host", .has_arg
= 1, .flag
= 0, .val
= '2' },
50 { .name
= "req", .has_arg
= 1, .flag
= 0, .val
= '3' },
51 { .name
= "path", .has_arg
= 1, .flag
= 0, .val
= '4' },
52 { .name
= "query", .has_arg
= 1, .flag
= 0, .val
= '5' },
53 { .name
= "hore", .has_arg
= 1, .flag
= 0, .val
= '6' },
57 static int parse(int c
, char **argv
, int invert
, unsigned int *flags
,
58 const struct ip6t_entry
*entry
, unsigned int *nfcache
,
59 struct ip6t_entry_match
**match
)
64 struct ipt_web_info
*info
;
66 if ((c
< '1') || (c
> '6')) return 0;
68 if (*flags
) exit_error(PARAMETER_PROBLEM
, "Multiple modes are not supported");
71 info
= (struct ipt_web_info
*)(*match
)->data
;
74 info
->mode
= IPT_WEB_HOST
;
77 info
->mode
= IPT_WEB_RURI
;
80 info
->mode
= IPT_WEB_PATH
;
83 info
->mode
= IPT_WEB_QUERY
;
86 info
->mode
= IPT_WEB_HORE
;
88 default: // IPT_WEB_HTTP
92 if (entry
->ipv6
.proto
!= IPPROTO_TCP
) {
93 exit_error(PARAMETER_PROBLEM
, "web match requires -p tcp");
96 check_inverse(optarg
, &invert
, &optind
, 0);
97 if (invert
) info
->invert
= 1;
99 // convert arg to text\0text\0\0
100 s
= argv
[optind
- 1];
102 if ((p
= malloc(strlen(s
) + 2)) == NULL
) {
103 exit_error(PARAMETER_PROBLEM
, "Not enough memory");
108 while ((*s
== ' ') || (*s
== '\n') || (*s
== '\t')) ++s
;
110 while ((*s
!= 0) && (*s
!= ' ') && (*s
!= '\n') && (*s
!= '\t')) {
127 exit_error(PARAMETER_PROBLEM
, "Text is too short");
129 if (n
>= IPT_WEB_MAXTEXT
) {
130 exit_error(PARAMETER_PROBLEM
, "Text is too long");
132 memcpy(info
->text
, p
, n
);
133 memset(info
->text
+ n
, 0, IPT_WEB_MAXTEXT
- n
); // term, need to clear rest for ipt rule cmp
138 static void final_check(unsigned int flags
)
142 static void print_match(const struct ipt_web_info
*info
)
146 if (info
->invert
) printf("! ");
148 switch (info
->mode
) {
173 if (*text
== '"') printf("\\\"");
174 else putc(*text
, stdout
);
178 if (*text
== 0) break;
184 static void print(const struct ip6t_ip6
*ip
, const struct ip6t_entry_match
*match
, int numeric
)
187 print_match((const struct ipt_web_info
*)match
->data
);
190 static void save(const struct ip6t_ip6
*ip
, const struct ip6t_entry_match
*match
)
193 print_match((const struct ipt_web_info
*)match
->data
);
197 static struct ip6tables_match web_match
= {
200 .version
= IPTABLES_VERSION
,
201 .size
= IP6T_ALIGN(sizeof(struct ipt_web_info
)),
202 .userspacesize
= IP6T_ALIGN(sizeof(struct ipt_web_info
)),
206 .final_check
= &final_check
,
214 register_match6(&web_match
);