1*8a272653SPeter Holm#!/bin/sh 2*8a272653SPeter Holm 3*8a272653SPeter Holm# Multicast test example by Mark Claypool, claypool at cs.wpi.edu 4*8a272653SPeter Holm# https://web.cs.wpi.edu/~claypool/courses/4514-B99/samples/multicast.c 5*8a272653SPeter Holm 6*8a272653SPeter Holm# Kernel page fault seen with WiP branch: 7*8a272653SPeter Holm# https://people.freebsd.org/~pho/stress/log/kip036.txt 8*8a272653SPeter Holm 9*8a272653SPeter Holm. ../default.cfg 10*8a272653SPeter Holm 11*8a272653SPeter Holmdir=/tmp 12*8a272653SPeter Holmodir=`pwd` 13*8a272653SPeter Holmcd $dir 14*8a272653SPeter Holmsed '1,/^EOF/d' < $odir/$0 > $dir/multicast.c 15*8a272653SPeter Holmmycc -o multicast -Wall -Wextra -O0 -g multicast.c || exit 1 16*8a272653SPeter Holmrm -f multicast.c 17*8a272653SPeter Holmcd $odir 18*8a272653SPeter Holm 19*8a272653SPeter Holmcd $dir 20*8a272653SPeter Holm( 21*8a272653SPeter Holm timeout -k 1s 20s ./multicast & 22*8a272653SPeter Holm sleep 1 23*8a272653SPeter Holm timeout -k 1s 25s ./multicast 1 24*8a272653SPeter Holm) > /dev/null 25*8a272653SPeter Holmwait 26*8a272653SPeter Holm 27*8a272653SPeter Holmrm -f $dir/multicast 28*8a272653SPeter Holmexit $s 29*8a272653SPeter HolmEOF 30*8a272653SPeter Holm/* 31*8a272653SPeter Holmmulticast.c 32*8a272653SPeter Holm 33*8a272653SPeter HolmThe following program sends or receives multicast packets. If invoked 34*8a272653SPeter Holmwith one argument, it sends a packet containing the current time to an 35*8a272653SPeter Holmarbitrarily chosen multicast group and UDP port. If invoked with no 36*8a272653SPeter Holmarguments, it receives and prints these packets. Start it as a sender on 37*8a272653SPeter Holmjust one host and as a receiver on all the other hosts 38*8a272653SPeter Holm 39*8a272653SPeter Holm*/ 40*8a272653SPeter Holm 41*8a272653SPeter Holm#include <sys/types.h> 42*8a272653SPeter Holm#include <sys/socket.h> 43*8a272653SPeter Holm 44*8a272653SPeter Holm#include <netinet/in.h> 45*8a272653SPeter Holm#include <arpa/inet.h> 46*8a272653SPeter Holm 47*8a272653SPeter Holm#include <string.h> 48*8a272653SPeter Holm#include <time.h> 49*8a272653SPeter Holm#include <stdio.h> 50*8a272653SPeter Holm#include <stdlib.h> 51*8a272653SPeter Holm#include <unistd.h> 52*8a272653SPeter Holm 53*8a272653SPeter Holm#define EXAMPLE_PORT 6000 54*8a272653SPeter Holm#define EXAMPLE_GROUP "239.0.0.1" 55*8a272653SPeter Holm 56*8a272653SPeter Holmint 57*8a272653SPeter Holmmain(int argc, char *argv[] __unused) 58*8a272653SPeter Holm{ 59*8a272653SPeter Holm struct ip_mreq mreq; 60*8a272653SPeter Holm struct sockaddr_in addr; 61*8a272653SPeter Holm socklen_t addrlen; 62*8a272653SPeter Holm int cnt, sock; 63*8a272653SPeter Holm char message[50]; 64*8a272653SPeter Holm 65*8a272653SPeter Holm /* set up socket */ 66*8a272653SPeter Holm sock = socket(AF_INET, SOCK_DGRAM, 0); 67*8a272653SPeter Holm if (sock < 0) { 68*8a272653SPeter Holm perror("socket"); 69*8a272653SPeter Holm exit(1); 70*8a272653SPeter Holm } 71*8a272653SPeter Holm bzero((char *)&addr, sizeof(addr)); 72*8a272653SPeter Holm addr.sin_family = AF_INET; 73*8a272653SPeter Holm addr.sin_addr.s_addr = htonl(INADDR_ANY); 74*8a272653SPeter Holm addr.sin_port = htons(EXAMPLE_PORT); 75*8a272653SPeter Holm addrlen = sizeof(addr); 76*8a272653SPeter Holm 77*8a272653SPeter Holm if (argc > 1) { 78*8a272653SPeter Holm /* send */ 79*8a272653SPeter Holm addr.sin_addr.s_addr = inet_addr(EXAMPLE_GROUP); 80*8a272653SPeter Holm while (1) { 81*8a272653SPeter Holm time_t t = time(0); 82*8a272653SPeter Holm sprintf(message, "time is %-24.24s", ctime(&t)); 83*8a272653SPeter Holm printf("sending: %s\n", message); 84*8a272653SPeter Holm cnt = sendto(sock, message, sizeof(message), 0, 85*8a272653SPeter Holm (struct sockaddr *) &addr, addrlen); 86*8a272653SPeter Holm if (cnt < 0) { 87*8a272653SPeter Holm perror("sendto"); 88*8a272653SPeter Holm exit(1); 89*8a272653SPeter Holm } 90*8a272653SPeter Holm sleep(5); 91*8a272653SPeter Holm } 92*8a272653SPeter Holm } else { 93*8a272653SPeter Holm 94*8a272653SPeter Holm /* receive */ 95*8a272653SPeter Holm if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 96*8a272653SPeter Holm perror("bind"); 97*8a272653SPeter Holm exit(1); 98*8a272653SPeter Holm } 99*8a272653SPeter Holm mreq.imr_multiaddr.s_addr = inet_addr(EXAMPLE_GROUP); 100*8a272653SPeter Holm mreq.imr_interface.s_addr = htonl(INADDR_ANY); 101*8a272653SPeter Holm if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, 102*8a272653SPeter Holm &mreq, sizeof(mreq)) < 0) { 103*8a272653SPeter Holm perror("setsockopt mreq"); 104*8a272653SPeter Holm exit(1); 105*8a272653SPeter Holm } 106*8a272653SPeter Holm while (1) { 107*8a272653SPeter Holm cnt = recvfrom(sock, message, sizeof(message), 0, 108*8a272653SPeter Holm (struct sockaddr *) &addr, &addrlen); 109*8a272653SPeter Holm if (cnt < 0) { 110*8a272653SPeter Holm perror("recvfrom"); 111*8a272653SPeter Holm exit(1); 112*8a272653SPeter Holm } else if (cnt == 0) { 113*8a272653SPeter Holm break; 114*8a272653SPeter Holm } 115*8a272653SPeter Holm printf("%s: message = \"%s\"\n", inet_ntoa(addr.sin_addr), message); 116*8a272653SPeter Holm } 117*8a272653SPeter Holm } 118*8a272653SPeter Holm} 119