From 69ff5a62caedb7d523624f892bffff0b80753f46 Mon Sep 17 00:00:00 2001 From: Martin/Geno Date: Sun, 5 Aug 2018 19:53:04 +0200 Subject: [PATCH] add multicast interface support --- wireless/wifictld/src/main.c | 26 +++++++++++++---- wireless/wifictld/src/socket.c | 52 +++++++++++++++++++++------------- wireless/wifictld/src/socket.h | 3 +- 3 files changed, 55 insertions(+), 26 deletions(-) diff --git a/wireless/wifictld/src/main.c b/wireless/wifictld/src/main.c index 19d4111..7ab3d5c 100644 --- a/wireless/wifictld/src/main.c +++ b/wireless/wifictld/src/main.c @@ -32,10 +32,11 @@ struct option longopts[] = { {"addr", required_argument, 0, 6}, {"maddr", required_argument, 0, 7}, {"port", required_argument, 0, 8}, - {"ifname", required_argument, 0, 9}, + {"if", required_argument, 0, 9}, + {"mif", required_argument, 0, 10}, // other extended option - {"socket-learning", optional_argument, 0, 10}, - {"socket-always-answer", optional_argument, 0, 11}, + {"socket-learning", optional_argument, 0, 11}, + {"socket-always-answer", optional_argument, 0, 12}, #endif }; @@ -64,7 +65,8 @@ void usage(int c) { printf(" --addr listen on ip address (current: %s)\n", addr); printf(" --maddr listen and request on multcast address (current: %s)\n", maddr); printf(" --port listen on port (current: %s)\n", port); - printf(" --ifname listen on interface for multicast (current: %s)\n", ifname); + printf(" --if listen on interface (current: %s)\n", ifname); + printf(" --mif listen on interface for multicast (current: %s)\n", ifname); printf("\nother extended options:\n"); printf(" --socket-learning learn clients during listen on socket (current: %s)\n", BOOL2STR(config_client_socket_learning)); printf(" --socket-always-answer answer on socket only with useful information (current: %s)\n", BOOL2STR(config_socket_always_answer)); @@ -167,14 +169,17 @@ int main(int argc, char *argv[]) case 9: ifname = optarg; break; - // other extended option case 10: + // skip - check later after init socket + break; + // other extended option + case 11: if(optarg) config_client_socket_learning = atoi(optarg); else config_client_socket_learning = !config_client_socket_learning; break; - case 11: + case 12: if(optarg) config_socket_always_answer = atoi(optarg); else @@ -215,6 +220,15 @@ int main(int argc, char *argv[]) log_error("exit with error on socket init\n"); return ret; } + c = 0; + indexptr = 0; + while ((c = getopt_long(argc, argv, "vht:s:fp",longopts, &indexptr)) != -1) { + switch (c) { + case 10: + socket_join_mcast(optarg); + break; + } + } #endif uloop_run(); uloop_done(); diff --git a/wireless/wifictld/src/socket.c b/wireless/wifictld/src/socket.c index 91d5dcd..faf93fa 100644 --- a/wireless/wifictld/src/socket.c +++ b/wireless/wifictld/src/socket.c @@ -6,8 +6,9 @@ #include "socket_handler.h" static struct uloop_fd server; -struct sockaddr_in6 ownaddr; -struct sockaddr_in6 client_addr; +int info_sock = 0; +struct sockaddr_in6 own_addr; +struct sockaddr_in6 multicast_addr; int socket_info(struct socket_msg *info) { int ret = 0; @@ -19,7 +20,7 @@ int socket_info(struct socket_msg *info) { return ret; } - ret = sendto(server.fd, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&client_addr, sizeof(client_addr)); + ret = sendto(info_sock, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&multicast_addr, sizeof(multicast_addr)); if (ret < 0) { log_error("socket_info: could not send message: %d\n", ret); } @@ -46,7 +47,7 @@ int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer return -1; } - if(bind(sock, (struct sockaddr*)&ownaddr, sizeof(ownaddr))) { + if(bind(sock, (struct sockaddr*)&own_addr, sizeof(own_addr))) { log_error("socket_request: could not bind to addr\n"); return -1; } @@ -58,7 +59,7 @@ int socket_request_timeout(struct socket_msg *request, struct socket_msg *answer return -1; } - ret = sendto(sock, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&client_addr, sizeof(client_addr)); + ret = sendto(sock, msg, REQUEST_MAXLEN, 0, (struct sockaddr *)&multicast_addr, sizeof(multicast_addr)); if (ret < 0) { close(sock); log_error("socket_request: could not send message: %d\n", ret); @@ -168,40 +169,45 @@ static void server_cb(struct uloop_fd *fd, unsigned int events) { int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socket_port) { server.cb = server_cb; - server.fd = usock(USOCK_UDP | USOCK_SERVER | USOCK_IPV6ONLY | USOCK_NUMERIC, socket_bind, socket_port); + server.fd = usock(USOCK_UDP | USOCK_SERVER | USOCK_IPV6ONLY | USOCK_NUMERIC, "::", socket_port); if (server.fd < 0) { + log_error("socket: error create socket to recv\n"); + return 1; + } + info_sock = usock(USOCK_UDP | USOCK_IPV6ONLY | USOCK_NUMERIC, socket_bind, socket_port); + if (info_sock < 0) { + log_error("socket: error create socket to send\n"); return 1; } - client_addr.sin6_family = AF_INET6; - client_addr.sin6_port = htons(atoi(socket_port)); - client_addr.sin6_scope_id = if_nametoindex(ifname); + multicast_addr.sin6_family = AF_INET6; + multicast_addr.sin6_port = htons(atoi(socket_port)); + multicast_addr.sin6_scope_id = if_nametoindex(ifname); - ownaddr.sin6_family = AF_INET6; - ownaddr.sin6_scope_id = client_addr.sin6_scope_id; + own_addr.sin6_family = AF_INET6; + own_addr.sin6_scope_id = multicast_addr.sin6_scope_id; - if(!inet_pton(AF_INET6, socket_bind, &ownaddr.sin6_addr)) { + if(!inet_pton(AF_INET6, socket_bind, &own_addr.sin6_addr)) { log_error("socket: could not parse address for socket_request\n"); return -1; } // listen multicast - if (!inet_pton(AF_INET6, socket_maddr, &client_addr.sin6_addr)) { + if (!inet_pton(AF_INET6, socket_maddr, &multicast_addr.sin6_addr)) { log_error("socket: invalid multicast group\n"); return -1; } - struct ipv6_mreq mreq = { - .ipv6mr_multiaddr = client_addr.sin6_addr, - .ipv6mr_interface = client_addr.sin6_scope_id, - }; - - if (setsockopt(server.fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1) { + if (socket_join_mcast(ifname) < 0) { log_error("socket: unable to join multicast group: %d\n", errno); return -1; } int loop = 0; + if(setsockopt(info_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) { + log_error("socket_request: unable to disable listen/loop own multicast package: %d\n", errno); + return -1; + } if(setsockopt(server.fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &loop, sizeof(loop)) < 0) { log_error("socket_request: unable to disable listen/loop own multicast package: %d\n", errno); return -1; @@ -212,6 +218,14 @@ int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socke return 0; } +int socket_join_mcast(char *ifname) { + struct ipv6_mreq mreq = { + .ipv6mr_multiaddr = multicast_addr.sin6_addr, + .ipv6mr_interface = if_nametoindex(ifname), + }; + return setsockopt(server.fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)); +} + void socket_close() { uloop_fd_delete(&server); //ustream_free(&(server.fd)); diff --git a/wireless/wifictld/src/socket.h b/wireless/wifictld/src/socket.h index e8870e9..274d61a 100644 --- a/wireless/wifictld/src/socket.h +++ b/wireless/wifictld/src/socket.h @@ -4,7 +4,8 @@ #include "include.h" #include "socket_msg.h" -int socket_init(); +int socket_init(char *ifname, char *socket_bind, char *socket_maddr, char *socket_port); +int socket_join_mcast(char *ifname); void socket_close(); int socket_info(struct socket_msg *info);