0

I had been learning how to use raw sockets in python.

Raw sockets in python can be used to send any arbitrary binary data, to any particular interface, without any other details such as MAC address or IP address.

For example, consider the following piece of code:

import socket
sock = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(3))
sock.bind(('lo',0))
sock.send('This is a sample Raw Socket Code'.encode())
sock.close()

When this is script is executed as a root user, we can capture a packet in Wireshark (or any sniffer) in the loopback interface (since I've bound the socket to 'lo'), that contains the binary string of the above text, and nothing else (of course, this is a malformed packet).

Thing is, I can't find out an implementation of this use case in C. Every implementation of raw sockets in C that I can find, deals with some kind of address. The sendto() requires the argument (struct sockaddr*), which is a generic version of (struct sockaddr_ll*) or (struct sockaddr_in*), which eventually requires an address.

How can we make an implementation of the above use case in C? I know we can straight away use python implementation, as it is available. But I'm curious to know how to implement in C.

  • You can do this with setsockopt, see this answer https://stackoverflow.com/a/14478657/1182653 – Viktor Latypov Nov 13 '20 at 15:34
  • Does this answer your question? [bind socket to network interface](https://stackoverflow.com/questions/14478167/bind-socket-to-network-interface) – Viktor Latypov Nov 13 '20 at 15:34
  • Using setsockopt is to bind to the interface. I'm able to do do that... but unable to send any arbitrary data through the interface – user143962 Nov 17 '20 at 12:13

1 Answers1

1

You can use following code for that

int send(int fd, int ifindex, const uint8_t* buf, size_t len) {
    struct sockaddr_ll to;
    struct sockaddr* to_ptr = (sockaddr*)&to;
    to.sll_family = AF_PACKET;
    to.sll_ifindex = ifindex;
    to.sll_halen = 6;
    memcpy(&to.sll_addr, buf, 6);
    int ret = sendto(fd, buf, len, 0, to_ptr, sizeof(to));
    return ret;
}

where

  • fd - socket id
  • ifindex - ifindex of the interface you want to use for sending
  • buf - is a buffer with a formed ethernet frame
  • len - len of the buffer
Pavel
  • 11
  • 3