Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C#

Network Sniffer and Analyzer Program - Part 1

Rate me:
Please Sign up or sign in to vote.
5.00/5 (6 votes)
20 Oct 2022CPOL5 min read 9.7K   990   31   9
Network Sniffer and Analyzer Program written in C# .NET 6.0 Windows Form (Sharppcap, PacketDotNet)
The program can capture and analyze DNS packets. It can also spoof ARP so that you can sniff Other Users Packets in the network. The program firstly scans the network to find connected devices in the network and then you can choose one of the found devices and sniff the incoming and the outgoing packets for this device.

Introduction

In this article, I will present my program (Network Sniffer and Analyzer) and show you the mechanism of the program by giving a step by step explanation of the code.

Image 1

Image 2

Note: To be able to understand the article, you should have general knowledge of networking and advanced C# knowledge.

Note: To fully explain the program, I will divide the article into several parts.
Each part will contain a full explanation of the functions used in the program. With each part of the article, I will upload a part of the program separately. In the last part of the article, I will upload the final version of the program, of course, after explaining the background and how to use the program.

The sequence of articles will be as follows:

  1. IP address analysis based on subnetmask
  2. Scan the network to get all available devices
  3. Arp Spoofing
  4. Monitor websites browsed through a specific device

Let's begin!

Part 1: IP Address Analysis Based on Subnetsmask

We will first get all the IPs available on the computer, then we will determine the appropriate subnets mask for this IP according to the IP class. We will also extract the Internet ID for this IP, the number of available hosts, the number of available Net IDs as well, the first IP and the last IP in this network. First, we will define the IP class for the given IP.

Generally, to determine the IP class, we need to take the first Number in the IP and analyze the Range to which it belongs. The order of the IP according to the class is as in the following table:

Class Range Subnetmask
A 1-126 \8
B 128-191 \16
C 192-223 \24
D 224-239 _
E 240-255 _

and that can be done as in the following code:

C#
public enum IPClass { A, B, C, D, E, notDetected }

IPClass getIPClass(string IP)
{
    if (!string.IsNullOrEmpty(IP) && IP.Split('.').Length == 4 && 
        !string.IsNullOrEmpty(IP.Split('.').Last()))
    {
        string ipclassstr = IP.Split('.').First();
        int ipclasssnum = int.Parse(ipclassstr);
        if (0 <= ipclasssnum && ipclasssnum <= 126)
        {
            return IPClass.A;
        }
        if (128 <= ipclasssnum && ipclasssnum <= 191)
        {
            return IPClass.B;
        }
        if (192 <= ipclasssnum && ipclasssnum <= 223)
        {
            return IPClass.C;
        }
        if (224 <= ipclasssnum && ipclasssnum <= 239)
        {
            return IPClass.D;
        }
        if (240 <= ipclasssnum && ipclasssnum <= 255)
        {
            return IPClass.E;
        }
    }
    else return IPClass.notDetected;
    return IPClass.notDetected;
}

and the subnet mask:

C#
int getSubnetMaskBitsCount(string ip)
    {
        IPClass iPClass = getIPClass(ip);

        if (iPClass == IPClass.A)
            return 8;
        if (iPClass == IPClass.B)
            return 16;
        if (iPClass == IPClass.C)
            return 24;
        if (iPClass == IPClass.D)
            return 31;
        if (iPClass == IPClass.E)
            return 32;

        return -1;
    }

In the next step, we will extract the net ID for the given IP, the number of available hosts, the number of available net IDs as well, the first IP and the last IP of this network, and this is in a flexible and dynamic way based on the current subnetmask and the number of its bits.

Extract the Net ID Form given IP Address

After finding the default mask value, we will perform AND operation with the given IP address to get the network IP address.
We will take the following IP as an example: ,,192.168.178.112".
As it is clear from the first number in the IP that it belongs to Class C, and this means that the subnet mask is \24 255.255 .255 .0
We will now convert the IP and its subnetmask into bits and calculate the net id through the AND operation:

11000000.10101000.10110010.01110000       (192.168.178.112)
       &
11111111.11111111.11111111.00000000       (255.255 .255 .0)

       ----------------------------------------------

11000000.10101000.10110010.00000000       (192.168.178.0)

That can be done in code as follows:

C#
public string getNetID(string ipadresse, string subnetmask)
  {
      StringBuilder sb = new StringBuilder();

      string[] subMaskValues = subnetmask.Split('.');

      string[] subIpValues = ipadresse.Split('.');

      for (int i = 0; i < subMaskValues.Length; i++)
      {
          if (i == subMaskValues.Length - 1)
              sb.Append((int.Parse(subMaskValues[i]) & 
                         int.Parse(subIpValues[i])).ToString());
          else
          {
              int maskvalue = int.Parse(subMaskValues[i]);
              int ipvalue = int.Parse(subIpValues[i]);
              string str = ((maskvalue & ipvalue).ToString());
              str += ".";
              sb.Append(str);
          }
      }
      return sb.ToString();
  }

Get the Number of Available Hosts

Total Number of Addresses

We can calculate the total number of addresses in a subnet using the following formula:

