Exemple #1
0
 internal extern static uint Icmp6SendEcho2(SafeCloseIcmpHandle icmpHandle, IntPtr Event, IntPtr apcRoutine, IntPtr apcContext,
     byte[] sourceSocketAddress, byte[] destSocketAddress, [In] SafeLocalAllocHandle data, ushort dataSize, ref IPOptions options, SafeLocalAllocHandle replyBuffer, uint replySize, uint timeout);
Exemple #2
0
        // internal method responsible for sending echo request on win2k and higher

        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 = UnsafeNetInfoNativeMethods.IcmpCreateFile ();
                if (handlePingV4.IsInvalid) {
                    handlePingV4 = null;
                    throw new Win32Exception(); // Gets last error
                }
            }
            else if (ipv6 && handlePingV6 == null) {
                handlePingV6 = UnsafeNetInfoNativeMethods.Icmp6CreateFile();
                if (handlePingV6.IsInvalid) {
                    handlePingV6 = null;
                    throw new Win32Exception(); // Gets last error
                }
            }


            //setup the options
            IPOptions ipOptions = new IPOptions (options);

            //setup the reply buffer
            if (replyBuffer == null) {
                replyBuffer = SafeLocalFree.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);
                }

                //Copy user dfata into the native world
                SetUnmanagedStructures (buffer);

                if (!ipv6) {
                    if (async) {
                        error = (int)UnsafeNetInfoNativeMethods.IcmpSendEcho2 (handlePingV4, pingEvent.SafeWaitHandle, IntPtr.Zero, IntPtr.Zero, (uint)address.m_Address, requestBuffer, (ushort)buffer.Length, ref ipOptions, replyBuffer, MaxUdpPacket, (uint)timeout);
                    }
                    else{
                        error = (int)UnsafeNetInfoNativeMethods.IcmpSendEcho2 (handlePingV4, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, (uint)address.m_Address, requestBuffer, (ushort)buffer.Length, ref ipOptions, replyBuffer, MaxUdpPacket, (uint)timeout);
                    }
                }
                else {                                                   
                    IPEndPoint ep = new IPEndPoint (address, 0);
                    SocketAddress remoteAddr = ep.Serialize ();
                    byte[] sourceAddr = new byte[28];
                    if(async){
                        error = (int)UnsafeNetInfoNativeMethods.Icmp6SendEcho2 (handlePingV6, pingEvent.SafeWaitHandle, IntPtr.Zero, IntPtr.Zero, sourceAddr, remoteAddr.m_Buffer, requestBuffer, (ushort)buffer.Length, ref ipOptions, replyBuffer, MaxUdpPacket, (uint)timeout);
                    }
                    else{
                        error = (int)UnsafeNetInfoNativeMethods.Icmp6SendEcho2 (handlePingV6, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, sourceAddr, remoteAddr.m_Buffer, requestBuffer, (ushort)buffer.Length, ref ipOptions, replyBuffer, MaxUdpPacket, (uint)timeout);
                    }
                }
            }
            catch
            {
                UnregisterWaitHandle();
                throw;
            }

            //need this if something is bogus.
            if (error == 0) {
                error = (int)Marshal.GetLastWin32Error();
                
                // Only skip Async IO Pending error value
                if (async && error == UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING)
                    return null; // Expected async return value
                
                // Cleanup
                FreeUnmanagedStructures();
                UnregisterWaitHandle();

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

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

            if (async) {
                return null;
            }

            FreeUnmanagedStructures ();

            //return the reply
            PingReply reply;
            if (ipv6) {
                Icmp6EchoReply icmp6Reply = (Icmp6EchoReply)Marshal.PtrToStructure(replyBuffer.DangerousGetHandle(), typeof(Icmp6EchoReply));
                reply = new PingReply(icmp6Reply, replyBuffer.DangerousGetHandle(), sendSize);
            }
            else {
                IcmpEchoReply icmpReply = (IcmpEchoReply)Marshal.PtrToStructure(replyBuffer.DangerousGetHandle(), typeof(IcmpEchoReply));
                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;
        }
Exemple #3
0
 internal extern static uint IcmpSendEcho2(SafeCloseIcmpHandle icmpHandle, SafeWaitHandle Event, IntPtr apcRoutine, IntPtr apcContext,
     uint ipAddress, [In] SafeLocalAllocHandle data, ushort dataSize, ref IPOptions options, SafeLocalAllocHandle replyBuffer, uint replySize, uint timeout);
Exemple #4
0
        //cancel pending async requests, close the handles
        private void InternalDispose () {
            disposeRequested = true;

            if (Interlocked.CompareExchange(ref status, Disposed, Free) != Free)
            {
                // Already disposed, or Finish will call Dispose again once Free
                return;
            }

            if (handlePingV4 != null) {
                handlePingV4.Close ();
                handlePingV4 = null;
            }

            if (handlePingV6 != null) {
                handlePingV6.Close ();
                handlePingV6 = null;
            }

            UnregisterWaitHandle();

            if (pingEvent != null) {
                pingEvent.Close();
                pingEvent = null;
            }

            if (replyBuffer != null) {
                replyBuffer.Close();
                replyBuffer = null;
            }

            if (asyncFinished != null) {
                asyncFinished.Close();
                asyncFinished = null;
            }
        }