summaryrefslogtreecommitdiff
path: root/mcast/mcast.c
diff options
context:
space:
mode:
Diffstat (limited to 'mcast/mcast.c')
-rw-r--r--mcast/mcast.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/mcast/mcast.c b/mcast/mcast.c
new file mode 100644
index 0000000..c1becc5
--- /dev/null
+++ b/mcast/mcast.c
@@ -0,0 +1,159 @@
+#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) ? mhost : "NULL") );
+ 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);
+ }
+ }
+ }
+}