mirror of
https://github.com/bol-van/zapret.git
synced 2024-11-29 21:40:52 +03:00
dvtws: do not use raw sockets on BSD. always use divert.
This commit is contained in:
parent
600b6c6521
commit
a863c35ce3
@ -1621,7 +1621,7 @@ static int rawsend_socket(sa_family_t family)
|
||||
// IPPROTO_RAW with ipv6 in FreeBSD always returns EACCES on sendto.
|
||||
// must use IPPROTO_TCP for ipv6. IPPROTO_RAW works for ipv4
|
||||
// divert sockets are always v4 but accept both v4 and v6
|
||||
*sock = (family==AF_INET) ? rawsend_socket_raw(family, IPPROTO_TCP) : rawsend_socket_divert(AF_INET);
|
||||
*sock = rawsend_socket_divert(AF_INET);
|
||||
#elif defined(__OpenBSD__) || defined (__APPLE__)
|
||||
// OpenBSD does not allow sending TCP frames through raw sockets
|
||||
// I dont know about macos. They have dropped ipfw in recent versions and their PF does not support divert-packet
|
||||
@ -1634,16 +1634,6 @@ static int rawsend_socket(sa_family_t family)
|
||||
perror("rawsend: socket()");
|
||||
return -1;
|
||||
}
|
||||
#ifdef BSD
|
||||
#if !(defined(__OpenBSD__) || defined (__APPLE__))
|
||||
// HDRINCL not supported for ipv6 in any BSD
|
||||
if (family==AF_INET && setsockopt(*sock,IPPROTO_IP,IP_HDRINCL,&yes,sizeof(yes)) == -1)
|
||||
{
|
||||
perror("rawsend: setsockopt(IP_HDRINCL)");
|
||||
goto exiterr;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __linux__
|
||||
if (setsockopt(*sock, SOL_SOCKET, SO_PRIORITY, &pri, sizeof(pri)) == -1)
|
||||
{
|
||||
@ -1691,51 +1681,19 @@ bool rawsend(const struct sockaddr* dst,uint32_t fwmark,const char *ifout,const
|
||||
memcpy(&dst2,dst,salen);
|
||||
if (dst->sa_family==AF_INET6)
|
||||
((struct sockaddr_in6 *)&dst2)->sin6_port = 0; // or will be EINVAL in linux
|
||||
#ifdef BSD
|
||||
/*
|
||||
// this works only for local connections and not working for transit : cant spoof source addr
|
||||
if (len>=sizeof(struct ip6_hdr))
|
||||
{
|
||||
// BSD ipv6 raw socks are limited. cannot pass the whole packet with ip6 header.
|
||||
struct sockaddr_storage sa_src;
|
||||
int v;
|
||||
extract_endpoints(NULL,(struct ip6_hdr *)data,NULL,NULL, &sa_src, NULL);
|
||||
v = ((struct ip6_hdr *)data)->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||
if (setsockopt(sock, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &v, sizeof(v)) == -1)
|
||||
perror("rawsend: setsockopt(IPV6_HOPLIMIT)");
|
||||
// the only way to control source address is bind. make it equal to ip6_hdr
|
||||
if (bind(sock, (struct sockaddr*)&sa_src, salen) < 0)
|
||||
perror("rawsend bind: ");
|
||||
//printf("BSD v6 RAWSEND "); print_sockaddr((struct sockaddr*)&sa_src); printf(" -> "); print_sockaddr((struct sockaddr*)&dst2); printf("\n");
|
||||
proto_skip_ipv6((uint8_t**)&data, &len, NULL);
|
||||
}
|
||||
*/
|
||||
|
||||
#if !(defined(__OpenBSD__) || defined (__APPLE__))
|
||||
// OpenBSD doesnt allow rawsending tcp frames. always use divert socket
|
||||
if (dst->sa_family==AF_INET6)
|
||||
#endif
|
||||
#if defined(BSD)
|
||||
bytes = rawsend_sendto_divert(dst->sa_family,sock,data,len);
|
||||
if (bytes==-1)
|
||||
{
|
||||
ssize_t bytes = rawsend_sendto_divert(dst->sa_family,sock,data,len);
|
||||
if (bytes==-1)
|
||||
{
|
||||
perror("rawsend: sendto_divert");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
perror("rawsend: sendto_divert");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
|
||||
#if defined(__FreeBSD__) && __FreeBSD__<=10
|
||||
// old FreeBSD requires some fields in host byte order
|
||||
if (dst->sa_family==AF_INET && len>=sizeof(struct ip))
|
||||
{
|
||||
((struct ip*)data)->ip_len = htons(((struct ip*)data)->ip_len);
|
||||
((struct ip*)data)->ip_off = htons(((struct ip*)data)->ip_off);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
|
||||
#if defined(__linux__)
|
||||
#ifdef __linux__
|
||||
struct sockaddr_storage sa_src;
|
||||
switch(dst->sa_family)
|
||||
{
|
||||
@ -1774,20 +1732,13 @@ nofix:
|
||||
|
||||
// normal raw socket sendto
|
||||
bytes = sendto(sock, data, len, 0, (struct sockaddr*)&dst2, salen);
|
||||
#if defined(__FreeBSD) && __FreeBSD__<=10
|
||||
// restore byte order
|
||||
if (dst->sa_family==AF_INET && len>=sizeof(struct ip))
|
||||
{
|
||||
((struct ip*)data)->ip_len = htons(((struct ip*)data)->ip_len);
|
||||
((struct ip*)data)->ip_off = htons(((struct ip*)data)->ip_off);
|
||||
}
|
||||
#endif
|
||||
if (bytes==-1)
|
||||
{
|
||||
perror("rawsend: sendto");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // not CYGWIN
|
||||
|
Loading…
Reference in New Issue
Block a user