I have two virtual machines in vmware infrastructure (workstation) running Ubuntu 22.04, that are in the same network. With one program I am sending in one virtual machine raw packets, with a MAC that does not fit with any of the computers in the network (is a requirement). In the other virtual machine I can see the raw packets in Wireshark but my C program can not see it. I check the Iptables rules and there is no denied to raw packets. Here is the code I use to open the raw socket and read:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <arpa/inet.h>
#include <linux/filter.h>
#include <fcntl.h>
int main(int arg, char** argv[])
{
int s, stat, cc;
unsigned char buf[ETH_FRAME_LEN];
struct sockaddr_ll saddr;
struct ifreq ifr;
char *interface = "ens33";
s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (s < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
strncpy(ifr.ifr_name, interface, IFNAMSIZ);
if(ioctl(s, SIOGIFINDEX, &ifr))
{
perror("ioctl");
close(s);
exit(EXIT_FAILURE);
}
saddr.sll_family = AF_PACKET;
saddr.sll_ifindex = ifr.ifr_ifindex;
saddr.sll_protocol = htons(ETH_P_ALL);
if (bind(s, (struct sockaddr *)&saddr, sizeof(saddr)))
{
perror("bind");
exit(EXIT_FAILURE);
}
stat = fcntl (s, F_SETFL, O_NONBLOCK);
if (stat < 0)
perror ("bloqueante");
while(1)
{
cc = read (s, buf, sizeof(buf));
// Process the information
}
}
I tried to use libpcap and works, but because of the infrastructure of the system I am not able to change the way the functions are used. I have one function to open the socket and another to read. This functions are used for other modules and it is not a possibility.
I change the MAC and the same problems. The virtual machines can see each other.
Set interface to promiscuous mode to receive packets not bound for it's MAC address.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <linux/if_packet.h>
#include <net/ethernet.h>
#include <arpa/inet.h>
#include <linux/filter.h>
#include <fcntl.h>
int main(int arg, char* argv[])
{
int s, stat;
size_t cc;
unsigned char buf[ETH_FRAME_LEN];
struct sockaddr_ll saddr = {};
struct ifreq ifopts; //for promiscuous mode
struct ifreq ifr = {};
const char *interface = "ens33";
s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (s < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
//Set Promiscuous Mode
strncpy(ifopts.ifr_name, interface, IFNAMSIZ-1);
ioctl(s, SIOCGIFFLAGS, &ifopts);
ifopts.ifr_flags |= IFF_PROMISC;
ioctl(s, SIOCSIFFLAGS, &ifopts);
strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);
if(ioctl(s, SIOGIFINDEX, &ifr))
{
perror("ioctl");
close(s);
exit(EXIT_FAILURE);
}
saddr.sll_family = AF_PACKET;
saddr.sll_ifindex = ifr.ifr_ifindex;
saddr.sll_protocol = htons(ETH_P_ALL);
if (bind(s, (struct sockaddr *)&saddr, sizeof(saddr)))
{
perror("bind");
exit(EXIT_FAILURE);
}
stat = fcntl (s, F_SETFL, O_NONBLOCK);
if (stat < 0)
perror ("bloqueante");
while(true)
{
cc = read (s, buf, sizeof(buf));
// Process the information
}
}