1 /* Multicast test, listener */
4 #include <sys/socket.h>
5 #include <netinet/in.h>
16 #define max(a, b) (((a) > (b)) ? (a) : (b))
18 #define V6_MULTICAST_ADDR "ff02::1:3"
19 #define V4_MULTICAST_ADDR "224.0.0.252"
20 #define IFACE_NAME "br0"
21 #define LLMNR_PORT 5355
23 static int setup_v6_socket(const char *multicast_addr,
24 const char *iface_name,
30 struct sockaddr_in6 name6;
31 ssize_t len6 = sizeof(name6);
32 struct ipv6_mreq mreq6;
34 sock6 = socket(AF_INET6, SOCK_DGRAM, 0);
36 perror("opening v6 listening socket");
40 err = setsockopt(sock6, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(int));
42 perror("setting IPV6_ONLY on sock6");
46 memset(&name6, 0, len6);
48 name6.sin6_family = PF_INET6;
49 name6.sin6_addr = in6addr_any;
50 name6.sin6_port = htons(port);
52 if (bind(sock6, (struct sockaddr *) &name6, len6) == -1) {
53 perror("binding to v6 socket");
57 memset(&mreq6, 0, sizeof(struct ipv6_mreq));
58 err = inet_pton(AF_INET6, multicast_addr, &mreq6.ipv6mr_multiaddr);
60 fprintf(stderr, "failed to convert %s to an address\n", multicast_addr);
63 mreq6.ipv6mr_interface = if_nametoindex(iface_name);
65 err = setsockopt(sock6, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq6,
66 sizeof(struct ipv6_mreq));
68 perror("joining v6 multicast group");
82 static int setup_v4_socket(const char *multicast_addr,
83 const char *iface_name,
88 struct sockaddr_in name4;
89 ssize_t len4 = sizeof(name4);
90 struct ip_mreqn mreq4;
92 sock4 = socket(AF_INET, SOCK_DGRAM, 0);
94 perror("creating v4 socket");
98 memset(&name4, 0, len4);
100 name4.sin_family = PF_INET;
101 name4.sin_addr.s_addr = INADDR_ANY;
102 name4.sin_port = htons(port);
104 if (bind(sock4, (struct sockaddr *) &name4, len4) == -1) {
105 perror("binding to v4 socket");
109 memset(&mreq4, 0, sizeof(struct ip_mreqn));
110 mreq4.imr_multiaddr.s_addr = inet_addr(V4_MULTICAST_ADDR);
111 mreq4.imr_ifindex = if_nametoindex(iface_name);
113 err = setsockopt(sock4, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq4,
114 sizeof(struct ip_mreqn));
116 perror("joining v4 multicast group");
129 int main(int argc, char **argv)
134 struct sockaddr_storage peer_addr;
137 socklen_t peer_addr_len;
138 char host[NI_MAXHOST], service[NI_MAXSERV];
141 sock6 = setup_v6_socket(V6_MULTICAST_ADDR, IFACE_NAME, LLMNR_PORT);
143 fprintf(stderr, "Failed to set up v6 socket");
147 sock4 = setup_v4_socket(V4_MULTICAST_ADDR, IFACE_NAME, LLMNR_PORT);
149 fprintf(stderr, "Failed to set up v4 socket");
159 FD_SET(sock6, &read_fds);
160 nfds = max(sock6, nfds);
162 FD_SET(sock4, &read_fds);
163 nfds = max(sock4, nfds);
165 err = select(nfds + 1, &read_fds, NULL, NULL, NULL);
167 if (err == -1 && errno == EINTR) {
176 if (FD_ISSET(sock6, &read_fds)) {
182 peer_addr_len = sizeof(struct sockaddr_storage);
183 msg_len = recvfrom(tmp_sock, buf, 1024, 0,
184 (struct sockaddr *)&peer_addr, &peer_addr_len);
186 perror("receiving data");
190 buf[2] |= 0x80; /* We're a reply, honest! */
192 err = getnameinfo((struct sockaddr *)&peer_addr, peer_addr_len,
193 host, NI_MAXHOST, service, NI_MAXSERV, NI_NUMERICSERV);
196 printf("Got %ld bytes from %s:%s\n", (long) msg_len,
199 fprintf(stderr, "getnameinfo: %s\n", gai_strerror(err));
203 if(sendto(tmp_sock, buf, msg_len, 0,
204 (struct sockaddr *)&peer_addr, peer_addr_len) != msg_len) {
205 perror("sending reply");
208 printf("Sent %ld bytes back\n", (long) msg_len);