2014-02-23 47 views
10

我在this (frequently cited) sample project上基于数据包嗅探器。在实现了HTTP数据包之后,我注意到我唯一正在拾取的HTTP数据包是请求,我没有收到任何响应。套接字只捕获传出数据包,不传入数据包

我已经看过很多不同的来源,但由于使用的代码经常是相同的,我倾向于认为它可能是本地的自己。

当我查看我的日志时,我发现每个数据包都有本地IP为SourceIP,这两个数据包都用于HTTP数据包以及到达其他端口的数据包。

我提供了一个工作示例here,您可以将其复制粘贴到LINQPad中并显示问题(添加System.NetSystem.Net.Socket程序集)。不要忘记以管理员身份执行LINQPad以访问套接字。

这会导致192.168.0范围内的数百/数千个条目,其中涉及我的托管提供商的IP地址总共有3个例外(使用nslookup进行检查)。

private readonly byte[] _data = new byte[4096]; 
private Socket _mainSocket; 

public void Capture() 
{ 
    _mainSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); 
    _mainSocket.Bind(new IPEndPoint(GetLocalIP(), 0)); 

    var byTrue = new byte[] {1, 0, 0, 0}; 
    var byOut = new byte[] {1, 0, 0, 0}; 

    _mainSocket.IOControl(IOControlCode.ReceiveAll, byTrue, byOut); 

    _mainSocket.EnableBroadcast = true; 
    _mainSocket.BeginReceive(_data, 0, _data.Length, SocketFlags.None, OnReceive, null); 
} 

private void OnReceive(IAsyncResult ar) 
{ 
    SocketError error; 
    var received = _mainSocket.EndReceive(ar, out error); 
    Parse(_data, received); 
    _mainSocket.BeginReceive(_data, 0, _data.Length, SocketFlags.None, OnReceive, null); 
} 

private void Parse(byte[] data, int size) 
{ 
    var packet = new IPHeader(data, size); 
    Console.WriteLine (packet.SourceIP.ToString()); 
} 
  • 的Windows 8.1
  • 杀手E2200千兆以太网控制器(NDIS 6.30) - 驱动
    • 安装独立网卡昨日的最新版本,它并没有改变任何东西。

A post的是最接近于我的问题描述的解决方案,我已经有工作代码。

为什么我只能跟踪出站数据包?

回答

0

由于@Saibal和@Saverio都提到过:防火墙是问题所在。暂时的解决方案是,当数据包跟踪器启动时禁用防火墙,并在停止时启用它(不会意外退出帐户)。

如果你在这里遇到同样的问题,那么你的第一个结果“禁用防火墙C#”可能是this blogpost。这在我的情况下不起作用,而是扔了NotImplementedException。我猜测这只可能在Windows XP上,因为this MSDN document表示。

幸运的是,有Vista和更高版本的替代品(只在Windows 8.1上测试,但this被认为是继任者,并提到了这一点)。

我的代码以禁用/启用防火墙:

private static readonly Type policyType = 
          Type.GetTypeFromProgID("HNetCfg.FwPolicy2"); 
private static readonly INetFwPolicy2 firewall = 
         (INetFwPolicy2) Activator.CreateInstance(policyType); 

private void DisableFirewall() 
{ 
    var firewallEnabled = firewall.get_FirewallEnabled(
           NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE); 
    if (firewallEnabled) 
    { 
      firewall.set_FirewallEnabled(
         NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE, false); 
    } 
} 

写这个的另一种方法是

firewall.FirewallEnabled[NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE] = false; 

可悲的是,MSDN只提供code samples in C/C++,但你仍然可以带走它的要点。

请记住,您必须将Interop.NetFwTypeLib库添加到您的项目。 \的Windows \ Syswow64资料\ FirewallAPI.dll或32位等价的:你可以在Ç找到它。

这是非常简陋但是。在后一阶段(每当我做这个职位将得到更新),我会考虑简单地添加程序例外的防火墙的名单,但现在这将有足够。

5

你试过看看你的OS/Standalone/Router防火墙吗? 它经常被忽略,但防火墙对传入和传出连接有不同的规则,这可能是您问题的原因。

+0

[看起来你是对的](http://stackoverflow.com/questions/21972478/socket-is-only-catching-outgoing-packets-not-incoming-ones#comment33438735_22051702)。我从来没有想过要关掉它,看看会发生什么,我只是在看设置。 –

+1

我很高兴我的帮助:) –

1

检查GetLocalIP()返回的地址。您可能正在接收环回IP,在这种情况下,您无法捕获进入的数据包。类似问题讨论here

+0

的IP返回的'192.168.0.199'。 –

+0

啊!它的防火墙。关闭防火墙使其工作正常。需要弄清楚防火墙所需的配置以使事情发挥作用。为了快速测试禁用防火墙。至少对我的作品:) – Saibal

+0

事实上,它似乎也来这里工作。当我添加LINQPad为传入连接允许的程序列表中,它的工作与防火墙启用为好。这是非常好的进展。 –