/// <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); }
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.GetHostByName(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 { } }