Index: /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_defs.h
===================================================================
--- /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_defs.h	(revision 20344)
+++ /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_defs.h	(working copy)
@@ -262,7 +262,6 @@
 	uint16_t ports[RES_PORTS_MAX_NUM];
 	uint8_t res_type;
 
-	uint8_t is_hostname;
 	char hostname[128];
 } resource_t;
 
Index: /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_ui.c
===================================================================
--- /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_ui.c	(revision 20344)
+++ /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_ui.c	(working copy)
@@ -9,6 +9,8 @@
 #include <net/if.h>
 #include <net/if_types.h>
 #include <netinet/in_var.h>
+#include <stdint.h>
+#include <netinet/in.h>
 
 #include <click/sys/clickarray.h>
 #include <click/sys/clickaddr.h>
@@ -368,18 +370,19 @@
 	/* search the resource host whether has existed */
 	res_network_queue_p = &(rqt->network_queue);
 	TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
-		if (res->is_hostname == 1 && (res_network_p->hostname != NULL && res->hostname != NULL))
+		if (res_network_p->hostname[0] != '\0' && res->hostname[0] != '\0')
 		{
 			if (strcmp(res_network_p->hostname, res->hostname) == 0)
 			{
-				res_network_p->is_hostname = res->is_hostname;
 				break;
 			}
 		}
-		else if ((res_network_p->ip_addr.ip4.sin_addr.s_addr & res_network_p->netmask.ip4.sin_addr.s_addr) == (res->ip.ip4 & res->mask.ip4))
+		else if (res_network_p->hostname[0] == '\0' && res->hostname[0] == '\0')
 		{
-			res_network_p->is_hostname = 0;
-			break;
+			if ((res_network_p->ip_addr.ip4.sin_addr.s_addr & res_network_p->netmask.ip4.sin_addr.s_addr) == (res->ip.ip4 & res->mask.ip4))
+			{
+				break;
+			}
 		}
 	}
 
@@ -395,28 +398,25 @@
 		}
 		
 		TAILQ_INIT(&new_res_network_p->info_queue);
