mirror of
https://github.com/bol-van/zapret.git
synced 2025-01-06 08:20:34 +05: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.
|
// IPPROTO_RAW with ipv6 in FreeBSD always returns EACCES on sendto.
|
||||||
// must use IPPROTO_TCP for ipv6. IPPROTO_RAW works for ipv4
|
// must use IPPROTO_TCP for ipv6. IPPROTO_RAW works for ipv4
|
||||||
// divert sockets are always v4 but accept both v4 and v6
|
// 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__)
|
#elif defined(__OpenBSD__) || defined (__APPLE__)
|
||||||
// OpenBSD does not allow sending TCP frames through raw sockets
|
// 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
|
// 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()");
|
perror("rawsend: socket()");
|
||||||
return -1;
|
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__
|
#ifdef __linux__
|
||||||
if (setsockopt(*sock, SOL_SOCKET, SO_PRIORITY, &pri, sizeof(pri)) == -1)
|
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);
|
memcpy(&dst2,dst,salen);
|
||||||
if (dst->sa_family==AF_INET6)
|
if (dst->sa_family==AF_INET6)
|
||||||
((struct sockaddr_in6 *)&dst2)->sin6_port = 0; // or will be EINVAL in linux
|
((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__))
|
#if defined(BSD)
|
||||||
// OpenBSD doesnt allow rawsending tcp frames. always use divert socket
|
bytes = rawsend_sendto_divert(dst->sa_family,sock,data,len);
|
||||||
if (dst->sa_family==AF_INET6)
|
if (bytes==-1)
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
ssize_t bytes = rawsend_sendto_divert(dst->sa_family,sock,data,len);
|
perror("rawsend: sendto_divert");
|
||||||
if (bytes==-1)
|
return false;
|
||||||
{
|
|
||||||
perror("rawsend: sendto_divert");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
#endif
|
return true;
|
||||||
|
|
||||||
#if defined(__FreeBSD__) && __FreeBSD__<=10
|
#else
|
||||||
// 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
|
|
||||||
|
|
||||||
#if defined(__linux__)
|
#ifdef __linux__
|
||||||
struct sockaddr_storage sa_src;
|
struct sockaddr_storage sa_src;
|
||||||
switch(dst->sa_family)
|
switch(dst->sa_family)
|
||||||
{
|
{
|
||||||
@ -1774,20 +1732,13 @@ nofix:
|
|||||||
|
|
||||||
// normal raw socket sendto
|
// normal raw socket sendto
|
||||||
bytes = sendto(sock, data, len, 0, (struct sockaddr*)&dst2, salen);
|
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)
|
if (bytes==-1)
|
||||||
{
|
{
|
||||||
perror("rawsend: sendto");
|
perror("rawsend: sendto");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // not CYGWIN
|
#endif // not CYGWIN
|
||||||
|
Loading…
Reference in New Issue
Block a user