예제 #1
0
        /// <summary>根据字符串形式IP地址转为物理地址</summary>
        /// <param name="addr"></param>
        /// <returns></returns>
        public static String IPToAddress(this String addr)
        {
            if (addr.IsNullOrEmpty())
            {
                return(null);
            }

            // 有可能是NetUri
            var p = addr.IndexOf("://");

            if (p >= 0)
            {
                addr = addr.Substring(p + 3);
            }

            // 过滤IPv4/IPv6端口
            if (addr.Contains(":"))
            {
                addr = addr.Substring(0, addr.LastIndexOf(":"));
            }

            IPAddress ip = null;

            if (!IPAddress.TryParse(addr, out ip))
            {
                return(null);
            }

            return(ip.GetAddress());
        }
예제 #2
0
        // Any exceptions that escape synchronously will be caught by the caller and wrapped in a PingException.
        // We do not need to or want to capture such exceptions into the returned task.
        private Task <PingReply> SendPingAsyncCore(IPAddress address, byte[] buffer, int timeout, PingOptions options)
        {
            var tcs = new TaskCompletionSource <PingReply>();

            _taskCompletionSource = tcs;

            _ipv6     = (address.AddressFamily == AddressFamily.InterNetworkV6);
            _sendSize = buffer.Length;

            // Get and cache correct handle.
            if (!_ipv6 && _handlePingV4 == null)
            {
                _handlePingV4 = Interop.IpHlpApi.IcmpCreateFile();
                if (_handlePingV4.IsInvalid)
                {
                    _handlePingV4 = null;
                    throw new Win32Exception();                     // Gets last error.
                }
            }
            else if (_ipv6 && _handlePingV6 == null)
            {
                _handlePingV6 = Interop.IpHlpApi.Icmp6CreateFile();
                if (_handlePingV6.IsInvalid)
                {
                    _handlePingV6 = null;
                    throw new Win32Exception();                     // Gets last error.
                }
            }

            var ipOptions = new Interop.IpHlpApi.IPOptions(options);

            if (_replyBuffer == null)
            {
                _replyBuffer = SafeLocalAllocHandle.LocalAlloc(MaxUdpPacket);
            }

            // Queue the event.
            int error;

            try
            {
                if (_pingEvent == null)
                {
                    _pingEvent = new ManualResetEvent(false);
                }
                else
                {
                    _pingEvent.Reset();
                }

                _registeredWait = ThreadPool.RegisterWaitForSingleObject(_pingEvent, (state, _) => ((Ping)state).PingCallback(), this, -1, true);

                SetUnmanagedStructures(buffer);

                if (!_ipv6)
                {
                    SafeWaitHandle pingEventSafeWaitHandle = _pingEvent.GetSafeWaitHandle();
                    error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                        _handlePingV4,
                        pingEventSafeWaitHandle,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        (uint)address.GetAddress(),
                        _requestBuffer,
                        (ushort)buffer.Length,
                        ref ipOptions,
                        _replyBuffer,
                        MaxUdpPacket,
                        (uint)timeout);
                }
                else
                {
                    IPEndPoint ep = new IPEndPoint(address, 0);
                    SystemNet.Internals.SocketAddress remoteAddr = IPEndPointExtensions.Serialize(ep);
                    byte[] sourceAddr = new byte[28];

                    SafeWaitHandle pingEventSafeWaitHandle = _pingEvent.GetSafeWaitHandle();
                    error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                        _handlePingV6,
                        pingEventSafeWaitHandle,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        sourceAddr,
                        remoteAddr.Buffer,
                        _requestBuffer,
                        (ushort)buffer.Length,
                        ref ipOptions,
                        _replyBuffer,
                        MaxUdpPacket,
                        (uint)timeout);
                }
            }
            catch
            {
                UnregisterWaitHandle();
                throw;
            }

            if (error == 0)
            {
                error = Marshal.GetLastWin32Error();

                // Only skip Async IO Pending error value.
                if (error != Interop.IpHlpApi.ERROR_IO_PENDING)
                {
                    // Cleanup.
                    FreeUnmanagedStructures();
                    UnregisterWaitHandle();

                    throw new Win32Exception(error);
                }
            }

            return(tcs.Task);
        }
