diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index c93651d..d03ef2d 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -49,6 +49,7 @@
 #include <dns/tcpmsg.h>
 #include <dns/types.h>
 
+const char *conffile = "/etc/dns_port.conf";
 typedef ISC_LIST(dns_dispentry_t)	dns_displist_t;
 
 typedef struct dispsocket		dispsocket_t;
@@ -1933,6 +1934,168 @@ open_socket(isc_socketmgr_t *mgr, isc_sockaddr_t *local,
 	return (ISC_R_SUCCESS);
 }
 
+static int convert_num(char *str)
+{
+	int negative = 0;
+	int tval;
+	int val = 0;
+	int base = 10;
+	char *ptr = str;
+	if (str == NULL)
+		return -ISC_R_FAILURE;
+
+	if (*ptr == '-') {
+		negative = 1;
+		++ptr;
+	}
+
+	do {
+		tval = *ptr++;
+		/* XXX assumes ASCII... */
+		if (tval >= '0')
+			tval -= '0';
+		else {
+			syslog (LOG_ERR, "Bogus number: %s.", str);
+			return -ISC_R_BADNUMBER;
+		}
+		if (tval >= base) {
+			syslog (LOG_ERR, "Bogus number: %s.", str);
+			return -ISC_R_BADNUMBER;
+		}
+		val = val * base + tval;
+	} while (*ptr);
+
+	if (negative)
+		val = -val;
+	return val;
+}
+
+static int str_token(char *str, int *digit, unsigned int len, const char *semi)
+{
+	int num = 0;
+	char *p;
+	p = strtok(str, semi);
+	while (p !=NULL) {
+		if (num >= len-1) {
+			digit[num] = '\0';
+			break;
+		}
+		/* convert string to integer */
+		digit[num] = convert_num(p);
+		if (digit[num] < 0)
+			return -ISC_R_BADNUMBER;
+
+		p = strtok(NULL, semi);
+		num++;
+	}
+
+	return num;
+}
+
+static int parse_port_config(const char *buffer, const char *sub_buf, int *ports, unsigned int len, const char *semi)
+{
+	char *str;
+	char string[256] = {0};
+	int start, end;
+	int ret = -ISC_R_DISABLED;
+
+	if (str = strstr(buffer, sub_buf)) {
+		start = strlen(sub_buf);
+		end = strlen(str);
+		strncpy(string, str + start, end - start -1);
+		/* string segmentation with semi character */
+		ret = str_token(string, ports, len, semi);
+		if (ret < 0)
+			return -ISC_R_BADNUMBER;
+	}
+
+	return ret;
+}
+
+static isc_result_t
+parse_config(const char *file, in_port_t *port_lo, in_port_t *port_hi, in_port_t *no_use_ports)
+{
+	FILE *fp;
+	char *str = NULL;
+	char buffer[256] = {0};
+	int ports[8] = {0};
+	int unports[17] = {0};
+	int i = 0;
+	int ret;
+
+	fp = fopen(file, "r");
+	if (fp) {
+		while (fgets(buffer, 256, fp)) {
+                       const char *buffer_s = buffer;
+			str = buffer;
+			/* skip the comment line */
+			while (isspace(*str))
+				str++;
+			if (strncmp(str, "#", 1) == 0)
+				continue;
+			/* get default set of dispatch ports */
+			ret = parse_port_config(buffer_s, "dns-range-port", ports, 8, " ");
+			if (ret == 2) {
+				*port_lo = (in_port_t)ports[0];
+				*port_hi = (in_port_t)ports[1];
+				if (*port_lo < 1024 || *port_hi > 65535 || *port_lo > *port_hi) {
+					syslog(LOG_ERR,
+						"Unexpected ports contents in %s file.", file);
+					fclose(fp);
+					fp = NULL;
+					return ISC_R_INVALIDFILE;
+				}
+			} else if (ret != -ISC_R_DISABLED){
+				syslog(LOG_ERR,
+					"Unexpected ports contents in %s file.", file);
+				fclose(fp);
+				fp = NULL;
+				return ISC_R_INVALIDFILE;
+			}
+			/* get excluded ports */
+			ret = parse_port_config(buffer_s, "dns-excluded-ports", unports, 17, " ");
+			if (ret > 0) {
+				while (unports[i] != '\0') {
+					no_use_ports[i] = (in_port_t)unports[i];
+					i++;
+				}
+			} else if (ret != -ISC_R_DISABLED) {
+				syslog(LOG_ERR,
+					"Unexpected ports contents in %s file.", file);
+				fclose(fp);
+				fp = NULL;
+				return ISC_R_INVALIDFILE;
+			}
+		}
+
+		fclose(fp);
+		fp = NULL;
+		return ISC_R_SUCCESS;
+	}
+
+	syslog(LOG_ERR,
+		"Open %s fail, return.\n", file);
+	return ISC_R_FILENOTFOUND;
+}
+
+/*%
+ * Create a temporary port list to set the initial default set of dispatch
+ * ports and excluded ports.  This is almost meaningless as the application will
+ * normally set the ports explicitly, but is provided to fill some minor corner
+ * cases.
+ */
+static isc_result_t
+create_portset_by_range(isc_mem_t *mctx, isc_portset_t **portsetp, in_port_t port_lo, in_port_t port_hi, in_port_t *no_use_ports) {
+	isc_result_t result;
+
+	result = isc_portset_create(mctx, portsetp);
+	if (result != ISC_R_SUCCESS)
+		return (result);
+	isc_portset_addrange_by_range(*portsetp, port_lo, port_hi, no_use_ports);
+
+	return (ISC_R_SUCCESS);
+}
+
 /*%
  * Create a temporary port list to set the initial default set of dispatch
  * ports: [1024, 65535].  This is almost meaningless as the application will
@@ -1963,6 +2125,9 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
 	isc_result_t result;
 	isc_portset_t *v4portset = NULL;
 	isc_portset_t *v6portset = NULL;
+	in_port_t port_lo = 1024;
+	in_port_t port_hi = 65535;
+	in_port_t no_use_ports[17] = {0};
 
 	REQUIRE(mctx != NULL);
 	REQUIRE(mgrp != NULL && *mgrp == NULL);
@@ -2063,14 +2228,23 @@ dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
 	mgr->nv6ports = 0;
 	mgr->magic = DNS_DISPATCHMGR_MAGIC;
 
-	result = create_default_portset(mctx, &v4portset);
+	/* parse port list file, get default set of dispatch ports and excluded ports */
+	result = parse_config(conffile, &port_lo, &port_hi, no_use_ports);
 	if (result == ISC_R_SUCCESS) {
-		result = create_default_portset(mctx, &v6portset);
-		if (result == ISC_R_SUCCESS) {
-			result = dns_dispatchmgr_setavailports(mgr,
-							       v4portset,
-							       v6portset);
-		}
+		create_portset_by_range(mctx, &v4portset, port_lo, port_hi, no_use_ports);
+		if (result == ISC_R_SUCCESS)
+			result = create_portset_by_range(mctx, &v6portset, port_lo, port_hi, no_use_ports);
+	}
+	else {
+		result = create_default_portset(mctx, &v4portset);
+		if (result == ISC_R_SUCCESS)
+			result = create_default_portset(mctx, &v6portset);
+	}
+
+	if (result == ISC_R_SUCCESS) {
+		result = dns_dispatchmgr_setavailports(mgr,
+							   v4portset,
+							   v6portset);
 	}
 	if (v4portset != NULL)
 		isc_portset_destroy(mctx, &v4portset);
