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