Esempio n. 1
0
    public IPv6Benchmarks()
    {
        _net1     = (IpAddressNetworkV6)"2001:db8:8a2e:370::/80";
        _address1 = (IpAddressV6)"2001:0db8:8a2e:0370::7334";

        _net2     = (IpAddressNetworkV6)"fe80:ffff:1100::/40";
        _address2 = (IpAddressV6)"fe80:ffff:1111:2222:3333:4444:5555:6666";
    }
Esempio n. 2
0
 public void Setup()
 {
     _addressV4  = (IpAddressV4)"174.64.25.18";
     _networkV4  = (IpAddressNetworkV4)"174.64.25.18/24";
     _addressV6  = (IpAddressV6)"2001:0dff:44ff:0:1744:ffff";
     _networkV6  = (IpAddressNetworkV6)"2001:0dff:44ff:0:1744:ffff/64";
     _sb         = new StringBuilder();
     _charBuffer = new char[60];
 }
    /// <inheritdoc cref="Docs.IIPAddressNetworkDocs{IpAddressNetworkV6}.ContainsOrEqual(IpAddressNetworkV6)"/>
    public bool ContainsOrEqual(IpAddressNetworkV6 other)
    {
        if (other.Mask < _mask)
        {
            return(false);
        }

        IpAddressV6 sharedNetwork = NetworkMask & other._networkAddress;

        return(sharedNetwork == _networkAddress);
    }
Esempio n. 4
0
    public void BasicTest(string test, string expectedNetwork, string expectedEnd, byte expectedMask, string expectedSubnetSize)
    {
        IpAddressNetworkV6 net = IpAddressNetworkV6.Parse(test);

        net.Mask.Should().Be(expectedMask);
        net.NetworkAddress.Should().Be((IpAddressV6)expectedNetwork);
        net.EndAddress.Should().Be((IpAddressV6)expectedEnd);

        BigInteger bigExpectedSubnetSize = BigInteger.Parse(expectedSubnetSize);

        net.SubnetSize.Should().Be(bigExpectedSubnetSize);
    }
Esempio n. 5
0
    public void FullPropertyTest()
    {
        IpAddressNetworkV6 net = IpAddressNetworkV6.Parse("2001:db8::8a2e:371:7334/96");

        net.Mask.Should().Be(96);
        net.ToString().Should().Be("2001:db8::8a2e:0:0/96");
        net.NetworkAddress.Should().Be((IpAddressV6)"2001:db8::8a2e:0:0");
        net.EndAddress.Should().Be((IpAddressV6)"2001:db8::8a2e:ffff:ffff");
        net.NetworkMask.Should().Be((IpAddressV6)"ffff:ffff:ffff:ffff:ffff:ffff::");
        net.NetworkWildcardMask.Should().Be((IpAddressV6)"::ffff:ffff");
        net.SubnetSize.Should().Be(4294967296);
    }
Esempio n. 6
0
    public void ContainsTest(string network, string test, bool shouldContain)
    {
        IpAddressNetworkV6 net = (IpAddressNetworkV6)network;
        IpAddressV6        ip  = (IpAddressV6)test;

        if (shouldContain)
        {
            net.Contains(ip).Should().BeTrue();
        }
        else
        {
            net.Contains(ip).Should().BeFalse();
        }
    }
Esempio n. 7
0
    public void ValidIPv4InV6FormatTests(string expected, string test, byte cidr)
    {
        string expectedWithoutSlash = expected.Split('/').First();

        IpAddressNetworkV6 parsed     = IpAddressNetworkV6.Parse(test);
        IPAddress          expectedIp = IPAddress.Parse(expectedWithoutSlash);

        parsed.NetworkAddress.Should().Be(expectedIp);
        if (cidr == 128)
        {
            parsed.EndAddress.Should().Be(expectedIp);
        }
        parsed.Mask.Should().Be(cidr);

        // This representation is special, and should still be the IPv4 in IPv6 mapped
        expectedIp.ToString().Should().Be(expectedWithoutSlash);
        parsed.ToString().Should().Be(expected);
    }
 public IpAddressNetworkV6 CurrentIPv6UnstableParser()
 {
     return(IpAddressNetworkV6.ParseUnstable("2001:0dff:44ff:0:1744::ffff/64"));
 }