TNOA( Total number of addresses) = (2^(32 - Current Subnetmask Bits Count))

Max hosts Count

The network and broadcast addresses are not available to be assigned to hosts on the network. So, the number of available addresses that you can assign to hosts is the total number of addresses minus two = (2^(32 - Current Subnetmask Bits Count))-2.

That can be done in code as follows:

C#
int getHostcount(int Current_Subnetmask_Bits_Count)
{
    double resultbits = Math.Max(Math.Pow(2, 
                        (32 - (Current_Subnetmask_Bits_Count))) - 2, 0);

    return (int)resultbits;
}

Get the Number of Available Net IDs

We can calculate the number of Net IDs in a subnet using the following formula:

(2^(IP CLass Standart Subnetmask Bits Count - Current Subnetmask Bits Count))

That can be done in code as follows:

C#
int getNetcount(int IP_CLass_Standart_Subnetmask_Bits_Count,
                int Current_Subnetmask_Bits_Count)
   {
       double resultbits = Math.Max(
                           Math.Pow(
                                2, Current_Subnetmask_Bits_Count -
                                IP_CLass_Standart_Subnetmask_Bits_Count),
                                0);

       return (int)resultbits;
   }

Extract the First IP in the Subnet

Firstly, we need to define four variables:

  • A. for the given IP Class Standard Subnet Mask Bits Count
  • B. the given or current Subnet Mask Bits Count
  • C. Host Part Length = 32 - B
  • D. Subnet Part = B - A

Step 1: Get the Host Part from the given Subnet Mask.

Step 2: Change the Last Bit of the Host Part to 1.

Step 3: If D>0, get the Subnet Part from the Subnet Mask and then Apply the And Operation on the extracted Subnet Part and the equivalent Bits in the IP Address.

Step 4: Convert the Host and the Subnet Part form Binary to Integer.

Step 5: Replace the Host Part in the given IP Address.

Example: Address 192.168.178.112 and as example, we take Subnet Mask 255.255.255.128
IP Address is 192.168.178.112 => IP Class is C =>Standard Subnetmask is \24 255.255.255.0

Step 1: Convert in the example given Subnetmask to bits to get the host Part from it:

    255  .   255  .   255  . 128
 11111111.11111111.11111111.10000000
the Subnet Part(First One) <_ ---------->host part(just the Zeros)

Step 2: Change the Last Bit of the Host Part to 1 => 0000001

Step 3: If D>0, get the Subnet Part from the Subnet Mask and then apply the And operation on the extracted Subnet Part and the equivalent Bits in the IP Adresse => the subnet part is on the index: 25 = 1

                192  .   168  .  178   . 112 
             11000000.10101000.10110010.01110000 
                                        ->the equivalent Bit(the first one(0)) 
so 1 & 0 = 0 => now we add the Host Part 0000001 =>00000001

Step 4: Convert the Host and the Subnet Part form Binary to Integer =>00000001 = 1

Step 5: Replace the Host Part in the given IP Address => 192.168.178.1

That can be done in code as follows:

C#
public string getFirstIpAdresse(string ipadresse,
       int standard_subnet_mask_bits_count, int current_subnet_mask_bits_count,
       string current_subnet_mask_bits)
       {

           int hostlength = 32 - current_subnet_mask_bits_count;

           int subnet_length = current_subnet_mask_bits_count -
                               standard_subnet_mask_bits_count;

           string hostpart = current_subnet_mask_bits.Substring
                             (current_subnet_mask_bits_count, hostlength);

           string ip_bits = ip_to_bit_string(ipadresse);

           StringBuilder stringBuilder = new StringBuilder();

           for (int i = 0; i < hostpart.Length; i++)
           {
               if (i == hostpart.Length - 1) stringBuilder.Append("1");
               else stringBuilder.Append("0");
           }
           string net_id_plus_host = stringBuilder.ToString();

           if (subnet_length > 0)
           {

               string subnet_part = current_subnet_mask_bits.Substring
                             (standard_subnet_mask_bits_count, subnet_length);

               string to_operat_ip_bits = ip_bits.Substring
                      (standard_subnet_mask_bits_count, subnet_length);

            //   var And_operation_result = Convert.ToByte(to_operat_ip_bits, 2) &
            //   Convert.ToByte(subnet_part, 2);

               StringBuilder sb = new StringBuilder();

               for (int i = 0; i < subnet_part.Length; i++)
                   sb.Append(Convert.ToUInt64(to_operat_ip_bits[i].ToString(), 2)
                             & Convert.ToUInt64(subnet_part[i].ToString(), 2));

               for (int i = 0; i < hostpart.Length; i++)
                   if (i == hostpart.Length - 1) sb.Append("1");
                   else sb.Append("0");

               net_id_plus_host = sb.ToString();
           }

           //*****************
           int IPPartsLength = net_id_plus_host.Length / 8;

           string[] ipnewparts = new string[IPPartsLength];

           int j = 0;

           for (int i = 0; i < ipnewparts.Length; i++)
           {
               ipnewparts[i] = net_id_plus_host.Substring(j, 8);
               j = j + 8;
           }

           string[] ipparts = ipadresse.Split('.');

           j = ipparts.Length - 1;
           for (int i = ipnewparts.Length - 1; i >= 0; i--)
           {
               ipparts[j] = Convert.ToInt64(ipnewparts[i], 2).ToString();
               j--;
           }
           StringBuilder stringBuilder1 = new StringBuilder();
           for (int i = 0; i < ipparts.Length; i++)
               if (i == ipparts.Length - 1) stringBuilder1.Append(ipparts[i]);
               else stringBuilder1.Append(ipparts[i] + ".");

           return stringBuilder1.ToString();

           //*****************
       }

