现有无线网卡和虚拟网卡 utun,想实现通过更改路由表,所有数据由 utun 接收并处理后,由无线网卡发出。
如 data[1.1.1.1] --> utun --> en0 --> server[1.1.1.1]
在 linux 下可通过socket.SO_BINDTODEVICE
选项,将 socket 数据绑定到指定网卡,如 eth0,实现从 tun 设备读取数据,再由 eth0 发出,实验是成功的
而在 mac 上,没有等同于socket.SO_BINDTODEVICE
的选项,搜索一圈,试了各种方法后都不可用!
setsockopt(s, IPPROTO_IP, IP_BOUND_IF, &index, sizeof(index));
int test_bind(int s, const char* dev){
int index = if_nametoindex(dev);
return setsockopt(s, IPPROTO_IP, IP_BOUND_IF, &index, sizeof(index));
}
bind(sock, pAdapterFound->ifa_addr, addrsize)
int BindToDevice(int sock, int family, const char* devicename)
{
struct ifaddrs* pList = NULL;
struct ifaddrs* pAdapter = NULL;
struct ifaddrs* pAdapterFound = NULL;
int bindresult = -1;
int result = getifaddrs(&pList);
if (result < 0)
return -1;
pAdapter = pList;
while (pAdapter)
{
if ((pAdapter->ifa_addr != NULL) && (pAdapter->ifa_name != NULL) && (family == pAdapter->ifa_addr->sa_family))
{
if (strcmp(pAdapter->ifa_name, devicename) == 0)
{
pAdapterFound = pAdapter;
break;
}
}
pAdapter = pAdapter->ifa_next;
}
if (pAdapterFound != NULL)
{
int addrsize = (family == AF_INET6)?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in);
bindresult = bind(sock, pAdapterFound->ifa_addr, addrsize);
}
freeifaddrs(pList);
return bindresult;
}
基本都是报错 Network is unreachable
So mac, what's your problem?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.