目录
介绍
在本文中,我将介绍我的程序(网络嗅探器和分析器),并通过逐步解释代码来向您展示该程序的机制。
注意:为了能够理解本文,您应该具备网络的一般知识和高级C#知识。
注意:为了充分解释该程序,我将文章分为几个部分。
每个部分都将包含程序中所用功能的完整说明。对于文章的每个部分,我将分别上传程序的一部分。在文章的最后一部分,我将上传该程序的最终版本,当然,在解释了背景和如何使用该程序之后。
文章顺序如下:
- 基于子网掩码的IP地址分析
- 扫描网络以获取所有可用设备
- Arp欺骗
- 监控通过特定设备浏览的网站
让我们开始吧!
第1部分:基于子网掩码的IP地址分析
我们将首先获取计算机上所有可用的IP,然后我们将根据IP类确定此IP的适当子网掩码。我们还将提取此IP的互联网ID、可用主机的数量、可用网络ID的数量、该网络中的第一个IP和最后一个IP。首先,我们将为给定IP定义IP类。
通常,要确定IP类别,我们需要取IP中的第一个数字并分析其所属的范围。根据类的IP顺序如下表所示:
类 | 范围 | 子网掩码 |
A | 1-126 | \8 |
B | 128-191 | \16 |
C | 192-223 | \24 |
D | 224-239 | _ |
E | 240-255 | _ |
这可以按照以下代码完成:
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;
}
和子网掩码:
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;
}
在下一步中,我们将提取给定 IP 的网络 ID、可用主机的数量、可用网络 ID 的数量、该网络的第一个IP和最后一个IP,这是基于当前子网掩码及其位数的灵活动态方式进行的。
提取给定IP地址的网络ID表单
找到默认掩码值后,我们将使用给定的IP地址执行操作以获取网络IP地址。
我们将以下IP为例:”192.168.178.112”。
从IP中的第一个数字可以清楚地看出它属于C类,这意味着子网掩码为\24 255.255 .255 .0
我们现在将IP及其子网掩码转换为位,并通过AND操作符计算网络 id:
11000000.10101000.10110010.01110000 (192.168.178.112)
&
11111111.11111111.11111111.00000000 (255.255 .255 .0)
----------------------------------------------
11000000.10101000.10110010.00000000 (192.168.178.0)
这可以在代码中完成,如下所示:
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();
}
获取可用主机的数量
地址总数
我们可以使用以下公式计算子网中的地址总数:
TNOA( Total number of addresses) = (2^(32 - Current Subnetmask Bits Count))
最大主机数
网络和广播地址不能分配给网络上的主机。因此,您可以分配给主机的可用地址数是地址总数减去2 =(2^(32 -当前子网掩码位计数))-2。
这可以在代码中完成,如下所示:
int getHostcount(int Current_Subnetmask_Bits_Count)
{
double resultbits = Math.Max(Math.Pow(2,
(32 - (Current_Subnetmask_Bits_Count))) - 2, 0);
return (int)resultbits;
}
获取可用网络ID的数量
我们可以使用以下公式计算子网中的网络ID数量:
(2^(IP CLass Standart Subnetmask Bits Count - Current Subnetmask Bits Count))
这可以在代码中完成,如下所示:
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;
}
提取子网中的第一个IP
首先,我们需要定义四个变量:
- A. 对于给定的IP类标准子网掩码位数
- B. 给定或当前子网掩码位数
- C. 主机零件长度 = 32 - B
- D. 子网部分 = B - A
第 1 步:从给定的子网掩码中获取主机部分。
第 2 步:将主机部分的最后一位更改为1。
第 3 步:如果为D>0,则从子网掩码中获取子网部分,然后对提取的子网部分和IP地址中的等效位应用And操作。
第 4 步:将主机和子网部分转换为二进制。
第 5 步:更换给定IP地址中的主机部分。
示例:地址192.168.178.112作为示例,我们采用子网掩码255.255.255.128 IP地址为192.168.178.112 =>IP类为C =>标准子网掩码为\24 255.255.255.0
步骤1:在给定的示例中将子网掩码转换为位以从中获取主机部分:
255 . 255 . 255 . 128
11111111.11111111.11111111.10000000
the Subnet Part(First One) <_ ---------->host part(just the Zeros)
步骤 2:将主机部分的最后一位更改为1 => 0000001
步骤 3:如果为D>0,则从子网掩码中获取子网部分,然后对提取的子网部分和IP地址中的等效位应用And操作 =>子网部分位于索引上: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
步骤 4:将主机和子网部分转换为二进制 =>00000001 = 1
步骤 5:替换给定IP地址中的主机部分=>192.168.178.1
这可以在代码中完成,如下所示:
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();
//*****************
}
提取子网中的最后一个IP
要提取最后一个IP,我们遵循与“第一个IP”相同的步骤,但我们更改了第二步,以便我们将所有主机位更改为1,除了我们保留为0的最后一个位和代码:
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();
//*****************
}
https://www.codeproject.com/Articles/5344688/Network-Sniffer-and-Analyzer-Program-Part-1