コード例 #1
0
 public void LinkLocal()
 {
     foreach (var a in MulticastService.GetIPAddresses())
     {
         Console.WriteLine($"{a} ll={a.IsIPv6LinkLocal} ss={a.IsIPv6SiteLocal}");
     }
 }
コード例 #2
0
        /// <summary>
        ///   Creates a new instance of the <see cref="ServiceProfile"/> class
        ///   with the specified details.
        /// </summary>
        /// <param name="instanceName">
        ///    A unique identifier for the specific service instance.
        /// </param>
        /// <param name="serviceName">
        ///   The <see cref="ServiceName">name</see> of the service.
        /// </param>
        /// <param name="port">
        ///   The TCP/UDP port of the service.
        /// </param>
        /// <param name="addresses">
        ///   The IP addresses of the specific service instance. If <b>null</b> then
        ///   <see cref="MulticastService.GetIPAddresses"/> is used.
        /// </param>
        /// <remarks>
        ///   The SRV, TXT and A/AAAA resoruce records are added to the <see cref="Resources"/>.
        /// </remarks>
        public ServiceProfile(DomainName instanceName, DomainName serviceName, ushort port, IEnumerable <IPAddress> addresses = null)
        {
            InstanceName = instanceName;
            ServiceName  = serviceName;
            var fqn = FullyQualifiedName;

            var simpleServiceName = new DomainName(ServiceName.ToString()
                                                   .Replace("._tcp", "")
                                                   .Replace("._udp", "")
                                                   .Trim('_')
                                                   .Replace("_", "-"));

            HostName = DomainName.Join(InstanceName, simpleServiceName, Domain);
            Resources.Add(new SRVRecord
            {
                Name   = fqn,
                Port   = port,
                Target = HostName
            });
            Resources.Add(new TXTRecord
            {
                Name    = fqn,
                Strings = { "txtvers=1" }
            });

            foreach (var address in addresses ?? MulticastService.GetIPAddresses())
            {
                Resources.Add(AddressRecord.Create(HostName, address));
            }
        }
コード例 #3
0
        public void Multiple_Services()
        {
            var     service  = Guid.NewGuid().ToString() + ".local";
            var     done     = new ManualResetEvent(false);
            Message response = null;

            var a = new MulticastService();

            a.QueryReceived += (s, e) =>
            {
                var msg = e.Message;
                if (msg.Questions.Any(q => q.Name == service))
                {
                    var res       = msg.CreateResponse();
                    var addresses = MulticastService.GetIPAddresses()
                                    .Where(ip => ip.AddressFamily == AddressFamily.InterNetwork);
                    foreach (var address in addresses)
                    {
                        res.Answers.Add(new ARecord
                        {
                            Name    = service,
                            Address = address
                        });
                    }
                    a.SendAnswer(res);
                }
            };

            var b = new MulticastService();

            b.NetworkInterfaceDiscovered += (s, e) => b.SendQuery(service);
            b.AnswerReceived             += (s, e) =>
            {
                var msg = e.Message;
                if (msg.Answers.Any(ans => ans.Name == service))
                {
                    response = msg;
                    done.Set();
                }
            };
            try
            {
                a.Start();
                b.Start();
                Assert.IsTrue(done.WaitOne(TimeSpan.FromSeconds(1)), "answer timeout");
                Assert.IsNotNull(response);
                Assert.IsTrue(response.IsResponse);
                Assert.AreEqual(MessageStatus.NoError, response.Status);
                Assert.IsTrue(response.AA);
                Assert.AreNotEqual(0, response.Answers.Count);
            }
            finally
            {
                b.Stop();
                a.Stop();
            }
        }
コード例 #4
0
        public void Reachable_Ipv4()
        {
            var me = MulticastService.GetIPAddresses()
                     .First(a => a.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(a));

            Assert.IsTrue(me.IsReachable(me));
            Assert.IsFalse(me.IsReachable(IPAddress.Parse("1.1.1.1")));

            //var nat = IPAddress.Parse("165.84.19.151"); // NAT PCP assigned address
            //Assert.IsTrue(nat.IsReachable(IPAddress.Parse("1.1.1.1")));
        }
