user330841
user330841

Reputation: 41

Socket ReceiveAll

I am trying to capture ip packets in c#. Everything is working fine, except that i only get outgoing packets.

My Code:

using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP))
{
    sock.Bind(new IPEndPoint(MYADDRESS, 0));
    sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);
    sock.IOControl(IOControlCode.ReceiveAll, BitConverter.GetBytes(1), null);

    while (true)
    {
        byte[] buffer = new byte[sock.ReceiveBufferSize];
        int count = sock.Receive(buffer);

        // ...
    }
}

The problem is definitely my pc! But maybe there is a workaround ...

Upvotes: 4

Views: 5812

Answers (5)

Chris Taylor
Chris Taylor

Reputation: 53709

I believe the problem is that you are binding to the loopback IP, assuming that 'LOCALHOST' in your code implies 127.0.0.1. Try binding to the IP address of the interface you want to capture the packets for.

I took your code an did a quick test, and definately I see data flowing in both directions, using Windows 7. NB I am running this as Administrator, not sure how well it works otherwise.

  using (Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP))
  {
    sock.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.121"), 0));

    sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true);

    sock.IOControl(IOControlCode.ReceiveAll, BitConverter.GetBytes(1), null);

    while (true)
    {
      byte[] buffer = new byte[sock.ReceiveBufferSize];

      int count = sock.Receive(buffer);
      IpHeader hdr = IpHeader.FromPacket(buffer, count);
      if ((ProtocolType)hdr.Protocol == ProtocolType.Tcp)
      {
        Console.WriteLine("{0} : {1} -> {2}", (ProtocolType)hdr.Protocol, new IPAddress(hdr.SrcAddr).ToString(), new IPAddress(hdr.DestAddr).ToString());
      }
    }
  }

IpHeader is from a library I wrote years ago, I used that to quickly decode the packets to ensure I was seeing data in both directions.

Here is a quick capture from the code above to verify (AA.BB.CC.DD is my public IP)

Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : AA.BB.CC.DD -> 83.221.14.72
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : AA.BB.CC.DD -> 83.221.14.72
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : AA.BB.CC.DD -> 83.221.14.72
Tcp : AA.BB.CC.DD -> 83.221.14.72
Tcp : AA.BB.CC.DD -> 83.221.14.72
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : 83.221.14.72 -> AA.BB.CC.DD
Tcp : AA.BB.CC.DD -> 83.221.14.72

Upvotes: 3

wodzu
wodzu

Reputation: 3172

In my case I had to allow the the vshost.exe in the windows firewall

Upvotes: 2

MEF2A
MEF2A

Reputation: 238

It is likely that that the Windows firewall is blocking incoming packets. Add your program to the firewall exclusions.

Upvotes: 4

Cristian T
Cristian T

Reputation: 2321

What about a different approach like using WinPcap for .Net with SharpPcap (more info)

It provides an API for capturing, injecting, analyzing and building packets using any .NET language such as C# and VB.NET

....sounds more promising

Upvotes: 3

Cristian T
Cristian T

Reputation: 2321

I think the problem is in the IOControl call. To be honest I don't really understand the documentation provided by MSDN about this function but there is an example in codeproject (here) about this topic, and my guess is that by passing null in the last parameter you are not getting the incoming packets. Try this instead:

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

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

Upvotes: 0

Related Questions