Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET权限异常中的网络数据包嗅探_C#_.net_Network Programming_Ip - Fatal编程技术网

C# .NET权限异常中的网络数据包嗅探

C# .NET权限异常中的网络数据包嗅探,c#,.net,network-programming,ip,C#,.net,Network Programming,Ip,我有一本名为.NET中的网络编程的书,其中有以下用于嗅探网络堆栈上IP数据包的代码示例。我已经逐字逐句地从书中复制了代码示例,因此请原谅缺乏文体惯例等 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

我有一本名为.NET中的网络编程的书,其中有以下用于嗅探网络堆栈上IP数据包的代码示例。我已经逐字逐句地从书中复制了代码示例,因此请原谅缺乏文体惯例等

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", " "));
    }
}
List packets=newlist();
公开募捐
{
int len_receive_buf=4096;
int len_send_buf=4096;
byte[]receive_buf=新字节[len_receive_buf];
byte[]send_buf=新字节[len_send_buf];
int cout_接收字节;
Socket Socket=新套接字(AddressFamily.InterNetwork,SocketType.Raw,ProtocolType.IP);
socket.Blocking=false;
IPHostEntry IPHost=Dns.GetHostByName(Dns.GetHostName());
绑定(新的IPEndPoint(IPAddress.Parse(IPHost.AddressList[0].ToString()),0));
socket.SetSocketOption(SocketOptionLevel.IP,SocketOptionName.header包括在内,1);
字节[]IN=新字节[4]{1,0,0,0};
字节[]输出=新字节[4];
int-SIO_RCVALL=未选中((int)0x9800001);
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);
接收(接收字节,不能接收字节);
}
}
公共无效接收(字节[]buf,整数len)
{
if(buf[9]==6)
{
packets.Add(Encoding.ASCII.GetString(buf.Replace)(“\0”,”);
}
}
我第一次测试它是在几年前(甚至在Vista出现之前),我使用的机器是一个32位的WindowsXP专业平台,带有运行在IPv4上的NIC

我现在正尝试在64位Windows7平台上测试,该平台带有运行IPv6的NIC,但不起作用。我认为这与IPv6有关。有人能建议我如何有效地解决这个问题吗

编辑:这是我尝试运行时遇到的异常


标题在和之间有显著差异

因此,检查:

if(buf[9] == 6)
它检查数据包是否为TCP for IPv4,并正在查询IPv6数据包的部分源地址字段。对于IPv6,它应该检查偏移量为6*的“下一个标头”。当然,现在您还必须首先检查IP版本,以了解是检查偏移量6还是偏移量9


对于异常消息,您可能不是以管理员身份运行,您需要以管理员身份进行侦听(本机文档,但仍然适用):

使用SOCK_RAW类型的套接字需要管理权限。运行使用原始套接字的Winsock应用程序的用户必须是本地计算机上Administrators组的成员,否则原始套接字调用将失败,错误代码为。在Windows Vista和更高版本上,在创建套接字时强制对原始套接字进行访问。在早期版本的Windows中,在其他套接字操作期间强制执行对原始套接字的访问



(*)当然,在你发现它是一个TCP数据包之前,可能有多个IPv6头需要处理。

我会严肃地质疑任何包含gem(如
IPAddress.Parse(IPHost.AddressList[0].ToString())
-嗯,为什么不干脆
IPHost.AddressList[0]
?@Damien\u我非常同意你的观点@MartinLiversage…请参阅我的上一次编辑。对于例外情况,正如提示所提示的,您需要访问
ErrorCode
属性,以便更好地指导该问题。@Damien_不信者出于某种原因,即使单击该链接也不起作用:-/Hi,感谢发布。代码显然需要更新很多…请参阅我上次编辑的示例异常。感谢您上次编辑。当我以提升的权限运行时,它可以工作(给定正确的IP地址)。-接受答复