/// <summary>
        /// Attempts to send an Internet Control Message Protocol (ICMP) echo message with the specified data buffer to the computer that has the specified IPAddress and receive a corresponding ICMP echo reply message from that computer. This overload allows you to specify a time-out value for the operation and control fragmentation and Time-to-Live values for the ICMP echo message packet.
        /// </summary>
        /// <param name="address">An <see cref="IPAddress"/> that identifies the computer that is the destination for the ICMP echo message.</param>
        /// <param name="timeout">An <see cref="Int32"/> value that specifies the maximum number of milliseconds (after sending the echo message) to wait for the ICMP echo reply message.</param>
        /// <param name="buffer">A <see cref="Byte"/> array that contains data to be sent with the ICMP echo message and returned in the ICMP echo reply message.
        /// The array cannot contain more than 65,500 bytes.</param>
        /// <param name="options">A <see cref="PingOptions"/> object used to control fragmentation and Time-to-Live values for the ICMP echo message packet.</param>
        /// <returns>A <see cref="PingReply"/> object that provides information about the ICMP echo reply message, if one was received, or provides the reason for the failure, if no message was received.
        /// The method will return PacketTooBig if the packet exceeds the Maximum Transmission Unit (MTU). </returns>
        /// <exception cref="ArgumentNullException">address is a null reference (Nothing in Visual Basic).
        /// <para>-or-</para>
        /// buffer is a null reference (Nothing in Visual Basic).</exception>
        /// <exception cref="ArgumentOutOfRangeException">timeout is less than zero.</exception>
        /// <exception cref="ArgumentException">The size of buffer exceeds 65500 bytes.
        /// <para>-or-</para>
        /// address is not a valid IP address.</exception>
        public PingReply Send(IPAddress address, int timeout, byte[] buffer, PingOptions options)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }

            if (buffer.Length > 0xffdc)
            {
                throw new ArgumentException(Properties.Resources.net_invalidPingBufferSize, "buffer");
            }

            if (timeout < 0)
            {
                throw new ArgumentOutOfRangeException("timeout");
            }

            if (address == null)
            {
                throw new ArgumentNullException("address");
            }

            if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
            {
                throw new ArgumentException(Properties.Resources.net_invalid_ip_addr, "address");
            }

            int       a        = BitConverter.ToInt32(address.GetAddressBytes(), 0);
            IPOptions options2 = new IPOptions(options);

            int returned = NativeMethods.IcmpSendEcho(handle, a, buffer, (short)buffer.Length, ref options2, replyBuffer, 0x100ff, timeout);

            if (returned == 0)
            {
                returned = Marshal.GetLastWin32Error();
                if (returned != 0)
                {
                    return(new PingReply((IPStatus)returned));
                }
            }

            return(new PingReply((IcmpEchoReply)Marshal.PtrToStructure(this.replyBuffer, typeof(IcmpEchoReply))));
        }
 internal PingOptions(IPOptions options)
 {
     this.ttl          = 0x80;
     this.ttl          = options.ttl;
     this.dontFragment = (options.flags & 2) > 0;
 }
 internal static extern int IcmpSendEcho(IntPtr icmpHandle, int destinationAddress,
                                         byte[] requestData, short requestSize,
                                         ref IPOptions requestOptions,
                                         IntPtr replyBuffer, int replySize,
                                         int timeout);