Joas
Joas

Reputation: 2016

C# raw socket ARP reply

I am a student trying to learn more about the ARP and sockets in C#

To do this I am trying to send ARP requests and replies using a raw Socket in C#.

I have manually reconstructed an ARP reply in an byte array and I am trying to send it using the Socket.Send method.

static void Main(string[] args)
{
    // Create a raw socket
    var socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Raw);

    // Setup ARP headers
    byte[] buffer = new byte[]
    {
        0x34, 0x97, 0xf6, 0x22, 0x04, 0xe8, // Ethernet Destination mac
        0x70, 0x1c, 0xe7, 0x51, 0x94, 0x0b, // Ethernet source mac
        0x08, 0x06,                         // Type: ARP
        00, 0x01,                           // Hardware type: Ethernet
        0x08, 0x00,                         // Protocol type: IPv4
        0x06,                               // Hardware size: 6
        0x04,                               // Protocol size: 4
        00, 0x02,                           // Opcode: Reply
        0x70, 0x1c, 0xe7, 0x51, 0x94, 0x0b, // Sender mac addr
        0xc0, 0xa8, 0x01, 0x34,             // Sender IP addr 192.168.1.52
        0x34, 0x97, 0xf6, 0x22, 0x04, 0xe8, // Target mac addr
        0xc0, 0xa8, 0x01, 0x01              // Target ip addr 192.168.1.1
    };

    // Send ARP reply
    socket.Send(buffer, buffer.Length, SocketFlags.None);

    Console.ReadKey();
}

When I try to run this code, the application throws a SocketException:

A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied

Tho, to my understanding, I have supplied the destination MAC address in the request.

How should I correctly send an ARP reply(/request) using a Socket?

PS: I know there is probably a library for this, but I think I won't learn much about sockets and ARP when using a library.

Upvotes: 5

Views: 2250

Answers (1)

Joas
Joas

Reputation: 2016

After a while I'd forgotten about this question but got the answer from an article my teacher showed me about Raw Sockets in a WinSock annex on MSDN.

One section of this article is particular interesting regarding the question:

Limitations on Raw Sockets

On Windows 7, Windows Vista, Windows XP with Service Pack 2 (SP2), and Windows XP with Service Pack 3 (SP3), the ability to send traffic over raw sockets has been restricted in several ways:

  • TCP data cannot be sent over raw sockets.
  • UDP datagrams with an invalid source address cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped. This change was made to limit the ability of malicious code to create distributed denial-of-service attacks and limits the ability to send spoofed packets (TCP/IP packets with a forged source IP address).
  • A call to the bind function with a raw socket for the IPPROTO_TCP protocol is not allowed.

UDP datagrams with an invalid source address cannot be sent over raw sockets. The IP source address for any outgoing UDP datagram must exist on a network interface or the datagram is dropped. This change was made to limit the ability of malicious code to create distributed denial-of-service attacks and limits the ability to send spoofed packets (TCP/IP packets with a forged source IP address).

So the simple answer to this question is: Sending packets like this with plain C# .net Framework is not possible.

For anyone who does want to send packets using C#: You can use the sharppcap library.

Upvotes: 6

Related Questions