2013-11-27 233 views
7

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

这里是我的代码:

/* 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; 
} 

但是我有我的电脑上2张NIC卡,我想只听其中之一。让我们说道德。我发现两个选项绑定和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; 
} 

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

+1

你试过'strlen(ifName)'而不是'IFNAMSIZ-1'吗?只是猜测... –

+0

@PerJohansson:这将是一个坏主意。手册页上说:“传递的选项是一个可变长度** null结尾的**接口名称字符串,其最大大小为'IFNAMSIZ'”,但是'strlen'不能为null。 –

回答

9

从Linux手册页man 7 socket套接字选项SO_BINDTODEVICE:

请注意,这仅适用于一些套接字类型,特别是 AF_INET 插座。它不支持数据包套接字(在那里使用正常的 bind(2))。

0

这里是工作版本。

{ 
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) { 
     } 
}