pf-handler: Correctly bind packet socket to an interface

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.
This commit is contained in:
Tobias Brunner
2025-01-31 11:20:32 +01:00
parent abbf9d28b0
commit 00d8c36d6f
+28 -3
View 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;
}