]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/libsystemd-network/icmp6-util.c
tree-wide: use in_addr_is_set() or friends
[thirdparty/systemd.git] / src / libsystemd-network / icmp6-util.c
index e535b12cda16d8027eb0ac470ef3f6918f9a9f2c..d079ad40e992d14694c94417b6d6089e6fde16d9 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
 /***
   Copyright © 2014 Intel Corporation. All rights reserved.
 ***/
@@ -9,7 +9,6 @@
 #include <netinet/ip6.h>
 #include <stdio.h>
 #include <string.h>
-#include <sys/socket.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <net/if.h>
@@ -31,9 +30,8 @@
 
 static int icmp6_bind_router_message(const struct icmp6_filter *filter,
                                      const struct ipv6_mreq *mreq) {
-        int index = mreq->ipv6mr_interface;
+        int ifindex = mreq->ipv6mr_interface;
         _cleanup_close_ int s = -1;
-        char ifname[IF_NAMESIZE] = "";
         int r;
 
         s = socket(AF_INET6, SOCK_RAW | SOCK_CLOEXEC | SOCK_NONBLOCK, IPPROTO_ICMPV6);
@@ -52,7 +50,7 @@ static int icmp6_bind_router_message(const struct icmp6_filter *filter,
            IPV6_PKTINFO socket option also applies for ICMPv6 multicast.
            Empirical experiments indicates otherwise and therefore an
            IPV6_MULTICAST_IF socket option is used here instead */
-        r = setsockopt_int(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, index);
+        r = setsockopt_int(s, IPPROTO_IPV6, IPV6_MULTICAST_IF, ifindex);
         if (r < 0)
                 return r;
 
@@ -76,21 +74,18 @@ static int icmp6_bind_router_message(const struct icmp6_filter *filter,
         if (r < 0)
                 return r;
 
-        if (if_indextoname(index, ifname) == 0)
-                return -errno;
-
-        r = setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
+        r = socket_bind_to_ifindex(s, ifindex);
         if (r < 0)
-                return -errno;
+                return r;
 
         return TAKE_FD(s);
 }
 
-int icmp6_bind_router_solicitation(int index) {
+int icmp6_bind_router_solicitation(int ifindex) {
         struct icmp6_filter filter = {};
         struct ipv6_mreq mreq = {
                 .ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
-                .ipv6mr_interface = index,
+                .ipv6mr_interface = ifindex,
         };
 
         ICMP6_FILTER_SETBLOCKALL(&filter);
@@ -99,11 +94,11 @@ int icmp6_bind_router_solicitation(int index) {
         return icmp6_bind_router_message(&filter, &mreq);
 }
 
-int icmp6_bind_router_advertisement(int index) {
+int icmp6_bind_router_advertisement(int ifindex) {
         struct icmp6_filter filter = {};
         struct ipv6_mreq mreq = {
                 .ipv6mr_multiaddr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
-                .ipv6mr_interface = index,
+                .ipv6mr_interface = ifindex,
         };
 
         ICMP6_FILTER_SETBLOCKALL(&filter);
@@ -150,13 +145,11 @@ int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
         return 0;
 }
 
-int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
-                  triple_timestamp *timestamp) {
-        union {
-                struct cmsghdr cmsghdr;
-                uint8_t buf[CMSG_SPACE(sizeof(int)) + /* ttl */
-                            CMSG_SPACE(sizeof(struct timeval))];
-        } control = {};
+int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
+                  triple_timestamp *ret_timestamp) {
+
+        CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int)) + /* ttl */
+                         CMSG_SPACE(sizeof(struct timeval))) control;
         struct iovec iov = {};
         union sockaddr_union sa = {};
         struct msghdr msg = {
@@ -168,13 +161,15 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
                 .msg_controllen = sizeof(control),
         };
         struct cmsghdr *cmsg;
+        struct in6_addr addr = {};
+        triple_timestamp t;
         ssize_t len;
 
         iov = IOVEC_MAKE(buffer, size);
 
-        len = recvmsg(fd, &msg, MSG_DONTWAIT);
+        len = recvmsg_safe(fd, &msg, MSG_DONTWAIT);
         if (len < 0)
-                return -errno;
+                return (int) len;
 
         if ((size_t) len != size)
                 return -EINVAL;
@@ -182,8 +177,8 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
         if (msg.msg_namelen == sizeof(struct sockaddr_in6) &&
             sa.in6.sin6_family == AF_INET6)  {
 
-                *dst = sa.in6.sin6_addr;
-                if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) dst) <= 0)
+                addr = sa.in6.sin6_addr;
+                if (!in6_addr_is_link_local(&addr))
                         return -EADDRNOTAVAIL;
 
         } else if (msg.msg_namelen > 0)
@@ -207,11 +202,13 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
                 if (cmsg->cmsg_level == SOL_SOCKET &&
                     cmsg->cmsg_type == SO_TIMESTAMP &&
                     cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
-                        triple_timestamp_from_realtime(timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
+                        triple_timestamp_from_realtime(&t, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
         }
 
-        if (!triple_timestamp_is_set(timestamp))
-                triple_timestamp_get(timestamp);
+        if (!triple_timestamp_is_set(&t))
+                triple_timestamp_get(&t);
 
+        *ret_dst = addr;
+        *ret_timestamp = t;
         return 0;
 }