Linux 绑定与 SO_BINDTODEVICE 套接字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20240260/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:28:17  来源:igfitidea点击:

bind vs SO_BINDTODEVICE socket

clinuxsockets

提问by Ami DATA

I'm running a project on linux (ubuntu 13.10) which uses raw socket connecting to a device.

我正在 linux (ubuntu 13.10) 上运行一个项目,它使用连接到设备的原始套接字。

Here is my code:

这是我的代码:

/* builed socket */
if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))) == -1) {
  perror("listener: socket");
  return -1;
}

/* Set interface to promiscuous mode */
strncpy(ifopts.ifr_name, ifName, IFNAMSIZ-1);
ioctl(sockfd, SIOCGIFFLAGS, &ifopts);
ifopts.ifr_flags |= IFF_PROMISC;
ioctl(sockfd, SIOCSIFFLAGS, &ifopts);

/* Allow the socket to be reused - incase connection is closed prematurely */
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
  perror("setsockopt");
  close(sockfd);
  return -2;
}

However I have 2 NIC cards on my computer and I would like to listen only to one of them. lets say etho. I found two options bind and SO_BINDTODEVICE as follows:

但是,我的计算机上有 2 个 NIC 卡,我只想听其中一个。让我们说精神。我发现两个选项 bind 和 SO_BINDTODEVICE 如下:

/* option 1. Bind to device */
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, IFNAMSIZ-1) == -1)  {
  perror("SO_BINDTODEVICE");
  close(sockfd);
  return -4;
}


/* option 2. Bind to device */
memset(&sock_address, 0, sizeof(sock_address));
sock_address.sll_family = PF_PACKET;
sock_address.sll_protocol = htons(ETH_P_ALL);
sock_address.sll_ifindex = if_nametoindex(ifName);
if (bind(sockfd, (struct sockaddr*) &sock_address, sizeof(sock_address)) < 0) {
  perror("bind failed\n");
  close(sockfd);
  return -4;
}

Only bind works. So my question is what is the difference between the two ?

只有绑定有效。所以我的问题是两者之间有什么区别?

回答by thuovila

From the Linux man-page man 7 socketfor socket option SO_BINDTODEVICE:

从 Linux 手册页man 7 socketfor socket option SO_BINDTODEVICE:

Note that this works only for some socket types, particularly AF_INET sockets. It is not supported for packet sockets (use normal bind(2) there).

请注意,这仅适用于某些套接字类型,尤其是 AF_INET 套接字。数据包套接字不支持它(在那里使用普通的 bind(2))。

回答by snake_xy

here is the work version.

这是工作版。

{
struct ifreq if_bind;
strncpy(if_bind.ifr_name, ifName.c_str(), IFNAMSIZ);

if(setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&if_bind,  sizeof(if_bind)) < 0) {
        }
}