-		/* initialize ip of resource with hostname as 0 */
-		if (res->is_hostname == 1 && res->hostname != NULL) {
+		if (res->hostname[0] != '\0')
+		{
 			strncpy(new_res_network_p->hostname, res->hostname, 127);
     			new_res_network_p->hostname[127] = '\0';
 			new_res_network_p->ip_addr.ip4.sin_len = sizeof(struct sockaddr_in);
-			new_res_network_p->ip_addr.ip4.sin_addr.s_addr = 0;
 			new_res_network_p->netmask.ip4.sin_len = sizeof(struct sockaddr_in);
 			new_res_network_p->netmask.ip4.sin_addr.s_addr = res->mask.ip4;
-			new_res_network_p->is_hostname = res->is_hostname;
 		}
 		else {
 			new_res_network_p->ip_addr.ip4.sin_len = sizeof(struct sockaddr_in);
 			new_res_network_p->ip_addr.ip4.sin_addr.s_addr = res->ip.ip4;
 			new_res_network_p->netmask.ip4.sin_len = sizeof(struct sockaddr_in);
 			new_res_network_p->netmask.ip4.sin_addr.s_addr = res->mask.ip4;
-			new_res_network_p->is_hostname = res->is_hostname;
 		}
 		
 		/* insert new resource host into the resource queue tree */
 		node = rqt->tree->rnh_addaddr((caddr_t)&new_res_network_p->ip_addr,
 						(caddr_t)&new_res_network_p->netmask, rqt->tree, new_res_network_p->nodes);
-		if (node != NULL || new_res_network_p->is_hostname == 1) {
+		if (node != NULL || new_res_network_p->hostname[0] != '\0') {
 			TAILQ_INSERT_TAIL(res_network_queue_p, new_res_network_p, next_network);
 		} else {
 			free(new_res_network_p, M_VPN_NETWORK);
@@ -634,17 +634,19 @@
 	/* search the matched resource host */
 	res_network_queue_p = &rqt->network_queue;	
 	TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
-		if (res->is_hostname == 1 && (res_network_p->hostname != NULL && res->hostname != NULL))
+		if (res_network_p->hostname[0] != '\0' && res->hostname[0] != '\0')
 		{
 			if (strcmp(res_network_p->hostname, res->hostname) == 0)
 			{
 				break;
 			}
 		}
-		else if (res_network_p->ip_addr.ip4.sin_addr.s_addr == res->ip.ip4 &&
-			res_network_p->netmask.ip4.sin_addr.s_addr == res->mask.ip4)
+		else if (res_network_p->hostname[0] == '\0' && res->hostname[0] == '\0')
 		{
-			break;
+			if ((res_network_p->ip_addr.ip4.sin_addr.s_addr & res_network_p->netmask.ip4.sin_addr.s_addr) == (res->ip.ip4 & res->mask.ip4))
+			{
+				break;
+			}
 		}
 	}
 
@@ -2266,7 +2268,7 @@
 
 	bzero(res, sizeof(*res));
 	res->protocol = RESOURCE_PROT_ALL;
-	res->is_hostname = 0;
+	res->hostname[0] = '\0';
 
 	if (!isdigit(*start)) {
 		if (strncasecmp(start, "udp://", sizeof("udp://") - 1) == 0) {
@@ -2286,7 +2288,6 @@
             		res->port_type = RESOURCE_PORTS_RANGE;
             		res->ports[0] = 0;
             		res->ports[1] = 65535;
-            		res->is_hostname = 1;
 
             		return 0;
 			// vpn_debug("resource %s have invalid resource type", start);
@@ -2488,7 +2489,6 @@
 
 	bzero(res, sizeof(*res));
 	res->protocol = RESOURCE_PROT_ALL;
-	res->is_hostname = 0;
 
 	/* parse protocol */
 	if (*start != '[') {
@@ -3433,9 +3433,10 @@
 
 	res_network_queue_p = &(vrg->network_list.network_queue);
 	TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
+
 		res_info_queue_p = &res_network_p->info_queue;
 		TAILQ_FOREACH(res_info_p, res_info_queue_p, next_info) {
-            		if (res_network_p->is_hostname == 1 && res_network_p->hostname != NULL)
+			if (res_network_p->hostname[0] != '\0')
 			{
                 		strncpy(buffer, res_network_p->hostname, SEC_RESOURCE_LEN + 1);
             		}
@@ -3469,7 +3470,7 @@
 	TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
 		res_info_queue_p = &res_network_p->info_queue;
 		TAILQ_FOREACH(res_info_p, res_info_queue_p, next_info) {
-			if (res_network_p->is_hostname == 1 && res_network_p->hostname != NULL)
+			if (res_network_p->hostname[0] != '\0')
 			{
                 		strncpy(buffer, res_network_p->hostname, SEC_RESOURCE_LEN + 1);
             		}
@@ -4019,9 +4020,10 @@
 
 		res_network_queue_p = &(vrg->network_list.network_queue);
 		TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
+
 			res_info_queue_p = &res_network_p->info_queue;
 			TAILQ_FOREACH(res_info_p, res_info_queue_p, next_info) {
-				if (res_network_p->is_hostname == 1 && res_network_p->hostname != NULL)
+				if (res_network_p->hostname[0] != '\0')
 				{
 					strncpy(buffer, res_network_p->hostname, SEC_RESOURCE_LEN + 1);
 				}
@@ -4382,7 +4384,7 @@
 		TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
 			res_info_queue_p = &res_network_p->info_queue;
 			TAILQ_FOREACH(res_info_p, res_info_queue_p, next_info) {
-				if (res_network_p->is_hostname == 1 && res_network_p->hostname != NULL)
+				if (res_network_p->hostname[0] != '\0')
 				{
 					strncpy(buffer, res_network_p->hostname, SEC_RESOURCE_LEN + 1);
 				}
Index: /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_var.h
===================================================================
--- /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_var.h	(revision 20344)
+++ /branches/rel_ag_9_4_5/FreeBSD/src/sys/click/app/vpn/vpn_var.h	(working copy)
@@ -126,7 +126,6 @@
 		struct sockaddr_in6 ip6;
 	} netmask;
 
-	uint8_t is_hostname;
 	char hostname[128];
 
 	TAILQ_HEAD(resource_info_head, resource_info) info_queue;
Index: /branches/rel_ag_9_4_5/aaa/aaa_localdb.c
===================================================================
--- /branches/rel_ag_9_4_5/aaa/aaa_localdb.c	(revision 20344)
+++ /branches/rel_ag_9_4_5/aaa/aaa_localdb.c	(working copy)
@@ -5,6 +5,49 @@
 #include <regex.h>
 #include <click/app/proxy/proxy_shm.h>
 #include <sys_mail.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#define MAX_IPS 10
+#define MAX_BUFFER_SIZE 8192
+
+typedef struct {
+    uint32_t ip_addresses[MAX_IPS];
+    int count;
+} ip_list_t;
+
+/* resolve domain name to ip address */
+static ip_list_t 
+*resolve_domain_to_ipv4(char domain[128]) 
+{
+	struct addrinfo hints, *res;
+	struct addrinfo *p;
+	int status;
+	ip_list_t *ip_list = malloc(sizeof(ip_list_t));
+	ip_list->count = 0;
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = AF_INET;
+	hints.ai_socktype = SOCK_STREAM;
+
+	status = getaddrinfo(domain, NULL, &hints, &res);
+
+	if (status != 0) 
+	{
+		aaa_error_log("(%s):resource resolve failed, %s", __FUNCTION__, domain);
+		return NULL;
+	}
+	for (p = res; p != NULL && ip_list->count < MAX_IPS; p = p->ai_next) {
+        	struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
+        	ip_list->ip_addresses[ip_list->count] = ipv4->sin_addr.s_addr;
+        	ip_list->count++;
+    	}
+
+	freeaddrinfo(res);
+	return ip_list;
+}
 
 int cli_sync(char* cli, char *vsite);
 
@@ -784,7 +827,6 @@
 void
 hardwareid_sendmail(char *address, char *subject, char *content)
 {
-
 	/*help variables*/
 	char str[MAX_LINE_SIZE+ 1] = "";
 	char hostname[MAX_LINE_SIZE + 1] = "";
@@ -819,6 +861,116 @@
 	return;
 }
 
+void 
+run_add_vpnres(char *show_resource, char *vsite, int is_exclude)
+{
+	/* split the output to get vpn group name and resource */
+	char *content_start = strstr(show_resource, "\"content\":");
+    	if (!content_start) {
+		aaa_error_log("(%s): Error: 'content' not found", __FUNCTION__);
+		return;
+    	}
+
+	content_start = strchr(content_start, '[');
+    	if (!content_start) {
+		aaa_error_log("(%s): Error: '[' not found", __FUNCTION__);
+		return;
+    	}
+
+    	char *current = content_start + 1;
+	/* get resourcegroup */
+    	while ((current = strstr(current, "\"resourcegroup\":")) != NULL) {
+        	char group_name[256] = {0};
+        	char netresource[256] = {0};
+
+        	char *group_start = strchr(current, ':');
+		if (group_start) {
+			group_start = strchr(group_start, '\"');
+			if (group_start) {
+				char *group_end = strchr(group_start + 1, '\"');
+				if (group_end) {
+					strncpy(group_name, group_start + 1, group_end - group_start - 1);
+					group_name[group_end - group_start - 1] = '\0';
+				}
+			}
+		}
+		aaa_debug_log("(%s): group_name \"%s\"", __FUNCTION__, group_name);
+
+		/* get network resource */
+        	current = strstr(current, "\"netresource\":");
+		if (!current) {
+			break;
+		}
+
+		char *net_start = strchr(current, ':');
+		char *net_end = NULL;
+		if (net_start) {
+			net_start = strchr(net_start, '\"');
+			if (net_start) {
+				net_end = strchr(net_start + 1, '\"');
+				if (net_end) {
+					strncpy(netresource, net_start + 1, net_end - net_start - 1);
+					netresource[net_end - net_start - 1] = '\0';
+				}
+			}
+		}
+		aaa_debug_log("(%s): netresource \"%s\"", __FUNCTION__, netresource);
+		/* resolve the resource and add it into vpn group */
+		char cli[MAX_LINE_SIZE + 1];
+		ip_list_t *ips;
+		struct in_addr addr;
+		int i;
+		ips = resolve_domain_to_ipv4(netresource);
+		if (ips != NULL)
+		{
+			for (i = 0; i < ips->count; i++) {
+				addr.s_addr = ips->ip_addresses[i];
+				if (!is_exclude)
+				{
+					snprintf(cli, sizeof(cli), "/ca/bin/backend -s \"%s\" -C \"vpn resource groupitem network \"%s\" %s/32\"", vsite, group_name, inet_ntoa(addr));
+					system(cli);
+					aaa_debug_log("(%s): use system command: %s", __FUNCTION__, cli);
+				}
+				else {
+					snprintf(cli, sizeof(cli), "/ca/bin/backend -s \"%s\" -C \"vpn resource groupexcludeditem network \"%s\" %s/32\"", vsite, group_name, inet_ntoa(addr));
+					system(cli);
+					aaa_debug_log("(%s): use system command: %s", __FUNCTION__, cli);
+				}
+			}
+		}
+		 current = net_end ? net_end + 1 : current + 1;
+    	}
+}
+
+void 
+run_backend_cmd(char cmd[MAX_LINE_SIZE + 1], char *vsite, int is_exclude)
+{
+	/* run backend command and get the output */
+	char show_vpnres_output[MAX_BUFFER_SIZE];
+	memset(show_vpnres_output, 0, sizeof(show_vpnres_output));
+
+	FILE *fp;
+	size_t bytes_read = 0;
+	fp = popen(cmd, "r");
+	if (fp == NULL) {
+		perror("popen failed");
+		aaa_error_log("(%s): popen failed", __FUNCTION__);
+	}
+
+	while (fgets(show_vpnres_output + bytes_read, MAX_BUFFER_SIZE - bytes_read, fp) != NULL) {
+        	bytes_read += strlen(show_vpnres_output + bytes_read);
+        	if (bytes_read >= MAX_BUFFER_SIZE - 1) {
+			break;
+		}
+    	}
+	aaa_debug_log("(%s): show vpn resource \"%s\"", __FUNCTION__, show_vpnres_output);
+
+	/* add vpn resource with the output */
+	run_add_vpnres(show_vpnres_output, vsite, is_exclude);
+
+    	pclose(fp);
+}
+
 int32_t
 ldb_authorize_hardwareid(struct request_handle *qh, char *vsite, char *username, char *groupname, 
                                   char *orig_hardwareid, hardwareid_pending_list_t *pending_list)
@@ -843,6 +995,17 @@
 	char err_str[128] = {0};
 	uint16_t userlimit = 0;
 	uint8_t email_act = 0;
+	char show_vpnres[MAX_LINE_SIZE + 1];
+	char show_excl_vpnres[MAX_LINE_SIZE + 1];
+	
+	aaa_debug_log("(%s) :site (%s) get network vpn resource item and excluded item", __FUNCTION__, vsite);
+
+	snprintf(show_vpnres, sizeof(show_vpnres), "/ca/bin/backend -s \"%s\" -C \"show vpn resource groupitem network\"", vsite);
+	snprintf(show_excl_vpnres, sizeof(show_excl_vpnres), "/ca/bin/backend -s \"%s\" -C \"show vpn resource groupexcludeditem network\"", vsite);
+	
+	/* run show resource command */
+	run_backend_cmd(show_vpnres, vsite, 0);
+	run_backend_cmd(show_excl_vpnres, vsite, 1);
 
 	aaa_info_log(ULOG_NO1164, 0, 0, 0, 0, 0, 0, 0);
 	aaa_debug_log("(%s) :site (%s) user (%s) assigned group (%s) hardwareid (%s)",
Index: /branches/rel_ag_9_4_5/uproxy/http_proxy/vpn_proxy/vpn_tunnel.c
===================================================================
--- /branches/rel_ag_9_4_5/uproxy/http_proxy/vpn_proxy/vpn_tunnel.c	(revision 20344)
+++ /branches/rel_ag_9_4_5/uproxy/http_proxy/vpn_proxy/vpn_tunnel.c	(working copy)
@@ -2643,7 +2643,7 @@
 	resource_network_t *res_network_p;
 	uint32_t getdomainip;
 	TAILQ_FOREACH(res_network_p, res_network_queue_p, next_network) {
-		if (res_network_p->is_hostname == 1 && (res_network_p->hostname != NULL))
+		if (res_network_p->hostname[0] != '\0')
 		{
 			getdomainip = resolve_domain_to_ipv4(res_network_p->hostname);
 			if (getdomainip != 0) 
@@ -2657,7 +2657,6 @@
 				res_network_p->ip_addr.ip4.sin_addr.s_addr = inet_addr("1.1.1.1");
 				vpn_log_sendid("(%s): resolve_domain_to_ipv4 failed: %s", __FUNCTION__, res_network_p->hostname);
 			}
-	
 		}
 	}
 }
