Why ethernet packet is not received on destination interface?

455 Views Asked by At

I am running the ethersend.c program at http://hacked10bits.blogspot.co.uk/2011/12/sending-raw-ethernet-frames-in-6-easy.html on Ubuntu 17.04 installed on VirtualBox.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>    /* Must precede if*.h */
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <sys/ioctl.h>

union ethframe
{
  struct
  {
    struct ethhdr    header;
    unsigned char    data[ETH_DATA_LEN];
  } field;
  unsigned char    buffer[ETH_FRAME_LEN];
};

int main(int argc, char **argv) {
  char *iface = "enp0s3";
  unsigned char dest[ETH_ALEN]
           = { 0x08, 0x00, 0x27, 0x1e, 0x7f, 0x5c };
  unsigned short proto = 0x1234;
  unsigned char *data = "hi";
  unsigned short data_len = strlen(data);

  int s;
  if ((s = socket(AF_PACKET, SOCK_RAW, htons(proto))) < 0) {
    printf("Error: could not open socket\n");
    return -1;
  }

  struct ifreq buffer;
  int ifindex;
  memset(&buffer, 0x00, sizeof(buffer));
  strncpy(buffer.ifr_name, iface, IFNAMSIZ);
  if (ioctl(s, SIOCGIFINDEX, &buffer) < 0) {
    printf("Error: could not get interface index\n");
    close(s);
    return -1;
  }
  ifindex = buffer.ifr_ifindex;

  unsigned char source[ETH_ALEN];
  if (ioctl(s, SIOCGIFHWADDR, &buffer) < 0) {
    printf("Error: could not get interface address\n");
    close(s);
    return -1;
  }
  memcpy((void*)source, (void*)(buffer.ifr_hwaddr.sa_data),
         ETH_ALEN);

  union ethframe frame;
  memcpy(frame.field.header.h_dest, dest, ETH_ALEN);
  memcpy(frame.field.header.h_source, source, ETH_ALEN);
  frame.field.header.h_proto = htons(proto);
  memcpy(frame.field.data, data, data_len);

  unsigned int frame_len = data_len + ETH_HLEN;

  struct sockaddr_ll saddrll;
  memset((void*)&saddrll, 0, sizeof(saddrll));
  saddrll.sll_family = PF_PACKET;   
  saddrll.sll_ifindex = ifindex;
  saddrll.sll_halen = ETH_ALEN;
  memcpy((void*)(saddrll.sll_addr), (void*)dest, ETH_ALEN);

  if (sendto(s, frame.buffer, frame_len, 0,
             (struct sockaddr*)&saddrll, sizeof(saddrll)) > 0)
    printf("Success!\n");
  else
    printf("Error, could not send\n");

  close(s);

  return 0;
}

The VM has two interfaces with MAC addresses as mentioned below:

enp0s3 08:00:27:1f:fc:2b
enp0s8 08:00:27:1e:7f:5c

I am sending the frame from enp0s3 to destination 08:00:27:1e:7f:5c, that is, to enp0s8.

When I listen on enp0s3 using tcpdump I can see the packet:

sam@sam:~$ sudo tcpdump -A -i enp0s3
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
16:04:55.868207 08:00:27:1f:fc:2b (oui Unknown) > 08:00:27:1e:7f:5c (oui 
Unknown), ethertype Unknown (0x1234), length 16: 
0x0000:  6869                                     hi
hi

However, when I listen on enp0s8 using tcpdump (where the packet should reach) I can see no output in tcpdump.

Why is the packet not reaching enp0s8?

Edit: enp0s3 was a NAT adapter and enp0s8 was a host-only adapter. Possibly that was causing the problem. Now I added another host-only adapter called enp0s9 and now the communication works intermittently. Why does it not work always?

0

There are 0 best solutions below