/// <summary> /// Reads an IcmpPacket from the wire using the specified socket from the specified end point /// </summary> /// <param name="socket">The socket to read</param> /// <param name="packet">The packet read</param> /// <param name="ep">The end point read from</param> /// <returns></returns> public virtual bool Read(Socket socket, EndPoint ep, int timeout, out IcmpPacket packet, out int bytesReceived) { const int MAX_PATH = 256; packet = null; bytesReceived = 0; /* * check the parameters * */ if (socket == null) throw new ArgumentNullException("socket"); if (socket == null) throw new ArgumentNullException("ep"); // see if any data is readable on the socket bool success = socket.Poll(timeout * 1000, SelectMode.SelectRead); // if there is data waiting to be read if (success) { // prepare to receive data byte[] bytes = new byte[MAX_PATH]; bytesReceived = socket.ReceiveFrom(bytes, bytes.Length, SocketFlags.None, ref ep); /* * convert the bytes to an icmp packet * */ // packet = IcmpPacket.FromBytes(bytes); } return success; }
/// <summary> /// Writes the IcmpPacket to the wire over the specified socket to the specified end point /// </summary> /// <param name="socket">The socket to write to</param> /// <param name="packet">The packet to write</param> /// <param name="ep">The end point to write to</param> /// <returns></returns> public virtual int Write(Socket socket, IcmpPacket packet, EndPoint ep) { /* * check the parameters * */ if (socket == null) { throw new ArgumentNullException("socket"); } if (socket == null) { throw new ArgumentNullException("packet"); } if (socket == null) { throw new ArgumentNullException("ep"); } // convert the packet to a byte array byte[] bytes = IcmpPacket.GetBytes(packet); // send the data using the specified socket, returning the number of bytes sent int bytesSent = socket.SendTo(bytes, bytes.Length, SocketFlags.None, ep); /* * validate bytes sent * */ return(bytesSent); }
/// <summary> /// Writes the IcmpPacket to the wire over the specified socket to the specified end point /// </summary> /// <param name="socket">The socket to write to</param> /// <param name="packet">The packet to write</param> /// <param name="ep">The end point to write to</param> /// <returns></returns> public virtual int Write(Socket socket, IcmpPacket packet, EndPoint ep) { /* * check the parameters * */ if (socket == null) throw new ArgumentNullException("socket"); if (socket == null) throw new ArgumentNullException("packet"); if (socket == null) throw new ArgumentNullException("ep"); // convert the packet to a byte array byte[] bytes = IcmpPacket.GetBytes(packet); // send the data using the specified socket, returning the number of bytes sent int bytesSent = socket.SendTo(bytes, bytes.Length, SocketFlags.None, ep); /* * validate bytes sent * */ return bytesSent; }
/// <summary> /// Returns an IcmpPacket from an array of bytes /// </summary> /// <param name="bytes"></param> /// <returns></returns> public static IcmpPacket FromBytes(byte[] bytes) { Debug.Assert(bytes != null); IcmpPacket packet = new IcmpPacket(); packet.Type = bytes[0]; packet.Code = bytes[1]; packet.Checksum = BitConverter.ToUInt16(bytes, 2); packet.Identifier = BitConverter.ToUInt16(bytes, 4); packet.SequenceNumber = BitConverter.ToUInt16(bytes, 6); packet.Payload = new byte[bytes.Length - (bytes.Length - 8)]; Array.Copy(bytes, 8, packet.Payload, bytes.Length - 8, packet.Payload.Length); return(packet); }
/// <summary> /// Returns an array of bytes from an IcmpPacket /// </summary> /// <returns></returns> public static byte[] GetBytes(IcmpPacket packet) { Debug.Assert(packet != null); int index = 0; byte[] bytes = new byte[packet.Payload.Length + 8]; byte[] typeBytes = new byte[] { packet.Type }; byte[] codeBytes = new byte[] { packet.Code }; byte[] checksumBytes = BitConverter.GetBytes(packet.Checksum); byte[] idBytes = BitConverter.GetBytes(packet.Identifier); byte[] sequenceBytes = BitConverter.GetBytes(packet.SequenceNumber); // type Array.Copy(typeBytes, 0, bytes, index, typeBytes.Length); index += typeBytes.Length; // code Array.Copy(codeBytes, 0, bytes, index, codeBytes.Length); index += codeBytes.Length; // checksum Array.Copy(checksumBytes, 0, bytes, index, checksumBytes.Length); index += checksumBytes.Length; // identifier Array.Copy(idBytes, 0, bytes, index, idBytes.Length); index += idBytes.Length; // sequence number Array.Copy(sequenceBytes, 0, bytes, index, sequenceBytes.Length); index += sequenceBytes.Length; // payload Array.Copy(packet.Payload, 0, bytes, index, packet.Payload.Length); index += packet.Payload.Length; return(bytes); }
/// <summary> /// Reads an IcmpPacket from the wire using the specified socket from the specified end point /// </summary> /// <param name="socket">The socket to read</param> /// <param name="packet">The packet read</param> /// <param name="ep">The end point read from</param> /// <returns></returns> public virtual bool Read(Socket socket, EndPoint ep, int timeout, out IcmpPacket packet, out int bytesReceived) { const int MAX_PATH = 256; packet = null; bytesReceived = 0; /* * check the parameters * */ if (socket == null) { throw new ArgumentNullException("socket"); } if (socket == null) { throw new ArgumentNullException("ep"); } // see if any data is readable on the socket bool success = socket.Poll(timeout * 1000, SelectMode.SelectRead); // if there is data waiting to be read if (success) { // prepare to receive data byte[] bytes = new byte[MAX_PATH]; bytesReceived = socket.ReceiveFrom(bytes, bytes.Length, SocketFlags.None, ref ep); /* * convert the bytes to an icmp packet * */ // packet = IcmpPacket.FromBytes(bytes); } return(success); }
/// <summary> /// Returns an array of bytes from an IcmpPacket /// </summary> /// <returns></returns> public static byte[] GetBytes(IcmpPacket packet) { Debug.Assert(packet != null); int index = 0; byte[] bytes = new byte[packet.Payload.Length + 8]; byte[] typeBytes = new byte[] {packet.Type}; byte[] codeBytes = new byte[] {packet.Code}; byte[] checksumBytes = BitConverter.GetBytes(packet.Checksum); byte[] idBytes = BitConverter.GetBytes(packet.Identifier); byte[] sequenceBytes = BitConverter.GetBytes(packet.SequenceNumber); // type Array.Copy(typeBytes, 0, bytes, index, typeBytes.Length); index += typeBytes.Length; // code Array.Copy(codeBytes, 0, bytes, index, codeBytes.Length); index += codeBytes.Length; // checksum Array.Copy(checksumBytes, 0, bytes, index, checksumBytes.Length); index += checksumBytes.Length; // identifier Array.Copy(idBytes, 0, bytes, index, idBytes.Length); index += idBytes.Length; // sequence number Array.Copy(sequenceBytes, 0, bytes, index, sequenceBytes.Length); index += sequenceBytes.Length; // payload Array.Copy(packet.Payload, 0, bytes, index, packet.Payload.Length); index += packet.Payload.Length; return bytes; }
/// <summary> /// Returns an IcmpPacket from an array of bytes /// </summary> /// <param name="bytes"></param> /// <returns></returns> public static IcmpPacket FromBytes(byte[] bytes) { Debug.Assert(bytes != null); IcmpPacket packet = new IcmpPacket(); packet.Type = bytes[0]; packet.Code = bytes[1]; packet.Checksum = BitConverter.ToUInt16(bytes, 2); packet.Identifier = BitConverter.ToUInt16(bytes, 4); packet.SequenceNumber = BitConverter.ToUInt16(bytes, 6); packet.Payload = new byte[bytes.Length - (bytes.Length - 8)]; Array.Copy(bytes, 8, packet.Payload, bytes.Length - 8, packet.Payload.Length); return packet; }
private void OnThreadRun(object sender, BackgroundThreadStartEventArgs e) { // const int SOCKET_ERROR = -1; try { string address = (string)e.Args[0]; int timesToPing = (int)e.Args[1]; #region Address Resolution bool isHostName = false; IPAddress ipAddress = null; try { ipAddress = IPAddress.Parse(address); } catch (Exception) { try { ipAddress = Dns.GetHostEntry(address).AddressList[0]; isHostName = true; } catch (Exception ex) { throw ex; } } #endregion // create the source and destination end points IPEndPoint sourceIPEP = new IPEndPoint(IPAddress.Any, 0); IPEndPoint destinationIPEP = new IPEndPoint(ipAddress, 0); EndPoint source = sourceIPEP; EndPoint destination = destinationIPEP; // create an icmp socket Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp); // create an icmp echo packet IcmpEchoPacket packet = new IcmpEchoPacket(); // serialize the packet to a byte array byte[] bytes = IcmpPacket.GetBytes(packet); // create the checksum for the packet based on it's data packet.Checksum = IcmpPacket.CreateChecksum(bytes); // create a packet reader and writer IcmpPacketReader reader = new IcmpPacketReader(); IcmpPacketWriter writer = new IcmpPacketWriter(); // raise the ping started event this.OnPingStarted(this, new PingerEventArgs(address, isHostName, ipAddress, timesToPing)); // ping statistics int packetsSent = 0; int packetsReceived = 0; int[] elapsedTimes = new int[timesToPing]; // now ping the destination X number of times as instructed for (int i = 0; i < timesToPing; i++) { int start = System.Environment.TickCount; int end = 0; int elapsed = 0; try { // send the icmp echo request int bytesSent = writer.Write(socket, packet, destination); packetsSent++; // wait for a response IcmpPacket response; int bytesReceived; bool receivedResponse = reader.Read(socket, source, 1000 /* 1 second timeout */, out response, out bytesReceived); // calculate the end and elapsed time in milliseconds end = System.Environment.TickCount; elapsed = end - start; elapsedTimes[i] = elapsed; if (receivedResponse) { packetsReceived++; } // raise the ping result event this.OnPingResult(this, new PingerResultEventArgs(address, isHostName, ipAddress, timesToPing, !receivedResponse, bytesReceived, elapsed)); } catch (Exception ex) { /* * this should never hit * * raw sockets shouldn't pose a problem when targeting icmp * */ this.OnException(this, new ExceptionEventArgs(ex)); } } // calculate the percentage lost int percentLost = (int)(((double)(packetsSent - packetsReceived) / (double)packetsSent) * 100d); int min = int.MaxValue; int max = int.MinValue; int average = 0; int total = 0; for (int i = 0; i < timesToPing; i++) { if (elapsedTimes[i] < min) { min = elapsedTimes[i]; } if (elapsedTimes[i] > max) { max = elapsedTimes[i]; } total += elapsedTimes[i]; } average = (int)((double)total / (double)timesToPing); PingerStatisticsEventArgs ea = new PingerStatisticsEventArgs( address, isHostName, ipAddress, timesToPing, packetsSent, packetsReceived, packetsSent - packetsReceived, percentLost, min, max, average); this.OnPingStatistics(this, ea); } catch (ThreadAbortException) { } catch (Exception ex) { Debug.WriteLine(ex); this.OnException(this, new ExceptionEventArgs(ex)); } finally { } }