/**************************************************************/ /* Multicast listener (server) */ /* */ /* Activation using: {program name} {Multicast IP} {port} */ /* {program name} - This program name */ /* {Multicast IP} - The IP address to listen to (Class D) */ /* {port} - The port hnumber to listen on */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* */ /* This is free software released under the GPL license. */ /* See the GNU GPL for details. */ /* */ /* (c) Juan-Mariano de Goyeneche. 1998, 1999. */ /**************************************************************/ #include <stdio.h> /* printf(), snprintf() */ #include <stdlib.h> /* strtol(), exit() */ #include <sys/types.h> #include <sys/socket.h> /* socket(), setsockopt(), bind(), recvfrom(), sendto() */ #include <errno.h> /* perror() */ #include <netinet/in.h> /* IPPROTO_IP, sockaddr_in, htons(), htonl() */ #include <arpa/inet.h> /* inet_addr() */ #include <unistd.h> /* fork(), sleep() */ #include <sys/utsname.h> /* uname() */ #include <string.h> /* memset() */ #define MAXLEN 1024 int main(int argc, char* argv[]) { u_char no = 0; u_int yes = 1; /* Used with SO_REUSEADDR. In Linux both u_int */ /* and u_char are valid. */ int send_s, recv_s; /* Sockets for sending and receiving. */ u_char ttl; struct sockaddr_in mcast_group; struct ip_mreq mreq; struct utsname name; int n; int len; struct sockaddr_in from; char message [MAXLEN+1]; if (argc != 3) { fprintf(stderr, "Usage: %s mcast_group port\n", argv[0]); exit(1); } memset(&mcast_group, 0, sizeof(mcast_group)); mcast_group.sin_family = AF_INET; mcast_group.sin_port = htons((unsigned short int)strtol(argv[2], NULL, 0)); mcast_group.sin_addr.s_addr = inet_addr(argv[1]); if ( (recv_s=socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror ("recv socket"); exit(1); } if (setsockopt(recv_s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { perror("reuseaddr setsockopt"); exit(1); } if (bind(recv_s, (struct sockaddr*)&mcast_group, sizeof(mcast_group)) < 0) { perror ("bind"); exit(1); } /* Preparatios for using Multicast */ mreq.imr_multiaddr = mcast_group.sin_addr; mreq.imr_interface.s_addr = htonl(INADDR_ANY); /* Tell the kernel we want to join that multicast group. */ if (setsockopt(recv_s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) { perror ("add_membership setsockopt"); exit(1); } for (;;) { len=sizeof(from); if ( (n=recvfrom(recv_s, message, MAXLEN, 0, (struct sockaddr*)&from, &len)) < 0) { perror ("recv"); exit(1); } message[n] = '\0'; /* null-terminate string */ printf("%s: Received message from %s, size=%d !!\n", name.nodename, inet_ntoa(from.sin_addr), n); printf("\t%s \n", message); } }