function checkIPAddress(obj)
{
	var returnVal = true;
	var value = obj.val();
	
	if(!COMM_ValidV4Format(value) || !COMM_ValidV4Addr(value))
	{	
		returnVal = false;
	}
	return returnVal;	
}

/* Check ipv6 address format, it should be x.x.x.x and digit.*/
function COMM_ValidV6Format(ipstr)
{
	var ret  = false;
	var expression = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/;

	if (expression.test(ipstr))
		ret = true;
	
	return ret;
}


/* Check ipv4 address format, it should be x.x.x.x and digit.*/
function COMM_ValidV4Format(ipstr)
{
	var vals = ipstr.split(".");
	if (vals.length!=4) return false;
	for (var i=0; i<4; i++)
	{
		if (!COMM_IsDigit(vals[i]) || vals[i]>255 || vals[3] < 1)
		{
			return false;
	}
	}
	return true;
}

/* Check ipv4 address value, return true if the ipaddr is a valid v4 dot-number IP address. */
function COMM_ValidV4Addr(ipaddr)
{
	var host = COMM_IPv4HOST(ipaddr, 0);
	if (host == ""||host == 0) return false;
	
	var network = COMM_IPv4NETWORK(ipaddr, 8);
	var tmp = network.split(".");
	if(tmp[0] < 1) return false;
	if(tmp[0] > 223) return false;
	if(tmp[0] == 127) return false;
	
	return true;
}

function COMM_ValidV4HOST(ipaddr, mask)
{
	var hostid = COMM_IPv4HOST(ipaddr, mask);
	if(hostid == "") return false;
	var maxhid = COMM_IPv4MAXHOST(mask);
	if(hostid > 0 && hostid < maxhid) return true;
	return false;
}

function hostidandmask(subnet, ip)
{	
	var mask = COMM_IPv4MASK2INT(subnet);
	var hostid = COMM_IPv4HOST(ip, mask);
	var returnVal = true;
	if(hostid==0 || hostid>=COMM_IPv4MAXHOST(mask)){
		returnVal = false;
	}
	return returnVal;	
}
function checkSubnetMaskAddress(obj)
{
	var value = obj.val();
	var mask = COMM_IPv4MASK2INT(value);
	var returnVal = false;
	
	if(mask == 8 || mask == 16 || (24 <= mask && mask <= 30))
	{
		returnVal = true;
	}
	return returnVal;	
}
function checkNumberValue(obj, min, max)
{
	var value = obj.val();
	var reg = /(^[0-9]+$)/;
	var result = true;
	if (reg.test(value))
	{
		value = parseInt(value, 10);
		if (value < min || value > max)
		{
			result = false;
		}
	}
	else
	{
		result = false;
	}
	return result;	
}
function checkNum(obj)
{
	var value=obj.val();
	var result=/^[1-9]\d*$/g.test(value);
	if(result)
		return true;
	else
		return false;
}
function checkDomain(value)
{
	//var regEpx=/^((http|https|ftp|rtsp|mms)+:\/\/)?(\w+(-\w+)*)((\.|\/)(\w+(-\w+)*)){2,}(\?\S*)?(\/)?$/gi;
	var regEpx=/^((\w)+:\/\/)?(\w+(-\w+)*)((\.|\/)(\w+(-\w+)*))*(\?\S*)?(\/)?$/gi;
	if (regEpx.test(value))
	{
		return true;
	}
	return false;
}
function checkIllegalChar(obj, len)
{
	var value = obj.val();
	if(len == null)
		reg = /(^[A-Za-z0-9_-]+$)/;
	else
		reg = /^([0-9a-zA-Z-_]{1,len})$/;
	var result = false;
	if (reg.test(value))
	{
		result = true;
	}
	return result;
	
}
function checkIPFormat(obj)
{
	var value = obj.val();
	var reg = /(^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\-(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))+$/;
	var reg2 = /(^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))+$/;
	var result = false;
	if (reg.test(value))
	{
		result = true;
	}
	if (reg2.test(value))
	{
		result = true;
	}
	return result;
}

