Skip to content

Instantly share code, notes, and snippets.

@cnlohr
Last active March 19, 2024 20:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cnlohr/c30db04f8d48f47eb80aaa13a83655d6 to your computer and use it in GitHub Desktop.
Save cnlohr/c30db04f8d48f47eb80aaa13a83655d6 to your computer and use it in GitHub Desktop.
Read/write raw packets in C in Linux
//Based on https://github.com/cnlohr/lamenet/blob/master/librawp.c
#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <linux/if_packet.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#include <pthread.h>
#include <unistd.h>
int sock_raw;
void * ReceiveThread()
{
printf( "Preparing to receive from socket %d\n", sock_raw );
while(1)
{
uint8_t rbuff[8192];
int rx = recv( sock_raw, rbuff, sizeof( rbuff ), 0 );
printf( "RX: %4d:", rx );
int i;
for( i = 0; i < 20; i++ )
{
printf( "%02x ", rbuff[i] );
}
printf( "\n" );
}
}
int main()
{
const char * interface = "enp10s0";
struct ifreq ifr;
struct sockaddr_ll sa;
size_t if_name_len=strlen(interface);
int ss = 0;
sock_raw = socket( PF_PACKET, SOCK_RAW, htons(ETH_P_ALL) );
if( sock_raw < 0 )
{
fprintf( stderr, "Error: Can't open socket.\n" );
return -1;
}
if (if_name_len<sizeof(ifr.ifr_name)) {
memcpy(ifr.ifr_name,interface,if_name_len);
ifr.ifr_name[if_name_len]=0;
}
else
{
close( sock_raw );
return -1;
}
ioctl( sock_raw, SIOCGIFINDEX, &ifr );
memset( &sa, 0, sizeof( sa ) );
sa.sll_family=PF_PACKET;
sa.sll_protocol = 0x0000;
sa.sll_ifindex = ifr.ifr_ifindex;
sa.sll_hatype = 0;
sa.sll_pkttype = PACKET_HOST;
// Not sure why, this is required for receiving on some systems.
bind( sock_raw,(const struct sockaddr *)&sa, sizeof( sa ) );
ss = setsockopt( sock_raw, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface) );
pthread_t thd;
pthread_create( &thd, 0, ReceiveThread, 0 );
if( ss < 0 )
{
close( sock_raw );
return -1;
}
while(1)
{
struct sockaddr_ll socket_address;
uint8_t my_packet[] = {
0x81, 0x23, 0x45, 0x67, 0x89, 0xac, //dst mac
0x81, 0x23, 0x45, 0x67, 0x89, 0xab, //src mac
10,
0x00, 0x00, 0x00, 0x00, 0x0,
0x00, 0x00, 0x00, 0x00, 0x0,
};
// Setup sending address for packet.
socket_address.sll_ifindex = ifr.ifr_ifindex;
socket_address.sll_halen = ETH_ALEN;
memcpy( socket_address.sll_addr, my_packet+6, 6 );
if (sendto(sock_raw, my_packet, sizeof(my_packet), 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0)
printf("Send failed\n");
sleep(1);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment