tags:

views:

178

answers:

3
+1  Q: 

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 ...

+2  A: 

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
Chris Taylor
No, its bound to an extern IPv4 address, but thx :)
@rielz: Then I would sure change the name of that constant of yours to something else than `LOCALHOST`
Svish
yeah that was not clear, sry
i was afraid that the problem was not my code ... but sniffers like wireshark or ms network monitor are working correctly .. so it should be possible somehow =/
Sniffers use Kernel mode drivers to achieve this, that is not nearly the same thing as Raw sockets. WireShark use WinPcap, Christian, provided a link to the .NET WinPCap interface wrapper.
Chris Taylor
program is running with admin rights, otherwise an exception would be thrown for using a raw socket
@rielz: Admin rights are not the same as kernel mode.
Aaronaught
no, no .. i meant that the program is running under them to use SIO_RCVALL
A: 

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);
Cristian
already tried, doesnt work(I think this field would give you data back for other control codes)
@Christian, I also thought that might be a problem, but I tested with that and the OPs version and on my machine at least, both worked.
Chris Taylor
they say in the comments of that page that raw sockets have some limtations from WinXP SP2 and on
Cristian
my os is win7 enterprise with .net 4
+1  A: 

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

Cristian
sry, i wanted to write something on my own, but maybe ill take a look at it if there is no solution for my code
writing one on your own is great for practicing and for appreciating the great effort behind a library that does what you want when you use it. For quick results the library is a good option
Cristian
@Cristian thats true, but as you said im doing it for practicing ... so i have no really need for some quick results.