#include #include #include #ifdef __Lynx__ #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #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); } } } }