ser*_*0ne 2 .net c# ip network-programming
我有一本名为.NET Programming Network Programming的书,其中包含以下用于在网络堆栈上嗅探IP数据包的代码示例.我从书中复制了代码示例WORD-FOR-WORD,请原谅缺乏风格约定等.
List<string> packets = new List<string>();
public void Run()
{
int len_receive_buf = 4096;
int len_send_buf = 4096;
byte[] receive_buf = new byte[len_receive_buf];
byte[] send_buf = new byte[len_send_buf];
int cout_receive_bytes;
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
socket.Blocking = false;
IPHostEntry IPHost = Dns.GetHostByName(Dns.GetHostName());
socket.Bind(new IPEndPoint(IPAddress.Parse(IPHost.AddressList[0].ToString()), 0));
socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, 1);
byte[] IN = new byte[4] { 1, 0, 0, 0 };
byte[] OUT = new byte[4];
int SIO_RCVALL = unchecked((int)0x98000001);
int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);
while(true)
{
IAsyncResult ar = socket.BeginReceive(receive_buf, 0, len_receive_buf, SocketFlags.None, null, this);
cout_receive_bytes = socket.EndReceive(ar);
Receive(receive_buf, cout_receive_bytes);
}
}
public void Receive(byte[] buf, int len)
{
if(buf[9] == 6)
{
packets.Add(Encoding.ASCII.GetString(buf).Replace("\0", " "));
}
}
Run Code Online (Sandbox Code Playgroud)
我第一次测试这是几年前(甚至在Vista存在之前),我使用的机器是一个32位Windows XP Proferssional平台,其中一个NIC运行在IPv4上.
我现在正试图在64位Windows 7平台上测试一个运行IPv6的网卡,但它无法正常工作.我假设这与IPv6有关.谁能建议我如何有效地解决这个问题?
编辑:这是我尝试运行时遇到的异常...

所以检查:
if(buf[9] == 6)
Run Code Online (Sandbox Code Playgroud)
检查数据包是否为IPv4的TCP是查询IPv6数据包的源地址字段的一部分.对于IPv6,它应该检查偏移6*的"Next Header".当然,现在您还必须首先检查IP版本,以了解是否检查偏移6或偏移9.
对于异常消息,您可能没有以管理员身份运行,您需要在原始套接字上侦听(本机文档,但仍然适用):
要使用SOCK_RAW类型的套接字,需要管理权限.运行使用原始套接字的Winsock应用程序的用户必须是本地计算机上Administrators组的成员,否则原始套接字调用将失败,错误代码为
WSAEACCES.在Windows Vista及更高版本中,在创建套接字时强制访问原始套接字.在早期版本的Windows中,在其他套接字操作期间强制访问原始套接字.
(*)当然,在发现它是TCP数据包之前,可能会有多个IPv6标头可供使用.