The FindMask Program



The FindMask Program

The FindMask program uses another ICMP message type to automatically discover the subnet mask of the subnet the device is connected to. This section describes the ICMP Subnet Request packet type, along with the FindMask.cs program, which can determine the subnet mask of the local network.

The Subnet Request Packet

One of the extended ICMP types is the Subnet Request packet (ICMP Type 17). It can query devices on a network to determine what the network subnet mask is. Figure shows the layout of the Subnet Request packet. Its Identifier and Sequence fields are similar to the Echo Request packet. Each packet must have unique Identifier and Sequence values to distinguish it from other Subnet Request packets sent out by the device.

Click To expand
Figure: The ICMP Subnet Request packet format

After the Identifier and Sequence field comes a 4-byte integer field that identifies the subnet. The Subnet Request packet places all zeros in this field. A responding device on the network will replace the zeros with the appropriate value for the subnet. Because the

value is returned as a long integer, you will want to convert it to an IPAddress object for easier reading. The IPAddress constructor can do this:

ICMP response = new ICMP(data, recv);
long answer = BitConverter.ToUInt32(response.Data, 4);
IPAddress netmask = new IPAddress(answer);

The BitConverter class extracts the 4-byte value from the received ICMP packet and convert it to a long integer value. The long integer value can create a new IPAddress object.

Listing 11.6, the FindMask.cs program broadcasts a Subnet Request ICMP packet on the local subnet. If there are any devices configured to respond to the ICMP packet, they should return an answer.

Listing 11.6: The FindMask.cs program
Start example
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class FindMask
{
  public static void Main ()
  {
   byte[] data = new byte[1024];
   int recv;
   Socket host = new Socket(AddressFamily.InterNetwork,
      SocketType.Raw, ProtocolType.Icmp);
   IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, 0);
   EndPoint ep = (EndPoint)iep;
   ICMP packet = new ICMP();
   packet.Type = 0x11;
   packet.Code = 0x00;
   packet.Checksum = 0;
   Buffer.BlockCopy(BitConverter.GetBytes(1), 0, packet.Message, 0, 2);
   Buffer.BlockCopy(BitConverter.GetBytes(1), 0, packet.Message, 2, 2);
   Buffer.BlockCopy(BitConverter.GetBytes(0), 0, packet.Message, 4, 4);
   packet.MessageSize = 8;
   int packetsize = packet.MessageSize + 4;
   UInt16 chksm = packet.getChecksum();
   packet.Checksum = chksm;
   host.SetSocketOption(SocketOptionLevel.Socket,
              SocketOptionName.ReceiveTimeout, 3000);
   host.SetSocketOption(SocketOptionLevel.Socket,
              SocketOptionName.Broadcast, 1);
   host.SendTo(packet.getBytes(), packetsize, SocketFlags.None, iep);
   try
   {
     data = new byte[1024];
     recv = host.ReceiveFrom(data, ref ep);
   } catch (SocketException)
   {
     Console.WriteLine("Unable to determine subnet mask for this subnet");
     return;
   }
   ICMP response = new ICMP(data, recv);
   Console.WriteLine("Received an ICMP type {0} packet", response.Type);
   long answer = BitConverter.ToUInt32(response.Message, 4);
   IPAddress netmask = new IPAddress(answer);
   Console.WriteLine("The subnet mask for this subnet is: {0}",
     netmask.ToString());
  }
}
End example

Similar to the other ICMP programs presented in this chapter, the FindMask.cs program must be compiled with the ICMP.cs class file:

csc FindMask.cs ICMP.cs

The FindMask program first builds an ICMP Subnet Request packet by creating an ICMP object and filling in the appropriate elements in the class. The subnet field is set to zero for the request and will be filled in by the responding network device.

Because you will want the program to terminate cleanly if no response is received, the ReceiveTimeout socket option is set to a reasonable value. Also, this program is using IP broadcasting to send the request out to all devices on the subnet, so the Broadcast socket option must also be set:

host.SetSocketOption(SocketOptionLevel.Socket,
   SocketOptionName.ReceiveTimeout, 3000);
host.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);

After the broadcast packet is sent, the ReceiveFrom() method is called, waiting for a response from a device on the network. When a response is received, the subnet mask address is extracted and converted to an IPAddress object.

Testing FindMask.cs

To test the FindMask program, just open a command-prompt window and run the program. If one or more devices on your subnet respond to the request, you will see the result displayed:

C:\>FindMask
Received an ICMP type 18 packet
The subnet mask for this subnet is: 255.255.252.0
C:\>

It’s possible that there aren’t any devices on your network that will respond to the Type 17 ICMP packet. It’s also possible that a network device may respond to your ICMP packet with an ICMP error packet of a different type. If you receive anything other than a type 18 packet, a device on the network is sending you a different ICMP packet.

What’s more interesting than the output is watching what happens behind the scenes on the network. You can use WinDump or Analyzer to watch how many (if any) devices respond to your request. Listing 11.7 shows a sample output from the WinDump program when running the FindMask program.

Listing 11.7: The WinDump output from the FindMask program
Start example
C:\>windump -X icmp
windump    listening on\Device\Packet_El90x1
13:21:49.576074 192.168.1.32 > 255.255.255.255: icmp: address mask request
0x0000  4500 0020 b355 0000 8001 6c55 c0a8 0120    E....U....lU..}.
0x0010  ffff ffff 1100 ecff 0100 0100 0000 0000    ................
13:21:49.576203 192.168.1.149 > 192.168.1.32: icmp: address mask is 0xfffffc00
0x0000  4500 0020 6103 0000 ff01 23ff c0a8 0195    E...a.....#...}.
0x0010  c0a8 0120 1200 effe 0100 0100 ffff fc00    ..}.............
0x0020  0000 0000 0000 0000 0000 0000 0000       ..............
13:21:49.576236 192.168.1.143 > 192.168.1.32: icmp: address mask is 0xfffffc00
0x0000  4500 0020 8db8 0000 ff01 f74f c0a8 018f    E..........O..}.
0x0010  c0a8 0120 1200 effe 0100 0100 ffff fc00    ..}.............
0x0020  0000 0000 0000 0000 0000 0000 0000       ..............
13:21:49.576320 192.168.1.5 > 192.168.1.32: icmp: address mask is 0xfffffc00
0x0000  4500 0020 de96 0000 3c01 6afc c0a8 0105    E.......<.j...|.
0x0010  c0a8 0120 1200 effe 0100 0100 ffff fc00    ..}.............
0x0020  0000 0000 0000 0000 0000 0000 0000 0000    ................
0x0030  0000 0000 0000                 ......
408 packets received by filter
0 packets dropped by kernel
C:\>
End example

On this particular subnet, three separate devices responded to the Subnet Request broadcast. As expected, they all returned the same subnet mask value.

 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows