我有一个Linux设备(实际上是原型的BeagleBoard),带有两个以太网适配器.我想要的是这个:
主以太网接口(eth0)连接到客户端的网络(可以是DHCP或分配静态IP).
第二个以太网接口(eth1)直接连接到另一个Linux板.
Beagle上的用户级C程序可以侦听来自客户端网络的传入连接(在eth0上),根据需要进行响应,并可能连接到eth1上的其他设备
我们希望第二个设备完全隐藏在网络的其余部分,这样只有Beagle上的程序才能连接到它.
我希望这两个接口可以完全分开,我的代码可以选择它想要监听/打开连接的接口.典型代码:
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
memset(&client_addr, 0, sizeof(client_addr));
client_addr.sin_family = AF_INET;
inet_pton( AF_INET, address, (void *)(&(client_addr.sin_addr.s_addr)) );
client_addr.sin_port = htons(port);
/* Connect to remote on TCP port: */
connect(*socket_desc, (struct sockaddr*) &client_addr, sizeof(client_addr) );
...
Run Code Online (Sandbox Code Playgroud)
我们可以设置要连接的地址和端口,但不能设置以太网接口.我找到了这个答案.这是否意味着我想要实现的内容必须留给内核路由?
我知道我可以将eth1设置为自己的子网,但我有一个问题:鉴于我们对客户端的网络一无所知,我怎么知道我使用的子网不会最终冲突与客户的网络?例如,我在这里使用192.168.1.0,所以我可以将eth1放在192.168.0.0上...但是如果客户端使用该范围怎么办?我们不希望为每个部署重新配置eth1及其连接设备的设置,尽管我们可能必须配置eth0.
那么有更好的方法吗?或者也许是我可以用于eth1子网的保留IP地址范围,保证不与客户端网络冲突(例如169.254.1.x)?
对不起,这有点模糊,但我已经谷歌搜索了好几天,可能会变得更加困惑而不是更少.
编辑 - 2013-08-29:
我刚刚发现这个问题提供了部分答案:您可以使用带有SO_BINDTODEVICE的setsockopt(...)来绑定到特定的设备/接口.这似乎有效,尽管在"内部"网络恰好与连接到eth0的"外部"网络具有相同的IP地址范围的情况下,我仍然无法弄清楚如何设置路由表以便可靠地工作.
我正在努力将原始套接字绑定到接口,我的目标是实现简单的数据包嗅探器.已经专门的时间搜索网络并浏览了参考文献,其中一部分列在底部.
我能够打开套接字,绑定没有错误,但是当剥离以太网报头并观察IP报头时,我看到捕获的环回(127.0.0.1)和其他不受欢迎的ethX ifaces流量.
其中一个结论是在我的情况下不能使用setsockopt,这是我的代码片段:
struct sockaddr_ll sll;
int raw_sock;
raw_sock = socket( PF_PACKET , SOCK_RAW , htons(ETH_P_ALL)) ;
// also tried with AF_PACKET
bzero(&sll , sizeof(sll));
sll.sll_family = PF_PACKET;
// also tried with AF_PACKET
sll.sll_ifindex =get_iface_index(raw_sock,"eth1");
// returns valid ifr.ifr_ifindex;
sll.sll_protocol = htons(ETH_P_ALL);
if((bind(raw_sock , (struct sockaddr *)&sll , sizeof(sll))) ==-1)
{
perror("bind: ");
exit(-1);
}
saddr_size = (sizeof sll);
data_size = recvfrom(raw_sock , buffer_ptr, 65536, 0 , &sll , (socklen_t*)&saddr_size);
Run Code Online (Sandbox Code Playgroud)
提前谢谢!
参考文献: …
请任何人都可以帮助解决这个问题.请
在下面的示例代码中,我们将原始sock绑定到eth0.但是在运行程序时,原始sock的recvfrom正在同一台机器(xx_86)上从eth0和eth1接收数据包.我不清楚为什么,可以在这个问题上帮助一个人.我希望setsockopt不能正常运行OS:Fedora core 6(2.6.18-1.2798.fc6)
Sampe代码:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if_ether.h>
#include <net/if.h>
#include <linux/filter.h>
#include <sys/ioctl.h>
#include <string.h>
#include <arpa/inet.h>
int main(int argc, char **argv) {
int sock, i;
unsigned char buffer[2048];
unsigned char tbuff[2048];
unsigned char *iphead, *ethhead,*phead;
struct ifreq ethreq;
// NOTE: use TCPDUMP to build the filter array.
// set filter to sniff only port 443
// $ sudo tcpdump -dd port 443
// raw for recvfrom eth0 …Run Code Online (Sandbox Code Playgroud)