summaryrefslogblamecommitdiffstats
path: root/mcast/mcast.c
blob: 87c05176123a508a131bb19a0770d80114d309d8 (plain) (tree)






















































































                                                                                  
                                    






































































                                                                              
#include <stdio.h>
#include <sys/file.h>
#include <sys/types.h>
#ifdef  __Lynx__
#include <socket.h>
#else
#include <sys/socket.h>
#endif
#include <net/if.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>


#include "mcast_params.h"

#define ROUTERS_TO_HOP  10              //      Keep my traffic in the same subnet


static  struct sockaddr_in addr;
static  int so;
static  char    mhost[100];
static  unsigned long   hostaddr;

int msend(char *buf, int num)
{
  bzero(&addr, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_port = htons((u_short)MCAST_PORT);
  addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);
  if (sendto(so, buf, num, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    if (errno != EAGAIN)
      perror("sendto");
    return 0;
  }
  return 1;
}


int mrecv(char *buf, int num)
{
  socklen_t i;
  int n;

  bzero(&addr, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_port = htons((u_short)MCAST_PORT);
  addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);


  i = sizeof(addr);
  if ((n = recvfrom(so, buf, num, 0, (struct sockaddr *)&addr, &i)) == -1) {
    if (errno != EAGAIN)
      perror("recvfrom");
    return 0;
  }
  return n;
}


#if defined(__rtems__)
int mcast_main(int ac, char **av)
#else
int main(int ac, char **av)
#endif
{
  int yes=1;      
  char line[1024];
  struct ip_mreq imr;
  struct  hostent *h;
  unsigned char mttl;
  int mlen;
  unsigned long long i, j, k;


  if (ac > 1) mlen = atoi(av[1]);
  else       mlen = 0;

  if ((gethostname(mhost, 100) < 0)) {  //  Get the my hostname
    perror("gethostname");
    exit(1);
  }
  printf( "Hostname: %s\n", mhost );
  if (!(h = gethostbyname(mhost))) {    // Get host entry
    perror("gethostbyname");
    exit(1);
  }

  printf( "host=0x%08x\n", *(unsigned int *)h->h_addr );


  printf( "Creating socket\n" );
  if ((so = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
    perror("socket");
    exit(1);
  }

  printf( "Setting SO_REUSEADDR\n" );
  if (setsockopt(so, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
    perror("setsockopt, reuse");
    exit(1);
  }

  printf( "Binding\n" );
  //      Bind to port and address.
  bzero(&addr, sizeof(addr));
  addr.sin_family = AF_INET;
  addr.sin_port = htons((u_short)MCAST_PORT);
  addr.sin_addr.s_addr = INADDR_ANY;
  if (bind(so, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
    perror("bind");
    exit(1);
  }

  printf( "Performing IP_MULTICAST_TTL\n" );
  mttl = ROUTERS_TO_HOP + 1;              //      ttl should be atleast one.
  if (setsockopt(so, IPPROTO_IP, IP_MULTICAST_TTL, &mttl, sizeof(mttl)) < 0) {
    perror("setsockopt, ttl" );
    exit(1);
  }           
  hostaddr = *(unsigned int *)h->h_addr;
  imr.imr_interface.s_addr = htonl(INADDR_ANY);
  // For some reason, this doesn't seem to work.  I suspect it is because
  // the /etc/hosts included with this demo must match the IP of the
  // network interface you want to use.  I couldn't get this to work
  // so gave up.  INADDR_ANY seems to reliably find the NIC. --joel
  // imr.imr_interface.s_addr = hostaddr;
  imr.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR);

  printf( "Performing IP_ADD_MEMBERSHIP\n" );
  if (setsockopt(so, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr)) < 0) {
    perror( "can't join group" );
    close(so);
    exit(1);
  }           

  fcntl(so, F_SETFL, FNDELAY);
  j = k = 0;
  for(i = 1; 1; i++) {
    int     x;
    if (i == 0) j++;
    if (j == 0) k++;
    sleep(1);
    sprintf(line,
      "%s i %" PRId64 ", j %" PRId64 ", k %" PRId64 "", mhost, i, j, k);
    msend(line, strlen(line)+ mlen);
    while ((x = mrecv(line, 500)) > 0) {
      if (addr.sin_addr.s_addr != hostaddr) {
        line[x] = 0;
        printf("Raddr %s recv %s\n", inet_ntoa(addr.sin_addr), line);
      }
    }
  }
}