Feb. 12, 2007, 8:47 p.m.
posted by vendetta
A Simple Ping Program
The first ICMP application program discussed is a simple version of the ping program that is found on almost all network devices. Ping is an important and fundamental diagnostic tool that tells you whether a network device has network connectivity and can connect to a particular remote device on the network. The ping program uses the ICMP Echo Request packet (Type 8) to send a simple message to a remote host. When the remote host receives the message, it replies with an ICMP Echo Reply packet (Type 0), which contains the original message. Figure demonstrates this transaction.
Because you now have the ICMP class, implementing a simple ping program is a snap. Listing 11.3 is the SimplePing.cs program, which uses ICMP to ping a remote host on the network.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class SimplePing
{
public static void Main (string[] argv)
{
byte[] data = new byte[1024];
int recv;
Socket host = new Socket(AddressFamily.InterNetwork, SocketType.Raw,
ProtocolType.Icmp);
IPEndPoint iep = new IPEndPoint(IPAddress.Parse(argv[0]), 0);
EndPoint ep = (EndPoint)iep;
ICMP packet = new ICMP();
packet.Type = 0x08;
packet.Code = 0x00;
packet.Checksum = 0;
Buffer.BlockCopy(
BitConverter.GetBytes((short)1), 0, packet.Message, 0, 2);
Buffer.BlockCopy(
BitConverter.GetBytes((short)1), 0, packet.Message, 2, 2);
data = Encoding.ASCII.GetBytes("test packet");
Buffer.BlockCopy(data, 0, packet.Message, 4, data.Length);
packet.MessageSize = data.Length + 4;
int packetsize = packet.MessageSize + 4;
UInt16 chcksum = packet.getChecksum();
packet.Checksum = chcksum;
host.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout, 3000);
host.SendTo(packet.getBytes(), packetsize, SocketFlags.None, iep);
try
{
data = new byte[1024];
recv = host.ReceiveFrom(data, ref ep);
} catch (SocketException)
{
Console.WriteLine("No response from remote host");
return;
}
ICMP response = new ICMP(data, recv);
Console.WriteLine("response from: {0}", ep.ToString());
Console.WriteLine(" Type {0}", response.Type);
Console.WriteLine(" Code: {0}", response.Code);
int Identifier = BitConverter.ToInt16(response.Message, 0);
int Sequence = BitConverter.ToInt16(response.Message, 2);
Console.WriteLine(" Identifier: {0}", Identifier);
Console.WriteLine(" Sequence: {0}", Sequence);
string stringData = Encoding.ASCII.GetString(response.Message,
4, response.MessageSize - 4);
Console.WriteLine(" data: {0}", stringData);
host.Close();
}
}
This simple program doesn’t include any of the bells and whistles you may expect from real ping programs. For starters, SimplePing requires that an IP address be used on the command line of the program. (If desired, you can use the Dns.Resolve() method instead of the IPAddress.Parse() method to allow hostnames as well as IP addresses.)
In the first part of the program, an ICMP packet is created, defining the ICMP Type element as 8 and the Code element as 0. This creates an Echo Request packet that uses the Identifier and Sequence elements to track the individual ping packet, and allows you to enter any text into the data element.
Similar to connectionless UDP programs, a time-out value is set for the socket using the SetSocketOption() method. If no ICMP packet is received from the remote host in three seconds, an Exception is thrown and the program exits.
The returned ICMP packet (if one is returned) creates a new ICMP object, which can then be used to determine if the received packet is the match for the sent ICMP packet. The Identifier, Sequence, and data elements of the received packet should match the same values of the sent ICMP packet. If not, you’ve intercepted an ICMP packet from another application running on the same device, and you need to listen for your ICMP packet to be returned.
To compile the SimplePing program, you must include the ICMP.cs program on the csc command line:
csc SimplePing.cs ICMP.cs
Because the Main() method is defined in the SimplePing.cs program, the compiler creates a SimplePing.exe executable file that executes the program.
Testing SimplePing
You can test the SimplePing program by starting a command-prompt window and pinging the local device address. The output shows that you were indeed able to successfully ping yourself:
C:\>SimplePing 127.0.0.1 response from: 127.0.0.1:0 Type 0 Code: 0 Identifier: 1 Sequence: 1 data: test packet C:\>
The next test is to try and ping a nonexistent IP address. This should force the socket time-out feature to kick in and throw an Exception:
C:\>SimplePing 192.168.1.111 No response from remote host C:\>
So far, so good. The last test is to ensure that the ping packets can successfully traverse the network. You can do this by pinging either a device on the Internet or a remote device on your local network:
C:\>SimplePing 192.168.1.2 response from: 192.168.1.2:0 Type 0 Code: 0 Identifier: 1 Sequence: 1 data: test packet C:\>
| Warning |
In these days of high network security, do not be surprised if a ping to a remote device fails. Many sites use firewalls to protect their networks from ping attacks. |
You can use WinDump or Analyzer to watch the ping packets go out and (if all goes well) come back. Each ping packet appears in the trace as a separate ICMP packet on the network.
