用C#的RawSocket实现网络封包监视

用C#的RawSocket实现网络封包监视,第1张

用C#的RawSocket实现网络封包监视,第2张

说起socket编程,你可能会想到QQ和IE,没错。还有很多网络工具,比如在应用层实现的P2P、NetMeeting等应用,也是用socket实现的。Socket是一个网络编程接口,在网络应用层实现。Windows Socket包含了一套系统组件,充分利用了微软Windows消息驱动的特点。Socket规范的1.1版本发布于1993年1月,在Windows9x操作系统中被广泛使用。Socket版(它在Windows平台上的版本是Winsock2.2,也叫Winsock2)发布于1996年5月。Windows NT 5.0及更高版本的Windows系统支持Winsock2。在Winsock2中,支持多种传输协议的原始套接字、重叠I/O模型、服务质量控制等。

介绍了用C#实现的关于原始套接字的一些Windows Sockets编程,以及在此基础上实现的网络数据包监控技术。与Winsock1相比,Winsock2最明显的是支持原始套接字的套接字类型。使用原始套接字,可以将网卡设置为混杂模式。在这种模式下,我们可以接收网络上的IP包,包括目的不是我们自己机器的IP包。通过原有的socket,还可以更自由的控制Windows下的很多协议,控制网络底层的传输机制。

在这个例子中,我以nbyte的名义实现了RawSocket类。BasicClass 空,里面包含了包监听的核心技术。在实现这个类之前,您需要编写一个IP头结构来临时存储一些关于网络数据包的信息:

[StructLayout(LayoutKind。explicit)]
公共结构IP header
{
[field offset(0)]公共字节ip _ verlen//I4位头长度+4位IP版本号
[fieldoffset (1)]公共字节IP _ tos//8位服务类型tos
[field offset(2)]public ushort IP _ total length;//16位数据包总长度(字节)
[field offset(4)]public ushort IP _ ID;//16位ID
[field offset(6)]public ushort IP _ offset;//3位标志位
[字段偏移量(8)]公共字节IP _ TTL//8位生存期TTL
[fieldoffset (9)]公共字节IP _ protocol//8位协议(TCP,UDP,ICMP等。)
[field offset(10)]public ushort IP _ checksum;//16位IP头校验和
[field offset(12)]public uint IP _ srcaddr;//32位源IP地址
[field offset(16)]public uint IP _ destaddr;//32位目标IP地址
}

这样,当每个包到达时,包中的数据流可以通过强制类型转换转换成IPHeader对象。

让我们开始编写RawSocket类。首先,定义几个参数,包括:

发生了私有bool错误;//套接字在接收数据包时是否产生错误
public bool keep running;//Continue
Private static int len _ receive _ buf;//获取的数据流的长度
byte[]receive _ buf _ bytes;//接收字节
私有套接字socket = null//声明套接字

还有一个常数:

const int SIO _ RC vall = unchecked((int)0x 98000001);//监听所有数据包

在这里,SIO_RCVALL表示RawSocket接收所有的数据包,这些数据包将在未来的IOContrl函数中使用。在下面的构造函数中,初始化了一些变量参数:

public socket()//构造函数
{
error _ occurred = false;
len _ receive _ buf = 4096;
receive _ buf _ bytes = new byte[len _ receive _ buf];
}


下面的函数实现了RawSocket的创建,并将其绑定到端点(IPEndPoint: local IP and port):

Void创建并绑定socket(String IP)//建立并绑定socket
{
socket = new socket(address family。互联网工作,SocketType。原始协议类型。IP);
套接字。阻塞=假;//设置套接字非阻塞状态
socket . bind(new IP endpoint(IP address . parse(IP),0));//绑定套接字

if(SetSocketOption()= = false)error _ occurs = true;
}

其中,在句子socket = new socket(地址族。互联网工作,插座式。原始,协议类型。IP);中有3个参数:

第一个参数是设置AddressFamily。关于MSDN的描述是“指定套接字实例解析地址时使用的地址方案”。当你要将socket绑定到IPEndPoint时,需要使用网间成员,即采用IP第4版地址格式,这也是当今大多数socket编程采用的地址族。

第二个参数设置的SocketType是我们使用的原始类型。套接字类型是一种枚举数据类型,原始套接字类型支持对基本传输协议的访问。带有SocketType。Raw,不仅可以与传输控制协议(Tcp)和用户数据报协议(Udp)通信,还可以与互联网消息控制协议(Icmp)和互联网组管理协议(Igmp)通信。发送时,您的应用程序必须提供完整的IP报头。收到的数据报在返回时将保持其IP报头和选项不变。

第三个参数设置ProtocolType,Socket类使用protocoltype枚举数据类型通知Windows Socket API所请求的协议。这里使用的是IP协议,所以协议类型。应该采用IP参数。

位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » 用C#的RawSocket实现网络封包监视

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情