void SendIcmpMessageInBackground(UInt32 destinationIPAddress, IcmpMessageType icmpMessageType, IcmpMessageCode icmpMessageCode, byte[] restOfHeader, byte[] data)
        {
            IcmpMessage icmpMessage = new IcmpMessage(destinationIPAddress, icmpMessageType, icmpMessageCode, restOfHeader, data);

            _sendIcmpMessagesInBackgroundQueue.Enqueue(icmpMessage);
            _sendIcmpMessagesInBackgroundEvent.Set();
        }
        ///* this function returns true if ping was success, and false if ping was not successful */
        //bool PingDestinationIPAddress(UInt32 destinationIPAddress)
        //{
        //    byte[] restOfHeader = new byte[4];
        //    UInt16 identifier = 0x0000;
        //    UInt16 sequenceNumber = _nextEchoRequestSequenceNumber++;
        //    restOfHeader[0] = (byte)((identifier << 8) & 0xFF);
        //    restOfHeader[1] = (byte)(identifier & 0xFF);
        //    restOfHeader[2] = (byte)((sequenceNumber << 8) & 0xFF);
        //    restOfHeader[3] = (byte)(sequenceNumber & 0xFF);
        //    /* for data, we will include a simple 8-character array.  we could alternatively send a timestamp, etc. */
        //    byte[] data = System.Text.Encoding.UTF8.GetBytes("abcdefgh");

        //    EchoRequest echoRequest = new EchoRequest(destinationIPAddress, identifier, sequenceNumber, data);
        //    lock (_outstandingEchoRequests)
        //    {
        //        _outstandingEchoRequests.Add(echoRequest);
        //    }

        //    bool echoReplyReceived = false;
        //    try
        //    {
        //        Int64 timeoutInMachineTicks = 1 * TimeSpan.TicksPerSecond; /* wait up to one second for ping to be sent */

        //        /* send ICMP echo request */
        //        SendIcmpMessage(destinationIPAddress, IcmpMessageType.Echo, IcmpMessageCode.None, restOfHeader, data, timeoutInMachineTicks);

        //        /* wait for ICMP echo reply for up to one second */
        //        echoReplyReceived = echoRequest.WaitForResponse(1000);

        //    }
        //    finally
        //    {
        //        /* remove ICMP request from collection */
        //        lock (_outstandingEchoRequests)
        //        {
        //            _outstandingEchoRequests.Remove(echoRequest);
        //        }
        //    }

        //    /* if we did not get a match, return false */
        //    return echoReplyReceived;
        //}

        void SendIcmpMessagesThread()
        {
            while (true)
            {
                _sendIcmpMessagesInBackgroundEvent.WaitOne();

                // if we have been disposed, shut down our thread now.
                if (_isDisposed)
                {
                    return;
                }

                while ((_sendIcmpMessagesInBackgroundQueue != null) && (_sendIcmpMessagesInBackgroundQueue.Count > 0))
                {
                    try
                    {
                        IcmpMessage icmpMessage = (IcmpMessage)_sendIcmpMessagesInBackgroundQueue.Dequeue();
                        SendIcmpMessage(icmpMessage.DestinationIPAddress, icmpMessage.IcmpMessageType, icmpMessage.IcmpMessageCode, icmpMessage.RestOfHeader, icmpMessage.Data, Int64.MaxValue);
                    }
                    catch (InvalidOperationException)
                    {
                        // reply queue was empty
                    }

                    // if we have been disposed, shut down our thread now.
                    if (_isDisposed)
                    {
                        return;
                    }
                }
            }
        }
