K2.6 patches and update.
[tomato.git] / release / src / router / iptables / extensions / libip6t_web.c
blob153d78032f9185ee82b8aa4f75853bf9ff88935c
1 /*
3 web (experimental)
4 HTTP IPv6 client match
5 Copyright (C) 2006 Jonathan Zarate
7 Licensed under GNU GPL v2 or later.
9 */
10 #include <stdio.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <getopt.h>
15 #include <ip6tables.h>
16 #include <linux/netfilter_ipv6/ip6_tables.h>
17 #include <linux/netfilter_ipv4/ipt_web.h>
20 #undef IPTABLES_SAVE
23 static void help(void)
25 printf(
26 "web match v0.01 (experimental)\n"
27 "Copyright (C) 2006 Jonathan Zarate\n"
28 "Options:\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"
35 " <text> can be:\n"
36 " text contains\n"
37 " ^text begins with\n"
38 " text$ ends 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' },
54 { .name = 0 }
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)
61 const char *s;
62 char *e, *p;
63 int n;
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");
69 *flags = 1;
71 info = (struct ipt_web_info *)(*match)->data;
72 switch (c) {
73 case '2':
74 info->mode = IPT_WEB_HOST;
75 break;
76 case '3':
77 info->mode = IPT_WEB_RURI;
78 break;
79 case '4':
80 info->mode = IPT_WEB_PATH;
81 break;
82 case '5':
83 info->mode = IPT_WEB_QUERY;
84 break;
85 case '6':
86 info->mode = IPT_WEB_HORE;
87 break;
88 default: // IPT_WEB_HTTP
89 return 1;
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");
106 e = p;
107 while (*s) {
108 while ((*s == ' ') || (*s == '\n') || (*s == '\t')) ++s;
109 if (*s == 0) break;
110 while ((*s != 0) && (*s != ' ') && (*s != '\n') && (*s != '\t')) {
111 *e++ = *s++;
113 *e++ = 0;
115 n = (e - p);
117 #if 0
118 *e = 0;
119 e = p;
120 while (*e) {
121 printf("[%s]\n", e);
122 e += strlen(e) + 1;
124 #endif
126 if (n <= 1) {
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
134 free(p);
135 return 1;
138 static void final_check(unsigned int flags)
142 static void print_match(const struct ipt_web_info *info)
144 const char *text;
146 if (info->invert) printf("! ");
148 switch (info->mode) {
149 case IPT_WEB_HOST:
150 printf("--host");
151 break;
152 case IPT_WEB_RURI:
153 printf("--req");
154 break;
155 case IPT_WEB_PATH:
156 printf("--path");
157 break;
158 case IPT_WEB_QUERY:
159 printf("--query");
160 break;
161 case IPT_WEB_HORE:
162 printf("--hore");
163 break;
164 default:
165 printf("--http");
166 return;
169 text = info->text;
170 printf(" \"");
171 while (*text) {
172 while (*text) {
173 if (*text == '"') printf("\\\"");
174 else putc(*text, stdout);
175 ++text;
177 ++text;
178 if (*text == 0) break;
179 putc(' ', stdout);
181 printf("\" ");
184 static void print(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match, int numeric)
186 printf("web ");
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)
192 #ifdef IPTABLES_SAVE
193 print_match((const struct ipt_web_info *)match->data);
194 #endif
197 static struct ip6tables_match web_match = {
198 .next = NULL,
199 .name = "web",
200 .version = IPTABLES_VERSION,
201 .size = IP6T_ALIGN(sizeof(struct ipt_web_info)),
202 .userspacesize = IP6T_ALIGN(sizeof(struct ipt_web_info)),
203 .help = &help,
204 .init = &init,
205 .parse = &parse,
206 .final_check = &final_check,
207 .print = &print,
208 .save = &save,
209 .extra_opts = opts
212 void _init(void)
214 register_match6(&web_match);