예제 #3
0
        internal virtual NbtAddress[] GetHosts()
        {
            try
            {
                _waitResponse = false;

                byte[] bAddrBytes = laddr.GetAddressBytes();

                for (int i = 1; i <= 254; i++)
                {
                    NodeStatusRequest  request;
                    NodeStatusResponse response;

                    byte[] addrBytes =
                    {
                        bAddrBytes[0],
                        bAddrBytes[1],
                        bAddrBytes[2],
                        (byte)i
                    };

                    IPAddress addr = new IPAddress(addrBytes);

                    response = new NodeStatusResponse(new NbtAddress(NbtAddress.UnknownName,
                                                                     addr.GetAddress(), false, 0x20));
                    request      = new NodeStatusRequest(new Name(NbtAddress.AnyHostsName, unchecked (0x20), null));
                    request.Addr = addr;
                    Send(request, response, 0);
                }
            }
            catch (IOException ioe)
            {
                if (_log.Level > 1)
                {
                    Runtime.PrintStackTrace(ioe, _log);
                }
                throw new UnknownHostException(ioe);
            }

            _autoResetWaitReceive = new AutoResetEvent(false);
            _thread = new Thread(this);
            _thread.SetDaemon(true);
            _thread.Start();

            _autoResetWaitReceive.WaitOne();

            List <NbtAddress> result = new List <NbtAddress>();

            foreach (var key in _responseTable.Keys)
            {
                NodeStatusResponse resp = (NodeStatusResponse)_responseTable[key];

                if (resp.Received && resp.ResultCode == 0)
                {
                    foreach (var entry in resp.AddressArray)
                    {
                        if (entry.HostName.HexCode == 0x20)
                        {
                            result.Add(entry);
                        }
                    }
                }
            }

            _responseTable.Clear();

            _waitResponse = true;

            return(result.Count > 0 ? result.ToArray() : null);
        }
예제 #4
0
        // Any exceptions that escape synchronously will be caught by the caller and wrapped in a PingException.
        // We do not need to or want to capture such exceptions into the returned task.
        private Task<PingReply> SendPingAsyncCore(IPAddress address, byte[] buffer, int timeout, PingOptions options)
        {
            var tcs = new TaskCompletionSource<PingReply>();
            _taskCompletionSource = tcs;

            _ipv6 = (address.AddressFamily == AddressFamily.InterNetworkV6);
            _sendSize = buffer.Length;

            // Get and cache correct handle.
            if (!_ipv6 && _handlePingV4 == null)
            {
                _handlePingV4 = Interop.IpHlpApi.IcmpCreateFile();
                if (_handlePingV4.IsInvalid)
                {
                    _handlePingV4 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }
            else if (_ipv6 && _handlePingV6 == null)
            {
                _handlePingV6 = Interop.IpHlpApi.Icmp6CreateFile();
                if (_handlePingV6.IsInvalid)
                {
                    _handlePingV6 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }

            var ipOptions = new Interop.IpHlpApi.IPOptions(options);

            if (_replyBuffer == null)
            {
                _replyBuffer = SafeLocalAllocHandle.LocalAlloc(MaxUdpPacket);
            }

            // Queue the event.
            int error;
            try
            {
                if (_pingEvent == null)
                {
                    _pingEvent = new ManualResetEvent(false);
                }
                else
                {
                    _pingEvent.Reset();
                }

                _registeredWait = ThreadPool.RegisterWaitForSingleObject(_pingEvent, (state, _) => ((Ping)state).PingCallback(), this, -1, true);

                SetUnmanagedStructures(buffer);

                if (!_ipv6)
                {
                    SafeWaitHandle pingEventSafeWaitHandle = _pingEvent.GetSafeWaitHandle();
                    error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                        _handlePingV4,
                        pingEventSafeWaitHandle,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        (uint)address.GetAddress(),
                        _requestBuffer,
                        (ushort)buffer.Length,
                        ref ipOptions,
                        _replyBuffer,
                        MaxUdpPacket,
                        (uint)timeout);
                }
                else
                {
                    IPEndPoint ep = new IPEndPoint(address, 0);
                    Internals.SocketAddress remoteAddr = IPEndPointExtensions.Serialize(ep);
                    byte[] sourceAddr = new byte[28];

                    SafeWaitHandle pingEventSafeWaitHandle = _pingEvent.GetSafeWaitHandle();
                    error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                        _handlePingV6,
                        pingEventSafeWaitHandle,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        sourceAddr,
                        remoteAddr.Buffer,
                        _requestBuffer,
                        (ushort)buffer.Length,
                        ref ipOptions,
                        _replyBuffer,
                        MaxUdpPacket,
                        (uint)timeout);
                }
            }
            catch
            {
                UnregisterWaitHandle();
                throw;
            }

            if (error == 0)
            {
                error = Marshal.GetLastWin32Error();

                // Only skip Async IO Pending error value.
                if (error != Interop.IpHlpApi.ERROR_IO_PENDING)
                {
                    // Cleanup.
                    FreeUnmanagedStructures();
                    UnregisterWaitHandle();

                    throw new Win32Exception(error);
                }
            }

            return tcs.Task;
        }
