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