2014-02-23 84 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爲傳入連接允許的程序列表中,它的工作與防火牆啓用爲好。這是非常好的進展。 –