5 Copyright (C) 2006 Jonathan Zarate
7 Licensed under GNU GPL v2 or later.
16 #include <linux/netfilter_ipv4/ipt_web.h>
22 static void help(void)
25 "web match v0.01 (experimental)\n"
26 "Copyright (C) 2006 Jonathan Zarate\n"
28 "[!] --http (default) find an HTTP GET/POST request\n"
29 "[!] --host <text ...> find in host line\n"
30 "[!] --req <text ...> find in request\n"
31 "[!] --path <text ...> find in request path\n"
32 "[!] --query <text ...> find in request query\n"
33 "[!] --hore <text ...> find in host or request line\n"
36 " ^text begins with\n"
38 " ^text$ exact match\n");
41 static void init(struct ipt_entry_match
*m
, unsigned int *nfcache
)
43 *nfcache
|= NFC_UNKNOWN
;
46 static struct option opts
[] = {
47 { .name
= "http", .has_arg
= 0, .flag
= 0, .val
= '1' },
48 { .name
= "host", .has_arg
= 1, .flag
= 0, .val
= '2' },
49 { .name
= "req", .has_arg
= 1, .flag
= 0, .val
= '3' },
50 { .name
= "path", .has_arg
= 1, .flag
= 0, .val
= '4' },
51 { .name
= "query", .has_arg
= 1, .flag
= 0, .val
= '5' },
52 { .name
= "hore", .has_arg
= 1, .flag
= 0, .val
= '6' },
56 static int parse(int c
, char **argv
, int invert
, unsigned int *flags
,
57 const struct ipt_entry
*entry
, unsigned int *nfcache
,
58 struct ipt_entry_match
**match
)
63 struct ipt_web_info
*info
;
65 if ((c
< '1') || (c
> '6')) return 0;
67 if (*flags
) exit_error(PARAMETER_PROBLEM
, "Multiple modes are not supported");
70 info
= (struct ipt_web_info
*)(*match
)->data
;
73 info
->mode
= IPT_WEB_HOST
;
76 info
->mode
= IPT_WEB_RURI
;
79 info
->mode
= IPT_WEB_PATH
;
82 info
->mode
= IPT_WEB_QUERY
;
85 info
->mode
= IPT_WEB_HORE
;
87 default: // IPT_WEB_HTTP
91 if (entry
->ip
.proto
!= IPPROTO_TCP
) {
92 exit_error(PARAMETER_PROBLEM
, "web match requires -p tcp");
95 check_inverse(optarg
, &invert
, &optind
, 0);
96 if (invert
) info
->invert
= 1;
98 // convert arg to text\0text\0\0
101 if ((p
= malloc(strlen(s
) + 2)) == NULL
) {
102 exit_error(PARAMETER_PROBLEM
, "Not enough memory");
107 while ((*s
== ' ') || (*s
== '\n') || (*s
== '\t')) ++s
;
109 while ((*s
!= 0) && (*s
!= ' ') && (*s
!= '\n') && (*s
!= '\t')) {
126 exit_error(PARAMETER_PROBLEM
, "Text is too short");
128 if (n
>= IPT_WEB_MAXTEXT
) {
129 exit_error(PARAMETER_PROBLEM
, "Text is too long");
131 memcpy(info
->text
, p
, n
);
132 memset(info
->text
+ n
, 0, IPT_WEB_MAXTEXT
- n
); // term, need to clear rest for ipt rule cmp
137 static void final_check(unsigned int flags
)
141 static void print_match(const struct ipt_web_info
*info
)
145 if (info
->invert
) printf("! ");
147 switch (info
->mode
) {
172 if (*text
== '"') printf("\\\"");
173 else putc(*text
, stdout
);
177 if (*text
== 0) break;
183 static void print(const struct ipt_ip
*ip
, const struct ipt_entry_match
*match
, int numeric
)
186 print_match((const struct ipt_web_info
*)match
->data
);
189 static void save(const struct ipt_ip
*ip
, const struct ipt_entry_match
*match
)
192 print_match((const struct ipt_web_info
*)match
->data
);
197 static struct iptables_match web_match
= {
199 .version
= IPTABLES_VERSION
,
200 .size
= IPT_ALIGN(sizeof(struct ipt_web_info
)),
201 .userspacesize
= IPT_ALIGN(sizeof(struct ipt_web_info
)),
205 .final_check
= &final_check
,
213 register_match(&web_match
);