xref: /freebsd-src/tools/test/stress2/misc/multicast.sh (revision 8a272653d9fbd9fc37691c9aad6a05089b4ecb4d)
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