예제 #5
0
        private PingReply InternalSend(IPAddress address, byte[] buffer, int timeout, PingOptions options, bool async)
        {
            _ipv6     = (address.AddressFamily == AddressFamily.InterNetworkV6) ? true : false;
            _sendSize = buffer.Length;

            // Get and cache correct handle.
            if (!_ipv6 && _handlePingV4 == null)
            {
                _handlePingV4 = Interop.IpHlpApi.IcmpCreateFile();
                if (_handlePingV4.IsInvalid)
                {
                    _handlePingV4 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }
            else if (_ipv6 && _handlePingV6 == null)
            {
                _handlePingV6 = Interop.IpHlpApi.Icmp6CreateFile();
                if (_handlePingV6.IsInvalid)
                {
                    _handlePingV6 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }

            var ipOptions = new Interop.IpHlpApi.IPOptions(options);

            if (_replyBuffer == null)
            {
                _replyBuffer = SafeLocalAllocHandle.LocalAlloc(MaxUdpPacket);
            }

            // Queue the event.
            int error;

            try
            {
                if (async)
                {
                    if (pingEvent == null)
                    {
                        pingEvent = new ManualResetEvent(false);
                    }
                    else
                    {
                        pingEvent.Reset();
                    }

                    _registeredWait = ThreadPool.RegisterWaitForSingleObject(pingEvent, new WaitOrTimerCallback(PingCallback), this, -1, true);
                }

                SetUnmanagedStructures(buffer);

                if (!_ipv6)
                {
                    if (async)
                    {
                        SafeWaitHandle pingEventSafeWaitHandle = pingEvent.GetSafeWaitHandle();
                        error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                            _handlePingV4,
                            pingEventSafeWaitHandle,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            (uint)address.GetAddress(),
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                    else
                    {
                        error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                            _handlePingV4,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            (uint)address.GetAddress(),
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                }
                else
                {
                    IPEndPoint ep = new IPEndPoint(address, 0);
                    Internals.SocketAddress remoteAddr = IPEndPointExtensions.Serialize(ep);
                    byte[] sourceAddr = new byte[28];
                    if (async)
                    {
                        SafeWaitHandle pingEventSafeWaitHandle = pingEvent.GetSafeWaitHandle();
                        error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                            _handlePingV6,
                            pingEventSafeWaitHandle,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            sourceAddr,
                            remoteAddr.Buffer,
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                    else
                    {
                        error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                            _handlePingV6,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            sourceAddr,
                            remoteAddr.Buffer,
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                }
            }
            catch
            {
                UnregisterWaitHandle();
                throw;
            }

            if (error == 0)
            {
                error = Marshal.GetLastWin32Error();

                // Only skip Async IO Pending error value.
                if (async && error == Interop.IpHlpApi.ERROR_IO_PENDING)
                {
                    // Expected async return value.
                    return(null);
                }

                // Cleanup.
                FreeUnmanagedStructures();
                UnregisterWaitHandle();

                if (async || // No IPStatus async errors.
                    error < (int)IPStatus.DestinationNetworkUnreachable || // Min
                    error > (int)IPStatus.DestinationScopeMismatch)    // Max or Out of IPStatus range.
                {
                    throw new Win32Exception(error);
                }

                return(new PingReply((IPStatus)error)); // Synchronous IPStatus errors.
            }

            if (async)
            {
                return(null);
            }

            FreeUnmanagedStructures();

            PingReply reply;

            if (_ipv6)
            {
                Interop.IpHlpApi.Icmp6EchoReply icmp6Reply = Marshal.PtrToStructure <Interop.IpHlpApi.Icmp6EchoReply>(_replyBuffer.DangerousGetHandle());
                reply = new PingReply(icmp6Reply, _replyBuffer.DangerousGetHandle(), _sendSize);
            }
            else
            {
                Interop.IpHlpApi.IcmpEchoReply icmpReply = Marshal.PtrToStructure <Interop.IpHlpApi.IcmpEchoReply>(_replyBuffer.DangerousGetHandle());
                reply = new PingReply(icmpReply);
            }

            // IcmpEchoReply still has an unsafe IntPtr reference into replybuffer
            // and replybuffer was being freed prematurely by the GC, causing AccessViolationExceptions.
            GC.KeepAlive(_replyBuffer);

            return(reply);
        }
예제 #6
0
        private PingReply InternalSend(IPAddress address, byte[] buffer, int timeout, PingOptions options, bool async)
        {
            _ipv6 = (address.AddressFamily == AddressFamily.InterNetworkV6) ? true : false;
            _sendSize = buffer.Length;

            // Get and cache correct handle.
            if (!_ipv6 && _handlePingV4 == null)
            {
                _handlePingV4 = Interop.IpHlpApi.IcmpCreateFile();
                if (_handlePingV4.IsInvalid)
                {
                    _handlePingV4 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }
            else if (_ipv6 && _handlePingV6 == null)
            {
                _handlePingV6 = Interop.IpHlpApi.Icmp6CreateFile();
                if (_handlePingV6.IsInvalid)
                {
                    _handlePingV6 = null;
                    throw new Win32Exception(); // Gets last error.
                }
            }

            var ipOptions = new Interop.IpHlpApi.IPOptions(options);

            if (_replyBuffer == null)
            {
                _replyBuffer = SafeLocalAllocHandle.LocalAlloc(MaxUdpPacket);
            }

            // Queue the event.
            int error;

            try
            {
                if (async)
                {
                    if (pingEvent == null)
                    {
                        pingEvent = new ManualResetEvent(false);
                    }
                    else
                    {
                        pingEvent.Reset();
                    }

                    _registeredWait = ThreadPool.RegisterWaitForSingleObject(pingEvent, new WaitOrTimerCallback(PingCallback), this, -1, true);
                }

                SetUnmanagedStructures(buffer);

                if (!_ipv6)
                {
                    if (async)
                    {
                        SafeWaitHandle pingEventSafeWaitHandle = pingEvent.GetSafeWaitHandle();
                        error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                            _handlePingV4,
                            pingEventSafeWaitHandle,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            (uint)address.GetAddress(),
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                    else
                    {
                        error = (int)Interop.IpHlpApi.IcmpSendEcho2(
                            _handlePingV4,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            (uint)address.GetAddress(),
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                }
                else
                {
                    IPEndPoint ep = new IPEndPoint(address, 0);
                    Internals.SocketAddress remoteAddr = IPEndPointExtensions.Serialize(ep);
                    byte[] sourceAddr = new byte[28];
                    if (async)
                    {
                        SafeWaitHandle pingEventSafeWaitHandle = pingEvent.GetSafeWaitHandle();
                        error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                            _handlePingV6,
                            pingEventSafeWaitHandle,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            sourceAddr,
                            remoteAddr.Buffer,
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                    else
                    {
                        error = (int)Interop.IpHlpApi.Icmp6SendEcho2(
                            _handlePingV6,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            IntPtr.Zero,
                            sourceAddr,
                            remoteAddr.Buffer,
                            _requestBuffer,
                            (ushort)buffer.Length,
                            ref ipOptions,
                            _replyBuffer,
                            MaxUdpPacket,
                            (uint)timeout);
                    }
                }
            }
            catch
            {
                UnregisterWaitHandle();
                throw;
            }

            if (error == 0)
            {
                error = Marshal.GetLastWin32Error();

                // Only skip Async IO Pending error value.
                if (async && error == Interop.IpHlpApi.ERROR_IO_PENDING)
                {
                    // Expected async return value.
                    return null;
                }

                // Cleanup.
                FreeUnmanagedStructures();
                UnregisterWaitHandle();

                if (async // No IPStatus async errors.
                    || error < (int)IPStatus.DestinationNetworkUnreachable // Min
                    || error > (int)IPStatus.DestinationScopeMismatch) // Max or Out of IPStatus range.
                {
                    throw new Win32Exception(error);
                }

                return new PingReply((IPStatus)error); // Synchronous IPStatus errors.
            }

            if (async)
            {
                return null;
            }

            FreeUnmanagedStructures();

            PingReply reply;
            if (_ipv6)
            {
                Interop.IpHlpApi.Icmp6EchoReply icmp6Reply = Marshal.PtrToStructure<Interop.IpHlpApi.Icmp6EchoReply>(_replyBuffer.DangerousGetHandle());
                reply = new PingReply(icmp6Reply, _replyBuffer.DangerousGetHandle(), _sendSize);
            }
            else
            {
                Interop.IpHlpApi.IcmpEchoReply icmpReply = Marshal.PtrToStructure<Interop.IpHlpApi.IcmpEchoReply>(_replyBuffer.DangerousGetHandle());
                reply = new PingReply(icmpReply);
            }

            // IcmpEchoReply still has an unsafe IntPtr reference into replybuffer
            // and replybuffer was being freed prematurely by the GC, causing AccessViolationExceptions.
            GC.KeepAlive(_replyBuffer);

            return reply;
        }