SO_BINDTODEVICE

man socket(7)里对该选项的描述:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SO_BINDTODEVICE
Bind this socket to a particular device like “eth0”, as speci‐
fied in the passed interface name. If the name is an empty
string or the option length is zero, the socket device binding
is removed. The passed option is a variable-length null-ter‐
minated interface name string with the maximum size of IFNAM‐
SIZ. If a socket is bound to an interface, only packets
received from that particular interface are processed by the
socket. Note that this works only for some socket types, par‐
ticularly AF_INET sockets. It is not supported for packet
sockets (use normal bind(2) there).

Before Linux 3.8, this socket option could be set, but could
not retrieved with getsockopt(2). Since Linux 3.8, it is
readable. The optlen argument should contain the buffer size
available to receive the device name and is recommended to be
IFNAMSIZ bytes. The real device name length is reported back
in the optlen argument.
  1. 将套接字绑定到指定接口,例如eth0等。如果绑定了接口,这个套接字只能处理由该接口收到的数据。
  2. 注意,并不是所有套接字类型都有这个选项。AF_INET套接字支持,但是packet 套接字不支持(不过,可以使用bind函数绑定地址)

SOL_BINDTODEVICE是setsockopt设置中的一种套接口选项.当套接口被绑定到

指定的网络设备接口之后,只有来自该设备的数据包才会被套接口处理。

在Linux下, 对网络设备的引用是通过struct ifreq来完成.通过设置struct

ifreq中的 ifr_name[IFNAMSIZ]来指定网络设备接口.举例如下:

struct ifreq interface;

char *inf = “eth0”;

strncpy(interface.ifr_name, inf, IFNAMSIZ);

这样再通过设置:

if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,(char *)&interface, sizeof(interface)) < 0)

{

​ close(fd);

​ return -1;

}

就绑定到了接口”eth0”上,所有数据报的收发都只经过这个接口.

对于SOL_BINDTODEVICE的总结如下:

(1)对于TCP套接口、UDP套接口、RAW套接口,可以通过SO_BINDTODEVICE套接口选项将套接口绑定到指定的网络接口上。绑定之后,套接口的所有数据包收发都只经过指定的网络接口;

(2)对于PF_PACKET类型的套接口,不能通过SO_BINDTODEVICE绑定到指定 的网络接口上,而要通过bind(2)来与特定的网络接口绑定,所用的套接口地址结构为struct sockaddr_ll,此套 接口地址结构是链路层的地址结构,独立于具体的网络设备。比如,该地址结构既可以用于表示PPP设备,也能用于表示ethernet设备。

(3)SO_BINDTODEVICE套接口选项只适用于Linux系统。如果要编写运行在多操作系统平台上的程序,不能依赖SO_BINDTODEVICE来完成套接口 与具体设备的绑定