Exemple #1
0
        public static PingReply Send(IPAddress srcAddress, IPAddress destAddress, int timeout = 1500, byte[] buffer = null, PingOptions po = null)
        {
            if (destAddress == null || destAddress.AddressFamily != AddressFamily.InterNetwork || destAddress.Equals(IPAddress.Any))
            {
                throw new ArgumentException();
            }

            //Defining pinvoke args
            var source      = srcAddress == null ? 0 : BitConverter.ToUInt32(srcAddress.GetAddressBytes(), 0);
            var destination = BitConverter.ToUInt32(destAddress.GetAddressBytes(), 0);
            var sendbuffer  = buffer ?? new byte[] { };
            var options     = new Interop.Option {
                Ttl   = (po == null ? (byte)255 : (byte)po.Ttl),
                Flags = (po == null ? (byte)0 : po.DontFragment ? (byte)0x02 : (byte)0) //0x02
            };
            var fullReplyBufferSize = Interop.ReplyMarshalLength + sendbuffer.Length;   //Size of Reply struct and the transmitted buffer length.



            var allocSpace = Marshal.AllocHGlobal(fullReplyBufferSize); // unmanaged allocation of reply size. TODO Maybe should be allocated on stack

            try {
                DateTime start      = DateTime.Now;
                var      nativeCode = Interop.IcmpSendEcho2Ex(
                    Interop.IcmpHandle,       //_In_      HANDLE IcmpHandle,
                    default(IntPtr),          //_In_opt_  HANDLE Event,
                    default(IntPtr),          //_In_opt_  PIO_APC_ROUTINE ApcRoutine,
                    default(IntPtr),          //_In_opt_  PVOID ApcContext
                    source,                   //_In_      IPAddr SourceAddress,
                    destination,              //_In_      IPAddr DestinationAddress,
                    sendbuffer,               //_In_      LPVOID RequestData,
                    (short)sendbuffer.Length, //_In_      WORD RequestSize,
                    ref options,              //_In_opt_  PIP_OPTION_INFORMATION RequestOptions,
                    allocSpace,               //_Out_     LPVOID ReplyBuffer,
                    fullReplyBufferSize,      //_In_      DWORD ReplySize,
                    timeout                   //_In_      DWORD Timeout
                    );
                TimeSpan duration = DateTime.Now - start;
                var      reply    = (Interop.Reply)Marshal.PtrToStructure(allocSpace, typeof(Interop.Reply)); // Parse the beginning of reply memory to reply struct

                byte[] replyBuffer = null;
                if (sendbuffer.Length != 0)
                {
                    replyBuffer = new byte[sendbuffer.Length];
                    Marshal.Copy(allocSpace + Interop.ReplyMarshalLength, replyBuffer, 0, sendbuffer.Length); //copy the rest of the reply memory to managed byte[]
                }

                if (nativeCode == 0) //Means that native method is faulted.
                {
                    return(new PingReply(nativeCode, reply.Status, new IPAddress(reply.Address), duration));
                }
                else
                {
                    return(new PingReply(nativeCode, reply.Status, new IPAddress(reply.Address), reply.RoundTripTime, replyBuffer));
                }
            } finally {
                Marshal.FreeHGlobal(allocSpace); //free allocated space
            }
        }
Exemple #2
0
		/// <summary>
		///     Sends a ping using IcmpSendEcho2Ex function in Iphlpapi.dll. Use this method when you need to specify a source
		///     interface for a ping otherwise use .NET ping implementation.
		/// </summary>
		/// <param name="srcAddress">The IPv4 source address on which to issue the echo request.</param>
		/// <param name="destAddress">The IPv4 destination of the echo request.</param>
		/// <param name="timeout">The time, in milliseconds, to wait for replies.</param>
		/// <param name="buffer">A buffer that contains data to send in the request.</param>
		/// <param name="po">IP header options for the request.</param>
		/// <exception cref="ArgumentNullException"></exception>
		/// <exception cref="FormatException">When the destination address is no valid IpV4 address or not defining a specific IP.</exception>
		public static PingReply SendPing(IPAddress srcAddress, IPAddress destAddress, int timeout = 5000, byte[] buffer = null, PingOptions po = null)
		{
			if (destAddress == null)
				throw new ArgumentNullException("destAddress");
			if (destAddress.AddressFamily != AddressFamily.InterNetwork || srcAddress.AddressFamily != AddressFamily.InterNetwork || destAddress.Equals(IPAddress.Any))
				throw new FormatException();

			//Defining p invoke arguments.
			var source = srcAddress == null ? 0 : BitConverter.ToUInt32(srcAddress.GetAddressBytes(), 0);
			var destination = BitConverter.ToUInt32(destAddress.GetAddressBytes(), 0);
			var sendbuffer = buffer ?? new byte[] {};
			var options = new Interop.Option
						{
							Ttl = (po == null ? (byte) 255 : (byte) po.Ttl),
							Flags = (po == null ? (byte) 0 : po.DontFragment ? (byte) 0x02 : (byte) 0) //0x02
						};
			var fullReplyBufferSize = Interop.ReplyMarshalLength + sendbuffer.Length; //Size of Reply structure plus the transmitted buffer length.



			var allocSpace = Marshal.AllocHGlobal(fullReplyBufferSize); // unmanaged allocation of reply size. TODO Maybe should be allocated on stack
			try
			{
				DateTime start = DateTime.Now;
				var nativeCode = Interop.IcmpSendEcho2Ex(
					Interop.IcmpHandle, //_In_      HANDLE IcmpHandle,
					default(IntPtr), //_In_opt_  HANDLE Event,
					default(IntPtr), //_In_opt_  PIO_APC_ROUTINE ApcRoutine,
					default(IntPtr), //_In_opt_  PVOID ApcContext
					source, //_In_      IPAddr SourceAddress,
					destination, //_In_      IPAddr DestinationAddress,
					sendbuffer, //_In_      LPVOID RequestData,
					(short) sendbuffer.Length, //_In_      WORD RequestSize,
					ref options, //_In_opt_  PIP_OPTION_INFORMATION RequestOptions,
					allocSpace, //_Out_     LPVOID ReplyBuffer,
					fullReplyBufferSize, //_In_      DWORD ReplySize,
					timeout //_In_      DWORD Timeout
					);
				TimeSpan duration = DateTime.Now - start;
				var reply = (Interop.Reply) Marshal.PtrToStructure(allocSpace, typeof (Interop.Reply)); // Parse the beginning of reply memory to reply structure

				byte[] replyBuffer = null;
				if (sendbuffer.Length != 0)
				{
					replyBuffer = new byte[sendbuffer.Length];
					Marshal.Copy(allocSpace + Interop.ReplyMarshalLength, replyBuffer, 0, sendbuffer.Length); //copy the rest of the reply memory to managed byte[]
				}

				if (nativeCode == 0) //Means that native method is faulted.
					return new PingReply(nativeCode, reply.Status, new IPAddress(reply.Address), duration);
				else
					return new PingReply(nativeCode, reply.Status, new IPAddress(reply.Address), reply.RoundTripTime, replyBuffer);
			}
			finally
			{
				Marshal.FreeHGlobal(allocSpace); //free allocated space
			}
		}