function checkNULL(obj)
{
	var result = true;
	if((obj.val() == ""))
	{
		result = false;
	}
	return result;
}
function checkPort(obj)
{
	var value = obj.val();
	var ValidPortRangeRegex = /(^\d{1,})+$/;

	if (ValidPortRangeRegex.test(value))
	{
		if((parseInt(value, 10) > 65535)||(parseInt(value, 10)  <=0))
		{
			return false;
		}
	}
	else
		return false;
	
	return true;
}
function checkPortRange(obj)
{	
	var value = obj.val();
	var FullValue = value.replace(/\s/g, "");
	var eachPortValue = FullValue.split(",");
	var portValue;
	var ValidPortRangeRegex = /(^\d{1,})+$/;
	var ValidPortRangesRegex = /(^\d{1,}-\d{1,})$/;
	
	if(value=="")
	{
		return true;
	}
	else
	{
		for(var i = 0; i < eachPortValue.length; i ++)
		{
			if(eachPortValue[i].search("-") > -1)
			{
				if (ValidPortRangesRegex.test(eachPortValue[i]))
				{
					portValue = eachPortValue[i].split("-");
					var start = parseInt(portValue[0], 10);
					var end = parseInt(portValue[1], 10);
					if((start > 65535)||(start <=0) || (end > 65535)||(end <=0))
					{
						return false;
					}
					if(start > end)
					{
						return false;
					}
				}
				else
				{
					return false;
				}
			}
			else
			{
				if (ValidPortRangeRegex.test(eachPortValue[i]))
				{
					if(eachPortValue[i].indexOf("0") == 0)//0 can't be first digital
						return false;
					if((parseInt(eachPortValue[i], 10) > 65535)||(parseInt(eachPortValue[i], 10)  <=0))
					{
						return false;
					}
				}
				else
				{
					return false;
				}
			}

		}
	}

	return true;
}


function COMM_Pow(a, b)
{
	var c = 1;
	for (var i = 0; i < b; i+=1) c = c*a;
	return c;
}
function count_bits(val)
{
	for (var i = 7; i >= 0; i-=1) if ((val & COMM_Pow(2, i))==0) break;
	return 7-i;
}
/* COMM_IPv4INT2ADDR(16843009) -> "1.1.1.1" */
function COMM_IPv4INT2ADDR(val)
{
	var nums = new Array();
	var str;

	nums[3] = val % 256; val = (val-nums[3])/256;
	nums[2] = val % 256; val = (val-nums[2])/256;
	nums[1] = val % 256; val = (val-nums[1])/256;
	nums[0] = val % 256;
	str = nums[0]+"."+nums[1]+"."+nums[2]+"."+nums[3];
	return str;
}

/* COMM_IPv4NETWORK("192.168.1.1", 24) -> "192.168.1.0" */
function COMM_IPv4NETWORK(addr, mask)
{
	var addrArray = addr.split(".");
	var maskArray = COMM_IPv4INT2MASK(mask).split(".");
	var networkArray = new Array();
	var str = "";
	for (var i=0; i<4; i+=1)
	{
		if (isNaN(addrArray[i])||addrArray[i].length==0||parseInt(addrArray[i],10)>255) return "0.0.0.0";
		networkArray[i] = eval(addrArray[i] & maskArray[i]);
		str += str?"."+networkArray[i]:networkArray[i];
	}
	return str;
}

/* COMM_IPv4ADDR2INT("1.1.1.1") -> 16843009 */
function COMM_IPv4ADDR2INT(addr)
{
	var nums;
	var vals = new Array();
	var val;

	nums = addr.split(".");
	vals[0] = (parseInt(nums[0], [10]) % 256);
	vals[1] = (parseInt(nums[1], [10]) % 256);
	vals[2] = (parseInt(nums[2], [10]) % 256);
	vals[3] = (parseInt(nums[3], [10]) % 256);
	val = vals[0];
	val = val*256 + vals[1];
	val = val*256 + vals[2];
	val = val*256 + vals[3];
	return val;
}

