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; } } } }
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); } }
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); } }
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); }