1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (c) Linux Test Project, 2001-2022
4 */
5
6 #include <sys/types.h>
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <arpa/inet.h>
10 #include <errno.h>
11 #include <string.h>
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <netdb.h>
16
17 #define MAXBUFSIZ 8096
18
19 static int errors;
20
main(int argc,char * argv[])21 int main(int argc, char *argv[])
22 {
23 int s;
24 struct in_addr gimr;
25 struct ip_mreq simr;
26
27 unsigned int i1, i2, i3, i4;
28 struct hostent *hp, *gethostbyname();
29
30 char sintf[20], gintf[20] = {0};
31 unsigned char ttl;
32 char loop = 0;
33 unsigned int len = 0;
34
35 if (argc != 2) {
36 fprintf(stderr,
37 "usage: %s interface_name (or i.i.i.i)\n", argv[0]);
38 exit(1);
39 }
40 s = socket(AF_INET, SOCK_DGRAM, 0);
41 if (s == -1) {
42 perror("Error: can't open socket");
43 exit(1);
44 }
45
46 printf("agrv sub 1 is %s\n", argv[1]);
47 hp = gethostbyname(argv[1]);
48 if (hp)
49 memcpy(&simr.imr_interface.s_addr, hp->h_addr, hp->h_length);
50 else if (sscanf(argv[1], "%u.%u.%u.%u", &i1, &i2, &i3, &i4) != 4) {
51 fprintf(stderr, "Bad interface address\n");
52 exit(1);
53 } else
54 simr.imr_interface.s_addr =
55 htonl((i1 << 24) | (i2 << 16) | (i3 << 8) | i4);
56 strcpy(sintf, inet_ntoa(simr.imr_interface));
57
58 /* verify socket options */
59 if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
60 &simr.imr_interface.s_addr,
61 sizeof(simr.imr_interface.s_addr)) != 0) {
62 perror("Error: Setting IP_MULTICAST_IF");
63 errors++;
64 } else
65 printf("Set interface: %s for multicasting\n", sintf);
66
67 len = sizeof(gimr);
68 if (getsockopt
69 (s, IPPROTO_IP, IP_MULTICAST_IF, &gimr, (socklen_t *)&len) != 0) {
70 perror("Getting IP_MULTICAST_IF");
71 errors++;
72 } else {
73 strcpy(gintf, inet_ntoa(gimr));
74 printf("Got multicasting socket interface: %s\n", gintf);
75 }
76
77 /* Verify that the multicastion for the interface was set */
78 if (strcmp(sintf, gintf) != 0) {
79 printf("Error: IP_MULTICAST_IF was not set\n");
80 errors++;
81 } else
82 printf
83 ("Socket has been set for multicasting on interface: %s\n",
84 sintf);
85
86 len = sizeof(ttl);
87 if (getsockopt
88 (s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, (socklen_t *)&len) != 0) {
89 perror("Error: Gettting IP_MULTICAST_TTL");
90 errors++;
91 } else
92 printf("getsockopt: got ttl = %i\n", ttl);
93 if (ttl != 1)
94 printf("Error: IP_MULTICAST_TTL not default value, ttl = %i\n",
95 ttl);
96 ttl = 10; /* Set ttl to 10 */
97 len = sizeof(ttl);
98 if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL,
99 &ttl, sizeof(ttl)) != 0) {
100 perror("Error: Setting IP_MULTICAST_TTL");
101 errors++;
102 } else
103 printf("TTL set on multicast socket\n");
104 if (getsockopt
105 (s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, (socklen_t *)&len) != 0) {
106 perror("Error: Getting IP_MULTICAST_TTL");
107 errors++;
108 }
109 if (ttl != 10) {
110 printf("Error: IP_MULTICAST_TTL not set, ttl = %i\n", ttl);
111 errors++;
112 }
113
114 len = sizeof(loop);
115 if (getsockopt
116 (s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop,
117 (socklen_t *)&len) != 0) {
118 perror("Error: Getting IP_MULTICAST_LOOP");
119 errors++;
120 } else
121 printf("Got loopback setting\n");
122 if (loop != 1) {
123 printf("Error: IP_MULTICAST_LOOP not enabled, loop = %i\n",
124 loop);
125 errors++;
126 } else
127 printf("IP_MULTICAST_LOOP is enabled\n");
128
129 loop = 0; /* Disable IP_MULTICAST_LOOP */
130 if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(char)) !=
131 0) {
132 errors++;
133 perror("Error: Setting IP_MULTICAST_LOOP");
134 } else
135 printf("Multicast loopback disabled\n");
136 if (getsockopt
137 (s, IPPROTO_IP, IP_MULTICAST_LOOP, &loop,
138 (socklen_t *)&len) != 0) {
139 perror("Error: Getting IP_MULTICAST_LOOP");
140 errors++;
141 } else
142 printf("Got multicast loopback value\n");
143 if (loop != 0) {
144 printf("Error: IP_MULTICAST_LOOP not disabled, loop = %i\n",
145 loop);
146 errors++;
147 } else
148 printf("IP_MULTICAST_LOOP disabled\n");
149
150 close(s);
151 if (errors)
152 exit(1);
153 exit(0);
154 }
155