Example #3
0
        private PingReply SendPrivileged(IPAddress address, int timeout, byte [] buffer, PingOptions options)
        {
            IPEndPoint target = new IPEndPoint(address, 0);
            IPEndPoint client = new IPEndPoint(GetNonLoopbackIP(), 0);

            // FIXME: support IPv6
            using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp)) {
                if (options != null)
                {
                    s.DontFragment = options.DontFragment;
                    s.Ttl          = (short)options.Ttl;
                }
                s.SendTimeout    = timeout;
                s.ReceiveTimeout = timeout;
                // not sure why Identifier = 0 is unacceptable ...
                IcmpMessage send  = new IcmpMessage(8, 0, identifier, 0, buffer);
                byte []     bytes = send.GetBytes();
                s.SendBufferSize = bytes.Length;
                s.SendTo(bytes, bytes.Length, SocketFlags.None, target);

                DateTime sentTime = DateTime.Now;

                // receive
                bytes = new byte [100];
                do
                {
                    EndPoint    endpoint = client;
                    SocketError error    = 0;
                    int         rc       = s.ReceiveFrom(bytes, 0, 100, SocketFlags.None,
                                                         ref endpoint, out error);

                    if (error != SocketError.Success)
                    {
                        if (error == SocketError.TimedOut)
                        {
                            return(new PingReply(null, new byte [0], options, 0, IPStatus.TimedOut));
                        }
                        throw new NotSupportedException(String.Format("Unexpected socket error during ping request: {0}", error));
                    }
                    long rtt          = (long)(DateTime.Now - sentTime).TotalMilliseconds;
                    int  headerLength = (bytes [0] & 0xF) << 2;
                    int  bodyLength   = rc - headerLength;

                    // Ping reply to different request. discard it.
                    if (!((IPEndPoint)endpoint).Address.Equals(target.Address))
                    {
                        long t = timeout - rtt;
                        if (t <= 0)
                        {
                            return(new PingReply(null, new byte [0], options, 0, IPStatus.TimedOut));
                        }
                        s.ReceiveTimeout = (int)t;
                        continue;
                    }

                    IcmpMessage recv = new IcmpMessage(bytes, headerLength, bodyLength);

                    /* discard ping reply to different request or echo requests if running on same host. */
                    if (recv.Identifier != identifier || recv.Type == 8)
                    {
                        long t = timeout - rtt;
                        if (t <= 0)
                        {
                            return(new PingReply(null, new byte [0], options, 0, IPStatus.TimedOut));
                        }
                        s.ReceiveTimeout = (int)t;
                        continue;
                    }

                    return(new PingReply(address, recv.Data, options, rtt, recv.IPStatus));
                } while (true);
            }
        }
Example #4
0
File: Ping.cs Project: vargaz/mono
		private PingReply SendPrivileged (IPAddress address, int timeout, byte [] buffer, PingOptions options)
		{
			IPEndPoint target = new IPEndPoint (address, 0);
			IPEndPoint client = new IPEndPoint (GetNonLoopbackIP (), 0);

			// FIXME: support IPv6
			using (Socket s = new Socket (AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp)) {
				if (options != null) {
					s.DontFragment = options.DontFragment;
					s.Ttl = (short) options.Ttl;
				}
				s.SendTimeout = timeout;
				s.ReceiveTimeout = timeout;
				// not sure why Identifier = 0 is unacceptable ...
				IcmpMessage send = new IcmpMessage (8, 0, identifier, 0, buffer);
				byte [] bytes = send.GetBytes ();
				s.SendBufferSize = bytes.Length;
				s.SendTo (bytes, bytes.Length, SocketFlags.None, target);

				DateTime sentTime = DateTime.Now;

				// receive
				bytes = new byte [100];
				do {
					EndPoint endpoint = client;
					int error = 0;
					int rc = s.ReceiveFrom_nochecks_exc (bytes, 0, 100, SocketFlags.None,
							ref endpoint, false, out error);

					if (error != 0) {
						if (error == (int) SocketError.TimedOut) {
							return new PingReply (null, new byte [0], options, 0, IPStatus.TimedOut);
						}
						throw new NotSupportedException (String.Format ("Unexpected socket error during ping request: {0}", error));
					}
					long rtt = (long) (DateTime.Now - sentTime).TotalMilliseconds;
					int headerLength = (bytes [0] & 0xF) << 2;
					int bodyLength = rc - headerLength;

					// Ping reply to different request. discard it.
					if (!((IPEndPoint) endpoint).Address.Equals (target.Address)) {
						long t = timeout - rtt;
						if (t <= 0)
							return new PingReply (null, new byte [0], options, 0, IPStatus.TimedOut);
						s.ReceiveTimeout = (int) t;
						continue;
					}

					IcmpMessage recv = new IcmpMessage (bytes, headerLength, bodyLength);

					/* discard ping reply to different request or echo requests if running on same host. */
					if (recv.Identifier != identifier || recv.Type == 8) {
						long t = timeout - rtt;
						if (t <= 0)
							return new PingReply (null, new byte [0], options, 0, IPStatus.TimedOut);
						s.ReceiveTimeout = (int) t;
						continue; 
					}

					return new PingReply (address, recv.Data, options, rtt, recv.IPStatus);
				} while (true);
			}
		}
 void SendIcmpMessageInBackground(UInt32 destinationIPAddress, IcmpMessageType icmpMessageType, IcmpMessageCode icmpMessageCode, byte[] restOfHeader, byte[] data)
 {
     IcmpMessage icmpMessage = new IcmpMessage(destinationIPAddress, icmpMessageType, icmpMessageCode, restOfHeader, data);
     _sendIcmpMessagesInBackgroundQueue.Enqueue(icmpMessage);
     _sendIcmpMessagesInBackgroundEvent.Set();
 }
