| #include <stdlib.h> | 
 | #include <stdio.h> | 
 | #include <string.h> | 
 | #include <sys/ioctl.h> | 
 | #include <fcntl.h> | 
 | #include <getopt.h> | 
 | #include <strings.h> | 
 | #include <unistd.h> | 
 | #ifndef CONFIG_SUPPORT_OPENWRT | 
 | #include <linux/autoconf.h> | 
 | #endif | 
 |  | 
 | #if defined CONFIG_COLGIN_SUPPORT | 
 | #include "hnat_ioctl.h" | 
 | #else | 
 | #include "hwnat_ioctl.h" | 
 | #endif | 
 | #include "hwnat_api.h" | 
 | #include "util.h" | 
 |  | 
 | void show_usage(void) | 
 | { | 
 |     printf("Add Static Entry\n"); | 
 |     printf("hw_nat -a -P [PPE_INDEX] -h [SMAC] -i [DMAC] -1 [type:hnapt(0)/ipv6_rout(5)]-j [Sip] -2 [Dip] -l [Sp] -3 [Dp]\n"); | 
 |     printf("	   -n [New_Sip] -o [New_Dip] -p [New_Sp] -q [New_Dp] -4 [Vlan_layer] -5 [dscp]\n"); | 
 |     printf("	   -s [VLAN1_ID] -S [VLAN2_ID] -v [Tcp/Udp] -w [OutIf:CPU/GE1/GE2]\n"); | 
 |     printf("Ex(ipv4): hw_nat -a -P 0 -h 00:0C:43:28:80:11 -i E0:18:77:BD:D5:18 -1 0 -j 10.10.10.3 -2 10.10.20.3\n"); | 
 |     printf("-l 1000 -3 2000 -n 10.10.20.254 -o 10.10.20.3 -p 1000 -q 2000 -4 1 -s 1 -v Tcp -w GE2 -5 32\n\n"); | 
 |  | 
 |     printf("Ex(ipv6): hw_nat -a -P 0 -h 00:0C:43:28:02:14 -i 00:1B:21:00:9B:03 -1 5 -6 2001:1111:2222:3333:0000:0000:0000:2\n"); | 
 |     printf("-7 2001:aaa:6401:101:8000:0000:0000:2 -l 3000 -3 2000 -4 0 -v Tcp -w GE1 -5 32\n\n"); | 
 |  | 
 |     printf("Del Static Entry\n"); | 
 |     printf("hw_nat -b -P [PPE_INDEX] -1 [type:hnapt(0)/ipv6_rout(5)] -j [Sip] -2 [Dip] -l [Sp] -3 [Dp] -v [Tcp/Udp] \n"); | 
 |     printf("Ex: hw_nat -b -P 0 -j 10.10.10.3 -k 10.10.20.3 -l 30 -m 40 -v Tcp\n\n"); | 
 | #if defined (CONFIG_HW_NAT_SEMI_AUTO_MODE) | 
 |     printf("Add semi-auto Entry\n"); | 
 |     printf("hw_nat -a -1 [type:hnapt(0)/ipv6_rout(5)]-j [Sip] -2 [Dip] -l [Sp] -m [Dp]\n"); | 
 |     printf("hw_nat -a -1 0 -j 10.10.10.3 -2 10.10.20.3 -l 1000 -3 2000 \n"); | 
 |     printf("hw_nat -a -1 5 -j 2001:1111:2222:3333:0000:0000:0000:2 -2 2001:aaa:6401:101:8000:0000:0000:2 -l 3000 -3 2000\n"); | 
 |     printf("Delete semi-auto Entry\n"); | 
 |     printf("hw_nat -b -1 0 -j 10.10.10.3 -2 10.10.20.3 -l 1000 -3 2000\n"); | 
 |     printf("hw_nat -b -1 5 -j 2001:1111:2222:3333:0000:0000:0000:2 -2 2001:aaa:6401:101:8000:0000:0000:2 -l 3000 -3 2000\n"); | 
 | #endif | 
 |     printf("Show Foe Entry\n"); | 
 |     printf("hw_nat -c [entry_num] -P [ppe_index]\n"); | 
 |     printf("Ex: hw_nat -c 1234 -P 0\n\n"); | 
 |  | 
 |     printf("Set Debug Level (0:disable) \n"); | 
 |     printf("hw_nat -d [0~7]\n"); | 
 |     printf("Ex: hw_nat -d \n\n"); | 
 |  | 
 |     printf("Show All Foe Invalid Entry\n"); | 
 |     printf("Ex: hw_nat -e\n\n"); | 
 |  | 
 |     printf("Show All Foe Unbinded Entry\n"); | 
 |     printf("Ex: hw_nat -f\n\n"); | 
 |  | 
 |     printf("Show All Foe Binded Entry\n"); | 
 |     printf("Ex: hw_nat -g\n\n"); | 
 |  | 
 |     printf("Invalid Foe Entry\n"); | 
 |     printf("hw_nat -I [entry_num] -P [ppe_index]\n"); | 
 |     printf("Ex: hw_nat -I 1234 -P 0\n\n"); | 
 |  | 
 |     printf("Unbind Foe Entry\n"); | 
 |     printf("hw_nat -x [entry_num] -P [ppe_index]\n"); | 
 |     printf("Ex: hw_nat -x 1234 -P 0\n\n"); | 
 |  | 
 |     printf("Set Foe Entry to PacketDrop\n"); | 
 |     printf("hw_nat -k [entry_num] -P [ppe_index]\n"); | 
 |     printf("Ex: hw_nat -k 1234 -P 0\n\n"); | 
 |  | 
 |  | 
 | #if defined (CONFIG_PPE_MCAST) | 
 |     printf("Add member port in multicast entry\n"); | 
 |     printf("Ex: hw_nat -B [vid] [mac] [px_en] [px_qos_en] [mc_qos_qid]\n\n"); | 
 |  | 
 |     printf("Del member port multicast entry\n"); | 
 |     printf("Ex: hw_nat -C [vid] [mac] [px_en] [px_qos_en] [mc_qos_qid]\n\n"); | 
 |  | 
 |     printf("Dump all multicast entry\n"); | 
 |     printf("Ex: hw_nat -D\n\n"); | 
 | #endif | 
 |  | 
 |     printf("Set PPE Cofigurations:\n"); | 
 |     printf("Set HNAT binding threshold per second (d=30)\n"); | 
 |     printf("Ex: hw_nat -N [1~65535]\n\n"); | 
 |  | 
 |  | 
 |     printf("Set HNAT TCP/UDP keepalive interval (d=1, 1)(unit:4sec)\n"); | 
 |     printf("Ex: hw_nat -Q [1~255][1~255]\n\n"); | 
 |  | 
 |     printf("Disable Hook API (hook_id: 0=ETH, 1=MD, 2=WIFI, 3=RNDIS, 4=EXT, 5=SNPS)\n"); | 
 |     printf("Ex: hw_nat -O <hook_id>, hwnat -O [0/1/2/3/4/5]\n\n"); | 
 |  | 
 |     printf("Restore Hook API (hook_id: 0=ETH, 1=MD, 2=WIFI, 3=RNDIS, 4=EXT, 5=SNPS)\n"); | 
 |     printf("Ex: hw_nat -T <hook_id>, hwnat -T [0/1/2/3/4/5]\n\n"); | 
 |  | 
 |     printf("Disable Hook API on specific direction (hook_id: 0=ETH, 1=MD, 2=WIFI, 3=RNDIS, 4=EXT, 5=SNPS) (dir: 1:rx, 2:tx)\n"); | 
 |     printf("Ex: hw_nat -O <hook_id> -P <dir_id>, hwnat -O [0/1/2/3/4/5] -P[1/2]\n\n"); | 
 |  | 
 |     printf("Restore Hook API on specific direction (hook_id: 0=ETH, 1=MD, 2=WIFI, 3=RNDIS, 4=EXT, 5=SNPS) (dir: 1:rx, 2:tx)\n"); | 
 |     printf("Ex: hw_nat -T <hook_id> -P <dir_id>, hwnat -T [0/1/2/3/4/5] -P[1/2]\n\n"); | 
 |  | 
 |     printf("Set HNAT Life time of Binded TCP/UDP/FIN entry(d=5, 5, 5)(unit:1Sec) \n"); | 
 |     printf("Ex: hw_nat -U [1~65535][1~65535][1~65535]\n\n"); | 
 |  | 
 |     printf("Set LAN/WAN port VLAN ID\n"); | 
 |     printf("Ex: hw_nat -V [LAN_VID] [WAN_VID]\n\n"); | 
 |     printf("Ex: hw_nat -V 1 2\n\n"); | 
 |  | 
 |     printf("Only Speed UP (0=Upstream, 1=Downstream, 2=Bi-Direction) flow \n"); | 
 |     printf("Ex: hw_nat -Z 1\n\n"); | 
 |  | 
 | #if defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) | 
 |     printf("Switch Ds-Lite and Map-E(0=Ds-Lite, 1=Map-E,(d=0)):\n"); | 
 |     printf("Ex: hw_nat -W [0/1]\n\n"); | 
 | #endif | 
 | #if defined (CONFIG_PPE_MIB) | 
 |     printf("Get ppe entry mib counter\n"); | 
 |     printf("hw_nat -M -1 [type:hnapt(0)/ipv6_rout(5)]-j [Sip] -2 [Dip] -l [Sp] -m [Dp]\n"); | 
 |     printf("hw_nat -M -1 0 -j 10.10.10.3 -2 10.10.20.3 -l 1000 -3 2000 \n"); | 
 |     printf("hw_nat -M -1 5 -j 2001:1111:2222:3333:0000:0000:0000:2 -2 2001:aaa:6401:101:8000:0000:0000:2 -l 3000 -3 2000\n"); | 
 |     printf("Get ppe entry all mib counter sort by IP\n"); | 
 |     printf("hw_nat -X\n"); | 
 | #endif | 
 | #if defined (CONFIG_HW_NAT_IPI) | 
 |     printf("Set HNAT IPI control from extif:\n"); | 
 |     printf("EX: hw_nat -G [ipi_enable] [queue_thresh] [drop_pkt] [ipi_cnt_mod]\n\n"); | 
 |     printf("Set HNAT IPI control from ppehit:\n"); | 
 |     printf("EX: hw_nat -L [ipi_enable] [queue_thresh] [drop_pkt] [ipi_cnt_mod]\n\n"); | 
 |     printf("hw_nat -G 1 1000 20000 5\n"); | 
 |     printf("hw_nat -L 1 1000 20000 44\n"); | 
 | #endif | 
 | } | 
 | #if defined CONFIG_COLGIN_SUPPORT | 
 | static void dump_all_ip_cnt(struct hwnat_mib_all_ip_args *args) | 
 | { | 
 | 	int i; | 
 | 	if(args->entry_num > 0) | 
 | 		printf("IP            tx_packets     tx_bytes     rx_packets     rx_bytes\n"); | 
 | 	for(i=0; i<args->entry_num; i++) { | 
 | 		if(args->entries[i].is_ipv4) { //IPV4_NAPT | 
 | 			printf("%8x	%10ld  %10ld  %10ld  %10ld\n", | 
 | 			args->entries[i].ip.ipv4_addr, | 
 | 			args->entries[i].tx_packets, | 
 | 			args->entries[i].tx_bytes, | 
 | 			args->entries[i].rx_packets, | 
 | 			args->entries[i].rx_bytes); | 
 | 		} else { //IPV6_5T_ROUTE | 
 | 			printf(" %4x:%4x:%4x:%4x:%4x:%4x:%4x:%4x	%10ld  %10ld  %10ld  %10ld\n", | 
 | 				NIPHALF(args->entries[i].ip.ipv6_addr[0]), | 
 | 				NIPHALF(args->entries[i].ip.ipv6_addr[1]), | 
 | 				NIPHALF(args->entries[i].ip.ipv6_addr[2]), | 
 | 				NIPHALF(args->entries[i].ip.ipv6_addr[3]), | 
 | 				args->entries[i].tx_packets, | 
 | 				args->entries[i].tx_bytes, | 
 | 				args->entries[i].rx_packets, | 
 | 				args->entries[i].rx_bytes); | 
 | 		} | 
 | 	} | 
 | } | 
 | #endif | 
 | int main(int argc, char *argv[]) | 
 | { | 
 |     int opt; | 
 |  | 
 |     //char options[] = "aefgy?c:x:k:d:A:B:C:DN:O:P:Q:T:U:V:Z:"; | 
 |     char options[] = "abefgyzMD?c:m:r:A:B:C:G:I:J:K:L:S:d:h:i:j:1:k:2:l:3:n:o:p:q:4:s:P:t:u:v:w:5:x:y:N:O:Q:T:U:Z:L:7:8:9:E:F:H:R:6:X"; | 
 |  | 
 |     int fd, method = -1; | 
 |     int i=0; | 
 |     unsigned int entry_num; | 
 |     unsigned int debug; | 
 |     unsigned int type; | 
 |     struct hwnat_args *args = {0}; | 
 |     struct hwnat_tuple args2 = {0}; | 
 |     struct hwnat_ac_args args3; | 
 |     struct hwnat_config_args args4; | 
 | #if defined (CONFIG_HW_NAT_IPI) | 
 |     struct hwnat_ipi_args args6; | 
 |     struct hwnat_ipi_args args7; | 
 | #endif | 
 |  | 
 | #if defined (CONFIG_PPE_MCAST) | 
 |     struct hwnat_mcast_args args5; | 
 |     unsigned char mac[6]; | 
 | #endif | 
 | #if defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) | 
 | 	unsigned int swit; | 
 | #endif | 
 |     int	   result; | 
 | #if defined CONFIG_COLGIN_SUPPORT | 
 | 	int org_tot_len = 1362; | 
 | 	int org_id = 0; | 
 | 	int org_frag =0; | 
 | 	int chksum_tmp, tot_len_tmp, id_tmp, frag_tmp; | 
 | 	int chksum_base = 0; | 
 | 	struct hwnat_mib_all_ip_args *args8; | 
 | #endif | 
 |     fd = open("/dev/"HW_NAT_DEVNAME, O_RDONLY); | 
 |     if (fd < 0) | 
 |     { | 
 | 	printf("Open %s pseudo device failed\n","/dev/"HW_NAT_DEVNAME); | 
 | 	return 0; | 
 |     } | 
 |  | 
 |     if(argc < 2) { | 
 | 	show_usage(); | 
 |         close(fd); | 
 | 	return 0; | 
 |     } | 
 |  | 
 |     /* Max table size is 16K */ | 
 |     args=malloc(sizeof(struct hwnat_args)+sizeof(struct hwnat_tuple)*1024*16); | 
 |     if (NULL == args) | 
 |     { | 
 | 	    printf(" Allocate memory for hwnat_args and hwnat_tuple failed.\n"); | 
 |             close(fd); | 
 | 	    return 0; | 
 |     } | 
 |  | 
 |     while ((opt = getopt (argc, argv, options)) != -1) { | 
 | 	switch (opt) { | 
 | 	case 'h': | 
 | 		 str_to_mac(args2.smac, optarg); | 
 | 		 break; | 
 | 	case 'i': | 
 | 		 str_to_mac(args2.dmac, optarg); | 
 | 		 break; | 
 | 	case '1': | 
 | 		 type = strtoll(optarg, NULL, 10); | 
 | 		 args2.pkt_type = type; | 
 | 		 break; | 
 | 	case 'j': | 
 | 		if ((type == 0) || (type == 7)) { | 
 | 			str_to_ip(&args2.ing_sipv4, optarg); | 
 | 		} else if((type == 5) || (type == 3)) { | 
 | 			str_to_ipv6(&args2.ing_sipv6_0, optarg, 0); | 
 | 			str_to_ipv6(&args2.ing_sipv6_1, optarg, 1); | 
 | 			str_to_ipv6(&args2.ing_sipv6_2, optarg, 2); | 
 | 			str_to_ipv6(&args2.ing_sipv6_3, optarg, 3); | 
 | 		} else { | 
 | 			printf("hwnat type error\n"); | 
 | 			free(args); | 
 | 			close(fd); | 
 | 			return 0; | 
 | 		} | 
 | 		 break; | 
 | 	case '2': | 
 | 		if ((type == 0) || (type == 7)) { | 
 | 			str_to_ip(&args2.ing_dipv4, optarg); | 
 | 		} else if((type == 5) || (type == 3)) { | 
 | 			str_to_ipv6(&args2.ing_dipv6_0, optarg, 0); | 
 | 			str_to_ipv6(&args2.ing_dipv6_1, optarg, 1); | 
 | 			str_to_ipv6(&args2.ing_dipv6_2, optarg, 2); | 
 | 			str_to_ipv6(&args2.ing_dipv6_3, optarg, 3); | 
 | 		} else { | 
 | 			printf("hwnat type error\n"); | 
 | 			free(args); | 
 | 			close(fd); | 
 | 			return 0; | 
 | 		} | 
 | 		 break; | 
 | 	case 'l': | 
 | 		 args2.ing_sp = strtoll(optarg, NULL, 10); | 
 | 		 break; | 
 | 	case '3': | 
 | 		 args2.ing_dp = strtoll(optarg, NULL, 10); | 
 | 		 break; | 
 | 	case 'n': | 
 | 		 str_to_ip(&args2.eg_sipv4, optarg); | 
 | 		 break; | 
 | 	case 'o': | 
 | 		 str_to_ip(&args2.eg_dipv4, optarg); | 
 | 		 break; | 
 | 	case 'p': | 
 | 		 args2.eg_sp = strtoll(optarg, NULL, 10); | 
 | 		 break; | 
 | 	case 'q': | 
 | 		 args2.eg_dp = strtoll(optarg, NULL, 10); | 
 | 		 break; | 
 | 	case '4': | 
 | 		 args2.vlan_layer = strtoll(optarg, NULL, 10); | 
 | 		 break; | 
 | 	case 's': | 
 | 		 args2.vlan1 = strtoll(optarg, NULL, 10); | 
 |                  break; | 
 | 	case 'S': | 
 | 		 args2.vlan2 = strtoll(optarg, NULL, 10); | 
 | 		 break; | 
 | #if defined CONFIG_COLGIN_SUPPORT | 
 | 	case 'P': | 
 | 		args2.set_idx = strtoll(optarg, NULL, 16); | 
 | 		break; | 
 | #endif | 
 | 	case 't': | 
 | 		 if(strcasecmp(optarg,"Ins")==0){ | 
 | 			 args2.pppoe_act=1; | 
 | 		 }else if(strcasecmp(optarg,"Del")==0){ | 
 | 			 args2.pppoe_act=0; | 
 | 		 }else{ | 
 | 			 printf("Error: -t No/Mod/Ins/Del\n"); | 
 | 			 free(args); | 
 | 			 close(fd); | 
 | 			 return 0; | 
 | 		 } | 
 | 		 break; | 
 | 	case 'u': | 
 | 		 args2.pppoe_id = strtoll(optarg, NULL, 10); | 
 | 		 break; | 
 | 	case 'v': | 
 | 		 if(strcasecmp(optarg,"Tcp")==0){ | 
 | 			 args2.is_udp=0; | 
 | 		 }else if(strcasecmp(optarg,"Udp")==0){ | 
 | 			 args2.is_udp=1; | 
 | 		 }else { | 
 | 			 printf("Error: -v Tcp/Udp\n"); | 
 | 			 free(args); | 
 | 			 close(fd); | 
 | 			 return 0; | 
 | 		 } | 
 | 		 break; | 
 | 	case 'w': | 
 | 		 if(strcasecmp(optarg,"CPU")==0){ | 
 | 			 args2.dst_port=0; | 
 | 		 }else if(strcasecmp(optarg,"GE1")==0){ | 
 | 			 args2.dst_port=1; | 
 | 		 }else if(strcasecmp(optarg,"GE2")==0){ | 
 | 			 args2.dst_port=2; | 
 |     		 }else if(strcasecmp(optarg,"P7")==0){ | 
 | 			 args2.dst_port=7; | 
 | 		 }else if(strcasecmp(optarg,"P8")==0){ | 
 | 			 args2.dst_port=8; | 
 | 		 }else if(strcasecmp(optarg,"P9")==0){ | 
 | 			 args2.dst_port=9; | 
 | 		 }else if(strcasecmp(optarg,"p10")==0){ | 
 | 			 args2.dst_port=10; | 
 | 		 }else if(strcasecmp(optarg,"p11")==0){ | 
 | 			 args2.dst_port=11; | 
 | 		 }else if(strcasecmp(optarg,"p12")==0){ | 
 | 			 args2.dst_port=12; | 
 | 		 }else { | 
 | 			printf("Error: -w CPU/GE1/GE2/P7/P8/P9/P10/P11/P12\n"); | 
 | 			free(args); | 
 | 			close(fd); | 
 | 			return 0; | 
 | 		 } | 
 | 		 break; | 
 | 	case '5': | 
 | 		 args2.dscp = strtoll(optarg, NULL, 10); | 
 | 		 break; | 
 | 	case '7': | 
 | 		str_to_ipv6(&args2.ing_sipv6_0, optarg, 0); | 
 | 		str_to_ipv6(&args2.ing_sipv6_1, optarg, 1); | 
 | 		str_to_ipv6(&args2.ing_sipv6_2, optarg, 2); | 
 | 		str_to_ipv6(&args2.ing_sipv6_3, optarg, 3); | 
 | 		break; | 
 | 	case '8': | 
 | 		str_to_ipv6(&args2.ing_dipv6_0, optarg, 0); | 
 | 		str_to_ipv6(&args2.ing_dipv6_1, optarg, 1); | 
 | 		str_to_ipv6(&args2.ing_dipv6_2, optarg, 2); | 
 | 		str_to_ipv6(&args2.ing_dipv6_3, optarg, 3); | 
 | 		break; | 
 | #if defined CONFIG_COLGIN_SUPPORT | 
 | 	case '9': | 
 | 		args2.rmt = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | #endif | 
 | 	case 'E': | 
 | 		args2.hash_index = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | #if defined CONFIG_COLGIN_SUPPORT | 
 | 	case 'F': | 
 | 		args2.frag = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | 	case 'H': | 
 | 		chksum_tmp = strtoll(optarg, NULL, 16); | 
 | 		chksum_tmp = (0xffff-chksum_tmp); | 
 | 		chksum_tmp = (chksum_tmp - org_tot_len - org_id); | 
 | 		chksum_base = chksum_tmp & 0xFFFF; | 
 | 		printf("chksum_base = %x\n", chksum_base); | 
 | 		args2.checksum = chksum_base; | 
 | 		break; | 
 | 	case 'R': | 
 | 		args2.ttl = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | #endif | 
 | 	case 'a': | 
 | 		method = HW_NAT_ADD_ENTRY; | 
 | 		break; | 
 |  | 
 | 	case 'b': | 
 | 		method = HW_NAT_DEL_ENTRY; | 
 | 		break; | 
 | 	case 'z': | 
 | 		method = HW_NAT_DUMP_CACHE_ENTRY; | 
 | 		break; | 
 | 	case 'c': | 
 | 		method = HW_NAT_DUMP_ENTRY; | 
 | 		entry_num = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | 	case 'I': | 
 | 		method = HW_NAT_INVALID_ENTRY; | 
 | 		entry_num = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | 	case 'x': | 
 | 		method = HW_NAT_UNBIND_ENTRY; | 
 | 		entry_num = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | 	case 'k': | 
 | 		method = HW_NAT_DROP_ENTRY; | 
 | 		entry_num = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | 	case 'd': | 
 | 		method = HW_NAT_DEBUG; | 
 | 		debug = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | #if defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) | 
 | 	case 'W': | 
 | 		method = HW_NAT_SWITCH_DSL_MAPE; | 
 | 		swit = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | #endif | 
 | 	case 'e': | 
 | 		method = HW_NAT_GET_ALL_ENTRIES; | 
 | 		args->entry_state=0; /* invalid entry */ | 
 | 		break; | 
 | 	case 'f': | 
 | 		method = HW_NAT_GET_ALL_ENTRIES; | 
 | 		args->entry_state=1; /* unbinded entry */ | 
 | 		break; | 
 | 	case 'g': | 
 | 		method = HW_NAT_GET_ALL_ENTRIES; | 
 | 		args->entry_state=2; /* binded entry */ | 
 | 		break; | 
 | 	case 'y': | 
 | 		method = HW_NAT_TBL_CLEAR; | 
 | 		break; | 
 | 	case 'A': | 
 | 		method = HW_NAT_GET_AC_CNT; | 
 | 		args3.ag_index = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | #if defined (CONFIG_PPE_MCAST) | 
 | 	case 'B': | 
 | 		method = HW_NAT_MCAST_INS; | 
 | 		args5.mc_vid = strtoll(argv[2], NULL, 10); | 
 | 		str_to_mac(mac, argv[3]); | 
 | 		memcpy(args5.dst_mac, mac, sizeof(mac)); | 
 | 		args5.mc_px_en = strtoll(argv[4], NULL, 10); | 
 | 		args5.mc_px_qos_en = strtoll(argv[5], NULL, 10); | 
 | 		args5.mc_qos_qid = strtoll(argv[6], NULL, 10); | 
 | 		break; | 
 | 	case 'C': | 
 | 		method = HW_NAT_MCAST_DEL; | 
 | 		args5.mc_vid = strtoll(argv[2], NULL, 10); | 
 | 		str_to_mac(mac, argv[3]); | 
 | 		memcpy(args5.dst_mac, mac, sizeof(mac)); | 
 | 		memcpy(args5.dst_mac, mac, sizeof(mac)); | 
 | 		args5.mc_px_en = strtoll(argv[4], NULL, 10); | 
 | 		args5.mc_px_qos_en = strtoll(argv[5], NULL, 10); | 
 | 		args5.mc_qos_qid = strtoll(argv[6], NULL, 10); | 
 | 		break; | 
 | 	case 'D': | 
 | 		method = HW_NAT_MCAST_DUMP; | 
 | 		break; | 
 | #endif | 
 | #if defined (CONFIG_PPE_MIB) | 
 | 	case 'm': | 
 | 		method = HW_NAT_MIB_DUMP; | 
 | 		entry_num = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | 	case 'r': | 
 | 		method = HW_NAT_MIB_DRAM_DUMP; | 
 | 		entry_num = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | 	case 'M': | 
 | 		method = HW_NAT_MIB_GET; | 
 | 		break; | 
 | #if defined CONFIG_COLGIN_SUPPORT | 
 | 	case 'X': | 
 | 		method = HW_NAT_MIB_GET_ALL_IP; | 
 | 		break; | 
 | #endif | 
 | #endif | 
 | 	case 'N': | 
 | 		method = HW_NAT_BIND_THRESHOLD; | 
 | 		args4.bind_threshold = strtoll(argv[2], NULL, 10); | 
 | 		break; | 
 | 	case 'Q': | 
 | 		method = HW_NAT_KA_INTERVAL; | 
 | 		args4.foe_tcp_ka = strtoll(argv[2], NULL, 10); | 
 | 		args4.foe_udp_ka = strtoll(argv[3], NULL, 10); | 
 | 		break; | 
 | 	case 'U': | 
 | 		method = HW_NAT_BIND_LIFETIME; | 
 | 		args4.foe_tcp_dlta = strtoll(argv[2], NULL, 10); | 
 | 		args4.foe_udp_dlta = strtoll(argv[3], NULL, 10); | 
 | 		args4.foe_fin_dlta = strtoll(argv[4], NULL, 10); | 
 | 		break; | 
 | 	case 'V': | 
 | 		method = HW_NAT_VLAN_ID; | 
 | 		args4.lan_vid = strtoll(argv[2], NULL, 10); | 
 | 		args4.wan_vid = strtoll(argv[3], NULL, 10); | 
 | 		break; | 
 | 	case 'Z': | 
 | 		method = HW_NAT_BIND_DIRECTION; | 
 | 		args4.bind_dir = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | #if defined (CONFIG_HW_NAT_IPI) | 
 | 	case 'G': /*FIXME..........................*/ | 
 | 		method = HW_NAT_IPI_CTRL_FROM_EXTIF; | 
 | 		args6.hnat_ipi_enable = strtoll(argv[2], NULL, 10); | 
 | 		args6.queue_thresh = strtoll(argv[3], NULL, 10); | 
 | 		args6.drop_pkt = strtoll(argv[4], NULL, 10); | 
 | 		args6.ipi_cnt_mod = strtoll(argv[5], NULL, 10); | 
 | 		//printf("##### hnat_ipi_enable=%d, queue_thresh=%d, drop_pkt=%d #####\n", | 
 | 		//		args6.hnat_ipi_enable, args6.queue_thresh, args6.drop_pkt); | 
 | 		break; | 
 | 	case 'L': /*FIXME..........................*/ | 
 | 		method = HW_NAT_IPI_CTRL_FROM_PPEHIT; | 
 | 		args7.hnat_ipi_enable = strtoll(argv[2], NULL, 10); | 
 | 		args7.queue_thresh = strtoll(argv[3], NULL, 10); | 
 | 		args7.drop_pkt = strtoll(argv[4], NULL, 10); | 
 | 		args7.ipi_cnt_mod = strtoll(argv[5], NULL, 10); | 
 | 		//printf("##### hnat_ipi_enable2=%d, queue_thresh2=%d, drop_pkt2=%d #####\n", | 
 | 		//		args7.hnat_ipi_enable2, args7.queue_thresh2, args7.drop_pkt); | 
 | 		break; | 
 | #endif | 
 | 	case '6': | 
 | 		method = HW_NAT_DPORT; | 
 | 		break; | 
 | 	case 'O': | 
 | 		method = HW_NAT_CLEAR_HOOK; | 
 | 		args2.dst_port = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | 	case 'T': | 
 | 		method = HW_NAT_RESTORE_HOOK; | 
 | 		args2.dst_port = strtoll(optarg, NULL, 10); | 
 | 		break; | 
 | 	case '?': | 
 | 		show_usage(); | 
 |  | 
 | 	} | 
 |     } | 
 |  | 
 |     switch(method){ | 
 | //#if defined (CONFIG_HW_NAT_MANUAL_MODE) || defined (CONFIG_HW_NAT_SEMI_AUTO_MODE) | 
 |     case HW_NAT_ADD_ENTRY: | 
 | 	    result = HwNatAddEntry(&args2); | 
 | 	    break; | 
 |     case HW_NAT_DEL_ENTRY: | 
 | 	    result = HwNatDelEntry(&args2); | 
 | 	    break; | 
 | //#endif | 
 |     case HW_NAT_GET_ALL_ENTRIES: | 
 | 	    HwNatGetAllEntries(args); | 
 |  | 
 | 	    printf("Total Entry Count = %d\n",args->num_of_entries); | 
 | 	    for(i=0;i<args->num_of_entries;i++){ | 
 | 		if(args->entries[i].pkt_type==0) { //IPV4_NAPT | 
 | 		    	printf("IPv4_NAPT=%d : %u.%u.%u.%u:%d->%u.%u.%u.%u:%d => %u.%u.%u.%u:%d->%u.%u.%u.%u:%d (RX=%d FP=%d FQOS=%d QID=%d)\n", | 
 | 				args->entries[i].hash_index, | 
 | 				NIPQUAD(args->entries[i].ing_sipv4), | 
 | 				args->entries[i].ing_sp, | 
 | 				NIPQUAD(args->entries[i].ing_dipv4), | 
 | 				args->entries[i].ing_dp, | 
 | 				NIPQUAD(args->entries[i].eg_sipv4), | 
 | 				args->entries[i].eg_sp, | 
 | 				NIPQUAD(args->entries[i].eg_dipv4), | 
 | 				args->entries[i].eg_dp, | 
 | 				args->entries[i].rxif_idx, | 
 | 				args->entries[i].fport, | 
 | 				args->entries[i].fqos, | 
 | 				args->entries[i].qid); | 
 |  | 
 | 		} else if(args->entries[i].pkt_type==1) { //IPV4_NAT | 
 | 			printf("IPv4_NAT=%d : %u.%u.%u.%u->%u.%u.%u.%u => %u.%u.%u.%u->%u.%u.%u.%u (RX=%d FP=%d FQOS=%d QID=%d)\n", | 
 | 				args->entries[i].hash_index, | 
 | 				NIPQUAD(args->entries[i].ing_sipv4), | 
 | 				NIPQUAD(args->entries[i].ing_dipv4), | 
 | 				NIPQUAD(args->entries[i].eg_sipv4), | 
 | 				NIPQUAD(args->entries[i].eg_dipv4), | 
 | 				args->entries[i].rxif_idx, | 
 | 				args->entries[i].fport, | 
 | 				args->entries[i].fqos, | 
 | 				args->entries[i].qid); | 
 |  | 
 | 		} else if(args->entries[i].pkt_type==2) { //IPV6_ROUTING | 
 | 			printf("IPv6_1T= %d /DIP: %x:%x:%x:%x:%x:%x:%x:%x (RX=%d FP=%d FQOS=%d QID=%d)\n", | 
 | 				args->entries[i].hash_index, | 
 | 				NIPHALF(args->entries[i].ing_dipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_3), | 
 | 				args->entries[i].rxif_idx, | 
 | 				args->entries[i].fport, | 
 | 				args->entries[i].fqos, | 
 | 				args->entries[i].qid); | 
 |  | 
 | 		} else if(args->entries[i].pkt_type==3) { //IPV4_DSLITE | 
 | 		    	printf("DS-Lite= %d : %u.%u.%u.%u:%d->%u.%u.%u.%u:%d (%x:%x:%x:%x:%x:%x:%x:%x -> %x:%x:%x:%x:%x:%x:%x:%x)(RX=%d FP=%d FQOS=%d QID=%d)\n", \ | 
 | 				args->entries[i].hash_index, | 
 | 				NIPQUAD(args->entries[i].ing_sipv4), | 
 | 				args->entries[i].ing_sp, | 
 | 				NIPQUAD(args->entries[i].ing_dipv4), | 
 | 				args->entries[i].ing_dp, | 
 | 				NIPHALF(args->entries[i].eg_sipv6_0), | 
 | 				NIPHALF(args->entries[i].eg_sipv6_1), | 
 | 				NIPHALF(args->entries[i].eg_sipv6_2), | 
 | 				NIPHALF(args->entries[i].eg_sipv6_3), | 
 | 				NIPHALF(args->entries[i].eg_dipv6_0), | 
 | 				NIPHALF(args->entries[i].eg_dipv6_1), | 
 | 				NIPHALF(args->entries[i].eg_dipv6_2), | 
 | 				NIPHALF(args->entries[i].eg_dipv6_3), | 
 | 				args->entries[i].rxif_idx, | 
 | 				args->entries[i].fport, | 
 | 				args->entries[i].fqos, | 
 | 				args->entries[i].qid); | 
 |  | 
 | 		} else if(args->entries[i].pkt_type==4) { //IPV6_3T_ROUTE | 
 | 			printf("IPv6_3T= %d SIP: %x:%x:%x:%x:%x:%x:%x:%x DIP: %x:%x:%x:%x:%x:%x:%x:%x (RX=%d FP=%d FQOS=%d QID=%d)\n", | 
 | 				args->entries[i].hash_index, | 
 | 				NIPHALF(args->entries[i].ing_sipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_3), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_3), | 
 | 				args->entries[i].rxif_idx, | 
 | 				args->entries[i].fport, | 
 | 				args->entries[i].fqos, | 
 | 				args->entries[i].qid); | 
 |  | 
 | 		} else if(args->entries[i].pkt_type==5) { //IPV6_5T_ROUTE | 
 | 		    if(args->entries[i].ipv6_flowlabel==1) { | 
 | 			printf("IPv6_5T= %d SIP: %x:%x:%x:%x:%x:%x:%x:%x DIP: %x:%x:%x:%x:%x:%x:%x:%x (Flow Label=%x) (RX=%d FP=%d FQOS=%d QID=%d)\n", | 
 | 				args->entries[i].hash_index, | 
 | 				NIPHALF(args->entries[i].ing_sipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_3), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_3), | 
 | 				((args->entries[i].ing_sp << 16) | (args->entries[i].ing_dp))&0xFFFFF, | 
 | 				args->entries[i].rxif_idx, | 
 | 				args->entries[i].fport, | 
 | 				args->entries[i].fqos, | 
 | 				args->entries[i].qid); | 
 |  | 
 | 		    }else { | 
 | 			printf("IPv6_5T= %d SIP: %x:%x:%x:%x:%x:%x:%x:%x %d DIP: %x:%x:%x:%x:%x:%x:%x:%x %d (RX=%d FP=%d FQOS=%d QID=%d)\n", | 
 | 				args->entries[i].hash_index, | 
 | 				NIPHALF(args->entries[i].ing_sipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_3), | 
 | 				args->entries[i].ing_sp, | 
 | 				NIPHALF(args->entries[i].ing_dipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_3), | 
 | 				args->entries[i].ing_dp, | 
 | 				args->entries[i].rxif_idx, | 
 | 				args->entries[i].fport, | 
 | 				args->entries[i].fqos, | 
 | 				args->entries[i].qid); | 
 | 		    } | 
 |  | 
 | 		} else if(args->entries[i].pkt_type==7) { //IPV6_6RD | 
 | 		    if(args->entries[i].ipv6_flowlabel==1) { | 
 | 			printf("6RD= %d %x:%x:%x:%x:%x:%x:%x:%x->%x:%x:%x:%x:%x:%x:%x:%x [Flow Label=%x]\n", | 
 | 				args->entries[i].hash_index, \ | 
 | 				NIPHALF(args->entries[i].ing_sipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_3), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_3), | 
 | 				((args->entries[i].ing_sp << 16) | (args->entries[i].ing_dp))&0xFFFFF); | 
 | 				printf("(%u.%u.%u.%u->%u.%u.%u.%u)(RX=%d FP=%d FQOS=%d QID=%d)\n", | 
 | 					NIPQUAD(args->entries[i].eg_sipv4), | 
 | 					NIPQUAD(args->entries[i].eg_dipv4), | 
 | 					args->entries[i].rxif_idx, | 
 | 					args->entries[i].fport, | 
 | 					args->entries[i].fqos, | 
 | 					args->entries[i].qid); | 
 | 		    }else { | 
 | 			printf("6RD= %d /SIP: %x:%x:%x:%x:%x:%x:%x:%x [SP:%d] /DIP: %x:%x:%x:%x:%x:%x:%x:%x [DP=%d]", | 
 | 				args->entries[i].hash_index, | 
 | 				NIPHALF(args->entries[i].ing_sipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_sipv6_3), | 
 | 				args->entries[i].ing_sp, | 
 | 				NIPHALF(args->entries[i].ing_dipv6_0), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_1), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_2), | 
 | 				NIPHALF(args->entries[i].ing_dipv6_3), | 
 | 				args->entries[i].ing_dp); | 
 | 			printf("(%u.%u.%u.%u->%u.%u.%u.%u)(RX=%d FP=%d FQOS=%d QID=%d)\n", | 
 | 				NIPQUAD(args->entries[i].eg_sipv4), | 
 | 				NIPQUAD(args->entries[i].eg_dipv4), | 
 | 				args->entries[i].rxif_idx, | 
 | 				args->entries[i].fport, | 
 | 				args->entries[i].fqos, | 
 | 				args->entries[i].qid); | 
 | 		    } | 
 | 		} else{ | 
 | 		    printf("unknown packet type! (pkt_type=%d) \n", args->entries[i].pkt_type); | 
 | 		} | 
 | 	    } | 
 | 	    result = args->result; | 
 | 	    break; | 
 |     case HW_NAT_DUMP_CACHE_ENTRY: | 
 | 	    result = HwNatCacheDumpEntry(); | 
 | 	    break; | 
 |     case HW_NAT_DUMP_ENTRY: | 
 | 	    result = HwNatDumpEntry(entry_num, args2.set_idx); | 
 | 	    break; | 
 |     case HW_NAT_UNBIND_ENTRY: | 
 | 	    result = HwNatUnBindEntry(entry_num, args2.set_idx); | 
 | 	    break; | 
 |     case HW_NAT_DROP_ENTRY: | 
 | 	    result = HwNatDropEntry(entry_num, args2.set_idx); | 
 | 	    break; | 
 |     case HW_NAT_DEBUG: | 
 | 	    result = HwNatDebug(debug); | 
 | 	    break; | 
 | #if defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) | 
 | 	case HW_NAT_SWITCH_DSL_MAPE: | 
 | 	    result = HwNatSwitchDsliteMape(swit); | 
 | 	    break; | 
 | #endif | 
 |     case HW_NAT_GET_AC_CNT: | 
 | 	    HwNatGetAGCnt(&args3); | 
 | 	    printf("Byte cnt=%llu\n", args3.ag_byte_cnt); | 
 | 	    printf("Pkt cnt=%llu\n", args3.ag_pkt_cnt); | 
 | 	    result = args3.result; | 
 | 	    break; | 
 |  | 
 |     case HW_NAT_BIND_THRESHOLD: | 
 | 	    result = HwNatSetBindThreshold(&args4); | 
 | 	    break; | 
 |     case HW_NAT_MAX_ENTRY_LMT: | 
 | 	    HwNatSetMaxEntryRateLimit(&args4); | 
 | 	    result = args4.result; | 
 | 	    break; | 
 |     case HW_NAT_RULE_SIZE: | 
 | 	    HwNatSetRuleSize(&args4); | 
 | 	    result = args4.result; | 
 | 	    break; | 
 |     case HW_NAT_KA_INTERVAL: | 
 | 	    HwNatSetKaInterval(&args4); | 
 | 	    result = args4.result; | 
 | 	    break; | 
 |     case HW_NAT_UB_LIFETIME: | 
 | 	    HwNatSetUnbindLifeTime(&args4); | 
 | 	    result = args4.result; | 
 | 	    break; | 
 |     case HW_NAT_BIND_LIFETIME: | 
 | 	    result = HwNatSetBindLifeTime(&args4); | 
 | 	    break; | 
 |     case HW_NAT_VLAN_ID: | 
 | 	    result = HwNatSetVID(&args4); | 
 | 	    break; | 
 |     case HW_NAT_BIND_DIRECTION: | 
 | 	    result = HwNatSetBindDir(&args4); | 
 | 	    break; | 
 | #if defined (CONFIG_PPE_MCAST) | 
 |     case HW_NAT_MCAST_INS: | 
 | 	    result = HwNatMcastIns(&args5); | 
 | 	    break; | 
 |     case HW_NAT_MCAST_DEL: | 
 | 	    result = HwNatMcastDel(&args5); | 
 | 	    break; | 
 |     case HW_NAT_MCAST_DUMP: | 
 | 	    result = HwNatMcastDump(); | 
 | 	    break; | 
 | #endif | 
 | #if defined (CONFIG_PPE_MIB) | 
 |     case HW_NAT_MIB_DUMP: | 
 | 	    result = HwNatMibDumpEntry(entry_num); | 
 | 	    break; | 
 |     case HW_NAT_MIB_DRAM_DUMP: | 
 | 	    result = HwNatMibDramDumpEntry(entry_num); | 
 | 	    break; | 
 |     case HW_NAT_MIB_GET: | 
 | 	    result = HwNatMibGet(&args2); | 
 | 	    break; | 
 | #if defined CONFIG_COLGIN_SUPPORT | 
 | 	case HW_NAT_MIB_GET_ALL_IP: | 
 | 		args8=malloc(sizeof(struct hwnat_mib_all_ip_args)); | 
 | 		if (NULL == args8) | 
 | 		{ | 
 | 			printf(" Allocate memory for hwnat_mib_all_ip_args failed.\n"); | 
 | 			close(fd); | 
 | 			return 0; | 
 | 		} | 
 | 		memset(args8, 0, sizeof(struct hwnat_mib_all_ip_args)); | 
 | 		result = HwNatMibGetAllIP(args8); | 
 |         dump_all_ip_cnt(args8); | 
 |         free(args8); | 
 | 	    break; | 
 | #endif | 
 | #endif | 
 |     case HW_NAT_TBL_CLEAR: | 
 |             result = HwNatTblClear(); | 
 |             break; | 
 | #if defined (CONFIG_HW_NAT_IPI) | 
 |     case HW_NAT_IPI_CTRL_FROM_EXTIF: | 
 | 	    result = HwNatIPICtrlFromExtIf(&args6); | 
 | 	    break; | 
 |     case HW_NAT_IPI_CTRL_FROM_PPEHIT: | 
 | 	    result = HwNatIPICtrlFromPPEHit(&args7); | 
 | 	    break; | 
 | #endif | 
 |     case HW_NAT_DPORT: | 
 |     	    result = HwNatDumpDport(); | 
 |     	    break; | 
 |     case HW_NAT_INVALID_ENTRY: | 
 | 	    result = HwNatInvalEntry(entry_num, args2.set_idx); | 
 | 	    break; | 
 |     case HW_NAT_CLEAR_HOOK: | 
 |     	    result = HwNatHookModify(&args2, 1); | 
 |     	    break; | 
 |     case HW_NAT_RESTORE_HOOK: | 
 |     	    result = HwNatHookModify(&args2, 0); | 
 |     	    break; | 
 |     default: | 
 | 	    result = HWNAT_FAIL; | 
 |  | 
 |     } | 
 |  | 
 |     if(result==HWNAT_SUCCESS){ | 
 | 	printf("done\n"); | 
 |     }else if(result==HWNAT_ENTRY_NOT_FOUND) { | 
 | 	printf("entry not found\n"); | 
 |     }else { | 
 | 	printf("fail\n"); | 
 |     } | 
 |  | 
 |     free(args); | 
 |     close(fd); | 
 |     return 0; | 
 | } |