diff --git a/lib/isc/include/isc/portset.h b/lib/isc/include/isc/portset.h
index 774d6bb..cfd0bcb 100644
--- a/lib/isc/include/isc/portset.h
+++ b/lib/isc/include/isc/portset.h
@@ -125,6 +125,19 @@ isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo,
  */
 
 void
+isc_portset_addrange_by_range(isc_portset_t *portset, in_port_t port_lo,
+		     in_port_t port_hi, in_port_t *no_use_ports);
+/*%<
+ * Add a subset of [port_lo, port_hi] (inclusive) and no_use_ports(exclusive) to the portset.  Ports in the
+ * subset may or may not be stored in portset.
+ *
+ * Requires:
+ *\li	'portlist' to be valid.
+ *\li	port_lo <= port_hi
+ *\li   no_use_ports > 0
+ */
+
+void
 isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo,
 			in_port_t port_hi);
 /*%<
diff --git a/lib/isc/portset.c b/lib/isc/portset.c
index 471ca8e..0ebd79f 100644
--- a/lib/isc/portset.c
+++ b/lib/isc/portset.c
@@ -128,6 +128,31 @@ isc_portset_addrange(isc_portset_t *portset, in_port_t port_lo,
 }
 
 void
+isc_portset_addrange_by_range(isc_portset_t *portset, in_port_t port_lo,
+		     in_port_t port_hi, in_port_t *no_use_ports)
+{
+	in_port_t p;
+	int i, flag;
+	REQUIRE(portset != NULL);
+	REQUIRE(port_lo <= port_hi);
+
+	p = port_lo;
+	do {
+		i = 0;
+		flag = 0;
+		while (no_use_ports[i] != '\0') {
+			if (no_use_ports[i] == p) {
+				flag = 1;
+				break;
+			}
+			i++;
+		}
+		if (flag == 0)
+			portset_add(portset, p);
+	} while (p++ < port_hi);
+}
+
+void
 isc_portset_removerange(isc_portset_t *portset, in_port_t port_lo,
 			in_port_t port_hi)
 {