Esempio n. 9
0
 public void IPv6NetworkFormats(string network)
 {
     Assert.True(IpAddressNetworkV6.TryParse(network, out _));
 }
    internal static bool TryParse(ref Tokenizer tokenizer, out IpAddressNetworkV6 result)
    {
        // Shortest IPv6 is 2 chars (::)
        // Longest regular IPv6 is 43 chars (0000:0000:0000:0000:0000:0000:0000:0000/128)
        // Longest IPv4 mapped IPv6 is 49 chars (0000:0000:0000:0000:0000:ffff:255.255.255.255/128)
        if (tokenizer.Length < 2 || tokenizer.Length > 49)
        {
            result = default;
            return(false);
        }

        ulong high         = 0;
        ulong low          = 0;
        byte  cidr         = 128;
        byte  segmentsRead = 0;

        bool doReverse = false;

        // First pass, try reading a mask from the end of the input
        ParsedToken tkn = tokenizer.PeekReverse(false);

        if (tkn.Type == TokenType.Number)
        {
            // Could be a number, therefor a CIDR range or IPv4
            ParsedToken slashTkn = tokenizer.PeekReverse(false);
            if (slashTkn.Type == TokenType.Slash && tkn.Value <= 128)
            {
                cidr = (byte)tkn.Value;
                tokenizer.AdoptPeekOffsets();
            }
            else if (slashTkn.Type == TokenType.Dot)
            {
                // This could be an IPv4 mapped in IPv6
                // Carry on, see where it gets us
                tokenizer.ResetPeekOffsets();
            }
            else if (slashTkn.Type != TokenType.Number && slashTkn.Type != TokenType.Colon && slashTkn.Type != TokenType.DoubleColon && slashTkn.Type != TokenType.None)
            {
                // Any IPv6 should end on a number or double-colon (excluding the cidr mask), and the cidr mask should be 128 or lower
                // Single-token IPv6's are allowed, so we check for None as well
                result = default;
                return(false);
            }
        }

        // Test if this could be an IPv4 mapped IPv6
        // This could be the case if the last two tokens are [Dot, Number]
        // Like '::ffff:192.168.1.0'
        tkn = tokenizer.PeekReverse(false);
        if (tkn.Type == TokenType.Number)
        {
            // If the next-to-last is a Dot, pass it on
            ParsedToken tmpTkn = tokenizer.PeekReverse(false);

            tokenizer.ResetPeekOffsets();

            if (tmpTkn.Type == TokenType.Dot)
            {
                return(TryReadIPv4MappedIPv6(ref tokenizer, cidr, out result));
            }
        }

        tokenizer.ResetPeekOffsets();

        // Read up till a double-colon, eof or slash
        for (byte i = 0; i < 8; i++)
        {
            tkn = tokenizer.ParseAndAdvance(true);
            if (tkn.Type == TokenType.None)
            {
                break;
            }

            if (i > 0)
            {
                // The read token MUST be a colon or a double-colon
                if (tkn.Type == TokenType.Colon)
                {
                    // Advance once more
                    tkn = tokenizer.ParseAndAdvance(true);
                }
                else if (tkn.Type != TokenType.DoubleColon)
                {
                    result = default;
                    return(false);
                }
            }

            // Read a number or double-colon
            if (tkn.Type == TokenType.Number)
            {
                BitUtilities.SetTuplet(ref low, ref high, i, tkn.Value);
                segmentsRead++;
            }
            else if (tkn.Type == TokenType.DoubleColon)
            {
                doReverse = true;
                break;
            }
            else if (tkn.Type != TokenType.DoubleColon)
            {
                result = default;
                return(false);
            }
        }

        // Read reverse
        if (doReverse)
        {
            byte toRead = (byte)(8 - segmentsRead);

            for (byte i = 0; i < toRead; i++)
            {
                tkn = tokenizer.ParseAndAdvanceReverse(true);
                if (tkn.Type == TokenType.None)
                {
                    break;
                }

                if (i > 0)
                {
                    // The read token MUST be a colon
                    if (tkn.Type != TokenType.Colon)
                    {
                        result = default;
                        return(false);
                    }

                    // Advance once more
                    tkn = tokenizer.ParseAndAdvanceReverse(true);
                }

                // Read a number
                if (tkn.Type == TokenType.Number)
                {
                    BitUtilities.SetTuplet(ref low, ref high, (byte)(7 - i), tkn.Value);
                    segmentsRead++;
                }
                else
                {
                    result = default;
                    return(false);
                }
            }
        }

        result = new IpAddressNetworkV6(high, low, cidr);
        return(true);
    }
    public static bool TryParse(ReadOnlySpan <char> value, out IpAddressNetworkV6 result)
    {
        Tokenizer tokenizer = new Tokenizer(value);

        return(TryParse(ref tokenizer, out result));
    }
 public static bool TryParse(string value, out IpAddressNetworkV6 result)
 {
     return(TryParse(value.AsSpan(), out result));
 }
 public bool IsContainedInOrEqual(IpAddressNetworkV6 other)
 {
     return(other.ContainsOrEqual(this));
 }
