]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
pf-handler: Correctly bind packet socket to an interface
authorTobias Brunner <tobias@strongswan.org>
Thu, 30 Jan 2025 13:40:33 +0000 (14:40 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 31 Jan 2025 10:20:32 +0000 (11:20 +0100)
Binding such sockets via SO_BINDTODEVICE does not work at all. Instead,
bind() has to be used, as described in the packet(7) man page.

src/libcharon/network/pf_handler.c

index ef55671c4b6121b56f8b5bc34b11406a3d53bb58..aaaf7a177f963a80a41f36f62403a0137b42ae3c 100644 (file)
@@ -226,6 +226,30 @@ METHOD(pf_handler_t, destroy, void,
        free(this);
 }
 
+/**
+ * Bind the given packet socket to the a named device
+ */
+static bool bind_packet_socket_to_device(int fd, char *iface)
+{
+       struct sockaddr_ll addr = {
+               .sll_family = AF_PACKET,
+               .sll_ifindex = if_nametoindex(iface),
+       };
+
+       if (!addr.sll_ifindex)
+       {
+               DBG1(DBG_CFG, "unable to bind socket to '%s': not found", iface);
+               return FALSE;
+       }
+       if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
+       {
+               DBG1(DBG_CFG, "binding socket to '%s' failed: %s",
+                        iface, strerror(errno));
+               return FALSE;
+       }
+       return TRUE;
+}
+
 /**
  * Setup capturing via AF_PACKET socket
  */
@@ -248,14 +272,15 @@ static bool setup_internal(private_pf_handler_t *this, char *iface,
                         this->name, strerror(errno));
                return FALSE;
        }
-       if (iface && !bind_to_device(this->receive, iface))
+       if (iface && iface[0] && !bind_packet_socket_to_device(this->receive, iface))
        {
                return FALSE;
        }
        lib->watcher->add(lib->watcher, this->receive, WATCHER_READ,
                                          receive_packet, this);
-       DBG2(DBG_NET, "listening for %s (protocol=0x%04x) requests on fd=%d",
-                this->name, protocol, this->receive);
+       DBG2(DBG_NET, "listening for %s (protocol=0x%04x) requests on fd=%d bound "
+                "to %s", this->name, protocol, this->receive,
+                iface && iface[0] ? iface : "no interface");
        return TRUE;
 }