#include "multicast.h" #include /* functions declarations */ int CreateMcastSocket(); void chat(int McastSock); void sendMessage(int inSock,int outSock,int *FLAG); void getMessage(int inSock, int outSock); void map_mcast_address(char * session_numb); static void printdate(int); char GroupIPaddress[MAX_LEN];/* multicast group IP address */ int UDPport; /* port number */ u_char TimeToLive; /* ttl value */ main(int argc,char *argv[]) { int McastSock; int session_num; /* parse the command line to get the multicast group address */ if (argc != 2) { printf("Usage: go session_number\n"); exit(1); } else map_mcast_address(argv[1]); system("date > /dev/tty"); signal(SIGINT, printdate); McastSock = CreateMcastSocket(); joinGroup(McastSock, GroupIPaddress); chat(McastSock); leaveGroup(McastSock, GroupIPaddress); close(McastSock); } /* This functions: allocates a socket for getting the group multicast messages */ int CreateMcastSocket() { int s,length,err; u_char loop; /* variable used to enable/disable loopback */ struct sockaddr_in groupHost; /* multicast group host info structure */ /* Get the multicast group host information */ groupHost.sin_family=AF_INET; groupHost.sin_port=htons(UDPport); groupHost.sin_addr.s_addr = htonl(INADDR_ANY); /* Allocate a UDP socket and set the multicast options */ if ((s = socket(PF_INET,SOCK_DGRAM, 0)) < 0) { printf("can't create socket: \n", sys_errlist[errno]); exit(-1); } /* allow multipule processes to bind to same multicast port */ reusePort(s); /* bind the UDP socket to the mcast address to recv messages from the group */ if((bind(s,(struct sockaddr *) &groupHost, sizeof(groupHost))== -1)) { printf("error in bind\n"); exit(2); } /* allow multicast datagrams to be transmitted to any site anywhere value to ttl set according to the value put in "TimeToLive" variable */ setTTLvalue(s,&TimeToLive); /* disable or enable loopback according to value stored in the "loop" variable loopback. a value of 0 means disabling and 1 means enabling loopback by default, loopback is enabled */ loop = 1;/*enable loopback*/ setLoopback(s,loop); return s; } /* This functions takes care of the actual sending and recieving of messages with the group. It takes input from the STDINPUT and sends the message to the group and it reads messages sent by the group from the socket and displays them to the STDOUTPUT */ void chat(int McastSock) { fd_set rfds,rfds_copy; struct timeval wait; int DONE=FALSE; int len; int nb=0; /* set the bits corresponding to STDIN and the socket to be monitored */ FD_ZERO(&rfds); FD_ZERO(&rfds_copy); FD_SET(0,&rfds); FD_SET(McastSock,&rfds); len = McastSock +1; /* set the monitoring frequency to 1 second */ wait.tv_sec = 1; wait.tv_usec = 0; printf("type in message to be sent to the group followed by ENTER\n"); printf("hit CTRL-D to quit from the group \n"); /* monitor the socket and STDIN to get/send messages from/to the group */ while(!DONE) { #if defined(SUNOS4) || defined(IRIX5) bcopy(&rfds,&rfds_copy,len); #elif defined(SOLARIS2) memcpy(&rfds_copy,&rfds,len); #endif nb = select(len,&rfds_copy,(fd_set *) 0,(fd_set *) 0,&wait); if (nb<0) { printf("error in select \n"); exit(-1); } else if (nb > 0) { if(FD_ISSET(0,&rfds_copy)) sendMessage(0,McastSock,&DONE); if(FD_ISSET(McastSock,&rfds_copy)) getMessage(McastSock, 1); } } } /* This function reads the input from STDIN and sends it to the group */ void sendMessage(int inSock,int outSock,int *flag) { char sendBuf[MAX_LEN]; int bytes=0; struct sockaddr_in dest; #if defined(SUNOS4) || defined(IRIX5) bzero(sendBuf,MAX_LEN); #elif defined(SOLARIS2) memset(sendBuf, '\0', MAX_LEN); #endif bytes = read(inSock,sendBuf,MAX_LEN); if (bytes < 0) { printf("error in reading from STDIN \n"); exit(-1); } else if(bytes == 0){ *flag = TRUE; dest.sin_family = AF_INET; dest.sin_port = UDPport; dest.sin_addr.s_addr = inet_addr(GroupIPaddress); if ( sendto(outSock,"WAHAB",5,0,(struct sockaddr *) &dest, sizeof(dest)) < 0 ) { printf("error in sendto \n"); exit(-1); } }else /* send the message to the group */ { dest.sin_family = AF_INET; dest.sin_port = UDPport; dest.sin_addr.s_addr = inet_addr(GroupIPaddress); if ( sendto(outSock,sendBuf,bytes,0,(struct sockaddr *) &dest, sizeof(dest)) < 0 ) { printf("error in sendto \n"); exit(-1); } } } /* Get the multicast message sent by the group and print out to STDOUT */ void getMessage(int inSock, int outSock) { int bytes=0; char recvBuf[MAX_LEN]; #if defined(SUNOS4) || defined(IRIX5) bzero(recvBuf,MAX_LEN); #elif defined(SOLARIS2) memset(recvBuf,'\0',MAX_LEN); #endif bytes = recv(inSock,recvBuf,MAX_LEN,0); if (bytes < 0) { printf("error in reading from multicast socket\n"); exit(-1); } else if(bytes == 0) printf("zero bytes read\n"); else if (bytes == 5) { if (strcmp("WAHAB", recvBuf) == 0) printf("got wahab"); system("date > /dev/tty"); exit(0); } else /* print the message to STDOUT */ { if (write(outSock,recvBuf,bytes) < 0) { printf("error in write to STDOUT \n"); exit(-1); } } } /* This function maps the session number to the multicast address */ void map_mcast_address(char * session_numb) { char s[20]; #if defined(SUNOS4) || defined(IRIX5) bzero(GroupIPaddress,64); #elif defined(SOLARIS2) memset(GroupIPaddress,'\0',64); #endif strcpy(GroupIPaddress,MULTICAST_ADDRESS_BASE); strcat(GroupIPaddress,session_numb); UDPport = MULTICAST_PORT_BASE + atoi(session_numb); TimeToLive = DEFAULT_MULTICAST_TTL_VALUE; /* diagnostic message */ fprintf(stderr,"process joining multicast group %s:%d \n", GroupIPaddress, UDPport); } static void printdate(int signo) { printf("\nreceived interrupt\n" ); system("date > /dev/tty"); exit(0); }