Example #1
0
        // Private callback invoked when icmpsendecho APIs succeed.
        private void PingCallback()
        {
            TaskCompletionSource <PingReply> tcs = _taskCompletionSource;

            _taskCompletionSource = null;

            PingReply reply    = null;
            Exception error    = null;
            bool      canceled = false;

            try
            {
                lock (_lockObject)
                {
                    canceled = _canceled;

                    // Parse reply buffer.
                    SafeLocalAllocHandle buffer = _replyBuffer;

                    // Marshals and constructs new reply.
                    if (_ipv6)
                    {
                        Interop.IpHlpApi.Icmp6EchoReply icmp6Reply = Marshal.PtrToStructure <Interop.IpHlpApi.Icmp6EchoReply>(buffer.DangerousGetHandle());
                        reply = CreatePingReplyFromIcmp6EchoReply(icmp6Reply, buffer.DangerousGetHandle(), _sendSize);
                    }
                    else
                    {
                        Interop.IpHlpApi.IcmpEchoReply icmpReply = Marshal.PtrToStructure <Interop.IpHlpApi.IcmpEchoReply>(buffer.DangerousGetHandle());
                        reply = CreatePingReplyFromIcmpEchoReply(icmpReply);
                    }
                }
            }
            catch (Exception e)
            {
                // In case of failure, create a failed event arg.
                error = new PingException(SR.net_ping, e);
            }
            finally
            {
                FreeUnmanagedStructures();
                UnregisterWaitHandle();
                Finish();
            }

            // Once we've called Finish, complete the task
            if (canceled)
            {
                tcs.SetCanceled();
            }
            else if (reply != null)
            {
                tcs.SetResult(reply);
            }
            else
            {
                Debug.Assert(error != null);
                tcs.SetException(error);
            }
        }
Example #2
0
        private static PingReply CreatePingReplyFromIcmp6EchoReply(Interop.IpHlpApi.Icmp6EchoReply reply, IntPtr dataPtr, int sendSize)
        {
            IPAddress address  = new IPAddress(reply.Address.Address, reply.Address.ScopeID);
            IPStatus  ipStatus = (IPStatus)reply.Status;            // The icmpsendecho IP status codes.

            long rtt;

            byte[] buffer;

            rtt = reply.RoundTripTime;
            if (ipStatus == IPStatus.Success)
            {
                // Only copy the data if we succeed w/ the ping operation.
                buffer = new byte[sendSize];
                Marshal.Copy(IntPtrHelper.Add(dataPtr, 36), buffer, 0, sendSize);
            }
            else
            {
                buffer = Array.Empty <byte>();
            }

            return(new PingReply(address, default(PingOptions), ipStatus, rtt, buffer));
        }