source: network-demos/mcast/mcast.c @ 046d88c

4.11network-demos-4-10-branchnetwork-demos-4-9-branch
Last change on this file since 046d88c was 046d88c, checked in by Joel Sherrill <joel.sherrill@…>, on 09/19/07 at 21:52:02

2007-09-19 Joel Sherrill <joel.sherrill@…>

  • ChangeLog?, Makefile, README, init.c, listener.c, mcast.c, mcast_params.h, mcast_route.c, rootfs/etc/host.conf, rootfs/etc/hosts: New files.
  • Property mode set to 100644
File size: 3.8 KB
Line 
1#include <stdio.h>
2#include <sys/file.h>
3#include <sys/types.h>
4#ifdef  __Lynx__
5#include <socket.h>
6#else
7#include <sys/socket.h>
8#endif
9#include <net/if.h>
10#include <sys/ioctl.h>
11#include <netinet/in.h>
12#include <arpa/inet.h>
13#include <netdb.h>
14#include <errno.h>
15#include <stdlib.h>
16#include <inttypes.h>
17#include <string.h>
18
19
20#include "mcast_params.h"
21
22#define ROUTERS_TO_HOP  10              //      Keep my traffic in the same subnet
23
24
25static  struct sockaddr_in addr;
26static  int so;
27static  char    mhost[100];
28static  unsigned long   hostaddr;
29
30int msend(char *buf, int num)
31{
32  bzero(&addr, sizeof(addr));
33  addr.sin_family = AF_INET;
34  addr.sin_port = htons((u_short)MCAST_PORT);
35  addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);
36  if (sendto(so, buf, num, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
37    if (errno != EAGAIN)
38      perror("sendto");
39    return 0;
40  }
41  return 1;
42}
43
44
45int mrecv(char *buf, int num)
46{
47  socklen_t i;
48  int n;
49
50  bzero(&addr, sizeof(addr));
51  addr.sin_family = AF_INET;
52  addr.sin_port = htons((u_short)MCAST_PORT);
53  addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);
54
55
56  i = sizeof(addr);
57  if ((n = recvfrom(so, buf, num, 0, (struct sockaddr *)&addr, &i)) == -1) {
58    if (errno != EAGAIN)
59      perror("recvfrom");
60    return 0;
61  }
62  return n;
63}
64
65
66#if defined(__rtems__)
67int mcast_main(int ac, char **av)
68#else
69int main(int ac, char **av)
70#endif
71{
72  int yes=1;     
73  char line[1024];
74  struct ip_mreq imr;
75  struct  hostent *h;
76  unsigned char mttl;
77  int mlen;
78  unsigned long long i, j, k;
79
80
81  if (ac > 1) mlen = atoi(av[1]);
82  else       mlen = 0;
83
84  if ((gethostname(mhost, 100) < 0)) {  //  Get the my hostname
85    perror("gethostname");
86    exit(1);
87  }
88  printf( "Hostname: %s\n", ((mhost) ? mhost : "NULL") );
89  if (!(h = gethostbyname(mhost))) {    // Get host entry
90    perror("gethostbyname");
91    exit(1);
92  }
93
94  printf( "host=0x%08x\n", *(unsigned int *)h->h_addr );
95
96
97  printf( "Creating socket\n" );
98  if ((so = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
99    perror("socket");
100    exit(1);
101  }
102
103  printf( "Setting SO_REUSEADDR\n" );
104  if (setsockopt(so, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
105    perror("setsockopt, reuse");
106    exit(1);
107  }
108
109  printf( "Binding\n" );
110  //      Bind to port and address.
111  bzero(&addr, sizeof(addr));
112  addr.sin_family = AF_INET;
113  addr.sin_port = htons((u_short)MCAST_PORT);
114  addr.sin_addr.s_addr = INADDR_ANY;
115  if (bind(so, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
116    perror("bind");
117    exit(1);
118  }
119
120  printf( "Performing IP_MULTICAST_TTL\n" );
121  mttl = ROUTERS_TO_HOP + 1;              //      ttl should be atleast one.
122  if (setsockopt(so, IPPROTO_IP, IP_MULTICAST_TTL, &mttl, sizeof(mttl)) < 0) {
123    perror("setsockopt, ttl" );
124    exit(1);
125  }           
126  hostaddr = *(unsigned int *)h->h_addr;
127  imr.imr_interface.s_addr = htonl(INADDR_ANY);
128  // For some reason, this doesn't seem to work.  I suspect it is because
129  // the /etc/hosts included with this demo must match the IP of the
130  // network interface you want to use.  I couldn't get this to work
131  // so gave up.  INADDR_ANY seems to reliably find the NIC. --joel
132  // imr.imr_interface.s_addr = hostaddr;
133  imr.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR);
134
135  printf( "Performing IP_ADD_MEMBERSHIP\n" );
136  if (setsockopt(so, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr)) < 0) {
137    perror( "can't join group" );
138    close(so);
139    exit(1);
140  }           
141
142  fcntl(so, F_SETFL, FNDELAY);
143  j = k = 0;
144  for(i = 1; 1; i++) {
145    int     x;
146    if (i == 0) j++;
147    if (j == 0) k++;
148    sleep(1);
149    sprintf(line,
150      "%s i %" PRId64 ", j %" PRId64 ", k %" PRId64 "", mhost, i, j, k);
151    msend(line, strlen(line)+ mlen);
152    while ((x = mrecv(line, 500)) > 0) {
153      if (addr.sin_addr.s_addr != hostaddr) {
154        line[x] = 0;
155        printf("Raddr %s recv %s\n", inet_ntoa(addr.sin_addr), line);
156      }
157    }
158  }
159}
Note: See TracBrowser for help on using the repository browser.