/* u_mput.c 
   spedisce una sequenza di 10000 datagram UDP
   diretti all'indirizzo multicast 234.5.6.7
   e alla porta UDP 6001
   */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>

#define INVALID_SOCKET ((int)-1)
#define SOCKET_ERROR   ((int)-1)
#define TRUE  ((int)1)
#define FALSE ((int)0)


#define TEST_ADDR "234.5.6.7"
#define TEST_PORT 6001
#define BUFSIZE   (1024)
#define TTL_VALUE 100


int main()
{
  struct sockaddr_in stLocal, To, From;
  int addr_size;
  char msg[100];
  int socketfd, i, j;
  struct ip_mreq Mreq;
  int reuse, ttl, loopback, ris;

  /* get a datagram socket */
  socketfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (socketfd == INVALID_SOCKET) {
  	printf ("socket() failed, Err: %d \"%s\"\n", errno,strerror(errno));
  	exit(1);
  }

  /* avoid EADDRINUSE error on bind() */ 
  reuse = TRUE;
  ris = setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof(reuse));
  if (ris == SOCKET_ERROR) {
  	printf ("socket() failed, Err: %d \"%s\"\n", errno,strerror(errno));
  }

  /* join the multicast group. */
  Mreq.imr_multiaddr.s_addr = inet_addr(TEST_ADDR);
  Mreq.imr_interface.s_addr = INADDR_ANY;
  ris = setsockopt(socketfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&Mreq, sizeof(Mreq));
  if (ris == SOCKET_ERROR) {
  	printf ("setsockopt() IP_ADD_MEMBERSHIP failed, Err: %d \"%s\"\n", errno,strerror(errno));
  } 

  /* set TTL to traverse up to multiple routers */
  ttl = TTL_VALUE;
  ris = setsockopt(socketfd, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ris, sizeof(ris));
  if (ris == SOCKET_ERROR) {
  	printf ("setsockopt() IP_MULTICAST_TTL failed, Err: %d \"%s\"\n", errno,strerror(errno));
  }

  /* disable loopback */
  loopback = FALSE;
  ris = setsockopt(socketfd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopback, sizeof(loopback));
  if (ris == SOCKET_ERROR) {
  	printf ("setsockopt() IP_MULTICAST_LOOP failed, Err: %d \"$s\"\n", errno,strerror(errno));
  }

  /* assign our destination address */
  To.sin_family      = AF_INET;
  To.sin_addr.s_addr = inet_addr(TEST_ADDR);
  To.sin_port        = htons(TEST_PORT);

  // printf ("Now sending to multicast group: %s\n",TEST_ADDR);
  for (i=0;i<100000;i++) {

  	addr_size = sizeof(struct sockaddr_in);
  	/* send to the multicast address */
  	sprintf(msg,"Message number: %d",i);
      if(i%100==0) {
      	printf ("Now sending msg %d to multicast group: %s\n", i, TEST_ADDR);
      }
      ris = sendto(socketfd, msg, strlen(msg)+1, 0, (struct sockaddr*)&To, addr_size);
      if (ris < 0) {
     		printf ("sendto() failed, Error: %d \"%s\"\n", errno,strerror(errno));
		exit(1);
      }
    
  }

} /* end main() */  