Extract the Last IP in the Subnet

To extract the last IP, we follow the same steps as in "the first IP" but we change the second step so that we change all the host bits to 1 except the last bit which we leave as 0 and the code:

C#
public string getLastIpAdresse(string ipadresse,
int standard_subnet_mask_bits_count, int current_subnet_mask_bits_count,
string current_subnet_mask_bits)
       {

           int hostlength = 32 - current_subnet_mask_bits_count;

           int subnet_length = current_subnet_mask_bits_count -
                               standard_subnet_mask_bits_count;

           string hostpart = current_subnet_mask_bits.Substring
                             (current_subnet_mask_bits_count, hostlength);

           string ip_bits = ip_to_bit_string(ipadresse);

           StringBuilder stringBuilder = new StringBuilder();

           for (int i = 0; i < hostpart.Length; i++)
           {
               if (i == hostpart.Length - 1) stringBuilder.Append("0");
               else stringBuilder.Append("1");
           }
           string net_id_plus_host = stringBuilder.ToString();

           if (subnet_length > 0)
           {

               //   string net_id_part = current_subnet_mask_bits.Substring
               //  (standard_subnet_mask_bits_count, net_id_length).PadRight
               //  (net_id_length + hostlength, '0');
               string subnet_part = current_subnet_mask_bits.Substring
                                    (standard_subnet_mask_bits_count, subnet_length);

               string to_operat_ip_bits = ip_bits.Substring
                      (standard_subnet_mask_bits_count, subnet_length);

             //  var And_operation_result = Convert.ToByte(to_operat_ip_bits, 2)
             //  & Convert.ToByte(subnet_part, 2);

               StringBuilder sb = new StringBuilder();

               for (int i = 0; i < subnet_part.Length; i++)
                   sb.Append(Convert.ToUInt64(to_operat_ip_bits[i].ToString(), 2)
                             & Convert.ToUInt64(subnet_part[i].ToString(), 2));

               for (int i = 0; i < hostpart.Length; i++)
                   if (i == hostpart.Length - 1) sb.Append("0");
                   else sb.Append("1");

               net_id_plus_host = sb.ToString();
           }

           //*****************
           int IPPartsLength = net_id_plus_host.Length / 8;

           string[] ipnewparts = new string[IPPartsLength];

           int j = 0;

           for (int i = 0; i < ipnewparts.Length; i++)
           {
               ipnewparts[i] = net_id_plus_host.Substring(j, 8);
               j = j + 8;
           }

           string[] ipparts = ipadresse.Split('.');

           j = ipparts.Length - 1;
           for (int i = ipnewparts.Length - 1; i >= 0; i--)
           {
               ipparts[j] = Convert.ToInt64(ipnewparts[i], 2).ToString();
               j--;
           }
           StringBuilder stringBuilder1 = new StringBuilder();
           for (int i = 0; i < ipparts.Length; i++)
               if (i == ipparts.Length - 1) stringBuilder1.Append(ipparts[i]);
               else stringBuilder1.Append(ipparts[i] + ".");

           return stringBuilder1.ToString();

           //*****************
       }

History

  • 20th October, 2022: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Questionwhy there are IPAnalyser.exe & IPAnalyser.dll ?? is the exe file is a managed code! Pin
Ragheed Al-Tayeb23-Nov-22 2:37
Ragheed Al-Tayeb23-Nov-22 2:37 
Praisevery useful Pin
Southmountain29-Oct-22 7:27
Southmountain29-Oct-22 7:27 
QuestionMissing functions Pin
Salam Y. ELIAS21-Oct-22 22:03
professionalSalam Y. ELIAS21-Oct-22 22:03 
AnswerRe: Missing functions Pin
Ammar Albush 199722-Oct-22 0:22
Ammar Albush 199722-Oct-22 0:22 
QuestionFiles? Pin
Michael Black 202121-Oct-22 6:40
Michael Black 202121-Oct-22 6:40 
AnswerRe: Files? Pin
Ammar Albush 199721-Oct-22 7:41
Ammar Albush 199721-Oct-22 7:41 
QuestionDivision into class Pin
AchLog21-Oct-22 0:59
AchLog21-Oct-22 0:59 
Class A doesn't go up to 127?
Thank You
AnswerRe: Division into class Pin
Ammar Albush 199721-Oct-22 1:33
Ammar Albush 199721-Oct-22 1:33 
GeneralRe: Division into class Pin
AchLog21-Oct-22 2:42
AchLog21-Oct-22 2:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.