I have the following simple test program to create a UDP socket and bind it to a specific interface using SO_BINDTODEVICE , so I can then bind() do INADDR_ANY to receive UDP broadcasts specifically for this interface.
when I run this program as a non-root user, I get the following output:
$ ./bindtest UDP socket created set timeout to time [s]: 5 time [ms]: 0 set SO_BROADCAST worked ./bindtest: could not set SO_BINDTODEVICE (Operation not permitted)
which is pretty logical, because I'm not root , and SO_BINDTODEVICE is a privileged operation. but it is included in the CAP_NET_RAW , as I understand from this piece of code from the Linux kernel :
static int sock_setbindtodevice(struct sock *sk, char __user *optval, int optlen) { int ret = -ENOPROTOOPT; #ifdef CONFIG_NETDEVICES struct net *net = sock_net(sk); char devname[IFNAMSIZ]; int index; ret = -EPERM; if (!ns_capable(net->user_ns, CAP_NET_RAW)) goto out;
Ok when I do this:
$ getcap bindtest $ sudo setcap cap_net_raw+ep bindtest $ getcap bindtest bindtest = cap_net_raw+ep
I get the same error output:
$ ./bindtest UDP socket created set timeout to time [s]: 5 time [ms]: 0 set SO_BROADCAST worked ./bindtest: could not set SO_BINDTODEVICE (Operation not permitted)
And of course it works as root :
$ sudo ./bindtest UDP socket created set timeout to time [s]: 5 time [ms]: 0 set SO_BROADCAST worked SO_BINDTODEVICE worked bind() worked data sent socket closed
so why don't they work as expected?
source share