Linux OS X相当于SO_BINDTODEVICE

Linux OS X相当于SO_BINDTODEVICE,linux,macos,sockets,vpn,Linux,Macos,Sockets,Vpn,Linux允许执行以下代码将套接字绑定到某个特定的网络接口。因此,通过该套接字发送的数据将始终通过原始接口传输 setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name)) 据我所知,此功能用于VPN客户端。套接字连接到远程服务器并绑定到网络接口。这样,来自VPN客户端本身的流量就不会循环回VPN客户端 有没有OSX等效于这样做?或者 将套接字绑定到某个特定接口 将VPN客户端中的套接字标记为不环回 顺便说一句,我发

Linux允许执行以下代码将套接字绑定到某个特定的网络接口。因此,通过该套接字发送的数据将始终通过原始接口传输

setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, name, strlen(name))
据我所知,此功能用于VPN客户端。套接字连接到远程服务器并绑定到网络接口。这样,来自VPN客户端本身的流量就不会循环回VPN客户端

有没有OSX等效于这样做?或者

  • 将套接字绑定到某个特定接口

  • 将VPN客户端中的套接字标记为不环回

顺便说一句,我发现了类似的问题,但我不明白答案:

更新1

我发现一些VPN客户端使用TUN/TAP设备来防止环回问题。

然而,我并不是说所有的OSX VPN都使用它。

使用getifaddrs()来标识设备的地址,然后直接绑定到该设备是否有效?或者,除了传统的bind()调用之外,sou BINDTODEVICE是否还有其他行为

int-BindToDevice(int-sock、int-family、const-char*devicename)
{
ifaddrs*pList=NULL;
ifaddrs*pAdapter=NULL;
ifaddrs*pAdapterFound=NULL;
int bindresult=-1;
int result=getifaddrs(&pList);
如果(结果<0)
返回-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;
打破
}
}
pAdapter=pAdapter->ifa\u next;
}
if(pAdapterFound!=NULL)
{
int addrsize=(family==AF_INET6)?sizeof(sockaddr_in6):sizeof(sockaddr_in);
bindresult=bind(sock,pAdapterFound->ifa_addr,addrsize);
}
freeifaddrs(pList);
返回结果;
}

使用RFC 3542接口选择传出接口(IPV6\u PKTINFO)。 这对我很有效:

char ethInterface[4] = "en0";
setsockopt(sock, SOL_SOCKET, IP_RECVIF, ethInterface, strlen(ethInterface));

是的,如果

int idx = if_nametoindex("en0");
setsockopt(sockfd, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx))

但是,您可以将
bind()
与接口的IP地址一起使用,这通常会更简单。

我的印象是,bind()仅用于执行listen()和accept()的情况。但是,在我的例子中,我想做connect(),因为这个套接字是为客户机设计的。只要路由表允许,它也可以与客户机(connect)套接字一起工作。-1听起来不太正确。根据Stevens的说法,这不是用于指定接收/发送接口的名称,而是用于指定:“此套接字选项导致接收UDP数据报的接口的索引作为辅助数据由recvmsg返回。”
int idx = if_nametoindex("en0");
setsockopt(sockfd, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx))