Socket is only catching outgoing packets, not inco

2019-02-21 12:47发布

I have based a packet sniffer on this (frequently cited) sample project. After implementing the HTTP packets I have noticed that the only HTTP packets I'm picking up are requests, I'm not receiving any responses.

I have looked at many different sources but since the code used is very often the same I am inclined to think it might be local to myself.

When I look at my logs I see that every packet has my local IP as SourceIP, both for HTTP packets as well as packets that arrive at other ports.

I have provided a working sample here which you can copy-paste into LINQPad and should demonstrate the problem (add the System.Net and System.Net.Socket assemblies). Don't forget to execute LINQPad as administrator to have access to the socket.

This results in hundreds/thousands of entries in the 192.168.0 range with a total of 3 exceptions of IP addresses that refer to my hosting provider (checked using 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
  • Killer e2200 Gigabit Ethernet Controller (NDIS 6.30) - Latest version of driver
    • Installed a standalone network card yesterday, it didn't change anything.

A post's description that came closest to my problem has as solution the working code that I already have.

Why am I only able to trace outbound packets?

3条回答
啃猪蹄的小仙女
2楼-- · 2019-02-21 13:21

Check the address returned by your GetLocalIP(). You may be receiving a loopback ip, in which case you cannot capture packets coming in. Similar issue discussed here.

查看更多
小情绪 Triste *
3楼-- · 2019-02-21 13:32

Did you try looking into your OS / Standalone / Router firewall? It is often overlooked, but Firewalls have different rules for incoming and outgoing connections and that might be the cause of your issues.

查看更多
欢心
4楼-- · 2019-02-21 13:38

As both @Saibal and @Saverio have mentioned: the firewall is the issue. As a temporary solution for now I'm disabling the firewall when the packettracer starts and enabling it back when it stops (not taking an unexpected exit in account).

If you end up here with the same problem then your first result for "disable firewall C#" might be this blogpost. This did not work in my case and instead threw a NotImplementedException. I'm guessing that this is only possibly on Windows XP as this MSDN document indicates.

Luckily there are alternatives for Vista and upwards (only tested on Windows 8.1 but this is supposedly the successor and mentions this).

My code to disable/enable the firewall:

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);
    }
}

An alternative way of writing this is

firewall.FirewallEnabled[NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE] = false;

Sadly, MSDN offers only code samples in C / C++ but you can still take away the gist of it.

Keep in mind that you have to add the Interop.NetFwTypeLib library to your project. You can find it at C:\Windows\SysWOW64\FirewallAPI.dll or the 32bit equivalent.

This is very rudimentary however. In a later stage (this post will get updated whenever I do) I will look into simply adding the program to the firewall's list of exceptions but right now this will have to suffice.

查看更多
登录 后发表回答