Esempio n. 14
0
 protected override bool Contains(IpAddressNetworkV6 network, IpAddressNetworkV6 other) => network.ContainsOrEqual(other);
Esempio n. 15
0
 [InlineData("2001:0db8::8a2e:192.168.0.1")] // Badly formatted IPv4 in IPv6
 public void InvalidFormatsTests(string test)
 {
     IpAddressNetworkV6.TryParse(test, out _).Should().BeFalse();
 }
Esempio n. 16
0
    public void SplitTest()
    {
        // Check that Split fails fast on mask
        IpAddressNetworkV6 net = (IpAddressNetworkV6)"2001:db8::8a2e:371:7334/96";

        Assert.Throws <ArgumentOutOfRangeException>(() => net.Split(128));
        Assert.Throws <ArgumentOutOfRangeException>(() => net.Split(33));
        Assert.Throws <ArgumentOutOfRangeException>(() => net.Split(0));

        // Generic split in the lower-end of the IPv6 struct
        net = (IpAddressNetworkV6)"2001:db8::8a2e:371:7334/96";
        List <IpAddressNetworkV6> splits = net.Split(2).ToList();

        splits.Should().ContainInOrder(new IpAddressNetworkV6[]
        {
            (IpAddressNetworkV6)"2001:db8::8a2e:0000:0/98",
            (IpAddressNetworkV6)"2001:db8::8a2e:4000:0/98",
            (IpAddressNetworkV6)"2001:db8::8a2e:8000:0/98",
            (IpAddressNetworkV6)"2001:db8::8a2e:c000:0/98"
        });

        // Generic split in the higher-end of the IPv6 struct
        net    = (IpAddressNetworkV6)"2001:db8::/48";
        splits = net.Split(2).ToList();
        splits.Should().ContainInOrder(new IpAddressNetworkV6[]
        {
            (IpAddressNetworkV6)"2001:0db8:0000:0000::/50",
            (IpAddressNetworkV6)"2001:0db8:0000:4000::/50",
            (IpAddressNetworkV6)"2001:0db8:0000:8000::/50",
            (IpAddressNetworkV6)"2001:0db8:0000:c000::/50"
        });

        // Generic split across the two longs in the IPv6 struct
        net    = (IpAddressNetworkV6)"2001:db8:ff32:1234::/63";
        splits = net.Split(2).ToList();
        splits.Should().ContainInOrder(new IpAddressNetworkV6[]
        {
            (IpAddressNetworkV6)"2001:db8:ff32:1234:0000::/65",
            (IpAddressNetworkV6)"2001:db8:ff32:1234:8000::/65",
            (IpAddressNetworkV6)"2001:db8:ff32:1235:0000::/65",
            (IpAddressNetworkV6)"2001:db8:ff32:1235:8000::/65"
        });

        // Major split from ::/0 to ::/128, to ensure it can work (we will _not_ enumerate it)
        net    = (IpAddressNetworkV6)"::/0";
        splits = net.Split(128).Take(17).ToList();
        splits.Should().ContainInOrder(new IpAddressNetworkV6[]
        {
            (IpAddressNetworkV6)"::0/128",
            (IpAddressNetworkV6)"::1/128",
            (IpAddressNetworkV6)"::2/128",
            (IpAddressNetworkV6)"::3/128",
            (IpAddressNetworkV6)"::4/128",
            (IpAddressNetworkV6)"::5/128",
            (IpAddressNetworkV6)"::6/128",
            (IpAddressNetworkV6)"::7/128",
            (IpAddressNetworkV6)"::8/128",
            (IpAddressNetworkV6)"::9/128",
            (IpAddressNetworkV6)"::A/128",
            (IpAddressNetworkV6)"::B/128",
            (IpAddressNetworkV6)"::C/128",
            (IpAddressNetworkV6)"::D/128",
            (IpAddressNetworkV6)"::E/128",
            (IpAddressNetworkV6)"::F/128",
            (IpAddressNetworkV6)"::10/128"
        });
    }
    public IpAddressNetworkV6 Iterative()
    {
        IpAddressNetworkV6 ip = IterativeParse("2001:dff:44ff:0:1744::ffff:4d4d/120");

        return(ip);
    }