コード例 #5
0
        public void SubnetMask_All()
        {
            foreach (var a in MulticastService.GetIPAddresses())
            {
                var network = IPNetwork.Parse(a, a.GetSubnetMask());

                Console.WriteLine($"{a} mask {a.GetSubnetMask()} {network}");

                Assert.IsTrue(network.Contains(a), $"{a} is not reachable");
            }
        }
コード例 #6
0
        public void NicFromPattern()
        {
            var addresses = MulticastService.GetIPAddresses().ToArray();

            foreach (var address in addresses)
            {
                string pattern = address.ToString();
                if (pattern.Contains('.'))
                {
                    pattern = pattern.Substring(0, pattern.LastIndexOf('.')) + ".0/24";
                }
                var nic = MulticastService.GetNetworkInterfaceFromCIDR(pattern);
                Assert.IsNotNull(nic);
            }
        }
コード例 #7
0
        public void StartStop_SingleInterface()
        {
            var addresses = MulticastService.GetIPAddresses().ToArray();

            foreach (var address in addresses)
            {
                string pattern = address.ToString();
                if (pattern.Contains('.'))
                {
                    pattern = pattern.Substring(0, pattern.LastIndexOf('.')) + ".0/24";
                }
                var nic  = MulticastService.GetNetworkInterfaceFromCIDR(pattern);
                var mdns = new MulticastService(nic);
                Assert.IsTrue(mdns.IsUsingSingleInterface);
                mdns.Start();
                mdns.Stop();
            }
        }
コード例 #8
0
        public void Reachable_Loopback_From_Localhost()
        {
            var me = IPAddress.Loopback;

            foreach (var a in MulticastService.GetIPAddresses())
            {
                Assert.IsTrue(me.IsReachable(a), $"{a}");
            }
            Assert.IsFalse(me.IsReachable(IPAddress.Parse("1.1.1.1")));
            Assert.IsFalse(me.IsReachable(IPAddress.Parse("2606:4700:4700::1111")));

            me = IPAddress.IPv6Loopback;
            foreach (var a in MulticastService.GetIPAddresses())
            {
                Assert.IsTrue(me.IsReachable(a), $"{a}");
            }
            Assert.IsFalse(me.IsReachable(IPAddress.Parse("1.1.1.1")));
            Assert.IsFalse(me.IsReachable(IPAddress.Parse("2606:4700:4700::1111")));
        }
コード例 #9
0
        /// <summary>
        ///   Determines if the local IP address can be used by the
        ///   remote address.
        /// </summary>
        /// <param name="local"></param>
        /// <param name="remote"></param>
        /// <returns>
        ///   <b>true</b> if <paramref name="local"/> can be used by <paramref name="remote"/>;
        ///   otherwise, <b>false</b>.
        /// </returns>
        public static bool IsReachable(this IPAddress local, IPAddress remote)
        {
            // Loopback addresses are only reachable when the remote is
            // the same host.
            if (local.Equals(IPAddress.Loopback) || local.Equals(IPAddress.IPv6Loopback))
            {
                return(MulticastService.GetIPAddresses().Contains(remote));
            }

            // IPv4 addresses are reachable when on the same subnet.
            if (local.AddressFamily == AddressFamily.InterNetwork && remote.AddressFamily == AddressFamily.InterNetwork)
            {
                var mask = local.GetSubnetMask();
                if (mask != null)
                {
                    var network = IPNetwork.Parse(local, mask);
                    return(network.Contains(remote));
                }

                // A mask of null should not occur. Is the IP address available on the actual machine or are the local and remote addresses switched in the function call?
                return(false);
            }

            // IPv6 link local addresses are reachable when using the same scope id.
            if (local.AddressFamily == AddressFamily.InterNetworkV6 && remote.AddressFamily == AddressFamily.InterNetworkV6)
            {
                if (local.IsIPv6LinkLocal && remote.IsIPv6LinkLocal)
                {
                    return(local.ScopeId == remote.ScopeId);
                }

                // only interested in link local addresses
                return(false);
            }

            // If nothing of the above matched, they are probably not reachable. -> maybe a IPv4 to IPv6 transmission or vice verse.
            return(false);
        }
コード例 #10
0
        public void IPAddresses()
        {
            var addresses = MulticastService.GetIPAddresses().ToArray();

            Assert.AreNotEqual(0, addresses.Length);
        }