/* COMM_IPv4INT2MASK(24) -> "255.255.255.0" */
function COMM_IPv4INT2MASK(val)
{
	var bits = 0;
	if (val < 32) bits = COMM_Pow(2,32) - COMM_Pow(2,32-val);
	else if (val == 32) return "255.255.255.255";
	return COMM_IPv4INT2ADDR(bits);
}
/* COMM_IPv4HOST("192.168.0.1", 24) -> "1" */
function COMM_IPv4HOST(addr, mask)
{
	var addrArray = addr.split(".");
	var maskArray = COMM_IPv4INT2MASK(mask).split(".");
	var networkArray = new Array();
	var str = "";
	for (var i=0; i<4; i+=1)
	{
		networkArray[i] = eval(addrArray[i] & ~maskArray[i]);
		str += str?"."+networkArray[i]:networkArray[i];
	}
	return COMM_IPv4ADDR2INT(str);
}
/* COMM_IPv4MAXHOST(24) -> "255" */
function COMM_IPv4MAXHOST(mask)
{
	return COMM_IPv4HOST("255.255.255.255", mask);
}
function COMM_IPv4MASK2INT(mask)
{
	var nums = mask.split(".");
	var vals = new Array();
	var bits = 0;

	vals[0] = (parseInt(nums[0], [10]) % 256);
	vals[1] = (parseInt(nums[1], [10]) % 256);
	vals[2] = (parseInt(nums[2], [10]) % 256);
	vals[3] = (parseInt(nums[3], [10]) % 256);

	bits = count_bits(vals[0]);
	if (vals[0] == 255)
	{
		bits += count_bits(vals[1]);
		if (vals[1] == 255)
		{
			bits += count_bits(vals[2]);
			if (vals[2] == 255) bits += count_bits(vals[3]);
		}
	}
	if (mask != COMM_IPv4INT2MASK(bits)) return -1;
	return bits;
}

function COMM_IsDigit(no)
{
	if (no==""||no==null)
		return false;
	if (no.toString()!=parseInt(no, 10).toString())
		return false;

    return true;
}

function COMM_IsInteger(str)
{
	var y = parseInt(str);
	if (isNaN(y)) return false;
	return str===y.toString();
}
/* --------------公共函数：检查MAC地址是否正确 ------------------*/
function checkMacAddr(str)
{
	var result = CORRECT;
	if(""==str.length)
	{
		return ERR_MAC_EMPTY;
	}
	if (CORRECT != (result = verifyMacFormat(str)))
	{
		return result;
	}

	if (CORRECT != (result = verifyMacAddr(str)))
	{
		return result;
	}
	
		return result;
}

