xref: /haiku/src/tests/system/network/ipv6/multicast_sender.cpp (revision 5e54f6d4f9dd607ae2afcea4fe72f2f1763e4b5e)
1 /*
2  * Copyright 2010, Atis Elsts, the.kfx@gmail.com
3  * Distributed under the terms of the MIT license.
4  */
5 
6 
7 #include <unistd.h>
8 #include <memory.h>
9 #include <netinet/in.h>
10 #include <arpa/inet.h>
11 #include <errno.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 
15 
16 const unsigned short TEST_PORT = 40000;
17 
18 
19 int
main(int argc,char * argv[])20 main(int argc, char *argv[])
21 {
22 	int socketFamily = AF_INET;
23 
24 	int i = 1;
25 	if (argc > i) {
26 		if (!strcmp(argv[i], "-4")) {
27 			i++;
28 			socketFamily = AF_INET;
29 		} else if (!strcmp(argv[i], "-6")) {
30 			i++;
31 			socketFamily = AF_INET6;
32 		}
33 	}
34 	in_addr multicastSource;
35 	multicastSource.s_addr = 0;
36 	if (argc > i) {
37 		if (!strcmp(argv[i], "-s")) {
38 			++i;
39 			if (inet_aton(argv[i], &multicastSource) == 0) {
40 				fprintf(stderr, "IPv4 source address expected");
41 				return -1;
42 			}
43 			++i;
44 		}
45 	}
46 
47 	int fd = socket(socketFamily, SOCK_DGRAM, 0);
48 	if (fd < 0) {
49 		perror("socket");
50 		return -1;
51 	}
52 
53 	sockaddr_storage saddr;
54 	memset(&saddr, 0, sizeof(saddr));
55 	if (socketFamily == AF_INET) {
56 		sockaddr_in *sa = (sockaddr_in *) &saddr;
57 		sa->sin_family = AF_INET;
58 		sa->sin_port = htons(TEST_PORT);
59 		sa->sin_addr.s_addr = htonl(INADDR_ALLHOSTS_GROUP);
60 	} else {
61 		sockaddr_in6 *sa = (sockaddr_in6 *) &saddr;
62 		sa->sin6_family = AF_INET6;
63 		sa->sin6_port = htons(TEST_PORT);
64 		// ff01::1 (all nodes multicast)
65 		sa->sin6_addr.s6_addr[0] = 0xff;
66 		sa->sin6_addr.s6_addr[1] = 0x01;
67 		sa->sin6_addr.s6_addr[15] = 0x01;
68 	}
69 
70 	if (multicastSource.s_addr) {
71 		if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
72 				&multicastSource, sizeof(multicastSource)) < 0) {
73 			perror("setsockopt IP_MULTICAST_IF");
74 			return -1;
75 		}
76 	}
77 
78 	const char *buffer = "hello world";
79 	unsigned length = strlen(buffer);
80 	int status = sendto(fd, buffer, length, 0, (sockaddr *) &saddr,
81 		socketFamily == AF_INET ? sizeof(sockaddr_in) : sizeof(sockaddr_in6));
82 	if (status < length) {
83 		if (status < 0)
84 			perror("sendto");
85 		else if (status == 0)
86 			printf("no data sent!\n");
87 		else
88 			printf("not all data sent!\n");
89 	} else
90 		printf("send(): success\n");
91 
92 	close(fd);
93 	return 0;
94 }
95