ipt_webmon_info has different define in kernel and iptables.
[tomato.git] / release / src / router / iptables / extensions / libip6t_webmon.c
blob7e9386c383fd2747fb88eb04b3b53363ed13ccd9
1 /* webmon -- An iptables extension to match URLs in HTTP requests
2 * This module can match using string match or regular expressions
3 * Originally designed for use with Gargoyle router firmware (gargoyle-router.com)
6 * Copyright © 2008-2010 by Eric Bishop <eric@gargoyle-router.com>
7 *
8 * This file is free software: you may copy, redistribute and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 2 of the License, or (at your
11 * option) any later version.
13 * This file is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <stdio.h>
24 #include <netdb.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <getopt.h>
29 #include <arpa/inet.h>
32 * in iptables 1.4.0 and higher, iptables.h includes xtables.h, which
33 * we can use to check whether we need to deal with the new requirements
34 * in pre-processor directives below
36 #include <ip6tables.h>
37 #include <linux/netfilter_ipv6/ip6_tables.h>
39 #ifdef CONFIG_BCMWL6
40 #include <linux/netfilter/xt_webmon.h>
41 #define ipt_webmon_info xt_webmon_info
42 #else
43 #include <linux/netfilter_ipv4/ipt_webmon.h>
44 #endif
46 #ifdef _XTABLES_H
47 #define iptables_match xtables_match
48 #define ip6t_entry_match xt_entry_match
49 #endif
51 /*
52 * XTABLES_VERSION_CODE is only defined in versions 1.4.1 and later, which
53 * also require the use of xtables_register_match
55 * Version 1.4.0 uses register_match like previous versions
57 #ifdef XTABLES_VERSION_CODE
58 #define register_match6 xtables_register_match
59 #endif
61 unsigned char* read_entire_file(FILE* in, unsigned long read_block_size, unsigned long *length);
63 #define DEFAULT_MAX 300
65 #define SEARCH_LOAD_FILE 100
66 #define DOMAIN_LOAD_FILE 101
67 #define CLEAR_SEARCH 102
68 #define CLEAR_DOMAIN 103
70 static char* domain_load_file = NULL;
71 static char* search_load_file = NULL;
72 static uint32_t global_max_domains = DEFAULT_MAX;
73 static uint32_t global_max_searches = DEFAULT_MAX;
75 /* Function which prints out usage message. */
76 static void help(void)
78 printf( "webmon options:\n");
81 static struct option opts[] =
83 { .name = "max_domains", .has_arg = 1, .flag = 0, .val = WEBMON_MAXDOMAIN },
84 { .name = "max_searches", .has_arg = 1, .flag = 0, .val = WEBMON_MAXSEARCH },
85 { .name = "search_load_file", .has_arg = 1, .flag = 0, .val = SEARCH_LOAD_FILE },
86 { .name = "domain_load_file", .has_arg = 1, .flag = 0, .val = DOMAIN_LOAD_FILE },
87 { .name = "clear_search", .has_arg = 0, .flag = 0, .val = CLEAR_SEARCH },
88 { .name = "clear_domain", .has_arg = 0, .flag = 0, .val = CLEAR_DOMAIN },
90 { .name = 0 }
93 static void webmon_init(
94 #ifdef _XTABLES_H
95 struct xt_entry_match *match
96 #else
97 struct ip6t_entry_match *match, unsigned int *nfcache
98 #endif
101 struct ipt_webmon_info *info = (struct ipt_webmon_info *)match->data;
102 info->max_domains=DEFAULT_MAX;
103 info->max_searches=DEFAULT_MAX;
104 info->ref_count = NULL;
108 /* Function which parses command options; returns true if it ate an option */
109 static int parse( int c,
110 char **argv,
111 int invert,
112 unsigned int *flags,
113 #ifdef _XTABLES_H
114 const void *entry,
115 #else
116 const struct ip6t_entry *entry,
117 unsigned int *nfcache,
118 #endif
119 struct ip6t_entry_match **match
122 struct ipt_webmon_info *info = (struct ipt_webmon_info *)(*match)->data;
123 int valid_arg = 1;
124 long max;
125 switch (c)
127 case WEBMON_MAXSEARCH:
128 if( sscanf(argv[optind-1], "%ld", &max) == 0)
130 info->max_searches = DEFAULT_MAX ;
131 valid_arg = 0;
133 else
135 info->max_searches = (uint32_t)max;
136 global_max_searches = info->max_searches;
138 break;
139 case WEBMON_MAXDOMAIN:
140 if( sscanf(argv[optind-1], "%ld", &max) == 0)
142 info->max_domains = DEFAULT_MAX ;
143 valid_arg = 0;
145 else
147 info->max_domains = (uint32_t)max;
148 global_max_domains = info->max_domains;
150 break;
151 case SEARCH_LOAD_FILE:
152 search_load_file = strdup(optarg);
153 break;
154 case DOMAIN_LOAD_FILE:
155 domain_load_file = strdup(optarg);
156 break;
157 case CLEAR_SEARCH:
158 search_load_file = strdup("/dev/null");
159 break;
160 case CLEAR_DOMAIN:
161 domain_load_file = strdup("/dev/null");
162 break;
163 default:
164 valid_arg = 0;
166 return valid_arg;
172 static void print_webmon_args( struct ipt_webmon_info* info )
174 printf("--max_domains %ld ", (unsigned long int)info->max_domains);
175 printf("--max_searches %ld ", (unsigned long int)info->max_searches);
179 static void do_load(char* file, uint32_t max, unsigned char type)
181 if(file != NULL)
183 unsigned char* data = NULL;
184 unsigned long data_length = 0;
185 if(strcmp(file, "/dev/null") == 0)
187 data = (unsigned char*)malloc(10);
188 if(data != NULL)
190 uint32_t* maxp = (uint32_t*)(data+1);
191 data_length = 3+sizeof(uint32_t);
192 data[0] = type;
193 *maxp = max;
194 data[ sizeof(uint32_t)+1 ] = ' ';
195 data[ sizeof(uint32_t)+1 ] = '\0';
198 else
200 FILE* in = fopen(file, "r");
201 if(in != NULL)
203 char* file_data = read_entire_file(in, 4096, &data_length);
204 fclose(in);
205 if(file_data != NULL)
207 data_length = strlen(file_data) + sizeof(uint32_t)+2;
208 data = (unsigned char*)malloc(data_length);
209 if(data != NULL)
211 uint32_t* maxp = (uint32_t*)(data+1);
212 data[0] = type;
213 *maxp = max;
214 sprintf( (data+1+sizeof(uint32_t)), "%s", file_data);
216 free(file_data);
221 if(data != NULL && data_length > 0)
223 int sockfd = -1;
224 sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
225 if(sockfd >= 0)
227 setsockopt(sockfd, IPPROTO_IP, WEBMON_SET, data, data_length);
230 if(data != NULL)
232 free(data);
238 static void final_check(unsigned int flags)
240 do_load(domain_load_file, global_max_domains, WEBMON_DOMAIN);
241 do_load(search_load_file, global_max_searches, WEBMON_SEARCH);
244 /* Prints out the matchinfo. */
245 #ifdef _XTABLES_H
246 static void print(const void *ip, const struct xt_entry_match *match, int numeric)
247 #else
248 static void print(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match, int numeric)
249 #endif
251 printf("WEBMON ");
252 struct ipt_webmon_info *info = (struct ipt_webmon_info *)match->data;
254 print_webmon_args(info);
257 /* Saves the union ipt_matchinfo in parsable form to stdout. */
258 #ifdef _XTABLES_H
259 static void save(const void *ip, const struct xt_entry_match *match)
260 #else
261 static void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match)
262 #endif
264 struct ipt_webmon_info *info = (struct ipt_webmon_info *)match->data;
265 print_webmon_args(info);
268 static struct ip6tables_match webmon =
270 .next = NULL,
271 .name = "webmon",
272 #ifdef XTABLES_VERSION_CODE
273 .version = XTABLES_VERSION,
274 .family = PF_INET6,
275 #else
276 .version = IPTABLES_VERSION,
277 #endif
278 .size = IP6T_ALIGN(sizeof(struct ipt_webmon_info)),
279 .userspacesize = IP6T_ALIGN(sizeof(struct ipt_webmon_info)),
280 .help = &help,
281 .init = &webmon_init,
282 .parse = &parse,
283 .final_check = &final_check,
284 .print = &print,
285 .save = &save,
286 .extra_opts = opts
289 void _init(void)
291 register_match6(&webmon);
295 unsigned char* read_entire_file(FILE* in, unsigned long read_block_size, unsigned long *length)
297 int max_read_size = read_block_size;
298 unsigned char* read_string = (unsigned char*)malloc(max_read_size+1);
299 unsigned long bytes_read = 0;
300 int end_found = 0;
301 while(end_found == 0)
303 int nextch = '?';
304 while(nextch != EOF && bytes_read < max_read_size)
306 nextch = fgetc(in);
307 if(nextch != EOF)
309 read_string[bytes_read] = (unsigned char)nextch;
310 bytes_read++;
313 read_string[bytes_read] = '\0';
314 end_found = (nextch == EOF) ? 1 : 0;
315 if(end_found == 0)
317 unsigned char *new_str;
318 max_read_size = max_read_size + read_block_size;
319 new_str = (unsigned char*)malloc(max_read_size+1);
320 memcpy(new_str, read_string, bytes_read);
321 free(read_string);
322 read_string = new_str;
325 *length = bytes_read;
326 return read_string;