function COMM_IsMAC(mac)
{
	var RegExPattern =/^\s*([\d[a-f]{2}:){5}[\d[a-f]{2}\s*$/i;
	var RegExPattern2 =/^\s*([\d[a-f]{2}-){5}[\d[a-f]{2}\s*$/i;
  	if (mac.match(RegExPattern) || mac.match(RegExPattern2))
  		return true;
  	else return false;
}

function COMM_IsASCII(str)
{
	var ValidHEXRegex = /^[ -~]+$/;	
	var result = ValidHEXRegex.test(str);

	if(str == "")
		result = true;

	return result;
}

function COMM_ValidName(value) {
	var returnVal = true;
	var ValidHEXRegex = /^[A-Za-z0-9\s\-\_]+$/;

	if(ValidHEXRegex.test(value)){
		returnVal = true;
	} else {
		returnVal = false;
	}

	return returnVal;
}

function COMM_ValidChineseName(value) {
	var returnVal = true;
	var ValidHEXRegex = /^[A-Za-z0-9\s\-\_\u4E00-\u9FA5]+$/;

	if(ValidHEXRegex.test(value)){
		returnVal = true;
	} else {
		returnVal = false;
	}

	return returnVal;
}

function validate_ssid(ssid) {
	var reg = /^([0-9a-zA-Z-_]{1,32})$/;
	return reg.test(ssid);
}

function validateWifiPassword(password) {
	var reg = /^[a-zA-Z0-9-_]+$/;
	return reg.test(password);
}
function validate_username(str) {
	var reg = /^([A-Za-z0-9~!@#$%^&*()_+:";',\.\/<>\?]+)$/;
	return reg.test(str);
}
function validate_pwd(str) {
	var reg = /^([A-Za-z0-9~!@#$%^&*()_+:";',\.\/<>\?]+)$/;
	return reg.test(str);
}
function validate_trim(str)
{
	if(str != str.trim())
		return false;
	return true;
}
function getUTF8Length(s) {
  var len = 0;
  for (var i = 0; i < s.length; i++) {
    var code = s.charCodeAt(i);
    if (code <= 0x7f) {
      len += 1;
    } else if (code <= 0x7ff) {
      len += 2;
    } else if (code >= 0xd800 && code <= 0xdfff) {
      // Surrogate pair: These take 4 bytes in UTF-8 and 2 chars in UCS-2
      // (Assume next char is the other [valid] half and just skip it)
      len += 4; i++;
    } else if (code < 0xffff) {
      len += 3;
    } else {
      len += 4;
    }
  }
  return len;
}

function validateComment(s, len) {
    return getUTF8Length(s) <= len;
}

function validateString(s) {
    // 日本語以外の全文字列
    var reg = /^[\x20-\x7E]*$/;

    return reg.test(s);
}

function validateText(obj) {

	if(obj.val().indexOf('<') != -1 || obj.val().indexOf('>') != -1)
		return false;
	else
		return true;
} 
function validateHex(hex) {
    // 16進数
    var reg = /^[0-9A-Fa-f]*$/;

    return reg.test(hex);
}

function validateHostName(name) {
    // 半角英数字
    var reg = /^[0-9A-Za-z]*$/;
	
    return reg.test(name);
}
function validateDomainName(name)
{
	var reg = /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/;
	return reg.test(name);
}
function validateWANDHCPHostName(str)
{
	if (str.match(/[^a-z^A-Z^0-9^\-^_]/g) || str.indexOf(' ') != -1 || str.indexOf('^') != -1 || str == "")
		return false;
	else if (str.length > 30)
		return false;

	return true;
}

function validatePPP(s) {
    // PPPoE 
	var reg = /^([0-9a-zA-Z-_]{1,30})$/;
    return reg.test(s);
}

 function validateInt(s) {
    // 整数
    var reg = /^[0-9]+$/;

    return reg.test(s);
}

function isKeyboardInput(obj)
{
	var Str=obj.val();
    var i, len = Str.length;

    for(i = 0; i < len; i++)
    {
        if(Str.charAt(i) < ' ' || Str.charAt(i) > '~')
            return false;
    }
    
    return true;
}

function validateKey(obj)
{
	var str=obj.val();
   for (var i=0; i<str.length; i++) 
   {
    if ( (str.charAt(i) >= '0' && str.charAt(i) <= '9') || (str.charAt(i) == '.' ) )
			continue;
	return 0;
   }
  return 1;
}

function validateIp(str) {
    for (var i=0; i<str.length; i++) {
        if ( (str.charAt(i) >= '0' && str.charAt(i) <= '9') || (str.charAt(i) == '.' ) )
            continue;
	return false;
    }
    return true;
}
function checkDigitRange(str, num, min, max) {
    var d = getDigit(str,num);
    if (d > max || d < min)
        return false;
    return true;
}
function getDigit(str, num) {
    var i = 1;
    if (num !== 1) {
        while (i!=num && str.length!=0) {
            if (str.charAt(0) === '.') {
                i++;
            }
            str = str.substring(1);
        }
        if (i !==num )
            return -1;
    }
    for (i=0; i<str.length; i++) {
        if (str.charAt(i) === '.') {
            str = str.substring(0, i);
            break;
        }
    }
    if (str.length === 0)
        return -1;
    var d = parseInt(str, 10);
    return d;
}

function isBlank(s){
	var i;
	var c;
	for(i=0;i<s.length;i++)
	{
		c=s.charAt(i);
		if((c!=' ')&&(c!='\n')&&(c!='\t'))return false;
	}
	return true;
}

function inet_network(ip_str){
	if(!ip_str)
	return -1;
	var re = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/;
	if(re.test(ip_str)){
		var v1 = parseInt(RegExp.$1);
		var v2 = parseInt(RegExp.$2);
		var v3 = parseInt(RegExp.$3);
		var v4 = parseInt(RegExp.$4);
		if(v1 < 256 && v2 < 256 && v3 < 256 && v4 < 256)
			return v1*256*256*256+v2*256*256+v3*256+v4;
	}
	return -2;
}
function matchSubnet(wan_ip1, wan_sb1,lan_ip2,lan_sb2){
	var nsb;
	var nsb1 = inet_network(wan_sb1);
	var nsb2 = inet_network(lan_sb2);
	var nip1 = inet_network(wan_ip1);
	if(nip1 == 0 || nip1 == -1) // check if WAN IP = 0.0.0.0 or NULL (factory default value)
		return 1;
	if(nsb1 < nsb2 && nsb1 !=0)
		nsb = nsb1;
	else
		nsb = nsb2;
	if((inet_network(wan_ip1)&nsb) == (inet_network(lan_ip2)&nsb))
		return 1;
	else
		return 0;
}
function valid_email( value ) 
{
	return /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
}
/* Check ipv6 address format, it should be x.x.x.x and digit.*/
function COMM_ValidV6Format(ipstr)
{
 var ret  = false;
 var expression = /((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))/;

 if (expression.test(ipstr))
  ret = true;
 
 return ret;
}

function isNameUnsafe(compareChar) {
   var unsafeString = "\"<>%\\^[]`\+\$\,='#&@.: \t";

   if ( unsafeString.indexOf(compareChar) == -1 && compareChar.charCodeAt(0) > 32
        && compareChar.charCodeAt(0) < 123 )
      return false; // found no unsafe chars, return false
   else
      return true;
}

// Check if a name valid
function isValidName(name) {
   var i = 0;

   for ( i = 0; i < name.length; i++ ) {
      if ( isNameUnsafe(name.charAt(i)) == true )
         return false;
   }

   return true;
}

function isValidPort(port) {
   var fromport = 0;
   var toport = 100;

   portrange = port.split(':');
   if ( portrange.length < 1 || portrange.length > 2 ) {
       return false;
   }
   if ( isNaN(portrange[0]) )
       return false;
   fromport = parseInt(portrange[0]);

   if ( portrange.length > 1 ) {
       if ( isNaN(portrange[1]) )
          return false;
       toport = parseInt(portrange[1]);
       if ( toport <= fromport )
           return false;
   }

   if ( fromport < 1 || fromport > 65535 || toport < 1 || toport > 65535 )
       return false;

   return true;
}

function isValidIpAddress(address) {

   ipParts = address.split('/');
   if (ipParts.length > 2) return false;
   if (ipParts.length == 2) {
      num = parseInt(ipParts[1]);
      if (num <= 0 || num > 32)
         return false;
   }

   if (ipParts[0] == '0.0.0.0' ||
       ipParts[0] == '255.255.255.255' )
      return false;

   addrParts = ipParts[0].split('.');
   if ( addrParts.length != 4 ) return false;
   for (i = 0; i < 4; i++) {
      if (isNaN(addrParts[i]) || addrParts[i] =="")
         return false;
      num = parseInt(addrParts[i]);
      if ( num < 0 || num > 255 )
         return false;
   }
   return true;
}

function substr_count (haystack, needle, offset, length)
{
    var pos = 0, cnt = 0;

    haystack += '';
    needle += '';
    if (isNaN(offset)) {offset = 0;}
    if (isNaN(length)) {length = 0;}
    offset--;

    while ((offset = haystack.indexOf(needle, offset+1)) != -1){
        if (length > 0 && (offset+needle.length) > length){
            return false;
        } else{
            cnt++;
        }
    }

    return cnt;
}

function test_ipv6(ip)
{
  // Test for empty address
  if (ip.length<3)
  {
        return ip == "::";
  }

  // Check if part is in IPv4 format
  if (ip.indexOf('.')>0)
  {
        lastcolon = ip.lastIndexOf(':');

        if (!(lastcolon && isValidIpAddress(ip.substr(lastcolon + 1))))
            return false;

        // replace IPv4 part with dummy
        ip = ip.substr(0, lastcolon) + ':0:0';
  }

  // Check uncompressed
  if (ip.indexOf('::')<0)
  {
    var match = ip.match(/^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}$/i);
    return match != null;
  }

  // Check colon-count for compressed format
  if (substr_count(ip, ':'))
  {
    var match = ip.match(/^(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?$/i);
    return match != null;
  }

  // Not a valid IPv6 address
  return false;
}

function isValidIpAddress6(address) {
   ipParts = address.split('/');
   if (ipParts.length > 2) return false;
   if (ipParts.length == 2) {
      num = parseInt(ipParts[1]);
      if (num <= 0 || num > 128)
         return false;
   }

   return test_ipv6(ipParts[0]);
}

