1/*
2 * Copyright 2004, ASUSTek Inc.
3 * All Rights Reserved.
4 *
5 * THIS SOFTWARE IS OFFERED "AS IS", AND ASUS GRANTS NO WARRANTIES OF ANY
6 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
7 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
8 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
9 *
10 * $Id: firewall_ex.c,v 1.9 2008/12/04 10:52:32 james26_jang Exp $
11 */
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <signal.h>
16#include <sys/socket.h>
17#include <netinet/in.h>
18#include <arpa/inet.h>
19#include <sys/types.h>
20#include <dirent.h>
21
22#include <bcmnvram.h>
23#include <shutils.h>
24#include <rc.h>
25#include <netconf.h>
26#include <nvparse.h>
27
28#define foreach_x(x)	for(i=0; i<atoi(nvram_safe_get(x)); i++)
29char *mac_conv(char *mac_name, int idx, char *buf);
30int mkdir_if_none(char *dir);
31
32#ifdef WEBSTRFILTER/* Cherry Cho added in 2007/12/27. */
33#define USEOLDNV
34#define ADDRULE 0 /* 1:  Do Web URL filter by adding rules to iptables.*/
35int web_filter();
36#endif
37
38char *g_buf;
39char g_buf_pool[1024];
40
41void g_buf_init()
42{
43	g_buf = g_buf_pool;
44}
45
46char *g_buf_alloc(char *g_buf_now)
47{
48	g_buf += strlen(g_buf_now)+1;
49
50	return(g_buf_now);
51}
52
53void nvram_unsets(char *name, int count)
54{
55	char itemname_arr[32];
56	int i;
57
58	for(i=0; i<count; i++)
59	{
60		sprintf(itemname_arr, "%s%d", name, i);
61		nvram_unset(itemname_arr);
62	}
63}
64
65char *proto_conv(char *proto_name, int idx)
66{
67	char *proto;
68	char itemname_arr[32];
69
70	sprintf(itemname_arr,"%s%d", proto_name, idx);
71	proto=nvram_get(itemname_arr);
72
73	if(!strncasecmp(proto, "Both", 3)) strcpy(g_buf, "both");
74	else if(!strncasecmp(proto, "TCP", 3)) strcpy(g_buf, "tcp");
75	else if(!strncasecmp(proto, "UDP", 3)) strcpy(g_buf, "udp");
76	else if(!strncasecmp(proto, "OTHER", 5)) strcpy(g_buf, "other");
77	else strcpy(g_buf,"tcp");
78	return (g_buf_alloc(g_buf));
79}
80
81char *protoflag_conv(char *proto_name, int idx, int isFlag)
82{
83	char *proto;
84	char itemname_arr[32];
85
86	sprintf(itemname_arr,"%s%d", proto_name, idx);
87	proto=nvram_get(itemname_arr);
88
89	strcpy(g_buf, "");
90
91	if (!isFlag)
92	{
93		if(strncasecmp(proto, "UDP", 3)==0) strcpy(g_buf, "udp");
94		else strcpy(g_buf, "tcp");
95	}
96	else
97	{
98		if(strlen(proto)>3)
99		{
100			strcpy(g_buf, proto+4);
101		}
102		else strcpy(g_buf,"");
103	}
104	return (g_buf_alloc(g_buf));
105}
106
107char *portrange_ex_conv(char *port_name, int idx)
108{
109	char *port, *strptr;
110	char itemname_arr[32];
111
112	sprintf(itemname_arr,"%s%d", port_name, idx);
113	port=nvram_get(itemname_arr);
114
115	strcpy(g_buf, "");
116
117	if(!strncmp(port, ">", 1)) {
118		sprintf(g_buf, "%d-65535", atoi(port+1) + 1);
119	}
120	else if(!strncmp(port, "=", 1)) {
121		sprintf(g_buf, "%d-%d", atoi(port+1), atoi(port+1));
122	}
123	else if(!strncmp(port, "<", 1)) {
124		sprintf(g_buf, "1-%d", atoi(port+1) - 1);
125	}
126	else if ((strptr=strchr(port, ':')) != NULL)
127	{
128		strcpy(itemname_arr, port);
129		strptr = strchr(itemname_arr, ':');
130		sprintf(g_buf, "%d-%d", atoi(itemname_arr), atoi(strptr+1));
131	}
132	else if(*port)
133	{
134		sprintf(g_buf, "%d-%d", atoi(port), atoi(port));
135	}
136	else
137	{
138		g_buf[0] = 0;
139	}
140
141	return(g_buf_alloc(g_buf));
142}
143
144char *portrange_ex2_conv(char *port_name, int idx, int *start, int *end)
145{
146	char *port, *strptr;
147	char itemname_arr[32];
148
149	sprintf(itemname_arr,"%s%d", port_name, idx);
150	port=nvram_get(itemname_arr);
151
152	strcpy(g_buf, "");
153
154	if(!strncmp(port, ">", 1))
155	{
156		sprintf(g_buf, "%d-65535", atoi(port+1) + 1);
157		*start=atoi(port+1);
158		*end=65535;
159	}
160	else if(!strncmp(port, "=", 1))
161	{
162		sprintf(g_buf, "%d-%d", atoi(port+1), atoi(port+1));
163		*start=*end=atoi(port+1);
164	}
165	else if(!strncmp(port, "<", 1))
166	{
167		sprintf(g_buf, "1-%d", atoi(port+1) - 1);
168		*start=1;
169		*end=atoi(port+1);
170	}
171	else if( (strptr=strchr(port, ':')) != NULL)
172	{
173		strcpy(itemname_arr, port);
174		strptr = strchr(itemname_arr, ':');
175		sprintf(g_buf, "%d-%d", atoi(itemname_arr), atoi(strptr+1));
176		*start=atoi(itemname_arr);
177		*end=atoi(strptr+1);
178	}
179	else if(*port)
180	{
181		sprintf(g_buf, "%d-%d", atoi(port), atoi(port));
182		*start=atoi(port);
183		*end=atoi(port);
184	}
185	else
186	{
187		g_buf[0] = 0;
188		*start=0;
189		*end=0;
190	}
191
192	return(g_buf_alloc(g_buf));
193}
194
195char *portrange_conv(char *port_name, int idx)
196{
197	char itemname_arr[32];
198
199	sprintf(itemname_arr,"%s%d", port_name, idx);
200	strcpy(g_buf, nvram_safe_get(itemname_arr));
201
202	return(g_buf_alloc(g_buf));
203}
204
205char *iprange_conv(char *ip_name, int idx)
206{
207	char *ip;
208	char itemname_arr[32];
209	char startip[16], endip[16];
210	int i, j, k;
211
212	sprintf(itemname_arr,"%s%d", ip_name, idx);
213	ip=nvram_safe_get(itemname_arr);
214	strcpy(g_buf, "");
215
216	// scan all ip string
217	i=j=k=0;
218
219	while(*(ip+i))
220	{
221		if (*(ip+i)=='*')
222		{
223			startip[j++] = '1';
224			endip[k++] = '2';
225			endip[k++] = '5';
226			endip[k++] = '4';
227			// 255 is for broadcast
228		}
229		else
230		{
231			startip[j++] = *(ip+i);
232			endip[k++] = *(ip+i);
233		}
234		i++;
235	}
236
237	startip[j++] = 0;
238	endip[k++] = 0;
239
240	if (strcmp(startip, endip)==0)
241		sprintf(g_buf, "%s", startip);
242	else
243		sprintf(g_buf, "%s-%s", startip, endip);
244	return(g_buf_alloc(g_buf));
245}
246
247char *iprange_ex_conv(char *ip_name, int idx)
248{
249	char *ip;
250	char itemname_arr[32];
251	char startip[16], endip[16];
252	int i, j, k;
253	int mask;
254
255	sprintf(itemname_arr,"%s%d", ip_name, idx);
256	ip=nvram_safe_get(itemname_arr);
257	strcpy(g_buf, "");
258
259	// scan all ip string
260	i=j=k=0;
261	mask=32;
262
263	while(*(ip+i))
264	{
265		if (*(ip+i)=='*')
266		{
267			startip[j++] = '0';
268			endip[k++] = '0';
269			// 255 is for broadcast
270			mask-=8;
271		}
272		else
273		{
274			startip[j++] = *(ip+i);
275			endip[k++] = *(ip+i);
276		}
277		i++;
278	}
279
280	startip[j++] = 0;
281	endip[k++] = 0;
282
283	if (mask==32)
284		sprintf(g_buf, "%s", startip);
285	else if(mask==0)
286		strcpy(g_buf, "");
287	else sprintf(g_buf, "%s/%d", startip, mask);
288
289	return(g_buf_alloc(g_buf));
290}
291
292char *ip_conv(char *ip_name, int idx)
293{
294	char itemname_arr[32];
295
296	sprintf(itemname_arr,"%s%d", ip_name, idx);
297	sprintf(g_buf, "%s", nvram_safe_get(itemname_arr));
298	return(g_buf_alloc(g_buf));
299}
300
301
302char *general_conv(char *ip_name, int idx)
303{
304	char itemname_arr[32];
305
306	sprintf(itemname_arr,"%s%d", ip_name, idx);
307	sprintf(g_buf, "%s", nvram_safe_get(itemname_arr));
308	return(g_buf_alloc(g_buf));
309}
310
311char *filter_conv(char *proto, char *flag, char *srcip, char *srcport, char *dstip, char *dstport)
312{
313	char newstr[64];
314
315	//printf("filter : %s,%s,%s,%s,%s,%s\n", proto, flag, srcip, srcport, dstip, dstport);
316
317	strcpy(g_buf, "");
318
319        if (strcmp(proto, "")!=0)
320	{
321		sprintf(newstr, " -p %s", proto);
322        	strcat(g_buf, newstr);
323        }
324
325        if (strcmp(flag, "")!=0)
326        {
327        	sprintf(newstr, " --tcp-flags %s RST", flag);
328		strcat(g_buf, newstr);
329	}
330
331	if (strcmp(srcip, "")!=0)
332	{
333		if (strchr(srcip , '-'))
334			sprintf(newstr, " --src-range %s", srcip);
335		else
336			sprintf(newstr, " -s %s", srcip);
337		strcat(g_buf, newstr);
338	}
339
340	if (strcmp(srcport, "")!=0)
341	{
342		sprintf(newstr, " --sport %s", srcport);
343		strcat(g_buf, newstr);
344        }
345
346        if (strcmp(dstip, "")!=0)
347        {
348		if (strchr(dstip, '-'))
349			sprintf(newstr, " --dst-range %s", dstip);
350		else
351        		sprintf(newstr, " -d %s", dstip);
352		strcat(g_buf, newstr);
353        }
354
355        if (strcmp(dstport, "")!=0)
356        {
357        	sprintf(newstr, " --dport %s", dstport);
358		strcat(g_buf, newstr);
359	}
360	return(g_buf_alloc(g_buf));
361	//printf("str: %s\n", g_buf);
362}
363
364void timematch_conv(char *mstr, char *nv_date, char *nv_time)
365{
366	char *datestr[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
367	char timestart[6], timestop[6];
368	char *time, *date;
369	int i, head;
370
371	date = nvram_safe_get(nv_date);
372	time = nvram_safe_get(nv_time);
373
374	if (strlen(date)!=7||strlen(time)!=8) goto no_match;
375
376	if (strncmp(date, "1111111", 7)==0 &&
377	    strncmp(time, "00002359", 8)==0) goto no_match;
378
379	i=0;
380	strncpy(timestart, time, 2);
381	i+=2;
382	timestart[i++] = ':';
383	strncpy(timestart+i, time+2, 2);
384	i+=2;
385	timestart[i]=0;
386	i=0;
387	strncpy(timestop, time+4, 2);
388	i+=2;
389	timestop[i++] = ':';
390	strncpy(timestop+i, time+6, 2);
391	i+=2;
392	timestop[i]=0;
393
394	sprintf(mstr, "-m time --timestart %s:00 --timestop %s:00 --days",
395			timestart, timestop);
396
397	head=1;
398
399	for(i=0;i<7;i++)
400	{
401		if (*(date+i)=='1')
402		{
403			if (head)
404			{
405			    sprintf(mstr, "%s %s", mstr, datestr[i]);
406			    head=0;
407			}
408			else
409			{
410			    sprintf(mstr, "%s,%s", mstr, datestr[i]);
411			}
412		}
413	}
414	return;
415
416no_match:
417	mstr[0] = 0;
418	return;
419}
420
421void
422p(int step)
423{
424	dprintf("P: %d %s\n", step, g_buf);
425}
426
427void
428ip2class(char *lan_ip, char *netmask, char *buf)
429{
430	unsigned int val, ip;
431	struct in_addr in;
432	int i=0;
433
434	val = (unsigned int)inet_addr(netmask);
435	ip = (unsigned int)inet_addr(lan_ip);
436	in.s_addr = ip & val;
437
438        for (val = ntohl(val); val; i++)
439        	val <<= 1;
440
441        sprintf(buf, "%s/%d", inet_ntoa(in), i);
442	dprintf(buf);
443}
444
445void convert_routes(void)
446{
447	int i;
448	char *ip, *netmask, *gateway, *matric, *interface;
449	char wroutes[1024], lroutes[1024], mroutes[1024];
450
451	wroutes[0] = 0;
452	lroutes[0] = 0;
453	mroutes[0] = 0;
454
455	g_buf_init();
456
457	if (nvram_match("sr_enable_x", "1")) foreach_x("sr_num_x")
458	{
459		ip = general_conv("sr_ipaddr_x", i);
460		netmask = general_conv("sr_netmask_x", i);
461		gateway = general_conv("sr_gateway_x", i);
462		matric = general_conv("sr_matric_x", i);
463		interface = general_conv("sr_if_x", i);
464
465		dprintf("%x %s %s %s %s %s\n", i, ip, netmask, gateway, matric, interface);
466
467		if (!strcmp(interface, "WAN"))
468		{
469			sprintf(wroutes, "%s %s:%s:%s:%d", wroutes, ip, netmask, gateway, atoi(matric)+1);
470		}
471		else if (!strcmp(interface, "LAN"))
472		{
473			sprintf(lroutes, "%s %s:%s:%s:%d", lroutes, ip, netmask, gateway, atoi(matric)+1);
474		}
475		else if (!strcmp(interface, "MAN"))
476		{
477			sprintf(mroutes, "%s %s:%s:%s:%d", mroutes, ip, netmask, gateway, atoi(matric)+1);
478		}
479	}
480
481	//printf("route: %s %s\n", lroutes, wroutes);
482	nvram_set("lan_route", lroutes);
483	nvram_set("wan0_route", wroutes);
484	nvram_set("wan_route", mroutes);
485}
486
487void write_static_leases(char *file)
488{
489	FILE *fp;
490	char *ip, *mac;
491	int i;
492
493	fp=fopen(file, "w");
494
495	if (fp==NULL) return;
496
497	g_buf_init();
498
499       	foreach_x("dhcp_staticnum_x")
500       	{
501            	ip = general_conv("dhcp_staticip_x", i);
502		mac = general_conv("dhcp_staticmac_x", i);
503		fprintf(fp, "%s,%s\r\n", ip, mac);
504	}
505	fclose(fp);
506}
507
508#ifndef NOIPTABLES
509void
510write_upnp_forward(FILE *fp, char *wan_if, char *wan_ip, char *lan_if, char *lan_ip, char *lan_class, char *logaccept, char *logdrop)
511{
512	char name[] = "forward_portXXXXXXXXXX", value[512];
513	char *wan_port0, *wan_port1, *lan_ipaddr, *lan_port0, *lan_port1, *proto;
514	char *enable, *desc;
515	int i;
516
517	/* Set wan_port0-wan_port1>lan_ipaddr:lan_port0-lan_port1,proto,enable,desc */
518	for(i=0 ; i<15 ; i++)
519	{
520		snprintf(name, sizeof(name), "forward_port%d", i);
521
522		strncpy(value, nvram_safe_get(name), sizeof(value));
523
524		/* Check for LAN IP address specification */
525		lan_ipaddr = value;
526		wan_port0 = strsep(&lan_ipaddr, ">");
527		if (!lan_ipaddr)
528			continue;
529
530		/* Check for LAN destination port specification */
531		lan_port0 = lan_ipaddr;
532		lan_ipaddr = strsep(&lan_port0, ":");
533		if (!lan_port0)
534			continue;
535
536		/* Check for protocol specification */
537		proto = lan_port0;
538		lan_port0 = strsep(&proto, ":,");
539		if (!proto)
540			continue;
541
542		/* Check for enable specification */
543		enable = proto;
544		proto = strsep(&enable, ":,");
545		if (!enable)
546			continue;
547
548		/* Check for description specification (optional) */
549		desc = enable;
550		enable = strsep(&desc, ":,");
551
552		/* Check for WAN destination port range (optional) */
553		wan_port1 = wan_port0;
554		wan_port0 = strsep(&wan_port1, "-");
555		if (!wan_port1)
556			wan_port1 = wan_port0;
557
558		/* Check for LAN destination port range (optional) */
559		lan_port1 = lan_port0;
560
561		lan_port0 = strsep(&lan_port1, "-");
562	        if (!lan_port1)
563			lan_port1 = lan_port0;
564
565		/* skip if it's disabled */
566		if( strcmp(enable, "off") == 0 )
567			continue;
568
569		/* -A PREROUTING -p tcp -m tcp --dport 823 -j DNAT
570		                 --to-destination 192.168.1.88:23  */
571		if( !strcmp(proto,"tcp") || !strcmp(proto,"both") )
572		{
573	   		fprintf(fp, "-A VSERVER -p tcp -m tcp --dport %s "
574				  "-j DNAT --to-destination %s:%s\n"
575					, wan_port0, lan_ipaddr, lan_port0);
576		}
577		if( !strcmp(proto,"udp") || !strcmp(proto,"both") ){
578	   		fprintf(fp, "-A VSERVER -p udp -m udp --dport %s "
579				  "-j DNAT --to-destination %s:%s\n"
580				  	, wan_port0, lan_ipaddr, lan_port0);
581		}
582	}
583}
584
585char *ipoffset(char *ip, int offset, char *tmp)
586{
587	unsigned int ip1, ip2, ip3, ip4;
588
589	sscanf(ip, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4);
590	sprintf(tmp, "%d.%d.%d.%d", ip1, ip2, ip3, ip4+offset);
591
592	dprintf("ip : %s\n", tmp);
593	return(tmp);
594}
595
596#ifdef WEB_REDIRECT
597void redirect_setting()
598{
599	FILE *nat_fp = fopen("/tmp/nat_rules", "r");
600	FILE *redirect_fp = fopen("/tmp/redirect_rules", "w+");
601	char tmp_buf[1024];
602#ifndef NETGEAR_WAY
603	char http_rule[256];
604#endif
605	char dns_rule[256];
606	char *lan_ipaddr_t = nvram_safe_get("lan_ipaddr_t");
607	char *lan_netmask_t = nvram_safe_get("lan_netmask_t");
608
609	if(redirect_fp == NULL){
610		fprintf(stderr, "*** Can't make the file of the redirect rules! ***\n");
611		return;
612	}
613
614	if(nat_fp != NULL){
615		memset(tmp_buf, 0, sizeof(tmp_buf));
616		while((fgets(tmp_buf, sizeof(tmp_buf), nat_fp)) != NULL
617				&& strncmp(tmp_buf, "COMMIT", 6) != 0){
618			fprintf(redirect_fp, "%s", tmp_buf);
619			memset(tmp_buf, 0, sizeof(tmp_buf));
620		}
621
622		fclose(nat_fp);
623	}
624	else{
625// 2009.12 James. {
626		FILE *del_redirect_fp = fopen("/tmp/del_redirect_rules", "w+");
627		if(del_redirect_fp != NULL){
628			fprintf(del_redirect_fp, "*nat\n");
629			fprintf(del_redirect_fp, "-F\n");
630			fprintf(del_redirect_fp, "COMMIT\n");
631
632			fclose(del_redirect_fp);
633		}
634// 2009.12 James. }
635
636		fprintf(redirect_fp, "*nat\n");
637		fprintf(redirect_fp, ":PREROUTING ACCEPT [0:0]\n");
638	}
639
640#ifndef NETGEAR_WAY
641	memset(http_rule, 0, sizeof(http_rule));
642#endif
643	memset(dns_rule, 0, sizeof(dns_rule));
644#ifndef NETGEAR_WAY
645	sprintf(http_rule, "-A PREROUTING -i ! lo -d ! %s/%s -p tcp --dport 80 -j DNAT --to-destination %s:18017\n", lan_ipaddr_t, lan_netmask_t, lan_ipaddr_t);
646#endif
647	sprintf(dns_rule, "-A PREROUTING -i ! lo -p udp --dport 53 -j DNAT --to-destination %s:18018\n", lan_ipaddr_t);
648
649#ifndef NETGEAR_WAY
650	fprintf(redirect_fp, "%s", http_rule);
651#endif
652	fprintf(redirect_fp, "%s", dns_rule);
653	fprintf(redirect_fp, "COMMIT\n");
654
655	fclose(redirect_fp);
656}
657#endif
658
659void nat_setting(char *wan_if, char *wan_ip, char *lan_if, char *lan_ip, char *logaccept, char *logdrop)
660{
661	FILE *fp;
662	char lan_class[32];
663	int i;
664	int wan_port;
665	char dstips[32], dstports[12];
666
667	if ((fp=fopen("/tmp/nat_rules", "w"))==NULL) return;
668
669	fprintf(fp, "*nat\n"
670	       	":PREROUTING ACCEPT [0:0]\n"
671	       	":POSTROUTING ACCEPT [0:0]\n"
672	  	":OUTPUT ACCEPT [0:0]\n"
673	  	":VSERVER - [0:0]\n");
674
675	//Log
676   	//if(nvram_match("misc_natlog_x", "1"))
677   	// 	fprintf(fp, "-A PREROUTING -i %s -j LOG --log-prefix ALERT --log-level 4\n", wan_if);
678
679	/* VSERVER chain */
680	if (inet_addr_(wan_ip))
681		fprintf(fp, "-A PREROUTING -d %s -j VSERVER\n", wan_ip);
682
683	if (nvram_invmatch("wan0_ifname", wan_if) && inet_addr_(nvram_safe_get("wanx_ipaddr")))
684		fprintf(fp, "-A PREROUTING -d %s -j VSERVER\n", nvram_get("wanx_ipaddr"));
685
686   	if (nvram_match("misc_http_x", "1"))
687	{
688		wan_port=8080;
689   		if (nvram_invmatch("misc_httpport_x", ""))
690      			wan_port=atoi(nvram_safe_get("misc_httpport_x"));
691   		fprintf(fp, "-A VSERVER -p tcp -m tcp --dport %d -j DNAT --to-destination %s:%s\n",
692			wan_port, lan_ip, nvram_safe_get("http_lanport"));
693	}
694
695   	if (nvram_match("apps_dl_share", "1"))
696	{
697   		fprintf(fp, "-A VSERVER -p tcp -m tcp --dport %s:%s -j DNAT --to %s\n", nvram_safe_get("apps_dl_share_port_from"), nvram_safe_get("apps_dl_share_port_to"), lan_ip);
698   		fprintf(fp, "-A VSERVER -p udp -m udp --dport %s:%s -j DNAT --to %s\n", nvram_safe_get("apps_dl_share_port_from"), nvram_safe_get("apps_dl_share_port_to"), lan_ip);
699	}
700
701   	if (nvram_match("wan_nat_x", "1") && nvram_invmatch("upnp_enable", "0"))
702   	{
703		// upnp port forward
704        	write_upnp_forward(fp, wan_if, wan_ip, lan_if, lan_ip, lan_class, logaccept, logdrop);
705	}
706
707	// Port forwarding or Virtual Server
708	if (nvram_match("wan_nat_x", "1") && nvram_match("vts_enable_x", "1"))
709	{
710		g_buf_init();
711
712		foreach_x("vts_num_x")
713		{
714			char *proto;
715			char *protono;
716			char *port;
717			char *lport;
718			char *dstip;
719
720			proto = proto_conv("vts_proto_x", i);
721			protono = portrange_conv("vts_protono_x", i);
722			port = portrange_conv("vts_port_x", i);
723			lport = portrange_conv("vts_lport_x", i);
724			dstip = ip_conv("vts_ipaddr_x", i);
725
726			if (lport!=NULL && strlen(lport)!=0)
727			{
728				sprintf(dstips, "%s:%s", dstip, lport);
729				sprintf(dstports, "%s", lport);
730			}
731			else
732			{
733				sprintf(dstips, "%s:%s", dstip, port);
734				sprintf(dstports, "%s", port);
735			}
736
737			if (strcmp(proto, "tcp")==0 || strcmp(proto, "both")==0)
738			{
739				if (lport!=NULL && strlen(lport)!=0)
740				{
741					fprintf(fp, "-A VSERVER -p tcp -m tcp --dport %s -j DNAT --to-destination %s\n",
742					port, dstips);
743				}
744				else
745				{
746					fprintf(fp, "-A VSERVER -p tcp -m tcp --dport %s -j DNAT --to %s\n",
747					port, dstip);
748				}
749			}
750
751			if (strcmp(proto, "udp")==0 || strcmp(proto, "both")==0)
752			{
753				if (lport!=NULL && strlen(lport)!=0)
754				{
755					fprintf(fp, "-A VSERVER -p udp -m udp --dport %s -j DNAT --to-destination %s\n",
756					port, dstips);
757				}
758				else
759				{
760					fprintf(fp, "-A VSERVER -p udp -m udp --dport %s -j DNAT --to %s\n",
761					port, dstip);
762				}
763			}
764			if (strcmp(proto, "other")==0)
765			{
766				fprintf(fp, "-A VSERVER -p %s -j DNAT --to %s\n",
767					protono, dstip);
768			}
769		}
770	}
771
772   	if (nvram_match("wan_nat_x", "1") && nvram_invmatch("sp_battle_ips", "0") && inet_addr_(wan_ip))
773	{
774		#define BASEPORT 6112
775		#define BASEPORT_NEW 10000
776
777		ip2class(lan_ip, nvram_safe_get("lan_netmask"), lan_class);
778
779		/* run starcraft patch anyway */
780		fprintf(fp, "-A PREROUTING -p udp -d %s --sport %d -j NETMAP --to %s\n", wan_ip, BASEPORT, lan_class);
781
782		fprintf(fp, "-A POSTROUTING -p udp -s %s --dport %d -j NETMAP --to %s\n", lan_class, BASEPORT, wan_ip);
783	}
784
785   	// Exposed station
786   	if (nvram_match("wan_nat_x", "1") && nvram_invmatch("dmz_ip", ""))
787   	{
788      		fprintf(fp, "-A VSERVER -j DNAT --to %s\n", nvram_safe_get("dmz_ip"));
789      	}
790
791	if (nvram_match("wan_nat_x", "1"))
792	{
793		if(inet_addr_(wan_ip))
794			fprintf(fp, "-A POSTROUTING -o %s ! -s %s -j MASQUERADE\n", wan_if, wan_ip);
795
796   		/* masquerade physical WAN port connection */
797		if (nvram_invmatch("wan0_ifname", wan_if) && inet_addr_(nvram_safe_get("wanx_ipaddr")))
798			fprintf(fp, "-A POSTROUTING -o %s ! -s %s -j MASQUERADE\n",
799	   			nvram_get("wan0_ifname"), nvram_get("wanx_ipaddr"));
800
801		// masquerade lan to lan
802		ip2class(lan_ip, nvram_safe_get("lan_netmask"), lan_class);
803		fprintf(fp, "-A POSTROUTING -o %s -s %s -d %s -j MASQUERADE\n", lan_if, lan_class, lan_class);
804	}
805
806	fprintf(fp, "COMMIT\n");
807
808	fclose(fp);
809
810	eval("iptables-restore", "/tmp/nat_rules");
811
812#ifdef WEB_REDIRECT
813	// for rebuild the rule of wanduck
814	//kill_pidfile_s("/var/run/wanduck.pid", SIGUSR1);
815	redirect_setting();
816	nvram_set("wan_ready", "1");
817#endif
818}
819
820/* Rules for LW Filter and MAC Filter
821 * MAC ACCEPT
822 *     ACCEPT -> MACS
823 *            	 -> LW Disabled
824 *                  MACS ACCEPT
825 *               -> LW Default Accept:
826 *                  MACS DROP in rules
827 *                  MACS ACCEPT Default
828 *               -> LW Default Drop:
829 *                  MACS ACCEPT in rules
830 *                  MACS DROP Default
831 *     DROP    -> FORWARD DROP
832 *
833 * MAC DROP
834 *     DROP -> FORWARD DROP
835 *     ACCEPT -> FORWARD ACCEPT
836 */
837
838int
839filter_setting(char *wan_if, char *wan_ip, char *lan_if, char *lan_ip, char *logaccept, char *logdrop)
840{
841	FILE *fp;
842	char *proto, *flag, *srcip, *srcport, *dstip, *dstport;
843	char *setting, line[256];
844	char macaccept[32], chain[3];
845	char *ftype, *dtype, *fftype;
846	int num;
847	int i;
848	//int wan_port;
849#ifdef WEBSTRFILTER/* Cherry Cho added in 2007/12/12. */
850#if ADDRULE
851	char nvname[36], *filterstr;
852#endif
853#endif
854
855	if ((fp=fopen("/tmp/filter_rules", "w"))==NULL) return -1;
856
857	fprintf(fp, "*filter\n:INPUT ACCEPT [0:0]\n:FORWARD ACCEPT [0:0]\n:OUTPUT ACCEPT [0:0]\n:MACS - [0:0]\n:logaccept - [0:0]\n:logdrop - [0:0]\n");
858
859	strcpy(macaccept, "");
860
861	// FILTER from LAN to WAN Source MAC
862	if(nvram_invmatch("macfilter_enable_x", "0"))
863	{
864		// LAN/WAN filter
865		g_buf_init();
866
867		if (nvram_match("macfilter_enable_x", "2"))
868		{
869			dtype = logaccept;
870			ftype = logdrop;
871			fftype = logdrop;
872		}
873		else
874		{
875			dtype = logdrop;
876			ftype = logaccept;
877
878			strcpy(macaccept, "MACS");
879			fftype = macaccept;
880		}
881
882		num = atoi(nvram_safe_get("macfilter_num_x"));
883
884		for(i = 0; i < num; ++i)
885		{
886			fprintf(fp, "-A INPUT -i %s -m mac --mac-source %s -j %s\n", lan_if, mac_conv("macfilter_list_x", i, line), ftype);
887			fprintf(fp, "-A FORWARD -i %s -m mac --mac-source %s -j %s\n", lan_if, mac_conv("macfilter_list_x", i, line), fftype);
888
889#ifdef GUEST_ACCOUNT
890			if(nvram_match("wl_guest_enable", "1"))
891			{
892				fprintf(fp, "-A INPUT -i %s -m mac --mac-source %s -j %s\n", "wl0.1", mac_conv("macfilter_list_x", i, line), ftype);
893				fprintf(fp, "-A FORWARD -i %s -m mac --mac-source %s -j %s\n", "wl0.1", mac_conv("macfilter_list_x", i, line), fftype);
894			}
895#endif
896		}
897	}
898
899	if (nvram_invmatch("fw_enable_x", "1"))
900	{
901		if (nvram_match("macfilter_enable_x", "1"))
902		{
903			/* Filter known SPI state */
904			fprintf(fp, "-A INPUT -i %s -m state --state NEW -j %s\n"
905			,lan_if, logdrop);
906
907#ifdef GUEST_ACCOUNT
908
909			if(nvram_match("wl_guest_enable", "1"))
910			{
911				fprintf(fp, "-I INPUT -i %s -m state --state NEW -j %s\n"
912				, "wl0.1", logdrop);
913			}
914#endif
915		}
916	}
917	else
918	{
919		if (nvram_match("macfilter_enable_x", "1"))
920		{
921			/* Filter known SPI state */
922			fprintf(fp, "-A INPUT -m state --state INVALID -j %s\n"
923		          "-A INPUT -m state --state RELATED,ESTABLISHED -j %s\n"
924	        	  "-A INPUT -i lo -m state --state NEW -j %s\n"
925		          "-A INPUT -i %s -m state --state NEW -j %s\n"
926			,logdrop, logaccept, "ACCEPT", lan_if, logdrop);
927#ifdef GUEST_ACCOUNT
928			if(nvram_match("wl_guest_enable", "1"))
929			{
930				fprintf(fp, "-I INPUT -i %s -m state --state NEW -j %s\n"
931				, "wl0.1", logdrop);
932			}
933#endif
934		}
935		else
936		{
937			/* Filter known SPI state */
938			fprintf(fp, "-A INPUT -m state --state INVALID -j %s\n"
939		          "-A INPUT -m state --state RELATED,ESTABLISHED -j %s\n"
940	        	  "-A INPUT -i lo -m state --state NEW -j %s\n"
941		          "-A INPUT -i %s -m state --state NEW -j %s\n"
942			,logdrop, logaccept, "ACCEPT", lan_if, "ACCEPT");
943
944#ifdef GUEST_ACCOUNT
945			if(nvram_match("wl_guest_enable", "1"))
946			{
947				fprintf(fp, "-I INPUT -i %s -m state --state NEW -j %s\n"
948				, "wl0.1", "ACCEPT");
949			}
950#endif
951		}
952
953		/* Pass multicast */
954		if (nvram_match("mr_enable_x", "1")) {
955			fprintf(fp, "-A INPUT -p 2 -d 224.0.0.0/4 -j %s\n", logaccept);
956			fprintf(fp, "-A INPUT -p udp -d 224.0.0.0/4 -j %s\n", logaccept);
957		}
958
959		/* enable incoming packets from broken dhcp servers, which are sending replies
960		 * from addresses other than used for query, this could lead to lower level
961		 * of security, but it does not work otherwise (conntrack does not work) :-(
962		 */
963		if (nvram_match("wan0_proto", "dhcp")
964#ifdef BIGPOND
965				|| nvram_match("wan0_proto", "bigpond")
966#endif
967				|| nvram_match("wan_ipaddr", "0.0.0.0"))
968		{
969			fprintf(fp, "-A INPUT -p udp --sport 67 --dport 68 -j %s\n", logaccept);
970		}
971
972#ifdef GUEST_ACCOUNT
973		if(nvram_match("wl_guest_enable", "1"))
974		{
975			fprintf(fp, "-I INPUT -i %s -p tcp -m tcp --dport 80 -j %s\n", "wl0.1", logdrop);
976			//fprintf(fp, "-I INPUT -i %s -p icmp -j %s\n", "wl0.1", logdrop);
977			fprintf(fp, "-I FORWARD -i %s -o br0 -j %s\n", "wl0.1", logdrop);
978			fprintf(fp, "-I FORWARD -i br0 -o %s -j %s\n", "wl0.1", logdrop);
979
980#ifdef USB_SUPPORT
981			fprintf(fp, "-I INPUT -i %s -p tcp -m tcp --dport %s -j %s\n", "wl0.1", nvram_safe_get("usb_webhttpport_x"), logdrop);
982
983			fprintf(fp, "-I INPUT -i %s -p tcp -m tcp --dport %s -j %s\n", "wl0.1", nvram_safe_get("usb_ftpport_x"), logdrop);
984
985			fprintf(fp, "-I INPUT -i %s -p tcp -m tcp --dport %s -j %s\n", "wl0.1", nvram_safe_get("usb_webactivex_x"), logdrop);
986
987			fprintf(fp, "-I INPUT -i %s -p tcp -m tcp --dport %s -j %s\n", "wl0.1", "515", logdrop);
988
989			fprintf(fp, "-I INPUT -i %s -p tcp -m tcp --dport %s -j %s\n", "wl0.1", "9100", logdrop);
990
991			fprintf(fp, "-I INPUT -i %s -p tcp -m tcp --dport %s -j %s\n", "wl0.1", "3838", logdrop);
992#endif
993		}
994#endif
995
996		// Firewall between WAN and Local
997		if (nvram_match("misc_http_x", "1"))
998		{
999			fprintf(fp, "-A INPUT -p tcp -m tcp -d %s --dport 80 -j %s\n", nvram_safe_get("lan_ipaddr"), logaccept);
1000		}
1001
1002		if (nvram_match("usb_webenable_x", "2"))
1003		{
1004			fprintf(fp, "-A INPUT -p tcp -m tcp --dport %s -j %s\n", nvram_safe_get("usb_webhttpport_x"), logaccept);
1005
1006			fprintf(fp, "-A INPUT -p tcp -m tcp --dport %s -j %s\n", nvram_safe_get("usb_webactivex_x"), logaccept);
1007		}
1008
1009		if (nvram_invmatch("usb_ftpenable_x", "0"))
1010		{
1011			fprintf(fp, "-A INPUT -p tcp -m tcp --dport %s -j %s\n", nvram_safe_get("usb_ftpport_x"), logaccept);
1012		}
1013
1014		if (nvram_invmatch("misc_ping_x", "0"))
1015		{
1016			fprintf(fp, "-A INPUT -p icmp -j %s\n", logaccept);
1017		}
1018
1019		if (nvram_invmatch("misc_lpr_x", "0"))
1020		{
1021			fprintf(fp, "-A INPUT -p tcp -m tcp --dport %d -j %s\n", 515, logaccept);
1022			fprintf(fp, "-A INPUT -p tcp -m tcp --dport %d -j %s\n", 9100, logaccept);
1023			fprintf(fp, "-A INPUT -p tcp -m tcp --dport %d -j %s\n", 3838, logaccept);
1024		}
1025
1026		fprintf(fp, "-A INPUT -j %s\n", logdrop);
1027	}
1028
1029	/* Pass multicast */
1030	if (nvram_match("mr_enable_x", "1"))
1031	{
1032		fprintf(fp, "-A FORWARD -p udp -d 224.0.0.0/4 -j ACCEPT\n");
1033		if (strlen(macaccept)>0)
1034			fprintf(fp, "-A MACS -p udp -d 224.0.0.0/4 -j ACCEPT\n");
1035	}
1036
1037	/* Clamp TCP MSS to PMTU of WAN interface before accepting RELATED packets */
1038	if (nvram_match("wan_proto", "pppoe")
1039			|| nvram_match("wan_proto", "pptp")
1040			|| nvram_match("wan_proto", "l2tp")
1041#ifdef CDMA // HSDPA
1042			|| strcmp(nvram_safe_get("hsdpa_product"), "") != 0
1043#endif
1044			)
1045	{
1046		fprintf(fp, "-A FORWARD -p tcp --syn -j TCPMSS --clamp-mss-to-pmtu\n");
1047		if (strlen(macaccept)>0)
1048			fprintf(fp, "-A MACS -p tcp --syn -j TCPMSS --clamp-mss-to-pmtu\n");
1049 	}
1050
1051	fprintf(fp, "-A FORWARD -m state --state ESTABLISHED,RELATED -j %s\n", logaccept);
1052	if (strlen(macaccept)>0)
1053		fprintf(fp, "-A MACS -m state --state ESTABLISHED,RELATED -j %s\n", logaccept);
1054
1055	/* Filter out invalid WAN->WAN connections */
1056	fprintf(fp, "-A FORWARD -o %s ! -i %s -j %s\n", wan_if, lan_if, logdrop);
1057// 2008.03 James. {
1058	//if (nvram_invmatch("wan0_ifname", wan_if))
1059	if(nvram_invmatch("wan0_ifname", wan_if) && inet_addr_(nvram_safe_get("wanx_ipaddr")))
1060// 2008.03 James. }
1061		fprintf(fp, "-A FORWARD -o %s ! -i %s -j %s\n", nvram_get("wan0_ifname"), lan_if, logdrop);
1062
1063	/* Drop the wrong state, INVALID, packets */
1064	fprintf(fp, "-A FORWARD -m state --state INVALID -j %s\n", logdrop);
1065	if (strlen(macaccept)>0)
1066		fprintf(fp, "-A MACS -m state --state INVALID -j %s\n", logdrop);
1067
1068	/* Accept the redirect, might be seen as INVALID, packets */
1069	fprintf(fp, "-A FORWARD -i %s -o %s -j %s\n", lan_if, lan_if, logaccept);
1070	if (strlen(macaccept)>0)
1071	{
1072		fprintf(fp, "-A MACS -i %s -o %s -j %s\n", lan_if, lan_if, logaccept);
1073
1074#ifdef GUEST_ACCOUNT
1075
1076		if(nvram_match("wl_guest_enable", "1"))
1077		{
1078			fprintf(fp, "-A MACS -i wl0.1 -o wl0.1 -j %s\n", logaccept);
1079		}
1080#endif
1081	}
1082
1083	if (nvram_match("fw_enable_x", "1") && !nvram_match("fw_dos_x", "0"))
1084	{
1085   		// DoS attacks
1086   		// sync-flood protection
1087   		fprintf(fp, "-A FORWARD -i %s -p tcp --syn -m limit --limit 1/s -j %s\n", wan_if, logaccept);
1088   		// furtive port scanner
1089   		fprintf(fp, "-A FORWARD -i %s -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j %s\n", wan_if, logaccept);
1090   		// ping of death
1091   		fprintf(fp, "-A FORWARD -i %s -p icmp --icmp-type echo-request -m limit --limit 1/s -j %s\n", wan_if, logaccept);
1092	}
1093
1094	// FILTER from LAN to WAN
1095	// Rules for MAC Filter and LAN to WAN Filter
1096	// Drop rules always before Accept
1097	if(nvram_match("macfilter_enable_x", "1"))
1098		strcpy(chain, "MACS");
1099	else
1100		strcpy(chain, "FORWARD");
1101
1102	if(nvram_match("fw_lw_enable_x", "1"))
1103	{
1104		char lanwan_timematch[128];
1105		char ptr[32], *icmplist;
1106		char *ftype, *dtype;
1107
1108		timematch_conv(lanwan_timematch, "filter_lw_date_x", "filter_lw_time_x");
1109
1110		if (nvram_match("filter_lw_default_x", "DROP"))
1111		{
1112			dtype = logdrop;
1113			ftype = logaccept;
1114
1115		}
1116		else
1117		{
1118			dtype = logaccept;
1119			ftype = logdrop;
1120		}
1121
1122		// LAN/WAN filter
1123		g_buf_init();
1124
1125		foreach_x("filter_lw_num_x")
1126		{
1127			proto = protoflag_conv("filter_lw_proto_x", i, 0);
1128			flag = protoflag_conv("filter_lw_proto_x", i, 1);
1129			srcip = iprange_ex_conv("filter_lw_srcip_x", i);
1130			srcport = portrange_conv("filter_lw_srcport_x", i);
1131			dstip = iprange_ex_conv("filter_lw_dstip_x", i);
1132			dstport = portrange_conv("filter_lw_dstport_x", i);
1133			setting=filter_conv(proto, flag, srcip, srcport, dstip, dstport);
1134			fprintf(fp, "-A %s %s -i %s -o %s%s -j %s\n", chain, lanwan_timematch, lan_if, wan_if, setting, ftype);
1135		}
1136
1137		// ICMP
1138		foreach(ptr, nvram_safe_get("filter_lw_icmp_x"), icmplist)
1139		{
1140			fprintf(fp, "-A %s %s -i %s -o %s -p icmp --icmp-type %s -j %s\n", chain, lanwan_timematch, lan_if, wan_if, ptr, ftype);
1141		}
1142
1143		// Default
1144		fprintf(fp, "-A %s -i %s -o %s -j %s\n", chain, lan_if, wan_if, dtype);
1145	}
1146	else if (nvram_match("macfilter_enable_x", "1"))
1147	{
1148		fprintf(fp, "-A FORWARD -i %s -o %s -j %s\n", lan_if, wan_if, logdrop);
1149		fprintf(fp, "-A MACS -i %s -o %s -j %s\n", lan_if, wan_if, logaccept);
1150	}
1151
1152	// Filter from WAN to LAN
1153	if(nvram_match("fw_wl_enable_x", "1"))
1154	{
1155		char wanlan_timematch[128];
1156		char ptr[32], *icmplist;
1157		char *dtype, *ftype;
1158
1159		timematch_conv(wanlan_timematch, "filter_wl_date_x", "filter_wl_time_x");
1160		g_buf_init();
1161
1162		if (nvram_match("filter_wl_default_x", "DROP"))
1163		{
1164			dtype = logdrop;
1165			ftype = logaccept;
1166		}
1167		else
1168		{
1169			dtype = logaccept;
1170			ftype = logdrop;
1171		}
1172
1173       		foreach_x("filter_wl_num_x")
1174       		{
1175            		proto = protoflag_conv("filter_wl_proto_x", i, 0);
1176            		flag = protoflag_conv("filter_wl_proto_x", i, 1);
1177			srcip = iprange_ex_conv("filter_wl_srcip_x", i);
1178			srcport = portrange_conv("filter_wl_srcport_x", i);
1179			dstip = iprange_ex_conv("filter_wl_dstip_x", i);
1180			dstport = portrange_conv("filter_wl_dstport_x", i);
1181			setting=filter_conv(proto, flag, srcip, srcport, dstip, dstport);
1182
1183         		fprintf(fp, "-A FORWARD %s -i %s -o %s%s -j %s\n", wanlan_timematch, wan_if, lan_if, setting, ftype);
1184		}
1185
1186       		// ICMP
1187       		foreach(ptr, nvram_safe_get("filter_wl_icmp_x"), icmplist)
1188		{
1189	        	fprintf(fp, "-A FORWARD %s -i %s -o %s -p icmp --icmp-type %s -j %s\n", wanlan_timematch, wan_if, lan_if, ptr, ftype);
1190	        }
1191
1192		// thanks for Oleg
1193		// Default
1194		// fprintf(fp, "-A FORWARD -i %s -o %s -j %s\n", wan_if, lan_if, dtype);
1195	}
1196
1197
1198	/* Enable Virtual Servers */
1199	fprintf(fp, "-A FORWARD -m conntrack --ctstate DNAT -j %s\n", logaccept);
1200
1201	if (nvram_match("wan_nat_x", "1") && nvram_invmatch("sp_battle_ips", "0"))
1202	{
1203		fprintf(fp, "-A FORWARD -p udp --dport %d -j %s\n", BASEPORT, logaccept);
1204	}
1205
1206	if(nvram_match("fw_wl_enable_x", "1")) // Thanks for Oleg
1207	{
1208		// Default
1209		fprintf(fp, "-A FORWARD -i %s -o %s -j %s\n", wan_if, lan_if,
1210			nvram_match("filter_wl_default_x", "DROP") ? logdrop : logaccept);
1211	}
1212
1213	/* logaccept chain */
1214	fprintf(fp, "-A logaccept -m state --state NEW -j LOG --log-prefix \"ACCEPT \" "
1215		  "--log-tcp-sequence --log-tcp-options --log-ip-options\n"
1216		  "-A logaccept -j ACCEPT\n");
1217
1218	/* logdrop chain */
1219	fprintf(fp,"-A logdrop -m state --state NEW -j LOG --log-prefix \"DROP\" "
1220		  "--log-tcp-sequence --log-tcp-options --log-ip-options\n"
1221		  "-A logdrop -j DROP\n");
1222
1223#ifdef WEBSTRFILTER/* Cherry Cho added in 2007/12/12. */
1224#if ADDRULE
1225#ifdef USEOLDNV
1226if (nvram_match("url_enable_x", "1")){
1227		for(i=0; i<atoi(nvram_safe_get("url_num_x")); i++) {
1228			memset(nvname, 0x0, 36);
1229			sprintf(nvname, "url_keyword_x%d", i);
1230			filterstr =  nvram_safe_get(nvname);
1231			if(strcmp(filterstr,""))
1232				fprintf(fp,"-I FORWARD -p tcp -m webstr --url \"%s\" -j DROP\n", filterstr);
1233		}
1234}
1235#else
1236if(nvram_match("webstr_filter_enable" ,"enabled")){
1237	for(i = 0; i< 10; i++){
1238		memset(nvname, 0x0, 36);
1239		sprintf(nvname, "filter_host%d", i);
1240		filterstr =  nvram_safe_get(nvname);
1241		if(strcmp(filterstr,""))
1242			fprintf(fp,"-I FORWARD -p tcp -m webstr --host \"%s\" -j DROP\n", filterstr);
1243	}
1244	for(i = 0; i< 10; i++){
1245		memset(nvname, 0x0, 36);
1246		sprintf(nvname, "filter_keyword%d", i);
1247		filterstr =  nvram_safe_get(nvname);
1248		if(strcmp(filterstr,""))
1249			fprintf(fp,"-I FORWARD -p tcp -m webstr --url \"%s\" -j DROP\n", filterstr);
1250	}
1251}
1252#endif
1253#endif
1254#endif
1255
1256	fprintf(fp, "COMMIT\n\n");
1257       	fclose(fp);
1258
1259	eval("iptables-restore", "/tmp/filter_rules");
1260
1261	return 0;
1262}
1263
1264int porttrigger_setting()
1265{
1266	netconf_app_t apptarget, *app;
1267	int i;
1268	char *out_proto, *in_proto, *out_port, *in_port, *desc;
1269	int  out_start, out_end, in_start, in_end;
1270
1271	if (nvram_invmatch("wan_nat_x", "1") ||
1272	    nvram_invmatch("autofw_enable_x", "1"))
1273		return -1;
1274
1275	g_buf_init();
1276
1277     	foreach_x("autofw_num_x")
1278     	{
1279     		out_proto = proto_conv("autofw_outproto_x", i);
1280     		out_port = portrange_ex2_conv("autofw_outport_x", i, &out_start, &out_end);
1281     		in_proto = proto_conv("autofw_inproto_x", i);
1282		in_port = portrange_ex2_conv("autofw_inport_x", i, &in_start, &in_end);
1283		desc = general_conv("autofw_desc_x", i);
1284
1285		app = &apptarget;
1286		memset(app, 0, sizeof(netconf_app_t));
1287
1288		/* Parse outbound protocol */
1289		if (!strncasecmp(out_proto, "tcp", 3))
1290			app->match.ipproto = IPPROTO_TCP;
1291		else if (!strncasecmp(out_proto, "udp", 3))
1292			app->match.ipproto = IPPROTO_UDP;
1293		else continue;
1294
1295		/* Parse outbound port range */
1296		app->match.dst.ports[0] = htons(out_start);
1297		app->match.dst.ports[1] = htons(out_end);
1298
1299		/* Parse related protocol */
1300		if (!strncasecmp(in_proto, "tcp", 3))
1301			app->proto = IPPROTO_TCP;
1302		else if (!strncasecmp(in_proto, "udp", 3))
1303			app->proto = IPPROTO_UDP;
1304		else continue;
1305
1306		/* Parse related destination port range */
1307		app->dport[0] = htons(in_start);
1308		app->dport[1] = htons(in_end);
1309
1310		/* Parse mapped destination port range */
1311		app->to[0] = htons(in_start);
1312		app->to[1] = htons(in_end);
1313
1314		/* Parse description */
1315		if (desc)
1316			strncpy(app->desc, desc, sizeof(app->desc));
1317
1318		/* Set interface name (match packets entering LAN interface) */
1319		strncpy(app->match.in.name, nvram_safe_get("lan_ifname"), IFNAMSIZ);
1320
1321		/* Set LAN source port range (match packets from any source port) */
1322		app->match.src.ports[1] = htons(0xffff);
1323
1324		/* Set target (application specific port forward) */
1325		app->target = NETCONF_APP;
1326
1327		if (valid_autofw_port(app))
1328		{
1329			netconf_add_fw((netconf_fw_t *)app);
1330		}
1331	}
1332
1333	return 0;
1334}
1335
1336int
1337start_firewall_ex(char *wan_if, char *wan_ip, char *lan_if, char *lan_ip)
1338{
1339	DIR *dir;
1340	struct dirent *file;
1341	FILE *fp;
1342	char name[NAME_MAX];
1343	char logaccept[32], logdrop[32];
1344	char *mcast_ifname = nvram_get("wan0_ifname");
1345
1346	/* mcast needs rp filter to be turned off only for non default iface */
1347	if (!nvram_match("mr_enable_x", "1") ||	strcmp(wan_if, mcast_ifname) == 0)
1348		mcast_ifname = NULL;
1349
1350	/* Block obviously spoofed IP addresses */
1351	if (!(dir = opendir("/proc/sys/net/ipv4/conf")))
1352		perror("/proc/sys/net/ipv4/conf");
1353	while (dir && (file = readdir(dir))) {
1354		if (strncmp(file->d_name, ".", NAME_MAX) != 0 &&
1355		    strncmp(file->d_name, "..", NAME_MAX) != 0) {
1356			sprintf(name, "/proc/sys/net/ipv4/conf/%s/rp_filter", file->d_name);
1357			if (!(fp = fopen(name, "r+"))) {
1358				perror(name);
1359				break;
1360			}
1361			fputc(mcast_ifname && strncmp(file->d_name,
1362				mcast_ifname, NAME_MAX) == 0 ? '0' : '1', fp);
1363			fclose(fp);
1364		}
1365	}
1366	closedir(dir);
1367
1368	/* Determine the log type */
1369	if(nvram_match("fw_log_x", "accept") || nvram_match("fw_log_x", "both"))
1370		strcpy(logaccept, "logaccept");
1371	else
1372		strcpy(logaccept, "ACCEPT");
1373
1374	if(nvram_match("fw_log_x", "drop") || nvram_match("fw_log_x", "both"))
1375		strcpy(logdrop, "logdrop");
1376	else
1377		strcpy(logdrop, "DROP");
1378
1379	/* nat setting */
1380	if(nvram_match("wan_status_t", "Connected"))	// 2008.08 James.
1381		nat_setting(wan_if, wan_ip, lan_if, lan_ip, logaccept, logdrop);
1382
1383	/* Filter setting */
1384	filter_setting(wan_if, wan_ip, lan_if, lan_ip, logaccept, logdrop);
1385
1386	/* Trigger port setting */
1387	porttrigger_setting();
1388
1389#ifdef WEBSTRFILTER/* Cherry Cho added in 2007/12/28. */
1390#if !ADDRULE
1391	if(web_filter())
1392		printf("Fail to add web filter!!\n");
1393#endif
1394#endif
1395
1396	/* Add max conntrack as 4096, thanks for Oleg */
1397	if ((fp=fopen("/proc/sys/net/ipv4/ip_conntrack_max", "r+")))
1398	{
1399		if (nvram_get("misc_conntrack_x")==NULL) fputs("4096", fp);
1400		else fputs(nvram_safe_get("misc_conntrack_x"), fp);
1401		fclose(fp);
1402	}
1403
1404#ifdef XBOX_SUPPORT
1405	if( (fp=fopen("/proc/sys/net/ipv4/ip_conntrack_udp_timeouts", "r+")) ){
1406		fprintf(fp, "%d %d", 65, 180);
1407		fclose(fp);
1408	} else
1409		perror("/proc/sys/net/ipv4/ip_conntrack_udp_timeouts");
1410#endif
1411
1412	if( (fp=fopen("/proc/sys/net/ipv4/ip_forward", "r+")) ){
1413		fputc('1', fp);
1414		fclose(fp);
1415	} else
1416		perror("/proc/sys/net/ipv4/ip_forward");
1417
1418	return 0;
1419}
1420
1421
1422int portmapping_main(int argc, char *argv[])
1423{
1424	char actionname[32], portname[32], ipname[32];
1425	// Check wan interface
1426	// argv[1] = Set or Unset
1427	// argv[2] = Port
1428	// argv[3] = IP
1429	// argv[4] = Item
1430	sprintf(actionname, "4_MappedAction_%s", argv[4]);
1431	sprintf(ipname, "4_MappedIP_%s", argv[4]);
1432	sprintf(portname, "4_MappedInPort_%s", argv[4]);
1433
1434	if (strcmp(argv[1], "Set")==0)
1435	{
1436		nvram_set(actionname, argv[1]);
1437		nvram_set(portname, argv[2]);
1438		nvram_set(ipname, argv[3]);
1439	}
1440	else
1441	{
1442		nvram_set(actionname, argv[1]);
1443	}
1444
1445// 2008.03 James. {
1446	//if (nvram_match("wan_proto", "pppoe"))
1447	if(nvram_match("wan_proto", "pppoe")
1448			|| nvram_match("wan_proto", "pptp")
1449			|| nvram_match("wan_proto", "l2tp")
1450#ifdef CDMA // HSDPA
1451			|| strcmp(nvram_safe_get("hsdpa_product"), "") != 0
1452#endif
1453			)
1454// 2008.03 James. }
1455	{
1456		start_firewall_ex("ppp0", "", "br0", "");
1457	}
1458	else
1459	{
1460		start_firewall_ex("eth0", "", "br0", "");
1461	}
1462
1463	return 0;
1464}
1465/*
1466#ifdef USB_SUPPORT
1467void write_ftp_banip(FILE *fp)
1468{
1469	char *ip;
1470	int i;
1471
1472	g_buf_init();
1473
1474       	foreach_x("usb_bannum_x")
1475       	{
1476            	ip = general_conv("usb_ftpbanip_x", i);
1477		fprintf(fp, "ban=%s\n", ip);
1478	}
1479}
1480
1481
1482void write_ftp_userlist(FILE *fp)
1483{
1484	char *user, *pass, *max, *rights;
1485	int i, maxuser;
1486	char passwd[32];
1487	char dir[64];
1488
1489	g_buf_init();
1490
1491	mkdir_if_none("/tmp/harddisk/ftp_pub");
1492	mkdir_if_none("/tmp/harddisk/ftp_pvt");
1493
1494       	foreach_x("usb_ftpnum_x")
1495       	{
1496            	user = general_conv("usb_ftpusername_x", i);
1497            	pass = general_conv("usb_ftppasswd_x", i);
1498            	max = general_conv("usb_ftpmaxuser_x", i);
1499            	rights = general_conv("usb_ftprights_x", i);
1500
1501		if (strlen(max)==0) maxuser=0;
1502		else maxuser=atoi(max);
1503
1504		if (strlen(pass)==0) strcpy(passwd, "*");
1505		else strcpy(passwd, pass);
1506
1507		if (strcmp(rights, "Private")==0)
1508		{
1509			fprintf(fp, "user=%s %s /ftp_pvt/%s/ %d A\n", user, passwd, user, maxuser);
1510			sprintf(dir, "/tmp/harddisk/ftp_pvt/%s", user);
1511			mkdir_if_none(dir);
1512		}
1513		else if (strcmp(rights, "Private(WO)")==0)
1514		{
1515			fprintf(fp, "user=%s %s /ftp_pvt/%s/ %d U\n", user, passwd, user, maxuser);
1516			sprintf(dir, "/tmp/harddisk/ftp_pvt/%s", user);
1517			mkdir_if_none(dir);
1518		}
1519		else if (strcmp(rights, "Read/Write/Erase")==0)
1520			fprintf(fp, "user=%s %s /ftp_pub/ %d A\n", user, passwd, maxuser);
1521		else if (strcmp(rights, "Read/Write")==0)
1522			fprintf(fp, "user=%s %s /ftp_pub/ %d DUM\n", user, passwd, maxuser);
1523		else if (strcmp(rights, "Read Only")==0)
1524			fprintf(fp, "user=%s %s /ftp_pub/ %d DM\n", user, passwd, maxuser);
1525		else if (strcmp(rights, "Write Only")==0)
1526			fprintf(fp, "user=%s %s /ftp_pub/ %d U\n", user, passwd, maxuser);
1527		else	fprintf(fp, "user=%s %s /ftp_pub/ %d -\n", user, passwd, maxuser);
1528	}
1529}
1530#endif
1531*/
1532#endif
1533
1534#ifdef WEBSTRFILTER/* Cherry Cho added in 2007/12/27. */
1535int web_filter()
1536{
1537	netconf_filter_t entry; // 2009.06 James.
1538	netconf_filter_t *rule;
1539	int i, j, ret = 0, addFilter = 0;
1540	char nvname[36];
1541	char *activeDate, *activeTime;
1542	uint days[2] = {8, 8}; /* days[0]: start  days[1]: end  0: Sunday 1: Monday  6:Saturday*/
1543	uint activeTimeStart, activeTimeEnd;
1544
1545	activeDate = nvram_safe_get("url_date_x");
1546	activeTime = nvram_safe_get("url_time_x");
1547
1548	activeTimeStart=(((activeTime[0]-'0')*10+(activeTime[1]-'0'))*60 + (activeTime[2]-'0')*10 + (activeTime[3]-'0'))*60;
1549	activeTimeEnd=(((activeTime[4]-'0')*10+(activeTime[5]-'0'))*60 + (activeTime[6]-'0')*10 + (activeTime[7]-'0'))*60;
1550
1551	if (nvram_match("url_enable_x", "1")){
1552		for(j=0; j<7; j++){
1553			if(activeDate[j] == '1'){
1554				if(days[0]== 8){
1555					days[0] = j;
1556					days[1] = j;
1557				}
1558				else
1559					days[1] = j;
1560
1561				if(j==6)
1562					addFilter = 1;
1563			}
1564			else if((activeDate[j] == '0') && days[0]!= 8){
1565				addFilter = 1;
1566			}
1567
1568			if(addFilter){
1569				for(i=0; i<atoi(nvram_safe_get("url_num_x")); i++) {
1570					rule = &entry; // 2009.06 James.
1571					memset(rule, 0x0, sizeof(netconf_filter_t));
1572					if((days[0]>=0 && days[0]<=6) && (days[1]>=0 && days[1]<=6)){
1573						rule->match.days[0] = days[0];
1574						rule->match.days[1] = days[1];
1575					}
1576
1577					if((activeTimeStart>=0 && activeTimeStart<=(24 * 60 * 60))
1578							&& (activeTimeEnd>=0 && activeTimeEnd<=(24 * 60 * 60))){
1579						rule->match.secs[0] = activeTimeStart;
1580						rule->match.secs[1] = activeTimeEnd;
1581					}
1582
1583					memset(nvname, 0x0, 36);
1584					sprintf(nvname, "url_keyword_x%d", i);
1585					strcpy(rule->match.module_name, "webstr");
1586					strncpy(rule->match.webstr_info.string, nvram_safe_get(nvname), 256);
1587					rule->match.webstr_info.invert = 0;
1588					rule->match.webstr_info.len = strlen(nvram_safe_get(nvname));
1589					rule->match.webstr_info.type = NETCONF_WEBSTR_URL;
1590					rule->target = NETCONF_DROP;
1591					rule->dir = NETCONF_FORWARD;
1592					ret = netconf_add_fw((netconf_fw_t *)rule);
1593				}
1594
1595				days[0] = 8; /* Reset values of days[0] and days[1] */
1596				days[1] = 8;
1597				addFilter = 0;
1598			}
1599		}
1600	}
1601
1602	return ret;
1603}
1604#endif
1605