Esempio n. 18
0
 protected override int Mask(IpAddressNetworkV6 network) => network.Mask;
Esempio n. 19
0
 public bool IsContainedIn(IpAddressNetworkV6 network) => network.Contains(this);
Esempio n. 20
0
 protected override int Compare(IpAddressNetworkV6 network, IpAddressNetworkV6 other) => network.CompareTo(other);
    private static bool TryReadIPv4MappedIPv6(ref Tokenizer tokenizer, byte cidr, out IpAddressNetworkV6 result)
    {
        ulong       high         = 0;
        ulong       low          = 0;
        byte        segmentsRead = 0;
        ParsedToken token;

        // Read reverse, we're only interested in the IPv4 on the end
        byte toRead = 4;

        for (byte i = 0; i < toRead; i++)
        {
            token = tokenizer.ParseAndAdvanceReverse(false);
            if (token.Type == TokenType.None)
            {
                break;
            }

            if (i > 0)
            {
                // The read token MUST be a dot
                if (token.Type != TokenType.Dot)
                {
                    result = default;
                    return(false);
                }

                // Advance once more
                token = tokenizer.ParseAndAdvanceReverse(false);
            }

            // Read a number
            if (token.Type == TokenType.Number)
            {
                BitUtilities.SetByte(ref low, ref high, (byte)(15 - i), token.Value);
                segmentsRead++;
            }
            else
            {
                result = default;
                return(false);
            }
        }

        // Assert that the next tokens are [Double-/Colon, ffff, Colon]
        token = tokenizer.ParseAndAdvanceReverse(false);

        if (token.Type != TokenType.Colon)
        {
            result = default;
            return(false);
        }

        token = tokenizer.ParseAndAdvanceReverse(true);

        if (token.Type != TokenType.Number || token.Value != 0xffff)
        {
            result = default;
            return(false);
        }

        token = tokenizer.ParseAndAdvanceReverse(false);

        if (token.Type is not TokenType.Colon && token.Type is not TokenType.DoubleColon)
        {
            result = default;
            return(false);
        }

        // Place 0xFFFF in the correct position
        BitUtilities.SetTuplet(ref low, ref high, 5, 0xFFFF);

        result = new IpAddressNetworkV6(high, low, cidr);
        return(true);
    }