#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#define   MAX 1024
int       SEND = 0, RECEPT = 0, TTL=1;
short int PORT = 31415;
in_addr_t BROADCAST;
int       LEN = 16;
int perreur(char *s)
{
  perror( s );
  exit( 1 );
}
//mark=args
int args(int argc, char* argv[])
{
  char *optliste = "a:p:rs:t:h";
  int   opt;
  while ( ( opt = getopt(argc, argv, optliste )) >=0 ) {
	    switch ( opt ){
	    case 'a' : BROADCAST  = inet_addr(optarg); break;
	    case 's' : SEND   = atoi(optarg);              break;
            case 'r' : RECEPT = 1;                         break; 
	    case 't' : TTL =    atoi(optarg);              break;
	    case 'p' : PORT   = atoi(optarg);              break;
	    case 'h' : printf("\nusage %s : %s", argv[0], optliste);
	    default  : return 0;
	    }
	  }
return 1;
}
//mark=emission
//kwds=setsockopt
void  emission( int sock )
{  char bfr[ 1024 ]="\ndiffusion!";
   struct sockaddr_in adr; 
   unsigned int  broad =1;
   if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broad, sizeof(broad)) < 0)
      perreur("broadcast");

   memset( & adr, 0, sizeof( struct sockaddr_in) );  
   adr.sin_family       = AF_INET;
   adr.sin_addr.s_addr  = BROADCAST;
   adr.sin_port         = htons(PORT); 

   while ( SEND-- ) {
     if ( sendto(sock, bfr, 1024, 0, (struct sockaddr *)&adr, LEN) < 0 )
         perror("send");
     printf(" %d", SEND);
     sleep(1);
  }
}
//mark=reception
//kwds=setsockopt
void  reception( int sock )                                                
{ char bfr[ 1024 ];
  int  nb;
  struct ip_mreq rm;
  struct sockaddr_in adr;
   unsigned int  broadcast=1;
   
 if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0)
  perreur("broadcast");
  
  // plusieurs processus entre par sock :
  if ( setsockopt( sock , SOL_SOCKET, SO_REUSEADDR, (int *)&reuse, sizeof(reuse)) < 0 )
   perreur("reusing problem");
  

  memset( & adr, 0, sizeof( struct sockaddr_in) );  
  adr.sin_family       = AF_INET;
  adr.sin_addr.s_addr  = BROADCAST;//htonl(INADDR_ANY);
  adr.sin_port         = htons(PORT);
  //  
  if ( bind(sock,  (struct sockaddr*) & adr, len ) < 0 )
    perreur("bind");
  // joindre le groupe :
 
  while ( 1 ) {
   
      nb = recvfrom(sock, bfr, 1024, 0, (struct sockaddr *)& adr, &LEN);

      if ( nb > 0 ) printf("%s", bfr);
      else printf("\nerreur!");
      fflush(stdout);
  }
}
//mark=main
//kwds=reception, emission
int  main( int argc, char* argv[] )                                         
{ 
  int sock;
  if ( (sock = socket(PF_INET, SOCK_DGRAM, 0 )) < 0  )
    perreur("socket");

  BROADCAST = inet_addr("192.168.0.255");
 
  if ( ! args( argc, argv ) ) exit( 1 ); 

  if ( RECEPT ) reception( sock);
  if ( SEND   )  emission( sock); 
  
  close(sock);
  return 0;
}
// cut
