/// <summary> /// Handles Hexadecimal, octal, decimal, dotted decimal, dotted hex, dotted octal. /// @param testDomain the string we're testing /// @return Returns true if it's a valid ipv4 address /// </summary> private bool IsValidIpv4(string testDomain) { var valid = false; if (testDomain.Length > 0) { //handling format without dots. Ex: http://2123123123123/path/a, http://0x8242343/aksdjf if (_dots == 0) { try { long value; if (testDomain.Length > 2 && testDomain[0] == '0' && testDomain[1] == 'x') { // hex var isParsed = long.TryParse(testDomain.Substring(2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out value); if (!isParsed) { return(true); } } else if (testDomain[0] == '0') { // octal var possibleDomain = testDomain.Substring(1); if (OctalEncodingHelper.LooksLikeOctal(possibleDomain.AsSpan())) { value = Convert.ToInt64(possibleDomain, 8); } else { return(false); } } else { // decimal var isParsed = long.TryParse(testDomain, out value); if (!isParsed) { return(false); } } valid = value <= MAX_NUMERIC_DOMAIN_VALUE && value >= MIN_NUMERIC_DOMAIN_VALUE; } catch (Exception) { valid = false; } } else if (_dots == 3) { //Dotted decimal/hex/octal format var parts = CharUtils.SplitByDot(testDomain); valid = true; //check each part of the ip and make sure its valid. for (var i = 0; i < parts.Length && valid; i++) { var part = parts[i]; if (part.Length > 0) { string parsedNum; int @base; if (part.Length > 2 && part[0] == '0' && part[1] == 'x') { //dotted hex parsedNum = part.Substring(2); @base = 16; } else if (part[0] == '0') { //dotted octal parsedNum = part.Substring(1); @base = 8; } else { //dotted decimal parsedNum = part; @base = 10; } int section; if (parsedNum.Length == 0) { section = 0; } else { // For efficiency, we try to avoid try/catch and instead use tryparse if (@base == 16) { var isParsed = int.TryParse(parsedNum, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out section); if (!isParsed) { return(false); } } else if (@base == 10) { var isParsed = int.TryParse(parsedNum, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out section); if (!isParsed) { return(false); } } else { // for other bases, fall back to try/catch if (@base == 8 && OctalEncodingHelper.LooksLikeOctal(parsedNum.AsSpan())) { try { section = Convert.ToInt32(parsedNum, @base); } catch (Exception) { return(false); } } else { return(false); } } } if (section < MIN_IP_PART || section > MAX_IP_PART) { valid = false; } } else { valid = false; } } } } return(valid); }
/// <summary> /// This covers cases like: /// Hexadecimal: 0x1283983 /// Decimal: 12839273 /// Octal: 037362273110 /// Dotted Decimal: 192.168.1.1 /// Dotted Hexadecimal: 0xfe.0x83.0x18.0x1 /// Dotted Octal: 0301.00.046.00 /// Dotted Mixed: 0x38.168.077.1 /// if ipv4 was found, _bytes is set to the byte representation of the ipv4 address /// </summary> /// <param name="host"></param> /// <returns></returns> private static byte[] TryDecodeHostToIPv4(string host) { string[] parts = CharUtils.SplitByDot(host); int numParts = parts.Length; if (numParts != 4 && numParts != 1) { return(null); } byte[] bytes = new byte[16]; //An ipv4 mapped ipv6 bytes will have the 11th and 12th byte as 0xff bytes[10] = (byte)0xff; bytes[11] = (byte)0xff; for (int i = 0; i < parts.Length; i++) { string parsedNum; int @base; if (parts[i].StartsWith("0x")) { //hex parsedNum = parts[i].Substring(2); @base = 16; } else if (parts[i].StartsWith("0")) { //octal parsedNum = parts[i].Substring(1); @base = 8; } else { //decimal parsedNum = parts[i]; @base = 10; } long section; if (string.IsNullOrEmpty(parsedNum)) { section = 0; } else { try { if (16 == @base) { var isParsed = long.TryParse(parsedNum, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out section); if (!isParsed) { return(null); } } else if (8 == @base && OctalEncodingHelper.LooksLikeOctal(parsedNum.AsSpan())) { section = Convert.ToInt32(parsedNum, @base); } else { var isParsed = long.TryParse(parsedNum, out section); if (!isParsed) { return(null); } } } catch (Exception) { return(null); } } if (numParts == 4 && section > MAX_IPV4_PART || //This would look like 288.1.2.4 numParts == 1 && section > MAX_NUMERIC_DOMAIN_VALUE || //This would look like 4294967299 section < MIN_IP_PART) { return(null); } // bytes 13->16 is where the ipv4 address of an ipv4-mapped-ipv6-address is stored. if (numParts == 4) { var b = Convert.ToByte(section); bytes[IPV4_MAPPED_IPV6_START_OFFSET + i] = b; // section.byteValue(); } else { // numParts == 1 int index = IPV4_MAPPED_IPV6_START_OFFSET; bytes[index++] = (byte)((section >> 24) & 0xFF); bytes[index++] = (byte)((section >> 16) & 0xFF); bytes[index++] = (byte)((section >> 8) & 0xFF); bytes[index] = (byte)(section & 0xFF); return(bytes); } } return(bytes); }