Next, add another class and its code, you might name it WinsockPingClass. The Main() is in this class.
/// <summary> /// This class implements IPv4 and IPv6 ping. /// </summary> public class WinsockPingClass { /// <summary> /// Displays simple usage information for the ping sample. /// </summary> static void usage() { Console.WriteLine("Usage: Executable_file_name [-a 4 | 6] [-i ttl] [-l bytes] [-n count] destination"); Console.WriteLine(" Options:"); Console.WriteLine(" -a 4 | 6 Forces IPv4 or IPv6"); Console.WriteLine(" -i ttl Indicates the time-to-live (TTL) to set on ping requests"); Console.WriteLine(" -l byte-count Number of bytes to put in ping payload"); Console.WriteLine(" -n count Number of echo requests to send"); Console.WriteLine(" destination Destination address or host name to ping"); Console.WriteLine("...Else default values will be used..."); Console.WriteLine(); } |
Add the Main() code.
/// <summary> /// The main entry point for the application. /// </summary> static void Main(string[ ] args) { System.Diagnostics.Process proc; RawSocketPing pingSocket = null; AddressFamily addressFamily = AddressFamily.Unspecified; string remoteHost = "localhost"; IPAddress remoteAddress = null; int dataSize = 512, ttlValue = 128, sendCount = 4;
usage(); Console.WriteLine();
// Parse the command line for (int i = 0; i < args.Length; i++) { try { if ((args[i][0] == '-') || (args[i][0] == '/')) { switch (Char.ToLower(args[i][1])) { case 'a': // Force to ping over IPv4 or IPv6 int af = System.Convert.ToInt32(args[++i].ToString());
if (af == 4) { addressFamily = AddressFamily.InterNetwork; } else if (af == 6) { addressFamily = AddressFamily.InterNetworkV6; } else { usage(); return; } break; case 'i': // What TTL value to set on ping echo request? ttlValue = System.Convert.ToInt32(args[++i].ToString()); break; case 'l': // How many bytes in the ping echo request payload? dataSize = System.Convert.ToInt32(args[++i].ToString()); break; case 'n': // How many times to send an echo request sendCount = System.Convert.ToInt32(args[++i].ToString()); break; default: usage(); return; } } else { // If argument doesn't start with a '-' or '/' assume its the // hostname we're to ping remoteHost = args[i]; } } catch { usage(); return; } }
// Try to resolve the address or name passed try { IPHostEntry hostEntry = Dns.GetHostEntry(remoteHost);
if (hostEntry.AddressList.Length == 0) { Console.WriteLine("Ping request could not fine host {0}. Please check the name and try again", remoteHost); return; }
if (addressFamily == AddressFamily.Unspecified) { // No preference was specified so take first address remoteAddress = hostEntry.AddressList[0]; } else { // Try to find a resolved address that matches the user selection foreach (IPAddress addr in hostEntry.AddressList) { remoteAddress = addr;
if (remoteAddress.AddressFamily == addressFamily) break; remoteAddress = null; }
if (remoteAddress == null) { Console.WriteLine("Ping request could not fine host {0}. Please check the name and try again", remoteHost); return; } } } catch (SocketException err) { Console.WriteLine("Bad name {0}: {1}", remoteHost, err.Message); return; }
// Get our process ID which we'll use in the ICMP ID field proc = System.Diagnostics.Process.GetCurrentProcess();
try { // Create a RawSocketPing class that wraps all the ping functionality pingSocket = new RawSocketPing( remoteAddress.AddressFamily, ttlValue, dataSize, sendCount, (ushort)proc.Id );
Console.WriteLine("Starting from Main()..."); Console.WriteLine(); // Set the destination address we want to ping Console.WriteLine("Setting the destination address..."); pingSocket.PingAddress = remoteAddress; Console.WriteLine(); // Initialize the raw socket Console.WriteLine("Initializing the raw socket..."); pingSocket.InitializeSocket(); Console.WriteLine(); // Create the ICMP packets to send Console.WriteLine("Creating the ICMP packets to send..."); pingSocket.BuildPingPacket(); Console.WriteLine(); // Actually send the ping request and wait for response Console.WriteLine("Sending the ping request and wait for response..."); pingSocket.DoPing(); } catch (SocketException err) { Console.WriteLine("Socket error occurred: {0}", err.Message); } finally { if (pingSocket != null) pingSocket.Close(); } return; } |
We need to add references to the Protocol.cs so that all the definition defined in the ProtocolHeaderDefinition can be resolved. Select the project folder > Right click mouse > Select Add context menu > Select Existing Item context menu.
![]() |
|
Browse and find the Protocol.cs file created previously. Select the file and click Add.
You can see the Protocol.cs file is included under the project folder as shown in the following Figure.
Next, build the project and make sure there is no error.
Then, run the project. Any error will be thrown by the exception handlers.
The following is the sample output.
The following is a sample output when run at the command prompt.