Example #6
0
        public PingReply Send(IPAddress address, int timeout, byte [] buffer, PingOptions options)
        {
            if (address == null)
            {
                throw new ArgumentNullException("address");
            }
            if (timeout < 0)
            {
                throw new ArgumentOutOfRangeException("timeout", "timeout must be non-negative integer");
            }
            if (buffer == null)
            {
                throw new ArgumentNullException("buffer");
            }
            // options can be null.

            IPEndPoint target = new IPEndPoint(address, 0);
            IPEndPoint client = new IPEndPoint(GetNonLoopbackIP(), 0);

            // FIXME: support IPv6
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);

            if (options != null)
            {
                s.DontFragment = options.DontFragment;
                s.Ttl          = (short)options.Ttl;
            }
            s.SendTimeout    = timeout;
            s.ReceiveTimeout = timeout;
            // not sure why Identifier = 0 is unacceptable ...
            IcmpMessage send = new IcmpMessage(8, 0, identifier, 0, buffer);

            byte [] bytes = send.GetBytes();
            s.SendBufferSize = bytes.Length;
            s.SendTo(bytes, bytes.Length, SocketFlags.None, target);

            DateTime sentTime = DateTime.Now;

            // receive
            bytes = new byte [100];
            do
            {
                try {
                    EndPoint endpoint     = client;
                    int      rc           = s.ReceiveFrom(bytes, 100, SocketFlags.None, ref endpoint);
                    long     rtt          = (long)(DateTime.Now - sentTime).TotalMilliseconds;
                    int      headerLength = (bytes [0] & 0xF) << 2;
                    int      bodyLength   = rc - headerLength;

                    if (!((IPEndPoint)endpoint).Address.Equals(target.Address))                       // Ping reply to different request. discard it.
                    {
                        continue;
                    }

                    IcmpMessage recv = new IcmpMessage(bytes, headerLength, bodyLength);
                    if (recv.Identifier != identifier)
                    {
                        continue;                         // ping reply to different request. discard it.
                    }
                    return(new PingReply(address, recv.Data, options, rtt, recv.IPStatus));
                } catch (SocketException ex) {
                    IPStatus stat;
                    switch (ex.SocketErrorCode)
                    {
                    case SocketError.TimedOut:
                        stat = IPStatus.TimedOut;
                        break;

                    default:
                        throw new NotSupportedException(String.Format("Unexpected socket error during ping request: {0}", ex.SocketErrorCode));
                    }
                    return(new PingReply(null, new byte [0], options, 0, stat));
                }
            } while (true);
        }