Receiving raw packets in Linux without pcap

Since there was a lot of interest in my post on sending raw Ethernet packets, this is an example of receiving packets on a raw socket. A compiling version can be found on github: https://gist.github.com/2862515. The application that I developed this for was to receive packets sent to a specific MAC address. The main sections are explained below:

Open raw socket listening for ETHER_TYPE

	if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) {
		perror("listener: socket");	
		return -1;
	}

Set interface to promiscuous mode

	strncpy(ifopts.ifr_name, ifName, IFNAMSIZ-1);
	ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
	ifopts.ifr_flags |= IFF_PROMISC;
	ioctl(sockfd, SIOCSIFFLAGS, &ifopts);

Allow socket to be reused

	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
		perror("setsockopt");
		close(sockfd);
		exit(EXIT_FAILURE);
	}

Bind to device

	if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, IFNAMSIZ-1) == -1)	{
		perror("SO_BINDTODEVICE");
		close(sockfd);
		exit(EXIT_FAILURE);
	}

Receive on socket

	numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL);
	printf("listener: got packet %lu bytes\n", numbytes);

Print the data

	printf("\tData:");
	for (i=0; i<numbytes; i++) printf("%02x:", buf[i]);
	printf("\n");

Close socket

	close(sockfd);
Advertisements

8 thoughts on “Receiving raw packets in Linux without pcap

  1. Hi,
    I have a C-program to capture packets transmitted on an interface (Linux), using the functionalities of the pcap library. I need to change the destination address of these packets (in my C-code), thus providing a different route for transmission of the same. Can you suggest any method of doing so?
    Thanks!

    • Hi,

      I am happy to help, could you explain your problem in a bit more detail? Are you attempting to modify and retransmit received packets?

      Cheers,
      Austin.

      • Yes, thats precisely what I want to do. Through a C-program, I want to modify and redirect the received packets, by changing their destination address.
        For example, there are 4 machines M1, M2, M3, M4, and packets are transmitted from M1 to M2 and then M2 to M3. Now, I want to have a C-program on M2 which will change the destination address of packets received on M2, such that they arrive at M4 instead of the original path of M3. So the new path looks like M1 to M2 and then M2 to M4.

        I have used libpcap library in my C-program to capture packets and extract the contents of the packet fields. I need to know of ANY function/technique that will let me modify the data residing in a packet’s fields.

        I hope I have explained my problem clearly!

  2. I think the recvRawEth.c only work on eth0 regardless of the argument passed by. I got a Linux box with 2 NIC cards, eth1 and eth0.
    when running:
    # recvRawEth eth1
    I see packet comming with the c program stating: “Wrong destination MAC with the mac address of the eth0 nic. While there is no packet yet being sent on eth1 but alot on eth0.

  3. Hi,

    I wanted to extract the vlan-id from the packet received. But I’m not able to. Can you please help me with this

    TIA,
    Beth

  4. Hi,
    I came across your gist when I was looking for code on how to transceive raw ethernet frames.
    What I would like to know what you mean by “allow socket to be reused” and the SO_REUSEADDR flag. Do you mean to allow two sockets to bind to the same network interface?
    Richard

    • Hey Richard,
      Yep your assumption about SO_REUSEADDR is about right, checkout the man page for the official description
      http://man7.org/linux/man-pages/man7/socket.7.html
      Practically, you need the SO_REUSEADDR flag otherwise the starting multiple instances of the application will cause bind to give the annoying “Address already in use” error message.
      Cheers,
      Austin.

      • Out of curiosity, I decided to try running two instances of the application, both binding to the same interface. There was no issue at all, both binded, both instances printing out identical packets received. I get the feeling this flag only really applies to AF_INET/AF_INET6 sockets as opposed to packet sockets.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s