mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-13 22:03:09 +00:00
icmp and ipp support
This commit is contained in:
@@ -10,11 +10,11 @@ LIBS =
|
||||
LIBS_LINUX = -lz -lnetfilter_queue -lnfnetlink -lmnl -lm
|
||||
LIBS_SYSTEMD = -lsystemd
|
||||
LIBS_BSD = -lz -lm
|
||||
LIBS_CYGWIN = -lz -Lwindows/windivert -Iwindows -lwlanapi -lole32 -loleaut32
|
||||
LIBS_CYGWIN = -lz -Lwindows/windivert -Iwindows -lwlanapi -lole32 -loleaut32 -liphlpapi -lntdll
|
||||
LIBS_CYGWIN32 = -lwindivert32
|
||||
LIBS_CYGWIN64 = -lwindivert64
|
||||
RES_CYGWIN32 = windows/res/32/winmanifest.o windows/res/32/winicon.o
|
||||
RES_CYGWIN64 = windows/res/64/winmanifest.o windows/res/64/winicon.o
|
||||
RES_CYGWIN32 = windows/res/winws_res32.o
|
||||
RES_CYGWIN64 = windows/res/winws_res64.o
|
||||
SRC_FILES = *.c crypto/*.c
|
||||
|
||||
LUA_JIT?=1
|
||||
|
||||
@@ -95,10 +95,7 @@ static uint16_t do_csum(const uint8_t *buff, size_t len)
|
||||
return u16;
|
||||
}
|
||||
|
||||
uint16_t csum_partial(const void *buff, size_t len)
|
||||
{
|
||||
return do_csum(buff, len);
|
||||
}
|
||||
#define csum_partial(buff, len) do_csum((const uint8_t*)buff,len)
|
||||
|
||||
uint16_t csum_tcpudp_magic(uint32_t saddr, uint32_t daddr, size_t len, uint8_t proto, uint16_t sum)
|
||||
{
|
||||
@@ -107,7 +104,7 @@ uint16_t csum_tcpudp_magic(uint32_t saddr, uint32_t daddr, size_t len, uint8_t p
|
||||
|
||||
uint16_t ip4_compute_csum(const void *buff, size_t len)
|
||||
{
|
||||
return ~from64to16(do_csum(buff, len));
|
||||
return ~csum_partial(buff, len);
|
||||
}
|
||||
void ip4_fix_checksum(struct ip *ip)
|
||||
{
|
||||
@@ -158,3 +155,21 @@ void udp_fix_checksum(struct udphdr *udp, size_t len, const struct ip *ip, const
|
||||
else if (ip6hdr)
|
||||
udp6_fix_checksum(udp, len, &ip6hdr->ip6_src, &ip6hdr->ip6_dst);
|
||||
}
|
||||
|
||||
void icmp4_fix_checksum(struct icmp46 *icmp, size_t len)
|
||||
{
|
||||
icmp->icmp_cksum = 0;
|
||||
icmp->icmp_cksum = ~csum_partial(icmp, len);
|
||||
}
|
||||
void icmp6_fix_checksum(struct icmp46 *icmp, size_t len, const struct ip6_hdr *ip6hdr)
|
||||
{
|
||||
icmp->icmp_cksum = 0;
|
||||
icmp->icmp_cksum = csum_ipv6_magic(&ip6hdr->ip6_src, &ip6hdr->ip6_dst, len, IPPROTO_ICMPV6, csum_partial(icmp, len));
|
||||
}
|
||||
void icmp_fix_checksum(struct icmp46 *icmp, size_t len, const struct ip6_hdr *ip6hdr)
|
||||
{
|
||||
if (ip6hdr)
|
||||
icmp6_fix_checksum(icmp, len, ip6hdr);
|
||||
else
|
||||
icmp4_fix_checksum(icmp, len);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,20 @@
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
|
||||
// icmp 4 and 6 are basically compatible although checksums are calculated differently
|
||||
// do not use version specific structs
|
||||
struct icmp46
|
||||
{
|
||||
uint8_t icmp_type, icmp_code;
|
||||
uint16_t icmp_cksum;
|
||||
union
|
||||
{
|
||||
uint32_t icmp_data32;
|
||||
uint16_t icmp_data16[2];
|
||||
uint8_t icmp_data8[4];
|
||||
};
|
||||
};
|
||||
|
||||
uint16_t csum_partial(const void *buff, size_t len);
|
||||
uint16_t csum_tcpudp_magic(uint32_t saddr, uint32_t daddr, size_t len, uint8_t proto, uint16_t sum);
|
||||
uint16_t csum_ipv6_magic(const void *saddr, const void *daddr, size_t len, uint8_t proto, uint16_t sum);
|
||||
@@ -25,3 +39,7 @@ void tcp_fix_checksum(struct tcphdr *tcp,size_t len,const struct ip *ip,const st
|
||||
void udp4_fix_checksum(struct udphdr *udp,size_t len, const struct in_addr *src_addr, const struct in_addr *dest_addr);
|
||||
void udp6_fix_checksum(struct udphdr *udp,size_t len, const struct in6_addr *src_addr, const struct in6_addr *dest_addr);
|
||||
void udp_fix_checksum(struct udphdr *udp,size_t len,const struct ip *ip,const struct ip6_hdr *ip6hdr);
|
||||
|
||||
void icmp4_fix_checksum(struct icmp46 *icmp, size_t len);
|
||||
void icmp6_fix_checksum(struct icmp46 *icmp, size_t len, const struct ip6_hdr *ip6hdr);
|
||||
void icmp_fix_checksum(struct icmp46 *icmp, size_t len, const struct ip6_hdr *ip6hdr);
|
||||
|
||||
@@ -70,7 +70,7 @@ void ConntrackPoolInit(t_conntrack *p, time_t purge_interval, uint32_t timeout_s
|
||||
p->pool = NULL;
|
||||
}
|
||||
|
||||
void ConntrackExtractConn(t_conn *c, bool bReverse, const struct dissect *dis)
|
||||
bool ConntrackExtractConn(t_conn *c, bool bReverse, const struct dissect *dis)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
if (dis->ip)
|
||||
@@ -86,8 +86,9 @@ void ConntrackExtractConn(t_conn *c, bool bReverse, const struct dissect *dis)
|
||||
c->src.ip6 = bReverse ? dis->ip6->ip6_dst : dis->ip6->ip6_src;
|
||||
}
|
||||
else
|
||||
c->l3proto = -1;
|
||||
return false;
|
||||
extract_ports(dis->tcp, dis->udp, &c->l4proto, bReverse ? &c->dport : &c->sport, bReverse ? &c->sport : &c->dport);
|
||||
return c->l4proto!=IPPROTO_NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -225,7 +226,7 @@ static bool ConntrackPoolDoubleSearchPool(t_conntrack_pool **pp, const struct di
|
||||
t_conn conn, connswp;
|
||||
t_conntrack_pool *ctr;
|
||||
|
||||
ConntrackExtractConn(&conn, false, dis);
|
||||
if (!ConntrackExtractConn(&conn, false, dis)) return false;
|
||||
if ((ctr = ConntrackPoolSearch(*pp, &conn)))
|
||||
{
|
||||
if (bReverse) *bReverse = false;
|
||||
@@ -256,7 +257,7 @@ static bool ConntrackPoolFeedPool(t_conntrack_pool **pp, const struct dissect *d
|
||||
bool b_rev;
|
||||
uint8_t proto = dis->tcp ? IPPROTO_TCP : dis->udp ? IPPROTO_UDP : IPPROTO_NONE;
|
||||
|
||||
ConntrackExtractConn(&conn, false, dis);
|
||||
if (!ConntrackExtractConn(&conn, false, dis)) return false;
|
||||
if ((ctr = ConntrackPoolSearch(*pp, &conn)))
|
||||
{
|
||||
ConntrackFeedPacket(&ctr->track, (b_rev = false), dis);
|
||||
@@ -296,7 +297,7 @@ static bool ConntrackPoolDropPool(t_conntrack_pool **pp, const struct dissect *d
|
||||
{
|
||||
t_conn conn, connswp;
|
||||
t_conntrack_pool *t;
|
||||
ConntrackExtractConn(&conn, false, dis);
|
||||
if (!ConntrackExtractConn(&conn, false, dis)) return false;
|
||||
if (!(t = ConntrackPoolSearch(*pp, &conn)))
|
||||
{
|
||||
connswap(&conn, &connswp);
|
||||
|
||||
@@ -105,7 +105,7 @@ bool ConntrackPoolFeed(t_conntrack *p, const struct dissect *dis, t_ctrack **ctr
|
||||
// do not create, do not update. only find existing
|
||||
bool ConntrackPoolDoubleSearch(t_conntrack *p, const struct dissect *dis, t_ctrack **ctrack, bool *bReverse);
|
||||
bool ConntrackPoolDrop(t_conntrack *p, const struct dissect *dis);
|
||||
void ConntrackExtractConn(t_conn *c, bool bReverse, const struct dissect *dis);
|
||||
bool ConntrackExtractConn(t_conn *c, bool bReverse, const struct dissect *dis);
|
||||
void ConntrackPoolDump(const t_conntrack *p);
|
||||
void ConntrackPoolPurge(t_conntrack *p);
|
||||
void ConntrackClearHostname(t_ctrack *track);
|
||||
|
||||
@@ -103,9 +103,6 @@ int hkdfExtract(SHAversion whichSha,
|
||||
salt_len = USHAHashSize(whichSha);
|
||||
memset(nullSalt, '\0', salt_len);
|
||||
}
|
||||
else if (salt_len < 0) {
|
||||
return shaBadParam;
|
||||
}
|
||||
return hmac(whichSha, ikm, ikm_len, salt, salt_len, prk);
|
||||
}
|
||||
|
||||
@@ -154,11 +151,7 @@ int hkdfExpand(SHAversion whichSha, const uint8_t prk[], size_t prk_len,
|
||||
info = (const unsigned char *)"";
|
||||
info_len = 0;
|
||||
}
|
||||
else if (info_len < 0) {
|
||||
return shaBadParam;
|
||||
}
|
||||
if (okm_len <= 0) return shaBadParam;
|
||||
if (!okm) return shaBadParam;
|
||||
if (!okm || !okm_len) return shaBadParam;
|
||||
|
||||
hash_len = USHAHashSize(whichSha);
|
||||
if (prk_len < hash_len) return shaBadParam;
|
||||
|
||||
362
nfq2/darkmagic.c
362
nfq2/darkmagic.c
@@ -33,6 +33,8 @@
|
||||
#define ERROR_INVALID_IMAGE_HASH __MSABI_LONG(577)
|
||||
#endif
|
||||
|
||||
#include "nthacks.h"
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
@@ -102,7 +104,7 @@ void extract_ports(const struct tcphdr *tcphdr, const struct udphdr *udphdr, uin
|
||||
{
|
||||
if (sport) *sport = htons(tcphdr ? tcphdr->th_sport : udphdr ? udphdr->uh_sport : 0);
|
||||
if (dport) *dport = htons(tcphdr ? tcphdr->th_dport : udphdr ? udphdr->uh_dport : 0);
|
||||
if (proto) *proto = tcphdr ? IPPROTO_TCP : udphdr ? IPPROTO_UDP : -1;
|
||||
if (proto) *proto = tcphdr ? IPPROTO_TCP : udphdr ? IPPROTO_UDP : IPPROTO_NONE;
|
||||
}
|
||||
|
||||
bool extract_dst(const uint8_t *data, size_t len, struct sockaddr* dst)
|
||||
@@ -174,6 +176,11 @@ void extract_endpoints(const struct ip *ip,const struct ip6_hdr *ip6hdr,const st
|
||||
si->sin6_scope_id = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(src,0,sizeof(*src));
|
||||
memset(dst,0,sizeof(*dst));
|
||||
}
|
||||
}
|
||||
|
||||
const char *proto_name(uint8_t proto)
|
||||
@@ -192,8 +199,6 @@ const char *proto_name(uint8_t proto)
|
||||
return "igmp";
|
||||
case IPPROTO_ESP:
|
||||
return "esp";
|
||||
case IPPROTO_AH:
|
||||
return "ah";
|
||||
case IPPROTO_IPV6:
|
||||
return "6in4";
|
||||
case IPPROTO_IPIP:
|
||||
@@ -210,7 +215,7 @@ const char *proto_name(uint8_t proto)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
static void str_proto_name(char *s, size_t s_len, uint8_t proto)
|
||||
void str_proto_name(char *s, size_t s_len, uint8_t proto)
|
||||
{
|
||||
const char *name = proto_name(proto);
|
||||
if (name)
|
||||
@@ -228,6 +233,56 @@ uint16_t family_from_proto(uint8_t l3proto)
|
||||
}
|
||||
}
|
||||
|
||||
const char *icmp_type_name(bool v6, uint8_t type)
|
||||
{
|
||||
if (v6)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ICMP6_ECHO_REQUEST: return "echo_req6";
|
||||
case ICMP6_ECHO_REPLY: return "echo_reply6";
|
||||
case ICMP6_DST_UNREACH: return "dest_unreach6";
|
||||
case ICMP6_PACKET_TOO_BIG: return "packet_too_big";
|
||||
case ICMP6_TIME_EXCEEDED: return "time_exceeded6";
|
||||
case ICMP6_PARAM_PROB: return "param_problem6";
|
||||
case MLD_LISTENER_QUERY: return "mld_listener_query";
|
||||
case MLD_LISTENER_REPORT: return "mld_listener_report";
|
||||
case MLD_LISTENER_REDUCTION: return "mld_listener_reduction";
|
||||
case ND_ROUTER_SOLICIT: return "router_sol";
|
||||
case ND_ROUTER_ADVERT: return "router_adv";
|
||||
case ND_NEIGHBOR_SOLICIT: return "neigh_sol";
|
||||
case ND_NEIGHBOR_ADVERT: return "neigh_adv";
|
||||
case ND_REDIRECT: return "redirect6";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case ICMP_ECHOREPLY: return "echo_reply";
|
||||
case ICMP_DEST_UNREACH: return "dest_unreach";
|
||||
case ICMP_REDIRECT: return "redirect";
|
||||
case ICMP_ECHO: return "echo_req";
|
||||
case ICMP_TIME_EXCEEDED: return "time_exceeded";
|
||||
case ICMP_PARAMETERPROB: return "param_problem";
|
||||
case ICMP_TIMESTAMP: return "ts";
|
||||
case ICMP_TIMESTAMPREPLY: return "ts_reply";
|
||||
case ICMP_INFO_REQUEST: return "info_req";
|
||||
case ICMP_INFO_REPLY: return "info_reply";
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void str_icmp_type_name(char *s, size_t s_len, bool v6, uint8_t type)
|
||||
{
|
||||
const char *name = icmp_type_name(v6, type);
|
||||
if (name)
|
||||
snprintf(s,s_len,"%s",name);
|
||||
else
|
||||
snprintf(s,s_len,"%u",type);
|
||||
}
|
||||
|
||||
|
||||
static void str_srcdst_ip(char *s, size_t s_len, const void *saddr,const void *daddr)
|
||||
{
|
||||
char s_ip[16],d_ip[16];
|
||||
@@ -298,7 +353,21 @@ void print_udphdr(const struct udphdr *udphdr)
|
||||
str_udphdr(s,sizeof(s),udphdr);
|
||||
printf("%s",s);
|
||||
}
|
||||
|
||||
void str_icmphdr(char *s, size_t s_len, bool v6, const struct icmp46 *icmp)
|
||||
{
|
||||
char stype[32];
|
||||
str_icmp_type_name(stype,sizeof(stype),v6,icmp->icmp_type);
|
||||
if (icmp->icmp_type==ICMP_ECHO || icmp->icmp_type==ICMP_ECHOREPLY || icmp->icmp_type==ICMP6_ECHO_REQUEST || icmp->icmp_type==ICMP6_ECHO_REPLY)
|
||||
snprintf(s,s_len,"icmp_type=%s icmp_code=%u id=0x%04X seq=%u",stype,icmp->icmp_code,ntohs(icmp->icmp_data16[0]),ntohs(icmp->icmp_data16[1]));
|
||||
else
|
||||
snprintf(s,s_len,"icmp_type=%s icmp_code=%u data=0x%08X",stype,icmp->icmp_code,ntohl(icmp->icmp_data32));
|
||||
}
|
||||
void print_icmphdr(const struct icmp46 *icmp, bool v6)
|
||||
{
|
||||
char s[48];
|
||||
str_icmphdr(s,sizeof(s),v6,icmp);
|
||||
printf("%s",s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -340,7 +409,15 @@ void proto_skip_udp(const uint8_t **data, size_t *len)
|
||||
*data += sizeof(struct udphdr);
|
||||
*len -= sizeof(struct udphdr);
|
||||
}
|
||||
|
||||
bool proto_check_icmp(const uint8_t *data, size_t len)
|
||||
{
|
||||
return len >= sizeof(struct icmp46);
|
||||
}
|
||||
void proto_skip_icmp(const uint8_t **data, size_t *len)
|
||||
{
|
||||
*data += sizeof(struct icmp46);
|
||||
*len -= sizeof(struct icmp46);
|
||||
}
|
||||
bool proto_check_ipv6(const uint8_t *data, size_t len)
|
||||
{
|
||||
return len >= sizeof(struct ip6_hdr) && (data[0] & 0xF0) == 0x60;
|
||||
@@ -449,7 +526,7 @@ uint8_t *proto_find_ip6_exthdr(struct ip6_hdr *ip6, size_t len, uint8_t proto)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis)
|
||||
void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis, bool no_payload_check)
|
||||
{
|
||||
const uint8_t *p;
|
||||
|
||||
@@ -466,7 +543,7 @@ void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis)
|
||||
proto_skip_ipv4(&data, &len);
|
||||
dis->len_l3 = data-p;
|
||||
}
|
||||
else if (proto_check_ipv6(data, len) && proto_check_ipv6_payload(data, len))
|
||||
else if (proto_check_ipv6(data, len) && (no_payload_check || proto_check_ipv6_payload(data, len)))
|
||||
{
|
||||
dis->ip6 = (const struct ip6_hdr *) data;
|
||||
p = data;
|
||||
@@ -478,32 +555,37 @@ void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis)
|
||||
return;
|
||||
}
|
||||
|
||||
dis->transport_len = len;
|
||||
|
||||
if (dis->proto==IPPROTO_TCP && proto_check_tcp(data, len))
|
||||
{
|
||||
dis->tcp = (const struct tcphdr *) data;
|
||||
dis->transport_len = len;
|
||||
|
||||
p = data;
|
||||
proto_skip_tcp(&data, &len);
|
||||
dis->len_l4 = data-p;
|
||||
|
||||
dis->data_payload = data;
|
||||
dis->len_payload = len;
|
||||
|
||||
}
|
||||
else if (dis->proto==IPPROTO_UDP && proto_check_udp(data, len) && proto_check_udp_payload(data, len))
|
||||
else if (dis->proto==IPPROTO_UDP && proto_check_udp(data, len) && (no_payload_check || proto_check_udp_payload(data, len)))
|
||||
{
|
||||
dis->udp = (const struct udphdr *) data;
|
||||
dis->transport_len = len;
|
||||
|
||||
p = data;
|
||||
proto_skip_udp(&data, &len);
|
||||
dis->len_l4 = data-p;
|
||||
}
|
||||
else if ((dis->proto==IPPROTO_ICMP || dis->proto==IPPROTO_ICMPV6) && proto_check_icmp(data, len))
|
||||
{
|
||||
dis->icmp = (const struct icmp46 *) data;
|
||||
p = data;
|
||||
proto_skip_icmp(&data, &len);
|
||||
dis->len_l4 = data-p;
|
||||
}
|
||||
else
|
||||
{
|
||||
dis->len_l4 = 0;
|
||||
}
|
||||
|
||||
dis->data_payload = data;
|
||||
dis->len_payload = len;
|
||||
}
|
||||
}
|
||||
|
||||
void reverse_ip(struct ip *ip, struct ip6_hdr *ip6)
|
||||
{
|
||||
@@ -539,12 +621,137 @@ uint8_t ttl46(const struct ip *ip, const struct ip6_hdr *ip6)
|
||||
}
|
||||
|
||||
|
||||
bool get_source_ip4(const struct in_addr *target, struct in_addr *source)
|
||||
{
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0) return false;
|
||||
|
||||
struct sockaddr_in serv,name;
|
||||
socklen_t namelen;
|
||||
|
||||
memset(&serv,0,sizeof(serv)); // or valgrind complains about uninitialized
|
||||
serv.sin_family = AF_INET;
|
||||
serv.sin_addr = *target;
|
||||
serv.sin_port = 0xFFFF;
|
||||
|
||||
// Connect triggers the kernel's route lookup
|
||||
if (!connect(sock, (const struct sockaddr*)&serv, sizeof(serv)))
|
||||
{
|
||||
namelen = sizeof(name);
|
||||
if (!getsockname(sock, (struct sockaddr*)&name, &namelen))
|
||||
{
|
||||
close(sock);
|
||||
*source = name.sin_addr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
close(sock);
|
||||
return false;
|
||||
}
|
||||
bool get_source_ip6(const struct in6_addr *target, struct in6_addr *source)
|
||||
{
|
||||
int sock = socket(AF_INET6, SOCK_DGRAM, 0);
|
||||
if (sock < 0) return false;
|
||||
|
||||
struct sockaddr_in6 serv,name;
|
||||
socklen_t namelen;
|
||||
|
||||
memset(&serv,0,sizeof(serv)); // or valgrind complains about uninitialized
|
||||
serv.sin6_family = AF_INET6;
|
||||
serv.sin6_addr = *target;
|
||||
serv.sin6_port = 0xFFFF;
|
||||
|
||||
// Connect triggers the kernel's route lookup
|
||||
if (!connect(sock, (const struct sockaddr*)&serv, sizeof(serv)))
|
||||
{
|
||||
namelen = sizeof(name);
|
||||
if (!getsockname(sock, (struct sockaddr*)&name, &namelen))
|
||||
{
|
||||
close(sock);
|
||||
*source = name.sin6_addr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
close(sock);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
|
||||
uint32_t w_win32_error=0;
|
||||
|
||||
BOOL AdjustPrivileges(HANDLE hToken, const LPCTSTR *privs, BOOL bEnable)
|
||||
{
|
||||
DWORD dwSize, k, n;
|
||||
PTOKEN_PRIVILEGES TokenPrivsData;
|
||||
LUID luid;
|
||||
|
||||
dwSize = 0;
|
||||
GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &dwSize ); // will fail
|
||||
w_win32_error = GetLastError();
|
||||
if (w_win32_error == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
w_win32_error = 0;
|
||||
if (TokenPrivsData = (PTOKEN_PRIVILEGES)LocalAlloc(LMEM_FIXED, dwSize))
|
||||
{
|
||||
if (GetTokenInformation(hToken, TokenPrivileges, TokenPrivsData, dwSize, &dwSize))
|
||||
{
|
||||
n = 0;
|
||||
while (privs[n])
|
||||
{
|
||||
if (LookupPrivilegeValue(NULL, privs[n], &luid))
|
||||
{
|
||||
w_win32_error = ERROR_PRIVILEGE_NOT_HELD;
|
||||
for (k = 0; k < TokenPrivsData->PrivilegeCount; k++)
|
||||
if (!memcmp(&TokenPrivsData->Privileges[k].Luid, &luid, sizeof(LUID)))
|
||||
{
|
||||
if (bEnable)
|
||||
TokenPrivsData->Privileges[k].Attributes |= SE_PRIVILEGE_ENABLED;
|
||||
else
|
||||
TokenPrivsData->Privileges[k].Attributes &= ~SE_PRIVILEGE_ENABLED;
|
||||
w_win32_error = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
w_win32_error = GetLastError();
|
||||
if (w_win32_error) break;
|
||||
n++;
|
||||
}
|
||||
if (!w_win32_error)
|
||||
{
|
||||
if (!AdjustTokenPrivileges(hToken, FALSE, TokenPrivsData, 0, NULL, NULL))
|
||||
w_win32_error = GetLastError();
|
||||
}
|
||||
}
|
||||
else
|
||||
w_win32_error = GetLastError();
|
||||
LocalFree(TokenPrivsData);
|
||||
}
|
||||
else
|
||||
w_win32_error = GetLastError();
|
||||
}
|
||||
return !w_win32_error;
|
||||
}
|
||||
BOOL AdjustPrivilegesForCurrentProcess(const LPCTSTR *privs, BOOL bEnable)
|
||||
{
|
||||
HANDLE hTokenThisProcess;
|
||||
|
||||
w_win32_error = 0;
|
||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hTokenThisProcess))
|
||||
{
|
||||
if (!AdjustPrivileges(hTokenThisProcess, privs, bEnable))
|
||||
w_win32_error = GetLastError();
|
||||
CloseHandle(hTokenThisProcess);
|
||||
}
|
||||
else
|
||||
w_win32_error = GetLastError();
|
||||
|
||||
return !w_win32_error;
|
||||
}
|
||||
|
||||
static BOOL RemoveTokenPrivs(void)
|
||||
{
|
||||
BOOL bRes = FALSE;
|
||||
@@ -670,6 +877,26 @@ err:
|
||||
if (!bRes) w_win32_error = GetLastError();
|
||||
return bRes;
|
||||
}
|
||||
BOOL SetMandatoryLabelObject(HANDLE h, SE_OBJECT_TYPE ObjType, DWORD dwMandatoryLabelRID, DWORD dwAceRevision, DWORD dwAceFlags)
|
||||
{
|
||||
BOOL bRes = FALSE;
|
||||
DWORD dwErr;
|
||||
char buf_label[16], buf_pacl[32];
|
||||
PSID label = (PSID)buf_label;
|
||||
PACL pacl = (PACL)buf_pacl;
|
||||
|
||||
InitializeSid(label, &label_authority, 1);
|
||||
*GetSidSubAuthority(label, 0) = dwMandatoryLabelRID;
|
||||
if (InitializeAcl(pacl, sizeof(buf_pacl), ACL_REVISION) && AddMandatoryAce(pacl, dwAceRevision, dwAceFlags, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, label))
|
||||
{
|
||||
dwErr = SetSecurityInfo(h, ObjType, LABEL_SECURITY_INFORMATION, NULL, NULL, NULL, pacl);
|
||||
SetLastError(dwErr);
|
||||
bRes = dwErr == ERROR_SUCCESS;
|
||||
}
|
||||
if (!bRes) w_win32_error = GetLastError();
|
||||
return bRes;
|
||||
}
|
||||
|
||||
|
||||
bool ensure_file_access(const char *filename)
|
||||
{
|
||||
@@ -703,6 +930,85 @@ bool prepare_low_appdata()
|
||||
return b;
|
||||
}
|
||||
|
||||
// cygwin uses nt directory to store it's state. low mandatory breaks write access there and cause some functions to fail
|
||||
// it's not possible to reproduce exact directory names, have to iterate and set low integrity to all
|
||||
BOOL RelaxCygwinNTDir()
|
||||
{
|
||||
NTSTATUS status;
|
||||
PROCESS_SESSION_INFORMATION psi;
|
||||
WCHAR bno_name[32], cyg_name[256];
|
||||
CHAR scyg_name[256];
|
||||
UNICODE_STRING bno_us, cyg_us;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
HANDLE hDir, hDirCyg;
|
||||
BYTE buf[4096];
|
||||
ULONG context, rsize;
|
||||
BOOL b,ball,restart;
|
||||
POBJECT_DIRECTORY_INFORMATION pdir;
|
||||
|
||||
LPCTSTR Privs[] = { SE_TAKE_OWNERSHIP_NAME , NULL };
|
||||
|
||||
if (!AdjustPrivilegesForCurrentProcess(Privs, TRUE))
|
||||
return FALSE;
|
||||
|
||||
status = NtQueryInformationProcess(GetCurrentProcess(), ProcessSessionInformation, &psi, sizeof psi, NULL);
|
||||
if (NT_SUCCESS(status))
|
||||
swprintf(bno_name, sizeof(bno_name)/sizeof(*bno_name), L"\\Sessions\\BNOLINKS\\%u", psi.SessionId);
|
||||
else
|
||||
swprintf(bno_name, sizeof(bno_name)/sizeof(*bno_name), L"\\BaseNamedObjects");
|
||||
|
||||
RtlInitUnicodeString(&bno_us, bno_name);
|
||||
InitializeObjectAttributes(&attr, &bno_us, 0, NULL, NULL);
|
||||
|
||||
ball = TRUE;
|
||||
w_win32_error = 0;
|
||||
status = NtOpenDirectoryObject(&hDir, DIRECTORY_QUERY, &attr);
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
context = 0;
|
||||
restart = TRUE;
|
||||
while (NT_SUCCESS(status = NtQueryDirectoryObject(hDir, buf, sizeof(buf), restart, FALSE, &context, &rsize)))
|
||||
{
|
||||
|
||||
for (pdir = (POBJECT_DIRECTORY_INFORMATION)buf; pdir->Name.Length; pdir++)
|
||||
if (pdir->TypeName.Length == 18 && !memcmp(pdir->TypeName.Buffer, L"Directory", 18) &&
|
||||
pdir->Name.Length >= 14 && !memcmp(pdir->Name.Buffer, L"cygwin1", 14))
|
||||
{
|
||||
swprintf(cyg_name, sizeof(cyg_name)/sizeof(*cyg_name), L"%ls\\%ls", bno_name, pdir->Name.Buffer);
|
||||
if (!WideCharToMultiByte(CP_ACP, 0, cyg_name, -1, scyg_name, sizeof(scyg_name), NULL, NULL))
|
||||
*scyg_name=0;
|
||||
RtlInitUnicodeString(&cyg_us, cyg_name);
|
||||
InitializeObjectAttributes(&attr, &cyg_us, 0, NULL, NULL);
|
||||
status = NtOpenDirectoryObject(&hDirCyg, WRITE_OWNER, &attr);
|
||||
if (NT_SUCCESS(status))
|
||||
{
|
||||
b = SetMandatoryLabelObject(hDirCyg, SE_KERNEL_OBJECT, SECURITY_MANDATORY_LOW_RID, ACL_REVISION_DS, 0);
|
||||
if (!b)
|
||||
{
|
||||
w_win32_error = GetLastError();
|
||||
DLOG_ERR("could not set integrity label on '%s' . error %u\n", scyg_name, w_win32_error);
|
||||
}
|
||||
else
|
||||
DLOG("set low integrity label on '%s'\n", scyg_name);
|
||||
ball = ball && b;
|
||||
NtClose(hDirCyg);
|
||||
}
|
||||
}
|
||||
restart = FALSE;
|
||||
}
|
||||
NtClose(hDir);
|
||||
}
|
||||
else
|
||||
{
|
||||
w_win32_error = RtlNtStatusToDosError(status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return ball;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL JobSandbox()
|
||||
{
|
||||
BOOL bRes = FALSE;
|
||||
@@ -734,6 +1040,9 @@ bool win_sandbox(void)
|
||||
// there's no way to return privs
|
||||
if (!b_sandbox_set)
|
||||
{
|
||||
if (!RelaxCygwinNTDir())
|
||||
DLOG_ERR("could not set low mandatory label on cygwin NT directory. some functions may not work. error %u\n", w_win32_error);
|
||||
|
||||
if (!RemoveTokenPrivs())
|
||||
return FALSE;
|
||||
|
||||
@@ -1961,6 +2270,23 @@ void verdict_udp_csum_fix(uint8_t verdict, struct udphdr *udphdr, size_t transpo
|
||||
#endif
|
||||
}
|
||||
|
||||
void verdict_icmp_csum_fix(uint8_t verdict, struct icmp46 *icmphdr, size_t transport_len, const struct ip6_hdr *ip6hdr)
|
||||
{
|
||||
// always fix csum for windivert. original can be partial or bad
|
||||
// FreeBSD tend to pass ipv6 frames with wrong checksum (OBSERVED EARLIER, MAY BE FIXED NOW)
|
||||
// Linux passes correct checksums
|
||||
#ifndef __linux__
|
||||
if (!(verdict & VERDICT_NOCSUM) && (verdict & VERDICT_MASK)==VERDICT_PASS)
|
||||
{
|
||||
#ifdef __FreeBSD__
|
||||
if (ip6hdr)
|
||||
#endif
|
||||
DLOG("fixing icmp checksum\n");
|
||||
icmp_fix_checksum(icmphdr,transport_len,ip6hdr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void dbgprint_socket_buffers(int fd)
|
||||
{
|
||||
if (params.debug)
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
#ifdef __CYGWIN__
|
||||
#define INITGUID
|
||||
#include "windivert/windivert.h"
|
||||
#include "netinet/icmp6.h"
|
||||
#include "netinet/ip_icmp.h"
|
||||
#else
|
||||
#include <netinet/icmp6.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
#endif
|
||||
|
||||
#ifndef IPPROTO_DIVERT
|
||||
@@ -59,6 +64,31 @@
|
||||
#define IPPROTO_SHIM6 140
|
||||
#endif
|
||||
|
||||
#ifndef ICMP_DEST_UNREACH
|
||||
#define ICMP_DEST_UNREACH 3
|
||||
#endif
|
||||
#ifndef ICMP_TIME_EXCEEDED
|
||||
#define ICMP_TIME_EXCEEDED 11
|
||||
#endif
|
||||
#ifndef ICMP_PARAMETERPROB
|
||||
#define ICMP_PARAMETERPROB 12
|
||||
#endif
|
||||
#ifndef ICMP_TIMESTAMP
|
||||
#define ICMP_TIMESTAMP 13
|
||||
#endif
|
||||
#ifndef ICMP_TIMESTAMPREPLY
|
||||
#define ICMP_TIMESTAMPREPLY 14
|
||||
#endif
|
||||
#ifndef ICMP_INFO_REQUEST
|
||||
#define ICMP_INFO_REQUEST 15
|
||||
#endif
|
||||
#ifndef ICMP_INFO_REPLY
|
||||
#define ICMP_INFO_REPLY 16
|
||||
#endif
|
||||
#ifndef MLD_LISTENER_REDUCTION
|
||||
#define MLD_LISTENER_REDUCTION 132
|
||||
#endif
|
||||
|
||||
// returns netorder value
|
||||
uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment);
|
||||
uint32_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment);
|
||||
@@ -85,6 +115,7 @@ uint16_t tcp_find_mss(const struct tcphdr *tcp);
|
||||
bool tcp_synack_segment(const struct tcphdr *tcphdr);
|
||||
bool tcp_syn_segment(const struct tcphdr *tcphdr);
|
||||
|
||||
|
||||
bool make_writeable_dir();
|
||||
bool ensure_file_access(const char *filename);
|
||||
#ifdef __CYGWIN__
|
||||
@@ -121,16 +152,21 @@ int socket_divert(sa_family_t family);
|
||||
#endif
|
||||
|
||||
const char *proto_name(uint8_t proto);
|
||||
void str_proto_name(char *s, size_t s_len, uint8_t proto);
|
||||
const char *icmp_type_name(bool v6, uint8_t type);
|
||||
void str_icmp_type_name(char *s, size_t s_len, bool v6, uint8_t type);
|
||||
uint16_t family_from_proto(uint8_t l3proto);
|
||||
void print_ip(const struct ip *ip);
|
||||
void print_ip6hdr(const struct ip6_hdr *ip6hdr, uint8_t proto);
|
||||
void print_tcphdr(const struct tcphdr *tcphdr);
|
||||
void print_udphdr(const struct udphdr *udphdr);
|
||||
void print_icmphdr(const struct icmp46 *icmp, bool v6);
|
||||
void str_ip(char *s, size_t s_len, const struct ip *ip);
|
||||
void str_ip6hdr(char *s, size_t s_len, const struct ip6_hdr *ip6hdr, uint8_t proto);
|
||||
void str_srcdst_ip6(char *s, size_t s_len, const void *saddr,const void *daddr);
|
||||
void str_tcphdr(char *s, size_t s_len, const struct tcphdr *tcphdr);
|
||||
void str_udphdr(char *s, size_t s_len, const struct udphdr *udphdr);
|
||||
void str_icmphdr(char *s, size_t s_len, bool v6, const struct icmp46 *icmp);
|
||||
|
||||
bool proto_check_ipv4(const uint8_t *data, size_t len);
|
||||
void proto_skip_ipv4(const uint8_t **data, size_t *len);
|
||||
@@ -143,6 +179,9 @@ void proto_skip_tcp(const uint8_t **data, size_t *len);
|
||||
bool proto_check_udp(const uint8_t *data, size_t len);
|
||||
bool proto_check_udp_payload(const uint8_t *data, size_t len);
|
||||
void proto_skip_udp(const uint8_t **data, size_t *len);
|
||||
bool proto_check_icmp(const uint8_t *data, size_t len);
|
||||
void proto_skip_icmp(const uint8_t **data, size_t *len);
|
||||
|
||||
struct dissect
|
||||
{
|
||||
const uint8_t *data_pkt;
|
||||
@@ -153,19 +192,24 @@ struct dissect
|
||||
uint8_t proto;
|
||||
const struct tcphdr *tcp;
|
||||
const struct udphdr *udp;
|
||||
const struct icmp46 *icmp;
|
||||
size_t len_l4;
|
||||
size_t transport_len;
|
||||
const uint8_t *data_payload;
|
||||
size_t len_payload;
|
||||
};
|
||||
void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis);
|
||||
void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis, bool no_payload_check);
|
||||
void reverse_ip(struct ip *ip, struct ip6_hdr *ip6);
|
||||
void reverse_tcp(struct tcphdr *tcp);
|
||||
|
||||
uint8_t ttl46(const struct ip *ip, const struct ip6_hdr *ip6);
|
||||
|
||||
bool get_source_ip4(const struct in_addr *target, struct in_addr *source);
|
||||
bool get_source_ip6(const struct in6_addr *target, struct in6_addr *source);
|
||||
|
||||
void verdict_tcp_csum_fix(uint8_t verdict, struct tcphdr *tcphdr, size_t transport_len, const struct ip *ip, const struct ip6_hdr *ip6hdr);
|
||||
void verdict_udp_csum_fix(uint8_t verdict, struct udphdr *udphdr, size_t transport_len, const struct ip *ip, const struct ip6_hdr *ip6hdr);
|
||||
void verdict_icmp_csum_fix(uint8_t verdict, struct icmp46 *icmphdr, size_t transport_len, const struct ip6_hdr *ip6hdr);
|
||||
|
||||
void dbgprint_socket_buffers(int fd);
|
||||
bool set_socket_buffers(int fd, int rcvbuf, int sndbuf);
|
||||
|
||||
367
nfq2/desync.c
367
nfq2/desync.c
@@ -132,11 +132,79 @@ static void TLSDebug(const uint8_t *tls, size_t sz)
|
||||
TLSDebugHandshake(tls + 5, sz - 5);
|
||||
}
|
||||
|
||||
static void packet_debug(bool replay, const struct dissect *dis)
|
||||
{
|
||||
if (params.debug)
|
||||
{
|
||||
if (replay) DLOG("REPLAY ");
|
||||
if (dis->ip)
|
||||
{
|
||||
char s[66];
|
||||
str_ip(s, sizeof(s), dis->ip);
|
||||
DLOG("IP4: %s", s);
|
||||
}
|
||||
else if (dis->ip6)
|
||||
{
|
||||
char s[128];
|
||||
str_ip6hdr(s, sizeof(s), dis->ip6, dis->proto);
|
||||
DLOG("IP6: %s", s);
|
||||
}
|
||||
|
||||
if (dis->tcp)
|
||||
{
|
||||
char s[80];
|
||||
str_tcphdr(s, sizeof(s), dis->tcp);
|
||||
DLOG(" %s\n", s);
|
||||
if (dis->len_payload)
|
||||
{
|
||||
DLOG("TCP: len=%zu : ", dis->len_payload);
|
||||
hexdump_limited_dlog(dis->data_payload, dis->len_payload, PKTDATA_MAXDUMP);
|
||||
DLOG("\n");
|
||||
}
|
||||
}
|
||||
else if (dis->udp)
|
||||
{
|
||||
char s[30];
|
||||
str_udphdr(s, sizeof(s), dis->udp);
|
||||
DLOG(" %s\n", s);
|
||||
if (dis->len_payload)
|
||||
{
|
||||
DLOG("UDP: len=%zu : ", dis->len_payload);
|
||||
hexdump_limited_dlog(dis->data_payload, dis->len_payload, PKTDATA_MAXDUMP);
|
||||
DLOG("\n");
|
||||
}
|
||||
}
|
||||
else if (dis->icmp)
|
||||
{
|
||||
char s[72];
|
||||
str_icmphdr(s, sizeof(s), !!dis->ip6, dis->icmp);
|
||||
DLOG(" %s\nICMP: len=%zu : ", s, dis->len_payload);
|
||||
hexdump_limited_dlog(dis->data_payload, dis->len_payload, PKTDATA_MAXDUMP);
|
||||
DLOG("\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dis->len_payload)
|
||||
{
|
||||
char s_proto[16];
|
||||
str_proto_name(s_proto,sizeof(s_proto),dis->proto);
|
||||
DLOG("\nIP PROTO %s: len=%zu : ", s_proto, dis->len_payload);
|
||||
hexdump_limited_dlog(dis->data_payload, dis->len_payload, PKTDATA_MAXDUMP);
|
||||
DLOG("\n");
|
||||
}
|
||||
else
|
||||
DLOG("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ipr,ipr6 - reverse ip - ip of the other side of communication
|
||||
static bool dp_match(
|
||||
struct desync_profile *dp,
|
||||
uint8_t l3proto,
|
||||
const struct in_addr *ip, const struct in6_addr *ip6, uint16_t port,
|
||||
const struct in_addr *ip, const struct in6_addr *ip6,
|
||||
const struct in_addr *ipr, const struct in6_addr *ipr6,
|
||||
uint16_t port, uint8_t icmp_type, uint8_t icmp_code,
|
||||
const char *hostname, bool bNoSubdom, t_l7proto l7proto, const char *ssid,
|
||||
bool *bCheckDone, bool *bCheckResult, bool *bExcluded)
|
||||
{
|
||||
@@ -150,8 +218,23 @@ static bool dp_match(
|
||||
// L3 filter does not match
|
||||
return false;
|
||||
|
||||
if ((l3proto == IPPROTO_TCP && !port_filters_in_range(&dp->pf_tcp, port)) || (l3proto == IPPROTO_UDP && !port_filters_in_range(&dp->pf_udp, port)))
|
||||
// L4 filter does not match
|
||||
switch(l3proto)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
if (!port_filters_match(&dp->pf_tcp, port)) return false;
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
if (!port_filters_match(&dp->pf_udp, port)) return false;
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
if (!icmp_filters_match(&dp->icf, icmp_type, icmp_code)) return false;
|
||||
break;
|
||||
default:
|
||||
if (!ipp_filters_match(&dp->ipf, l3proto)) return false;
|
||||
}
|
||||
|
||||
if (l3proto == IPPROTO_ICMP && !icmp_filters_match(&dp->icf, icmp_type, icmp_code))
|
||||
// icmp filter does not match
|
||||
return false;
|
||||
|
||||
if (!l7_proto_match(l7proto, dp->filter_l7))
|
||||
@@ -166,7 +249,7 @@ static bool dp_match(
|
||||
if (!dp->hostlist_auto && !hostname && !bHostlistsEmpty)
|
||||
// avoid cpu consuming ipset check. profile cannot win if regular hostlists are present without auto hostlist and hostname is unknown.
|
||||
return false;
|
||||
if (!IpsetCheck(dp, ip, ip6))
|
||||
if (!IpsetCheck(dp, ip, ip6, ipr, ipr6))
|
||||
// target ip does not match
|
||||
return false;
|
||||
|
||||
@@ -197,7 +280,9 @@ static bool dp_match(
|
||||
static struct desync_profile *dp_find(
|
||||
struct desync_profile_list_head *head,
|
||||
uint8_t l3proto,
|
||||
const struct in_addr *ip, const struct in6_addr *ip6, uint16_t port,
|
||||
const struct in_addr *ip, const struct in6_addr *ip6,
|
||||
const struct in_addr *ipr, const struct in6_addr *ipr6,
|
||||
uint16_t port, uint8_t icmp_type, uint8_t icmp_code,
|
||||
const char *hostname, bool bNoSubdom, t_l7proto l7proto, const char *ssid,
|
||||
bool *bCheckDone, bool *bCheckResult, bool *bExcluded)
|
||||
{
|
||||
@@ -206,12 +291,21 @@ static struct desync_profile *dp_find(
|
||||
{
|
||||
char s[40];
|
||||
ntopa46(ip, ip6, s, sizeof(s));
|
||||
DLOG("desync profile search for %s ip=%s port=%u l7proto=%s ssid='%s' hostname='%s'\n", proto_name(l3proto), s, port, l7proto_str(l7proto), ssid ? ssid : "", hostname ? hostname : "");
|
||||
if (ipr || ipr6)
|
||||
{
|
||||
char sr[40];
|
||||
ntopa46(ipr, ipr6, sr, sizeof(sr));
|
||||
DLOG("desync profile search for %s ip1=%s ip2=%s port=%u icmp=%u:%u l7proto=%s ssid='%s' hostname='%s'\n",
|
||||
proto_name(l3proto), s, sr, port, icmp_type, icmp_code, l7proto_str(l7proto), ssid ? ssid : "", hostname ? hostname : "");
|
||||
}
|
||||
else
|
||||
DLOG("desync profile search for %s ip=%s port=%u icmp=%u:%u l7proto=%s ssid='%s' hostname='%s'\n",
|
||||
proto_name(l3proto), s, port, icmp_type, icmp_code, l7proto_str(l7proto), ssid ? ssid : "", hostname ? hostname : "");
|
||||
}
|
||||
if (bCheckDone) *bCheckDone = false;
|
||||
LIST_FOREACH(dpl, head, next)
|
||||
{
|
||||
if (dp_match(&dpl->dp, l3proto, ip, ip6, port, hostname, bNoSubdom, l7proto, ssid, bCheckDone, bCheckResult, bExcluded))
|
||||
if (dp_match(&dpl->dp, l3proto, ip, ip6, ipr, ipr6, port, icmp_type, icmp_code, hostname, bNoSubdom, l7proto, ssid, bCheckDone, bCheckResult, bExcluded))
|
||||
{
|
||||
DLOG("desync profile %u (%s) matches\n", dpl->dp.n, PROFILE_NAME(&dpl->dp));
|
||||
return &dpl->dp;
|
||||
@@ -455,8 +549,8 @@ static bool reasm_start(t_ctrack *ctrack, t_reassemble *reasm, uint8_t proto, ui
|
||||
static bool reasm_client_start(t_ctrack *ctrack, uint8_t proto, size_t sz, size_t szMax, const uint8_t *data_payload, size_t len_payload)
|
||||
{
|
||||
if (!ctrack) return false;
|
||||
// if winsize_calc==0 it means we dont know server window size - no incoming packets redirected ?
|
||||
if (proto==IPPROTO_TCP && ctrack->pos.server.winsize_calc && (ctrack->pos.server.winsize_calc < sz))
|
||||
// if pcounter==0 it means we dont know server window size - no incoming packets redirected ?
|
||||
if (proto==IPPROTO_TCP && ctrack->pos.server.pcounter && (ctrack->pos.server.winsize_calc < sz))
|
||||
{
|
||||
// this is rare but possible situation
|
||||
// server gave us too small tcp window
|
||||
@@ -640,6 +734,12 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr
|
||||
*hostname = 0;
|
||||
return true;
|
||||
}
|
||||
if (params.debug)
|
||||
{
|
||||
char s[40];
|
||||
ntopa46(a4, a6, s, sizeof(s));
|
||||
DLOG("ipcache hostname search for %s\n", s);
|
||||
}
|
||||
ip_cache_item *ipc = ipcacheTouch(¶ms.ipcache, a4, a6, NULL);
|
||||
if (!ipc)
|
||||
{
|
||||
@@ -648,7 +748,12 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr
|
||||
}
|
||||
if (ipc->hostname)
|
||||
{
|
||||
DLOG("got cached hostname (is_ip=%u): %s\n", ipc->hostname_is_ip, ipc->hostname);
|
||||
if (params.debug)
|
||||
{
|
||||
char s[40];
|
||||
ntopa46(a4, a6, s, sizeof(s));
|
||||
DLOG("got cached hostname for %s : %s (is_ip=%u)\n", s, ipc->hostname, ipc->hostname_is_ip);
|
||||
}
|
||||
snprintf(hostname, hostname_buf_len, "%s", ipc->hostname);
|
||||
if (hostname_is_ip) *hostname_is_ip = ipc->hostname_is_ip;
|
||||
}
|
||||
@@ -968,7 +1073,7 @@ static uint8_t desync(
|
||||
}
|
||||
else
|
||||
{
|
||||
b = lua_reconstruct_dissect(params.L, -1, mod_pkt, len_mod_pkt, false, false);
|
||||
b = lua_reconstruct_dissect(params.L, -1, mod_pkt, len_mod_pkt, false, false, false);
|
||||
lua_pop(params.L, 2);
|
||||
if (!b)
|
||||
{
|
||||
@@ -1116,7 +1221,7 @@ static bool play_prolog(
|
||||
DLOG("using cached desync profile %u (%s)\n", ps->dp->n, PROFILE_NAME(ps->dp));
|
||||
else if (!ps->ctrack_replay->dp_search_complete)
|
||||
{
|
||||
ps->dp = ps->ctrack_replay->dp = dp_find(¶ms.desync_profiles, dis->proto, ps->sdip4, ps->sdip6, ps->sdport, ps->ctrack_replay->hostname, ps->ctrack_replay->hostname_is_ip, ps->l7proto, ps->ssid, NULL, NULL, NULL);
|
||||
ps->dp = ps->ctrack_replay->dp = dp_find(¶ms.desync_profiles, dis->proto, ps->sdip4, ps->sdip6, NULL, NULL, ps->sdport, 0xFF, 0xFF, ps->ctrack_replay->hostname, ps->ctrack_replay->hostname_is_ip, ps->l7proto, ps->ssid, NULL, NULL, NULL);
|
||||
ps->ctrack_replay->dp_search_complete = true;
|
||||
}
|
||||
if (!ps->dp)
|
||||
@@ -1164,7 +1269,7 @@ static bool play_prolog(
|
||||
DLOG_ERR("strdup(host): out of memory\n");
|
||||
}
|
||||
}
|
||||
ps->dp = dp_find(¶ms.desync_profiles, dis->proto, ps->sdip4, ps->sdip6, ps->sdport, hostname, hostname_is_ip, ps->l7proto, ps->ssid, NULL, NULL, NULL);
|
||||
ps->dp = dp_find(¶ms.desync_profiles, dis->proto, ps->sdip4, ps->sdip6, NULL, NULL, ps->sdport, 0xFF, 0xFF, hostname, hostname_is_ip, ps->l7proto, ps->ssid, NULL, NULL, NULL);
|
||||
if (ps->ctrack)
|
||||
{
|
||||
ps->ctrack->dp = ps->dp;
|
||||
@@ -1249,7 +1354,7 @@ static bool dp_rediscovery(struct play_state *ps)
|
||||
{
|
||||
struct desync_profile *dp_prev = ps->dp;
|
||||
// search for desync profile again. it may have changed.
|
||||
ps->dp = dp_find(¶ms.desync_profiles, ps->dis->proto, ps->sdip4, ps->sdip6, ps->sdport,
|
||||
ps->dp = dp_find(¶ms.desync_profiles, ps->dis->proto, ps->sdip4, ps->sdip6, NULL, NULL, ps->sdport, 0xFF, 0xFF,
|
||||
ps->ctrack_replay ? ps->ctrack_replay->hostname : ps->bHaveHost ? ps->host : NULL,
|
||||
ps->ctrack_replay ? ps->ctrack_replay->hostname_is_ip : bHostIsIp,
|
||||
ps->l7proto, ps->ssid,
|
||||
@@ -1782,43 +1887,202 @@ pass_reasm_cancel:
|
||||
goto pass;
|
||||
}
|
||||
|
||||
// conntrack is supported only for RELATED icmp
|
||||
// ip matched in both directions if conntrack is unavailable
|
||||
static uint8_t dpi_desync_icmp_packet(
|
||||
uint32_t fwmark,
|
||||
const char *ifin, const char *ifout,
|
||||
const struct dissect *dis,
|
||||
uint8_t *mod_pkt, size_t *len_mod_pkt)
|
||||
{
|
||||
uint8_t verdict = VERDICT_PASS;
|
||||
|
||||
static void packet_debug(bool replay, const struct dissect *dis)
|
||||
// additional safety check
|
||||
if (!!dis->ip == !!dis->ip6) return verdict;
|
||||
|
||||
const uint8_t *pkt_attached;
|
||||
size_t len_attached;
|
||||
const char *ifname;
|
||||
struct sockaddr_storage src, dst;
|
||||
const char *ssid = NULL;
|
||||
struct desync_profile *dp = NULL;
|
||||
t_l7payload l7payload = L7P_UNKNOWN;
|
||||
t_ctrack *ctrack = NULL;
|
||||
bool bReverse, bReverseFixed;
|
||||
|
||||
extract_endpoints(dis->ip, dis->ip6, NULL, NULL, &src, &dst);
|
||||
|
||||
switch(dis->icmp->icmp_type)
|
||||
{
|
||||
if (params.debug)
|
||||
{
|
||||
if (replay) DLOG("REPLAY ");
|
||||
if (dis->ip)
|
||||
{
|
||||
char s[66];
|
||||
str_ip(s, sizeof(s), dis->ip);
|
||||
DLOG("IP4: %s", s);
|
||||
case ICMP_DEST_UNREACH:
|
||||
case ICMP_TIME_EXCEEDED:
|
||||
case ICMP_PARAMETERPROB:
|
||||
case ICMP_REDIRECT:
|
||||
case ICMP6_DST_UNREACH:
|
||||
//case ICMP6_TIME_EXCEEDED: // same as ICMP_TIME_EXCEEDED = 3
|
||||
case ICMP6_PACKET_TOO_BIG:
|
||||
case ICMP6_PARAM_PROB:
|
||||
pkt_attached = dis->data_payload;
|
||||
break;
|
||||
default:
|
||||
pkt_attached = NULL;
|
||||
}
|
||||
else if (dis->ip6)
|
||||
if (pkt_attached)
|
||||
{
|
||||
char s[128];
|
||||
str_ip6hdr(s, sizeof(s), dis->ip6, dis->proto);
|
||||
DLOG("IP6: %s", s);
|
||||
struct dissect adis;
|
||||
|
||||
len_attached = pkt_attached - dis->data_payload + dis->len_payload;
|
||||
proto_dissect_l3l4(pkt_attached, len_attached, &adis, true); // dissect without payload length checks - can be partial
|
||||
if (!dis->ip && !dis->ip6)
|
||||
DLOG("attached packet is invalid\n");
|
||||
else
|
||||
{
|
||||
l7payload = dis->ip ? L7P_IPV4 : L7P_IPV6;
|
||||
DLOG("attached packet\n");
|
||||
packet_debug(false, &adis);
|
||||
if (ConntrackPoolDoubleSearch(¶ms.conntrack, &adis, &ctrack, &bReverse))
|
||||
{
|
||||
// invert direction. they are answering to this packet
|
||||
bReverse = !bReverse;
|
||||
DLOG("found conntrack entry. inverted reverse=%u\n",bReverse);
|
||||
if (ctrack->dp_search_complete)
|
||||
{
|
||||
// RELATED icmp processed within base connection profile
|
||||
dp = ctrack->dp;
|
||||
DLOG("using desync profile %u (%s) from conntrack entry\n", dp->n, PROFILE_NAME(dp));
|
||||
}
|
||||
if (dis->tcp)
|
||||
{
|
||||
char s[80];
|
||||
str_tcphdr(s, sizeof(s), dis->tcp);
|
||||
DLOG(" %s\n", s);
|
||||
if (dis->len_payload) { DLOG("TCP: len=%zu : ", dis->len_payload); hexdump_limited_dlog(dis->data_payload, dis->len_payload, PKTDATA_MAXDUMP); DLOG("\n"); }
|
||||
}
|
||||
else if (dis->udp)
|
||||
{
|
||||
char s[30];
|
||||
str_udphdr(s, sizeof(s), dis->udp);
|
||||
DLOG(" %s\n", s);
|
||||
if (dis->len_payload) { DLOG("UDP: len=%zu : ", dis->len_payload); hexdump_limited_dlog(dis->data_payload, dis->len_payload, PKTDATA_MAXDUMP); DLOG("\n"); }
|
||||
}
|
||||
else
|
||||
DLOG("\n");
|
||||
DLOG("conntrack entry not found\n");
|
||||
}
|
||||
}
|
||||
|
||||
bReverseFixed = ctrack ? (bReverse ^ params.server) : (bReverse = ifin && *ifin && (!ifout || !*ifout));
|
||||
|
||||
#ifdef HAS_FILTER_SSID
|
||||
ifname = bReverse ? ifin : ifout;
|
||||
if ((ssid = wlan_ssid_search_ifname(ifname)))
|
||||
DLOG("found ssid for %s : %s\n", ifname, ssid);
|
||||
else if (!ctrack)
|
||||
{
|
||||
// we dont know direction for sure
|
||||
// search opposite interface
|
||||
ifname = bReverse ? ifout : ifin;
|
||||
if ((ssid = wlan_ssid_search_ifname(ifname)))
|
||||
DLOG("found ssid for %s : %s\n", ifname, ssid);
|
||||
}
|
||||
#endif
|
||||
if (!dp)
|
||||
{
|
||||
bool hostname_is_ip = false;
|
||||
char host[256];
|
||||
const char *hostname = NULL;
|
||||
if (ctrack && ctrack->hostname)
|
||||
{
|
||||
printf("ZZZZZz4 %p\n",ctrack->hostname);
|
||||
hostname = ctrack->hostname;
|
||||
hostname_is_ip = ctrack->hostname_is_ip;
|
||||
}
|
||||
else if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL, dis->ip6 ? &dis->ip6->ip6_dst : NULL, host, sizeof(host), &hostname_is_ip) && *host ||
|
||||
ipcache_get_hostname(dis->ip ? &dis->ip->ip_src : NULL, dis->ip6 ? &dis->ip6->ip6_src : NULL, host, sizeof(host), &hostname_is_ip) && *host)
|
||||
{
|
||||
hostname = host;
|
||||
}
|
||||
|
||||
dp = dp_find(
|
||||
¶ms.desync_profiles,
|
||||
dis->proto,
|
||||
dis->ip ? &dis->ip->ip_dst : NULL, dis->ip6 ? &dis->ip6->ip6_dst : NULL,
|
||||
dis->ip ? &dis->ip->ip_src : NULL, dis->ip6 ? &dis->ip6->ip6_src : NULL,
|
||||
0, dis->icmp->icmp_type, dis->icmp->icmp_code,
|
||||
hostname, hostname_is_ip,
|
||||
L7_UNKNOWN, ssid, NULL, NULL, NULL);
|
||||
if (!dp)
|
||||
{
|
||||
DLOG("matching desync profile not found\n");
|
||||
return verdict;
|
||||
}
|
||||
}
|
||||
|
||||
const struct in_addr *sdip4;
|
||||
const struct in6_addr *sdip6;
|
||||
sdip6 = dis->ip6 ? bReverseFixed ? &dis->ip6->ip6_src : &dis->ip6->ip6_dst : NULL;
|
||||
sdip4 = dis->ip ? bReverseFixed ? &dis->ip->ip_src : &dis->ip->ip_dst : NULL;
|
||||
|
||||
verdict = desync(
|
||||
dp, fwmark, ifin, ifout, bReverseFixed, ctrack, NULL, l7payload, L7_UNKNOWN,
|
||||
dis, sdip4, sdip6, 0, mod_pkt, len_mod_pkt, 0, 0, 0, NULL, 0, NULL, 0);
|
||||
|
||||
return verdict;
|
||||
}
|
||||
|
||||
// undissected l4+
|
||||
// conntrack is unsupported
|
||||
// ip matched in both directions
|
||||
static uint8_t dpi_desync_ip_packet(
|
||||
uint32_t fwmark,
|
||||
const char *ifin, const char *ifout,
|
||||
const struct dissect *dis,
|
||||
uint8_t *mod_pkt, size_t *len_mod_pkt)
|
||||
{
|
||||
uint8_t verdict = VERDICT_PASS;
|
||||
|
||||
// additional safety check
|
||||
if (!!dis->ip == !!dis->ip6) return verdict;
|
||||
|
||||
struct sockaddr_storage src, dst;
|
||||
const char *ssid;
|
||||
struct desync_profile *dp;
|
||||
|
||||
extract_endpoints(dis->ip, dis->ip6, NULL, NULL, &src, &dst);
|
||||
#ifdef HAS_FILTER_SSID
|
||||
if ((ssid = wlan_ssid_search_ifname(ifin)))
|
||||
DLOG("found ssid for %s : %s\n", ifin, ssid);
|
||||
else
|
||||
{
|
||||
// we dont know direction for sure
|
||||
// search opposite interface
|
||||
if ((ssid = wlan_ssid_search_ifname(ifout)))
|
||||
DLOG("found ssid for %s : %s\n", ifout, ssid);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool hostname_is_ip = false;
|
||||
const char *hostname = NULL;
|
||||
char host[256];
|
||||
if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL, dis->ip6 ? &dis->ip6->ip6_dst : NULL, host, sizeof(host), &hostname_is_ip) && *host ||
|
||||
ipcache_get_hostname(dis->ip ? &dis->ip->ip_src : NULL, dis->ip6 ? &dis->ip6->ip6_src : NULL, host, sizeof(host), &hostname_is_ip) && *host)
|
||||
{
|
||||
hostname = host;
|
||||
}
|
||||
dp = dp_find(
|
||||
¶ms.desync_profiles,
|
||||
dis->proto,
|
||||
dis->ip ? &dis->ip->ip_dst : NULL, dis->ip6 ? &dis->ip6->ip6_dst : NULL,
|
||||
dis->ip ? &dis->ip->ip_src : NULL, dis->ip6 ? &dis->ip6->ip6_src : NULL,
|
||||
0, 0xFF, 0xFF,
|
||||
hostname, hostname_is_ip,
|
||||
L7_UNKNOWN, ssid, NULL, NULL, NULL);
|
||||
if (!dp)
|
||||
{
|
||||
DLOG("matching desync profile not found\n");
|
||||
return verdict;
|
||||
}
|
||||
|
||||
bool bReverse = ifin && *ifin && (!ifout || !*ifout);
|
||||
|
||||
const struct in_addr *sdip4;
|
||||
const struct in6_addr *sdip6;
|
||||
sdip6 = dis->ip6 ? bReverse ? &dis->ip6->ip6_src : &dis->ip6->ip6_dst : NULL;
|
||||
sdip4 = dis->ip ? bReverse ? &dis->ip->ip_src : &dis->ip->ip_dst : NULL;
|
||||
|
||||
verdict = desync(
|
||||
dp, fwmark, ifin, ifout, bReverse, NULL, NULL, L7P_UNKNOWN, L7_UNKNOWN,
|
||||
dis, sdip4, sdip6, 0, mod_pkt, len_mod_pkt, 0, 0, 0, NULL, 0, NULL, 0);
|
||||
|
||||
return verdict;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t dpi_desync_packet_play(
|
||||
unsigned int replay_piece, unsigned int replay_piece_count, size_t reasm_offset, uint32_t fwmark, const char *ifin, const char *ifout,
|
||||
@@ -1831,19 +2095,19 @@ static uint8_t dpi_desync_packet_play(
|
||||
|
||||
// NOTE ! OS can pass wrong checksum to queue. cannot rely on it !
|
||||
|
||||
proto_dissect_l3l4(data_pkt, len_pkt, &dis);
|
||||
proto_dissect_l3l4(data_pkt, len_pkt, &dis, false);
|
||||
if (!!dis.ip != !!dis.ip6)
|
||||
{
|
||||
packet_debug(!!replay_piece_count, &dis);
|
||||
// fix csum if unmodified and if OS can pass wrong csum to queue (depends on OS)
|
||||
// modified means we have already fixed the checksum or made it invalid intentionally
|
||||
// this is the only point we VIOLATE const to fix the checksum in the original buffer to avoid copying to mod_pkt
|
||||
switch (dis.proto)
|
||||
{
|
||||
case IPPROTO_TCP:
|
||||
if (dis.tcp)
|
||||
{
|
||||
verdict = dpi_desync_tcp_packet_play(replay_piece, replay_piece_count, reasm_offset, fwmark, ifin, ifout, tpos, &dis, mod_pkt, len_mod_pkt);
|
||||
// fix csum if unmodified and if OS can pass wrong csum to queue (depends on OS)
|
||||
// modified means we have already fixed the checksum or made it invalid intentionally
|
||||
// this is the only point we VIOLATE const to fix the checksum in the original buffer to avoid copying to mod_pkt
|
||||
verdict_tcp_csum_fix(verdict, (struct tcphdr *)dis.tcp, dis.transport_len, dis.ip, dis.ip6);
|
||||
}
|
||||
break;
|
||||
@@ -1851,12 +2115,19 @@ static uint8_t dpi_desync_packet_play(
|
||||
if (dis.udp)
|
||||
{
|
||||
verdict = dpi_desync_udp_packet_play(replay_piece, replay_piece_count, reasm_offset, fwmark, ifin, ifout, tpos, &dis, mod_pkt, len_mod_pkt);
|
||||
// fix csum if unmodified and if OS can pass wrong csum to queue (depends on OS)
|
||||
// modified means we have already fixed the checksum or made it invalid intentionally
|
||||
// this is the only point we VIOLATE const to fix the checksum in the original buffer to avoid copying to mod_pkt
|
||||
verdict_udp_csum_fix(verdict, (struct udphdr *)dis.udp, dis.transport_len, dis.ip, dis.ip6);
|
||||
}
|
||||
break;
|
||||
case IPPROTO_ICMP:
|
||||
case IPPROTO_ICMPV6:
|
||||
if (dis.icmp)
|
||||
{
|
||||
verdict = dpi_desync_icmp_packet(fwmark, ifin, ifout, &dis, mod_pkt, len_mod_pkt);
|
||||
verdict_icmp_csum_fix(verdict, (struct icmp46 *)dis.icmp, dis.transport_len, dis.ip6);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
verdict = dpi_desync_ip_packet(fwmark, ifin, ifout, &dis, mod_pkt, len_mod_pkt);
|
||||
}
|
||||
}
|
||||
return verdict;
|
||||
|
||||
236
nfq2/filter.c
Normal file
236
nfq2/filter.c
Normal file
@@ -0,0 +1,236 @@
|
||||
#include "filter.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
bool pf_match(uint16_t port, const port_filter *pf)
|
||||
{
|
||||
return port && (((!pf->from && !pf->to) || (port>=pf->from && port<=pf->to)) ^ pf->neg);
|
||||
}
|
||||
bool pf_parse(const char *s, port_filter *pf)
|
||||
{
|
||||
unsigned int v1,v2;
|
||||
char c;
|
||||
|
||||
if (!s) return false;
|
||||
if (*s=='*' && s[1]==0)
|
||||
{
|
||||
pf->from=1; pf->to=0xFFFF;
|
||||
return true;
|
||||
}
|
||||
if (*s=='~')
|
||||
{
|
||||
pf->neg=true;
|
||||
s++;
|
||||
}
|
||||
else
|
||||
pf->neg=false;
|
||||
if (sscanf(s,"%u-%u%c",&v1,&v2,&c)==2)
|
||||
{
|
||||
if (v1>65535 || v2>65535 || v1>v2) return false;
|
||||
pf->from=(uint16_t)v1;
|
||||
pf->to=(uint16_t)v2;
|
||||
}
|
||||
else if (sscanf(s,"%u%c",&v1,&c)==1)
|
||||
{
|
||||
if (v1>65535) return false;
|
||||
pf->to=pf->from=(uint16_t)v1;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
// deny all case
|
||||
if (!pf->from && !pf->to) pf->neg=true;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool fltmode_parse(const char *s, uint8_t *mode)
|
||||
{
|
||||
if (*s=='*' && !s[1])
|
||||
{
|
||||
*mode = FLTMODE_ANY;
|
||||
return true;
|
||||
}
|
||||
else if (*s=='-' && !s[1])
|
||||
{
|
||||
*mode = FLTMODE_SKIP;
|
||||
return true;
|
||||
}
|
||||
*mode = FLTMODE_SKIP;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool icf_match(uint8_t type, uint8_t code, const icmp_filter *icf)
|
||||
{
|
||||
return icf->mode==FLTMODE_ANY || icf->mode==FLTMODE_FILTER && icf->type==type && (!icf->code_valid || icf->code==code);
|
||||
}
|
||||
bool icf_parse(const char *s, icmp_filter *icf)
|
||||
{
|
||||
unsigned int u1,u2;
|
||||
char c1,c2;
|
||||
|
||||
icf->type = icf->code = 0;
|
||||
icf->code_valid = false;
|
||||
if (fltmode_parse(s, &icf->mode)) return true;
|
||||
switch(sscanf(s,"%u%c%u%c",&u1,&c1,&u2,&c2))
|
||||
{
|
||||
case 1:
|
||||
if (u1>0xFF) return false;
|
||||
icf->type = (uint8_t)u1;
|
||||
icf->mode = FLTMODE_FILTER;
|
||||
break;
|
||||
case 3:
|
||||
if (c1!=':' || (u1>0xFF) || (u2>0xFF)) return false;
|
||||
icf->type = (uint8_t)u1;
|
||||
icf->code = (uint8_t)u2;
|
||||
icf->code_valid = true;
|
||||
icf->mode = FLTMODE_FILTER;
|
||||
break;
|
||||
default:
|
||||
icf->mode = FLTMODE_SKIP;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ipp_match(uint8_t proto, const ipp_filter *ipp)
|
||||
{
|
||||
return ipp->mode==FLTMODE_ANY || ipp->mode==FLTMODE_FILTER && ipp->proto==proto;
|
||||
}
|
||||
bool ipp_parse(const char *s, ipp_filter *ipp)
|
||||
{
|
||||
unsigned int u1;
|
||||
char c;
|
||||
|
||||
ipp->proto = 0xFF;
|
||||
if (fltmode_parse(s, &ipp->mode)) return true;
|
||||
if (sscanf(s,"%u%c",&u1,&c)!=1 || u1>0xFF) return false;
|
||||
ipp->proto = (uint8_t)u1;
|
||||
ipp->mode = FLTMODE_FILTER;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool packet_pos_parse(const char *s, struct packet_pos *pos)
|
||||
{
|
||||
if (*s!='n' && *s!='d' && *s!='s' && *s!='p' && *s!='b' && *s!='x' && *s!='a') return false;
|
||||
pos->mode=*s;
|
||||
if (pos->mode=='x' || pos->mode=='a')
|
||||
{
|
||||
pos->pos=0;
|
||||
return true;
|
||||
}
|
||||
return sscanf(s+1,"%u",&pos->pos)==1;
|
||||
}
|
||||
bool packet_range_parse(const char *s, struct packet_range *range)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
range->upper_cutoff = false;
|
||||
if (*s=='-' || *s=='<')
|
||||
{
|
||||
range->from = PACKET_POS_ALWAYS;
|
||||
range->upper_cutoff = *s=='<';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!packet_pos_parse(s,&range->from)) return false;
|
||||
if (range->from.mode=='x')
|
||||
{
|
||||
range->to = range->from;
|
||||
return true;
|
||||
}
|
||||
if (!(p = strchr(s,'-')))
|
||||
p = strchr(s,'<');
|
||||
if (p)
|
||||
{
|
||||
s = p;
|
||||
range->upper_cutoff = *s=='<';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (range->from.mode=='a')
|
||||
{
|
||||
range->to = range->from;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
s++;
|
||||
if (*s)
|
||||
{
|
||||
return packet_pos_parse(s,&range->to);
|
||||
}
|
||||
else
|
||||
{
|
||||
range->to = PACKET_POS_ALWAYS;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr)
|
||||
{
|
||||
char s_ip[16];
|
||||
*s_ip=0;
|
||||
inet_ntop(AF_INET, &cidr->addr, s_ip, sizeof(s_ip));
|
||||
snprintf(s,s_len,cidr->preflen<32 ? "%s/%u" : "%s", s_ip, cidr->preflen);
|
||||
}
|
||||
void print_cidr4(const struct cidr4 *cidr)
|
||||
{
|
||||
char s[19];
|
||||
str_cidr4(s,sizeof(s),cidr);
|
||||
printf("%s",s);
|
||||
}
|
||||
void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr)
|
||||
{
|
||||
char s_ip[40];
|
||||
*s_ip=0;
|
||||
inet_ntop(AF_INET6, &cidr->addr, s_ip, sizeof(s_ip));
|
||||
snprintf(s,s_len,cidr->preflen<128 ? "%s/%u" : "%s", s_ip, cidr->preflen);
|
||||
}
|
||||
void print_cidr6(const struct cidr6 *cidr)
|
||||
{
|
||||
char s[44];
|
||||
str_cidr6(s,sizeof(s),cidr);
|
||||
printf("%s",s);
|
||||
}
|
||||
bool parse_cidr4(char *s, struct cidr4 *cidr)
|
||||
{
|
||||
char *p,d;
|
||||
bool b;
|
||||
unsigned int plen;
|
||||
|
||||
if ((p = strchr(s, '/')))
|
||||
{
|
||||
if (sscanf(p + 1, "%u", &plen)!=1 || plen>32)
|
||||
return false;
|
||||
cidr->preflen = (uint8_t)plen;
|
||||
d=*p; *p=0; // backup char
|
||||
}
|
||||
else
|
||||
cidr->preflen = 32;
|
||||
b = (inet_pton(AF_INET, s, &cidr->addr)==1);
|
||||
if (p) *p=d; // restore char
|
||||
return b;
|
||||
}
|
||||
bool parse_cidr6(char *s, struct cidr6 *cidr)
|
||||
{
|
||||
char *p,d;
|
||||
bool b;
|
||||
unsigned int plen;
|
||||
|
||||
if ((p = strchr(s, '/')))
|
||||
{
|
||||
if (sscanf(p + 1, "%u", &plen)!=1 || plen>128)
|
||||
return false;
|
||||
cidr->preflen = (uint8_t)plen;
|
||||
d=*p; *p=0; // backup char
|
||||
}
|
||||
else
|
||||
cidr->preflen = 128;
|
||||
b = (inet_pton(AF_INET6, s, &cidr->addr)==1);
|
||||
if (p) *p=d; // restore char
|
||||
return b;
|
||||
}
|
||||
64
nfq2/filter.h
Normal file
64
nfq2/filter.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t from,to;
|
||||
bool neg;
|
||||
} port_filter;
|
||||
bool pf_match(uint16_t port, const port_filter *pf);
|
||||
bool pf_parse(const char *s, port_filter *pf);
|
||||
|
||||
#define FLTMODE_SKIP 0
|
||||
#define FLTMODE_ANY 1
|
||||
#define FLTMODE_FILTER 2
|
||||
typedef struct
|
||||
{
|
||||
uint8_t mode, type, code;
|
||||
bool code_valid;
|
||||
} icmp_filter;
|
||||
bool icf_match(uint8_t type, uint8_t code, const icmp_filter *icf);
|
||||
bool icf_parse(const char *s, icmp_filter *icf);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t mode, proto;
|
||||
} ipp_filter;
|
||||
bool ipp_match(uint8_t proto, const ipp_filter *ipp);
|
||||
bool ipp_parse(const char *s, ipp_filter *ipp);
|
||||
|
||||
struct packet_pos
|
||||
{
|
||||
char mode; // n - packets, d - data packets, s - relative sequence
|
||||
unsigned int pos;
|
||||
};
|
||||
struct packet_range
|
||||
{
|
||||
struct packet_pos from, to;
|
||||
bool upper_cutoff; // true - do not include upper limit, false - include upper limit
|
||||
};
|
||||
#define PACKET_POS_NEVER (struct packet_pos){'x',0}
|
||||
#define PACKET_POS_ALWAYS (struct packet_pos){'a',0}
|
||||
#define PACKET_RANGE_NEVER (struct packet_range){PACKET_POS_NEVER,PACKET_POS_NEVER}
|
||||
#define PACKET_RANGE_ALWAYS (struct packet_range){PACKET_POS_ALWAYS,PACKET_POS_ALWAYS}
|
||||
bool packet_range_parse(const char *s, struct packet_range *range);
|
||||
|
||||
struct cidr4
|
||||
{
|
||||
struct in_addr addr;
|
||||
uint8_t preflen;
|
||||
};
|
||||
struct cidr6
|
||||
{
|
||||
struct in6_addr addr;
|
||||
uint8_t preflen;
|
||||
};
|
||||
void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr);
|
||||
void print_cidr4(const struct cidr4 *cidr);
|
||||
void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr);
|
||||
void print_cidr6(const struct cidr6 *cidr);
|
||||
bool parse_cidr4(char *s, struct cidr4 *cidr);
|
||||
bool parse_cidr6(char *s, struct cidr6 *cidr);
|
||||
237
nfq2/helpers.c
237
nfq2/helpers.c
@@ -448,107 +448,6 @@ bool file_open_test(const char *filename, int flags)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool pf_in_range(uint16_t port, const port_filter *pf)
|
||||
{
|
||||
return port && (((!pf->from && !pf->to) || (port>=pf->from && port<=pf->to)) ^ pf->neg);
|
||||
}
|
||||
bool pf_parse(const char *s, port_filter *pf)
|
||||
{
|
||||
unsigned int v1,v2;
|
||||
char c;
|
||||
|
||||
if (!s) return false;
|
||||
if (*s=='*' && s[1]==0)
|
||||
{
|
||||
pf->from=1; pf->to=0xFFFF;
|
||||
return true;
|
||||
}
|
||||
if (*s=='~')
|
||||
{
|
||||
pf->neg=true;
|
||||
s++;
|
||||
}
|
||||
else
|
||||
pf->neg=false;
|
||||
if (sscanf(s,"%u-%u%c",&v1,&v2,&c)==2)
|
||||
{
|
||||
if (v1>65535 || v2>65535 || v1>v2) return false;
|
||||
pf->from=(uint16_t)v1;
|
||||
pf->to=(uint16_t)v2;
|
||||
}
|
||||
else if (sscanf(s,"%u%c",&v1,&c)==1)
|
||||
{
|
||||
if (v1>65535) return false;
|
||||
pf->to=pf->from=(uint16_t)v1;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
// deny all case
|
||||
if (!pf->from && !pf->to) pf->neg=true;
|
||||
return true;
|
||||
}
|
||||
bool pf_is_empty(const port_filter *pf)
|
||||
{
|
||||
return !pf->neg && !pf->from && !pf->to;
|
||||
}
|
||||
|
||||
bool packet_pos_parse(const char *s, struct packet_pos *pos)
|
||||
{
|
||||
if (*s!='n' && *s!='d' && *s!='s' && *s!='p' && *s!='b' && *s!='x' && *s!='a') return false;
|
||||
pos->mode=*s;
|
||||
if (pos->mode=='x' || pos->mode=='a')
|
||||
{
|
||||
pos->pos=0;
|
||||
return true;
|
||||
}
|
||||
return sscanf(s+1,"%u",&pos->pos)==1;
|
||||
}
|
||||
bool packet_range_parse(const char *s, struct packet_range *range)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
range->upper_cutoff = false;
|
||||
if (*s=='-' || *s=='<')
|
||||
{
|
||||
range->from = PACKET_POS_ALWAYS;
|
||||
range->upper_cutoff = *s=='<';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!packet_pos_parse(s,&range->from)) return false;
|
||||
if (range->from.mode=='x')
|
||||
{
|
||||
range->to = range->from;
|
||||
return true;
|
||||
}
|
||||
if (!(p = strchr(s,'-')))
|
||||
p = strchr(s,'<');
|
||||
if (p)
|
||||
{
|
||||
s = p;
|
||||
range->upper_cutoff = *s=='<';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (range->from.mode=='a')
|
||||
{
|
||||
range->to = range->from;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
s++;
|
||||
if (*s)
|
||||
{
|
||||
return packet_pos_parse(s,&range->to);
|
||||
}
|
||||
else
|
||||
{
|
||||
range->to = PACKET_POS_ALWAYS;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void fill_random_bytes(uint8_t *p,size_t sz)
|
||||
{
|
||||
@@ -581,12 +480,55 @@ bool fill_crypto_random_bytes(uint8_t *p,size_t sz)
|
||||
return b;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && !defined(__llvm__)
|
||||
__attribute__((optimize ("no-strict-aliasing")))
|
||||
#endif
|
||||
void bxor(const uint8_t *x1, const uint8_t *x2, uint8_t *result, size_t sz)
|
||||
{
|
||||
for (; sz>=8 ; x1+=8, x2+=8, result+=8, sz-=8)
|
||||
*(uint64_t*)result = *(uint64_t*)x1 ^ *(uint64_t*)x2;
|
||||
for (; sz ; x1++, x2++, result++, sz--)
|
||||
*result = *x1 ^ *x2;
|
||||
}
|
||||
#if defined(__GNUC__) && !defined(__llvm__)
|
||||
__attribute__((optimize ("no-strict-aliasing")))
|
||||
#endif
|
||||
void bor(const uint8_t *x1, const uint8_t *x2, uint8_t *result, size_t sz)
|
||||
{
|
||||
for (; sz>=8 ; x1+=8, x2+=8, result+=8, sz-=8)
|
||||
*(uint64_t*)result = *(uint64_t*)x1 | *(uint64_t*)x2;
|
||||
for (; sz ; x1++, x2++, result++, sz--)
|
||||
*result = *x1 | *x2;
|
||||
}
|
||||
#if defined(__GNUC__) && !defined(__llvm__)
|
||||
__attribute__((optimize ("no-strict-aliasing")))
|
||||
#endif
|
||||
void band(const uint8_t *x1, const uint8_t *x2, uint8_t *result, size_t sz)
|
||||
{
|
||||
for (; sz>=8 ; x1+=8, x2+=8, result+=8, sz-=8)
|
||||
*(uint64_t*)result = *(uint64_t*)x1 & *(uint64_t*)x2;
|
||||
for (; sz ; x1++, x2++, result++, sz--)
|
||||
*result = *x1 & *x2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void set_console_io_buffering(void)
|
||||
{
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
setvbuf(stderr, NULL, _IOLBF, 0);
|
||||
}
|
||||
void close_std(void)
|
||||
{
|
||||
// free memory allocated by setvbuf
|
||||
fclose(stdout);
|
||||
fclose(stderr);
|
||||
}
|
||||
void close_std_and_exit(int code)
|
||||
{
|
||||
close_std();
|
||||
exit(code);
|
||||
}
|
||||
|
||||
bool set_env_exedir(const char *argv0)
|
||||
{
|
||||
@@ -601,73 +543,6 @@ bool set_env_exedir(const char *argv0)
|
||||
return bOK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr)
|
||||
{
|
||||
char s_ip[16];
|
||||
*s_ip=0;
|
||||
inet_ntop(AF_INET, &cidr->addr, s_ip, sizeof(s_ip));
|
||||
snprintf(s,s_len,cidr->preflen<32 ? "%s/%u" : "%s", s_ip, cidr->preflen);
|
||||
}
|
||||
void print_cidr4(const struct cidr4 *cidr)
|
||||
{
|
||||
char s[19];
|
||||
str_cidr4(s,sizeof(s),cidr);
|
||||
printf("%s",s);
|
||||
}
|
||||
void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr)
|
||||
{
|
||||
char s_ip[40];
|
||||
*s_ip=0;
|
||||
inet_ntop(AF_INET6, &cidr->addr, s_ip, sizeof(s_ip));
|
||||
snprintf(s,s_len,cidr->preflen<128 ? "%s/%u" : "%s", s_ip, cidr->preflen);
|
||||
}
|
||||
void print_cidr6(const struct cidr6 *cidr)
|
||||
{
|
||||
char s[44];
|
||||
str_cidr6(s,sizeof(s),cidr);
|
||||
printf("%s",s);
|
||||
}
|
||||
bool parse_cidr4(char *s, struct cidr4 *cidr)
|
||||
{
|
||||
char *p,d;
|
||||
bool b;
|
||||
unsigned int plen;
|
||||
|
||||
if ((p = strchr(s, '/')))
|
||||
{
|
||||
if (sscanf(p + 1, "%u", &plen)!=1 || plen>32)
|
||||
return false;
|
||||
cidr->preflen = (uint8_t)plen;
|
||||
d=*p; *p=0; // backup char
|
||||
}
|
||||
else
|
||||
cidr->preflen = 32;
|
||||
b = (inet_pton(AF_INET, s, &cidr->addr)==1);
|
||||
if (p) *p=d; // restore char
|
||||
return b;
|
||||
}
|
||||
bool parse_cidr6(char *s, struct cidr6 *cidr)
|
||||
{
|
||||
char *p,d;
|
||||
bool b;
|
||||
unsigned int plen;
|
||||
|
||||
if ((p = strchr(s, '/')))
|
||||
{
|
||||
if (sscanf(p + 1, "%u", &plen)!=1 || plen>128)
|
||||
return false;
|
||||
cidr->preflen = (uint8_t)plen;
|
||||
d=*p; *p=0; // backup char
|
||||
}
|
||||
else
|
||||
cidr->preflen = 128;
|
||||
b = (inet_pton(AF_INET6, s, &cidr->addr)==1);
|
||||
if (p) *p=d; // restore char
|
||||
return b;
|
||||
}
|
||||
|
||||
bool parse_int16(const char *p, int16_t *v)
|
||||
{
|
||||
if (*p == '+' || *p == '-' || *p >= '0' && *p <= '9')
|
||||
@@ -678,3 +553,29 @@ bool parse_int16(const char *p, int16_t *v)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t mask_from_bitcount(uint32_t zct)
|
||||
{
|
||||
return zct<32 ? ~((1u << zct) - 1) : 0;
|
||||
}
|
||||
static void mask_from_bitcount6_make(uint32_t zct, struct in6_addr *a)
|
||||
{
|
||||
if (zct >= 128)
|
||||
memset(a->s6_addr,0x00,16);
|
||||
else
|
||||
{
|
||||
int32_t n = (127 - zct) >> 3;
|
||||
memset(a->s6_addr,0xFF,n);
|
||||
memset(a->s6_addr+n,0x00,16-n);
|
||||
a->s6_addr[n] = ~((1u << (zct & 7)) - 1);
|
||||
}
|
||||
}
|
||||
static struct in6_addr ip6_mask[129];
|
||||
void mask_from_bitcount6_prepare(void)
|
||||
{
|
||||
for (int zct=0;zct<=128;zct++) mask_from_bitcount6_make(zct, ip6_mask+zct);
|
||||
}
|
||||
const struct in6_addr *mask_from_bitcount6(uint32_t zct)
|
||||
{
|
||||
return ip6_mask+zct;
|
||||
}
|
||||
|
||||
@@ -85,55 +85,22 @@ time_t file_mod_time(const char *filename);
|
||||
bool file_size(const char *filename, off_t *size);
|
||||
bool file_open_test(const char *filename, int flags);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t from,to;
|
||||
bool neg;
|
||||
} port_filter;
|
||||
bool pf_in_range(uint16_t port, const port_filter *pf);
|
||||
bool pf_parse(const char *s, port_filter *pf);
|
||||
bool pf_is_empty(const port_filter *pf);
|
||||
|
||||
struct packet_pos
|
||||
{
|
||||
char mode; // n - packets, d - data packets, s - relative sequence
|
||||
unsigned int pos;
|
||||
};
|
||||
struct packet_range
|
||||
{
|
||||
struct packet_pos from, to;
|
||||
bool upper_cutoff; // true - do not include upper limit, false - include upper limit
|
||||
};
|
||||
#define PACKET_POS_NEVER (struct packet_pos){'x',0}
|
||||
#define PACKET_POS_ALWAYS (struct packet_pos){'a',0}
|
||||
#define PACKET_RANGE_NEVER (struct packet_range){PACKET_POS_NEVER,PACKET_POS_NEVER}
|
||||
#define PACKET_RANGE_ALWAYS (struct packet_range){PACKET_POS_ALWAYS,PACKET_POS_ALWAYS}
|
||||
bool packet_range_parse(const char *s, struct packet_range *range);
|
||||
|
||||
void fill_random_bytes(uint8_t *p,size_t sz);
|
||||
void fill_random_az(uint8_t *p,size_t sz);
|
||||
void fill_random_az09(uint8_t *p,size_t sz);
|
||||
bool fill_crypto_random_bytes(uint8_t *p,size_t sz);
|
||||
|
||||
void bxor(const uint8_t *x1, const uint8_t *x2, uint8_t *result, size_t sz);
|
||||
void band(const uint8_t *x1, const uint8_t *x2, uint8_t *result, size_t sz);
|
||||
void bor(const uint8_t *x1, const uint8_t *x2, uint8_t *result, size_t sz);
|
||||
|
||||
void set_console_io_buffering(void);
|
||||
void close_std(void);
|
||||
void close_std_and_exit(int code);
|
||||
bool set_env_exedir(const char *argv0);
|
||||
|
||||
|
||||
struct cidr4
|
||||
{
|
||||
struct in_addr addr;
|
||||
uint8_t preflen;
|
||||
};
|
||||
struct cidr6
|
||||
{
|
||||
struct in6_addr addr;
|
||||
uint8_t preflen;
|
||||
};
|
||||
void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr);
|
||||
void print_cidr4(const struct cidr4 *cidr);
|
||||
void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr);
|
||||
void print_cidr6(const struct cidr6 *cidr);
|
||||
bool parse_cidr4(char *s, struct cidr4 *cidr);
|
||||
bool parse_cidr6(char *s, struct cidr6 *cidr);
|
||||
|
||||
bool parse_int16(const char *p, int16_t *v);
|
||||
|
||||
uint32_t mask_from_bitcount(uint32_t zct);
|
||||
void mask_from_bitcount6_prepare(void);
|
||||
const struct in6_addr *mask_from_bitcount6(uint32_t zct);
|
||||
|
||||
@@ -42,7 +42,7 @@ bool AppendHostlistItem(hostlist_pool **hostlist, char *s)
|
||||
|
||||
bool AppendHostList(hostlist_pool **hostlist, const char *filename)
|
||||
{
|
||||
char *p, *e, s[256], *zbuf;
|
||||
char *p, *e, s[4096], *zbuf;
|
||||
size_t zsize;
|
||||
int ct = 0;
|
||||
FILE *F;
|
||||
|
||||
27
nfq2/ipset.c
27
nfq2/ipset.c
@@ -59,7 +59,7 @@ bool AppendIpsetItem(ipset *ips, char *ip)
|
||||
|
||||
static bool AppendIpset(ipset *ips, const char *filename)
|
||||
{
|
||||
char *p, *e, s[256], *zbuf;
|
||||
char *p, *e, s[4096], *zbuf;
|
||||
size_t zsize;
|
||||
int ct = 0;
|
||||
FILE *F;
|
||||
@@ -215,7 +215,11 @@ bool IpsetsReloadCheckForProfile(const struct desync_profile *dp)
|
||||
return IpsetsReloadCheck(&dp->ips_collection) && IpsetsReloadCheck(&dp->ips_collection_exclude);
|
||||
}
|
||||
|
||||
static bool IpsetCheck_(const struct ipset_collection_head *ips, const struct ipset_collection_head *ips_exclude, const struct in_addr *ipv4, const struct in6_addr *ipv6)
|
||||
static bool IpsetCheck_(
|
||||
const struct ipset_collection_head *ips, const struct ipset_collection_head *ips_exclude,
|
||||
const struct in_addr *ipv4, const struct in6_addr *ipv6,
|
||||
const struct in_addr *ipv4r, const struct in6_addr *ipv6r
|
||||
)
|
||||
{
|
||||
struct ipset_item *item;
|
||||
|
||||
@@ -227,6 +231,12 @@ static bool IpsetCheck_(const struct ipset_collection_head *ips, const struct ip
|
||||
DLOG("[%s] exclude ",item->hfile->filename ? item->hfile->filename : "fixed");
|
||||
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
||||
return false;
|
||||
if (ipv4r || ipv6r)
|
||||
{
|
||||
DLOG("[%s] exclude ",item->hfile->filename ? item->hfile->filename : "fixed");
|
||||
if (SearchIpset(&item->hfile->ipset, ipv4r, ipv6r))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// old behavior compat: all include lists are empty means check passes
|
||||
if (!ipset_collection_is_empty(ips))
|
||||
@@ -236,17 +246,26 @@ static bool IpsetCheck_(const struct ipset_collection_head *ips, const struct ip
|
||||
DLOG("[%s] include ",item->hfile->filename ? item->hfile->filename : "fixed");
|
||||
if (SearchIpset(&item->hfile->ipset, ipv4, ipv6))
|
||||
return true;
|
||||
if (ipv4r || ipv6r)
|
||||
{
|
||||
DLOG("[%s] include ",item->hfile->filename ? item->hfile->filename : "fixed");
|
||||
if (SearchIpset(&item->hfile->ipset, ipv4r, ipv6r))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6)
|
||||
bool IpsetCheck(
|
||||
const struct desync_profile *dp,
|
||||
const struct in_addr *ipv4, const struct in6_addr *ipv6,
|
||||
const struct in_addr *ipv4r, const struct in6_addr *ipv6r)
|
||||
{
|
||||
if (PROFILE_IPSETS_ABSENT(dp)) return true;
|
||||
DLOG("* ipset check for profile %u (%s)\n",dp->n,PROFILE_NAME(dp));
|
||||
return IpsetCheck_(&dp->ips_collection,&dp->ips_collection_exclude,ipv4,ipv6);
|
||||
return IpsetCheck_(&dp->ips_collection,&dp->ips_collection_exclude,ipv4,ipv6,ipv4r,ipv6r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
#include "pools.h"
|
||||
|
||||
bool LoadAllIpsets();
|
||||
bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *ipv4, const struct in6_addr *ipv6);
|
||||
bool IpsetCheck(
|
||||
const struct desync_profile *dp,
|
||||
const struct in_addr *ipv4, const struct in6_addr *ipv6,
|
||||
const struct in_addr *ipv4r, const struct in6_addr *ipv6r);
|
||||
struct ipset_file *RegisterIpset(struct desync_profile *dp, bool bExclude, const char *filename);
|
||||
void IpsetsDebug();
|
||||
bool AppendIpsetItem(ipset *ips, char *ip);
|
||||
|
||||
821
nfq2/lua.c
821
nfq2/lua.c
File diff suppressed because it is too large
Load Diff
17
nfq2/lua.h
17
nfq2/lua.h
@@ -42,8 +42,8 @@
|
||||
|
||||
void desync_instance(const char *func, unsigned int dp_n, unsigned int func_n, char *instance, size_t inst_size);
|
||||
|
||||
|
||||
bool lua_test_init_script_files(void);
|
||||
void lua_req_quit(void);
|
||||
bool lua_init(void);
|
||||
void lua_shutdown(void);
|
||||
void lua_dlog_error(void);
|
||||
@@ -54,6 +54,9 @@ int lua_absindex(lua_State *L, int idx);
|
||||
#define lua_rawlen lua_objlen
|
||||
#endif
|
||||
|
||||
const char *lua_reqlstring(lua_State *L,int idx,size_t *len);
|
||||
const char *lua_reqstring(lua_State *L,int idx);
|
||||
|
||||
// push - create object and push to the stack
|
||||
// pushf - create object and set it as a named field of a table already present on the stack
|
||||
// pushi - create object and set it as a index field of a table already present on the stack
|
||||
@@ -82,10 +85,19 @@ void lua_pushi_table(lua_State *L, lua_Integer idx);
|
||||
void lua_push_blob(lua_State *L, int idx_desync, const char *blob);
|
||||
void lua_pushf_blob(lua_State *L, int idx_desync, const char *field, const char *blob);
|
||||
|
||||
void lua_push_ipaddr(lua_State *L, const struct sockaddr *sa);
|
||||
void lua_pushf_ipaddr(lua_State *L, const char *field, const struct sockaddr *sa);
|
||||
void lua_pushi_ipaddr(lua_State *L, lua_Integer idx, const struct sockaddr *sa);
|
||||
void lua_pushi_str(lua_State *L, lua_Integer idx, const char *str);
|
||||
void lua_pushf_tcphdr_options(lua_State *L, const struct tcphdr *tcp, size_t len);
|
||||
void lua_push_tcphdr(lua_State *L, const struct tcphdr *tcp, size_t len);
|
||||
void lua_pushf_tcphdr(lua_State *L, const struct tcphdr *tcp, size_t len);
|
||||
void lua_push_udphdr(lua_State *L, const struct udphdr *udp, size_t len);
|
||||
void lua_pushf_udphdr(lua_State *L, const struct udphdr *udp, size_t len);
|
||||
void lua_pushf_icmphdr(lua_State *L, const struct icmp46 *icmp, size_t len);
|
||||
void lua_push_iphdr(lua_State *L, const struct ip *ip, size_t len);
|
||||
void lua_pushf_iphdr(lua_State *L, const struct ip *ip, size_t len);
|
||||
void lua_push_ip6hdr(lua_State *L, const struct ip6_hdr *ip6, size_t len);
|
||||
void lua_pushf_ip6hdr(lua_State *L, const struct ip6_hdr *ip6, size_t len);
|
||||
void lua_push_dissect(lua_State *L, const struct dissect *dis);
|
||||
void lua_pushf_dissect(lua_State *L, const struct dissect *dis);
|
||||
@@ -99,7 +111,8 @@ bool lua_reconstruct_ip6hdr(lua_State *L, int idx, struct ip6_hdr *ip6, size_t *
|
||||
bool lua_reconstruct_iphdr(lua_State *L, int idx, struct ip *ip, size_t *len);
|
||||
bool lua_reconstruct_tcphdr(lua_State *L, int idx, struct tcphdr *tcp, size_t *len);
|
||||
bool lua_reconstruct_udphdr(lua_State *L, int idx, struct udphdr *udp);
|
||||
bool lua_reconstruct_dissect(lua_State *L, int idx, uint8_t *buf, size_t *len, bool badsum, bool ip6_preserve_next);
|
||||
bool lua_reconstruct_icmphdr(lua_State *L, int idx, struct icmp46 *icmp);
|
||||
bool lua_reconstruct_dissect(lua_State *L, int idx, uint8_t *buf, size_t *len, bool keepsum, bool badsum, bool ip6_preserve_next);
|
||||
|
||||
typedef struct {
|
||||
unsigned int func_n;
|
||||
|
||||
426
nfq2/nfqws.c
426
nfq2/nfqws.c
@@ -52,7 +52,7 @@
|
||||
|
||||
struct params_s params;
|
||||
static volatile sig_atomic_t bReload = false;
|
||||
bool bQuit = false;
|
||||
volatile sig_atomic_t bQuit = false;
|
||||
|
||||
static void onhup(int sig)
|
||||
{
|
||||
@@ -109,21 +109,21 @@ static void onusr2(int sig)
|
||||
static void onint(int sig)
|
||||
{
|
||||
if (bQuit) return;
|
||||
|
||||
const char *msg = "INT received !\n";
|
||||
size_t wr = write(1, msg, strlen(msg));
|
||||
bQuit = true;
|
||||
lua_req_quit();
|
||||
}
|
||||
static void onterm(int sig)
|
||||
{
|
||||
if (bQuit) return;
|
||||
|
||||
const char *msg = "TERM received !\n";
|
||||
size_t wr = write(1, msg, strlen(msg));
|
||||
bQuit = true;
|
||||
lua_req_quit();
|
||||
}
|
||||
|
||||
static void pre_desync(void)
|
||||
static void catch_signals(void)
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
@@ -180,6 +180,26 @@ static bool test_list_files()
|
||||
}
|
||||
|
||||
|
||||
// writes and closes pidfile
|
||||
static int write_pidfile(FILE **Fpid)
|
||||
{
|
||||
if (*Fpid)
|
||||
{
|
||||
int r = fprintf(*Fpid, "%d", getpid());
|
||||
if (r <= 0)
|
||||
{
|
||||
DLOG_PERROR("write pidfile");
|
||||
fclose(*Fpid);
|
||||
*Fpid = NULL;
|
||||
return false;
|
||||
}
|
||||
fclose(*Fpid);
|
||||
*Fpid = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *cookie)
|
||||
{
|
||||
@@ -343,9 +363,24 @@ static int nfq_main(void)
|
||||
if (!rawsend_preinit(params.bind_fix4, params.bind_fix6))
|
||||
goto err;
|
||||
|
||||
if (!params.intercept)
|
||||
{
|
||||
if (params.daemon) daemonize();
|
||||
if (!write_pidfile(&Fpid)) goto err;
|
||||
notify_ready();
|
||||
}
|
||||
|
||||
catch_signals();
|
||||
|
||||
if (!lua_init())
|
||||
goto err;
|
||||
|
||||
if (!params.intercept)
|
||||
{
|
||||
DLOG("no intercept quit\n");
|
||||
goto exok;
|
||||
}
|
||||
|
||||
if (!nfq_init(&h, &qh))
|
||||
goto err;
|
||||
|
||||
@@ -362,19 +397,8 @@ static int nfq_main(void)
|
||||
#endif
|
||||
|
||||
if (params.daemon) daemonize();
|
||||
if (!write_pidfile(&Fpid)) goto err;
|
||||
|
||||
if (Fpid)
|
||||
{
|
||||
if (fprintf(Fpid, "%d", getpid()) <= 0)
|
||||
{
|
||||
DLOG_PERROR("write pidfile");
|
||||
goto err;
|
||||
}
|
||||
fclose(Fpid);
|
||||
Fpid = NULL;
|
||||
}
|
||||
|
||||
pre_desync();
|
||||
notify_ready();
|
||||
|
||||
fd = nfq_fd(h);
|
||||
@@ -451,6 +475,8 @@ static int dvt_main(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (params.intercept)
|
||||
{
|
||||
bp4.sin_family = AF_INET;
|
||||
bp4.sin_port = htons(params.port);
|
||||
bp4.sin_addr.s_addr = INADDR_ANY;
|
||||
@@ -467,7 +493,6 @@ static int dvt_main(void)
|
||||
goto exiterr;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
// in OpenBSD must use separate divert sockets for ipv4 and ipv6
|
||||
memset(&bp6, 0, sizeof(bp6));
|
||||
@@ -489,12 +514,12 @@ static int dvt_main(void)
|
||||
fdct++;
|
||||
#endif
|
||||
fdmax = (fd[0] > fd[1] ? fd[0] : fd[1]) + 1;
|
||||
}
|
||||
|
||||
DLOG_CONDUP("initializing raw sockets\n");
|
||||
if (!rawsend_preinit(false, false))
|
||||
goto exiterr;
|
||||
|
||||
|
||||
if (params.droproot && !droproot(params.uid, params.user, params.gid, params.gid_count))
|
||||
goto exiterr;
|
||||
print_id();
|
||||
@@ -503,23 +528,25 @@ static int dvt_main(void)
|
||||
if (!lua_test_init_script_files())
|
||||
goto exiterr;
|
||||
|
||||
catch_signals();
|
||||
|
||||
if (!params.intercept)
|
||||
{
|
||||
if (params.daemon) daemonize();
|
||||
if (!write_pidfile(&Fpid)) goto exiterr;
|
||||
}
|
||||
|
||||
if (!lua_init())
|
||||
goto exiterr;
|
||||
|
||||
if (!params.intercept)
|
||||
{
|
||||
DLOG("no intercept quit\n");
|
||||
goto exitok;
|
||||
}
|
||||
|
||||
if (params.daemon) daemonize();
|
||||
|
||||
if (Fpid)
|
||||
{
|
||||
if (fprintf(Fpid, "%d", getpid()) <= 0)
|
||||
{
|
||||
DLOG_PERROR("write pidfile");
|
||||
goto exiterr;
|
||||
}
|
||||
fclose(Fpid);
|
||||
Fpid = NULL;
|
||||
}
|
||||
|
||||
pre_desync();
|
||||
if (!write_pidfile(&Fpid)) goto exiterr;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@@ -637,6 +664,7 @@ static int win_main()
|
||||
int res=0;
|
||||
uint8_t packet[RECONSTRUCT_MAX_SIZE] __attribute__((aligned(16)));
|
||||
|
||||
// windows emulated fork logic does not cover objects outside of cygwin world. have to daemonize before inits
|
||||
if (params.daemon) daemonize();
|
||||
|
||||
if (*params.pidfile && !writepid(params.pidfile))
|
||||
@@ -651,7 +679,7 @@ static int win_main()
|
||||
res=w_win32_error; goto ex;
|
||||
}
|
||||
|
||||
pre_desync();
|
||||
catch_signals();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
@@ -675,6 +703,8 @@ static int win_main()
|
||||
res=w_win32_error; goto ex;
|
||||
}
|
||||
|
||||
DLOG_CONDUP(params.intercept ? "windivert initialized. capture is started.\n" : "windivert initialized\n");
|
||||
|
||||
if (!win_sandbox())
|
||||
{
|
||||
res=w_win32_error;
|
||||
@@ -688,7 +718,11 @@ static int win_main()
|
||||
res=ERROR_INVALID_PARAMETER; goto ex;
|
||||
}
|
||||
|
||||
DLOG_CONDUP("windivert initialized. capture is started.\n");
|
||||
if (!params.intercept)
|
||||
{
|
||||
DLOG("no intercept quit\n");
|
||||
goto ex;
|
||||
}
|
||||
|
||||
for (id = 0;; id++)
|
||||
{
|
||||
@@ -765,8 +799,7 @@ ex:
|
||||
static void exit_clean(int code)
|
||||
{
|
||||
cleanup_params(¶ms);
|
||||
|
||||
exit(code);
|
||||
close_std_and_exit(code);
|
||||
}
|
||||
|
||||
|
||||
@@ -1042,6 +1075,52 @@ static bool parse_pf_list(char *opt, struct port_filters_head *pfl)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_icf_list(char *opt, struct icmp_filters_head *icfl)
|
||||
{
|
||||
char *e, *p, c;
|
||||
icmp_filter icf;
|
||||
bool b;
|
||||
|
||||
for (p = opt; p; )
|
||||
{
|
||||
if ((e = strchr(p, ',')))
|
||||
{
|
||||
c = *e;
|
||||
*e = 0;
|
||||
}
|
||||
|
||||
b = icf_parse(p, &icf) && icmp_filter_add(icfl, &icf);
|
||||
if (e) *e++ = c;
|
||||
if (!b) return false;
|
||||
|
||||
p = e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool parse_ipp_list(char *opt, struct ipp_filters_head *ippl)
|
||||
{
|
||||
char *e, *p, c;
|
||||
ipp_filter ipp;
|
||||
bool b;
|
||||
|
||||
for (p = opt; p; )
|
||||
{
|
||||
if ((e = strchr(p, ',')))
|
||||
{
|
||||
c = *e;
|
||||
*e = 0;
|
||||
}
|
||||
|
||||
b = ipp_parse(p, &ipp) && ipp_filter_add(ippl, &ipp);
|
||||
if (e) *e++ = c;
|
||||
if (!b) return false;
|
||||
|
||||
p = e;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lua_call_param_add(char *opt, struct str2_list_head *args)
|
||||
{
|
||||
char c,*p;
|
||||
@@ -1260,6 +1339,82 @@ static bool wf_make_pf(char *opt, const char *l4, const char *portname, char *bu
|
||||
strncat(buf, ")", len - strlen(buf) - 1);
|
||||
return true;
|
||||
}
|
||||
static bool wf_make_icf(char *opt, char *buf, size_t len)
|
||||
{
|
||||
char *e, *p, c, s1[80];
|
||||
icmp_filter icf;
|
||||
|
||||
if (len < 3) return false;
|
||||
|
||||
for (p = opt, *buf = '(', buf[1] = 0; p;)
|
||||
{
|
||||
if ((e = strchr(p, ',')))
|
||||
{
|
||||
c = *e;
|
||||
*e = 0;
|
||||
}
|
||||
if (!icf_parse(p, &icf)) return false;
|
||||
switch(icf.mode)
|
||||
{
|
||||
case FLTMODE_FILTER:
|
||||
if (icf.code_valid)
|
||||
snprintf(s1, sizeof(s1), "icmp.Type==%u and icmp.Code==%u or icmpv6.Type==%u and icmpv6.Code==%u", icf.type, icf.code, icf.type, icf.code);
|
||||
else
|
||||
snprintf(s1, sizeof(s1), "icmp.Type==%u or icmpv6.Type==%u", icf.type, icf.type);
|
||||
break;
|
||||
case FLTMODE_ANY:
|
||||
snprintf(s1, sizeof(s1), "icmp or icmpv6");
|
||||
break;
|
||||
default:
|
||||
goto dont_add;
|
||||
}
|
||||
if (buf[1]) strncat(buf, " or ", len - strlen(buf) - 1);
|
||||
strncat(buf, s1, len - strlen(buf) - 1);
|
||||
dont_add:
|
||||
if (e) *e++ = c;
|
||||
p = e;
|
||||
}
|
||||
if (!buf[1]) return false; // nothing added
|
||||
strncat(buf, ")", len - strlen(buf) - 1);
|
||||
return true;
|
||||
}
|
||||
static bool wf_make_ipf(char *opt, char *buf, size_t len)
|
||||
{
|
||||
char *e, *p, c, s1[40];
|
||||
ipp_filter ipf;
|
||||
|
||||
if (len < 3) return false;
|
||||
|
||||
for (p = opt, *buf = '(', buf[1] = 0; p;)
|
||||
{
|
||||
if ((e = strchr(p, ',')))
|
||||
{
|
||||
c = *e;
|
||||
*e = 0;
|
||||
}
|
||||
if (!ipp_parse(p, &ipf)) return false;
|
||||
switch(ipf.mode)
|
||||
{
|
||||
case FLTMODE_FILTER:
|
||||
// NOTE: windivert can't walk ipv6 extension headers. instead of real protocol first ext header type will be matched
|
||||
snprintf(s1, sizeof(s1), "ip.Protocol==%u or ipv6.NextHdr==%u", ipf.proto, ipf.proto);
|
||||
break;
|
||||
case FLTMODE_ANY:
|
||||
snprintf(s1, sizeof(s1), "ip or ipv6");
|
||||
break;
|
||||
default:
|
||||
goto dont_add;
|
||||
}
|
||||
if (buf[1]) strncat(buf, " or ", len - strlen(buf) - 1);
|
||||
strncat(buf, s1, len - strlen(buf) - 1);
|
||||
dont_add:
|
||||
if (e) *e++ = c;
|
||||
p = e;
|
||||
}
|
||||
if (!buf[1]) return false; // nothing added
|
||||
strncat(buf, ")", len - strlen(buf) - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define DIVERT_NO_LOCALNETSv4_DST "(" \
|
||||
"(ip.DstAddr < 127.0.0.1 or ip.DstAddr > 127.255.255.255) and " \
|
||||
@@ -1306,6 +1461,8 @@ static bool wf_make_filter(
|
||||
const char *pf_tcp_src_out, const char *pf_tcp_dst_out,
|
||||
const char *pf_tcp_src_in, const char *pf_tcp_dst_in,
|
||||
const char *pf_udp_src_in, const char *pf_udp_dst_out,
|
||||
const char *icf_out, const char *icf_in,
|
||||
const char *ipf_out, const char *ipf_in,
|
||||
const struct str_list_head *wf_raw_part,
|
||||
bool bFilterOutLAN, bool bFilterOutLoopback)
|
||||
{
|
||||
@@ -1354,6 +1511,11 @@ static bool wf_make_filter(
|
||||
if (*pf_udp_dst_out) snprintf(wf + strlen(wf), len - strlen(wf), " or\n outbound and %s", pf_udp_dst_out);
|
||||
if (*pf_udp_src_in) snprintf(wf + strlen(wf), len - strlen(wf), " or\n inbound and %s", pf_udp_src_in);
|
||||
|
||||
if (*icf_in) snprintf(wf + strlen(wf), len - strlen(wf), " or\n inbound and %s", icf_in);
|
||||
if (*icf_out) snprintf(wf + strlen(wf), len - strlen(wf), " or\n outbound and %s", icf_out);
|
||||
if (*ipf_in) snprintf(wf + strlen(wf), len - strlen(wf), " or\n inbound and %s", ipf_in);
|
||||
if (*ipf_out) snprintf(wf + strlen(wf), len - strlen(wf), " or\n outbound and %s", ipf_out);
|
||||
|
||||
snprintf(wf + strlen(wf), len - strlen(wf), "\n)");
|
||||
|
||||
if (bFilterOutLAN)
|
||||
@@ -1403,6 +1565,7 @@ static void exithelp(void)
|
||||
" --version\t\t\t\t\t\t; print version and exit\n"
|
||||
" --dry-run\t\t\t\t\t\t; verify parameters and exit with code 0 if successful\n"
|
||||
" --comment=any_text\n"
|
||||
" --intercept=0|1\t\t\t\t\t; enable interception. if disabled - run lua-init and exit\n"
|
||||
#ifdef __linux__
|
||||
" --qnum=<nfqueue_number>\n"
|
||||
#elif defined(BSD)
|
||||
@@ -1433,10 +1596,14 @@ static void exithelp(void)
|
||||
" --wf-iface=<int>[.<int>]\t\t\t\t; numeric network interface and subinterface indexes\n"
|
||||
" --wf-l3=ipv4|ipv6\t\t\t\t\t; L3 protocol filter. multiple comma separated values allowed.\n"
|
||||
" --wf-tcp-in=[~]port1[-port2]\t\t\t\t; TCP in port filter. ~ means negation. multiple comma separated values allowed.\n"
|
||||
" --wf-udp-in=[~]port1[-port2]\t\t\t\t; UDP in port filter. ~ means negation. multiple comma separated values allowed.\n"
|
||||
" --wf-tcp-out=[~]port1[-port2]\t\t\t\t; TCP out port filter. ~ means negation. multiple comma separated values allowed.\n"
|
||||
" --wf-udp-in=[~]port1[-port2]\t\t\t\t; UDP in port filter. ~ means negation. multiple comma separated values allowed.\n"
|
||||
" --wf-udp-out=[~]port1[-port2]\t\t\t\t; UDP out port filter. ~ means negation. multiple comma separated values allowed.\n"
|
||||
" --wf-tcp-empty=[0|1]\t\t\t\t\t; enable processing of empty tcp packets without flags SYN,RST,FIN (default : 0)\n"
|
||||
" --wf-icmp-in=type[:code]\t\t\t\t; ICMP out filter. multiple comma separated values allowed.\n"
|
||||
" --wf-icmp-out=type[:code]\t\t\t\t; ICMP in filter. multiple comma separated values allowed.\n"
|
||||
" --wf-ipp-in=proto\t\t\t\t\t; IP protocol in filter. multiple comma separated values allowed.\n"
|
||||
" --wf-ipp-out=proto\t\t\t\t\t; IP protocol out filter. multiple comma separated values allowed.\n"
|
||||
" --wf-raw-part=<filter>|@<filename>\t\t\t; partial raw windivert filter string or filename\n"
|
||||
" --wf-filter-lan=0|1\t\t\t\t\t; add excluding filter for non-global IP (default : 1)\n"
|
||||
" --wf-filter-loopback=0|1\t\t\t\t; add excluding filter for loopback (default : 1)\n"
|
||||
@@ -1461,8 +1628,10 @@ static void exithelp(void)
|
||||
" --cookie[=<string>]\t\t\t\t\t; pass this profile-bound string to LUA\n"
|
||||
" --import=<name>\t\t\t\t\t; populate current profile with template data\n"
|
||||
" --filter-l3=ipv4|ipv6\t\t\t\t\t; L3 protocol filter. multiple comma separated values allowed.\n"
|
||||
" --filter-tcp=[~]port1[-port2]|*\t\t\t; TCP port filter. ~ means negation. setting tcp and not setting udp filter denies udp. comma separated list allowed.\n"
|
||||
" --filter-udp=[~]port1[-port2]|*\t\t\t; UDP port filter. ~ means negation. setting udp and not setting tcp filter denies tcp. comma separated list allowed.\n"
|
||||
" --filter-tcp=[~]port1[-port2]|*\t\t\t; TCP port filter. ~ means negation. setting tcp filter and not setting others denies others. comma separated list allowed.\n"
|
||||
" --filter-udp=[~]port1[-port2]|*\t\t\t; UDP port filter. ~ means negation. setting udp filter and not setting others denies others. comma separated list allowed.\n"
|
||||
" --filter-icmp=type[:code]|*\t\t\t\t; ICMP type+code filter. setting icmp filter and not setting others denies others. comma separated list allowed.\n"
|
||||
" --filter-ipp=proto\t\t\t\t\t; IP protocol filter. setting up ipp filter and not setting others denies others. comma separated list allowed.\n"
|
||||
" --filter-l7=proto[,proto]\t\t\t\t; L6-L7 protocol filter : %s\n"
|
||||
#ifdef HAS_FILTER_SSID
|
||||
" --filter-ssid=ssid1[,ssid2,ssid3,...]\t\t\t; per profile wifi SSID filter\n"
|
||||
@@ -1504,7 +1673,7 @@ static void exithelp(void)
|
||||
HOSTLIST_AUTO_UDP_OUT, HOSTLIST_AUTO_UDP_IN,
|
||||
all_payloads
|
||||
);
|
||||
exit(1);
|
||||
close_std_and_exit(1);
|
||||
}
|
||||
static void exithelp_clean(void)
|
||||
{
|
||||
@@ -1553,6 +1722,7 @@ static void ApplyDefaultBlobs(struct blob_collection_head *blobs)
|
||||
enum opt_indices {
|
||||
IDX_DEBUG,
|
||||
IDX_DRY_RUN,
|
||||
IDX_INTERCEPT,
|
||||
IDX_VERSION,
|
||||
IDX_COMMENT,
|
||||
#ifdef __linux__
|
||||
@@ -1610,6 +1780,8 @@ enum opt_indices {
|
||||
IDX_FILTER_L3,
|
||||
IDX_FILTER_TCP,
|
||||
IDX_FILTER_UDP,
|
||||
IDX_FILTER_ICMP,
|
||||
IDX_FILTER_IPP,
|
||||
IDX_FILTER_L7,
|
||||
#ifdef HAS_FILTER_SSID
|
||||
IDX_FILTER_SSID,
|
||||
@@ -1632,6 +1804,10 @@ enum opt_indices {
|
||||
IDX_WF_UDP_IN,
|
||||
IDX_WF_UDP_OUT,
|
||||
IDX_WF_TCP_EMPTY,
|
||||
IDX_WF_ICMP_IN,
|
||||
IDX_WF_ICMP_OUT,
|
||||
IDX_WF_IPP_IN,
|
||||
IDX_WF_IPP_OUT,
|
||||
IDX_WF_RAW,
|
||||
IDX_WF_RAW_PART,
|
||||
IDX_WF_FILTER_LAN,
|
||||
@@ -1648,6 +1824,7 @@ enum opt_indices {
|
||||
static const struct option long_options[] = {
|
||||
[IDX_DEBUG] = {"debug", optional_argument, 0, 0},
|
||||
[IDX_DRY_RUN] = {"dry-run", no_argument, 0, 0},
|
||||
[IDX_INTERCEPT] = {"intercept", optional_argument, 0, 0},
|
||||
[IDX_VERSION] = {"version", no_argument, 0, 0},
|
||||
[IDX_COMMENT] = {"comment", optional_argument, 0, 0},
|
||||
#ifdef __linux__
|
||||
@@ -1702,6 +1879,8 @@ static const struct option long_options[] = {
|
||||
[IDX_FILTER_L3] = {"filter-l3", required_argument, 0, 0},
|
||||
[IDX_FILTER_TCP] = {"filter-tcp", required_argument, 0, 0},
|
||||
[IDX_FILTER_UDP] = {"filter-udp", required_argument, 0, 0},
|
||||
[IDX_FILTER_ICMP] = {"filter-icmp", required_argument, 0, 0},
|
||||
[IDX_FILTER_IPP] = {"filter-ipp", required_argument, 0, 0},
|
||||
[IDX_FILTER_L7] = {"filter-l7", required_argument, 0, 0},
|
||||
#ifdef HAS_FILTER_SSID
|
||||
[IDX_FILTER_SSID] = {"filter-ssid", required_argument, 0, 0},
|
||||
@@ -1724,6 +1903,10 @@ static const struct option long_options[] = {
|
||||
[IDX_WF_UDP_IN] = {"wf-udp-in", required_argument, 0, 0},
|
||||
[IDX_WF_UDP_OUT] = {"wf-udp-out", required_argument, 0, 0},
|
||||
[IDX_WF_TCP_EMPTY] = {"wf-tcp-empty", optional_argument, 0, 0},
|
||||
[IDX_WF_ICMP_IN] = {"wf-icmp-in", required_argument, 0, 0},
|
||||
[IDX_WF_ICMP_OUT] = {"wf-icmp-out", required_argument, 0, 0},
|
||||
[IDX_WF_IPP_IN] = {"wf-ipp-in", required_argument, 0, 0},
|
||||
[IDX_WF_IPP_OUT] = {"wf-ipp-out", required_argument, 0, 0},
|
||||
[IDX_WF_RAW] = {"wf-raw", required_argument, 0, 0},
|
||||
[IDX_WF_RAW_PART] = {"wf-raw-part", required_argument, 0, 0},
|
||||
[IDX_WF_FILTER_LAN] = {"wf-filter-lan", required_argument, 0, 0},
|
||||
@@ -1738,6 +1921,29 @@ static const struct option long_options[] = {
|
||||
};
|
||||
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
#define TITLE_ICON MAKEINTRESOURCE(1)
|
||||
static void WinSetIcon(void)
|
||||
{
|
||||
HWND hConsole = GetConsoleWindow();
|
||||
HICON hIcon,hIconOld;
|
||||
if (hConsole)
|
||||
{
|
||||
if ((hIcon = LoadImage(GetModuleHandle(NULL),TITLE_ICON,IMAGE_ICON,32,32,LR_DEFAULTCOLOR|LR_SHARED)))
|
||||
{
|
||||
hIconOld = (HICON)SendMessage(hConsole, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||
if (hIconOld) DestroyIcon(hIconOld);
|
||||
}
|
||||
if ((hIcon = LoadImage(GetModuleHandle(NULL),TITLE_ICON,IMAGE_ICON,0,0,LR_DEFAULTCOLOR|LR_SHARED)))
|
||||
{
|
||||
hIconOld = (HICON)SendMessage(hConsole, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||
if (hIconOld) DestroyIcon(hIconOld);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define STRINGIFY(x) #x
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
#if defined(ZAPRET_GH_VER) || defined (ZAPRET_GH_HASH)
|
||||
@@ -1754,6 +1960,7 @@ static const struct option long_options[] = {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
enum {WF_TCP_IN, WF_UDP_IN, WF_TCP_OUT, WF_UDP_OUT, WF_ICMP_IN, WF_ICMP_OUT, WF_IPP_IN, WF_IPP_OUT, WF_RAW, WF_RAWF_PART, GLOBAL_SSID_FILTER, GLOBAL_NLM_FILTER, WF_RAWF, WF_COUNT} t_wf_index;
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef __CYGWIN__
|
||||
@@ -1762,6 +1969,9 @@ int main(int argc, char **argv)
|
||||
// we were running as service. now exit.
|
||||
return 0;
|
||||
}
|
||||
WinSetIcon();
|
||||
MAKE_VER(params.verstr, sizeof(params.verstr));
|
||||
printf("%s\n\n",params.verstr);
|
||||
#endif
|
||||
int result, v;
|
||||
int option_index = 0;
|
||||
@@ -1774,24 +1984,23 @@ int main(int argc, char **argv)
|
||||
char wf_save_file[256]="";
|
||||
bool wf_ipv4 = true, wf_ipv6 = true, wf_filter_lan = true, wf_filter_loopback = true, wf_tcp_empty = false;
|
||||
unsigned int IfIdx = 0, SubIfIdx = 0;
|
||||
unsigned int hash_wf_tcp_in = 0, hash_wf_udp_in = 0, hash_wf_tcp_out = 0, hash_wf_udp_out = 0, hash_wf_raw = 0, hash_wf_raw_part = 0, hash_ssid_filter = 0, hash_nlm_filter = 0;
|
||||
unsigned int hash_wf[WF_COUNT];
|
||||
#endif
|
||||
|
||||
if (argc < 2) exithelp();
|
||||
|
||||
srandom(time(NULL));
|
||||
aes_init_keygen_tables(); // required for aes
|
||||
mask_from_bitcount6_prepare();
|
||||
set_env_exedir(argv[0]);
|
||||
set_console_io_buffering();
|
||||
#ifdef __CYGWIN__
|
||||
memset(hash_wf,0,sizeof(hash_wf));
|
||||
prepare_low_appdata();
|
||||
#endif
|
||||
|
||||
init_params(¶ms);
|
||||
|
||||
MAKE_VER(params.verstr, sizeof(params.verstr));
|
||||
printf("%s\n\n",params.verstr);
|
||||
|
||||
ApplyDefaultBlobs(¶ms.blobs);
|
||||
|
||||
struct desync_profile_list *dpl;
|
||||
@@ -1818,23 +2027,11 @@ int main(int argc, char **argv)
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
params.windivert_filter = malloc(WINDIVERT_MAX);
|
||||
if (!params.windivert_filter)
|
||||
if (!params.windivert_filter || !alloc_windivert_portfilters(¶ms))
|
||||
{
|
||||
DLOG_ERR("out of memory\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
char **wdbufs[] =
|
||||
{¶ms.wf_pf_tcp_src_in, ¶ms.wf_pf_tcp_dst_in, ¶ms.wf_pf_udp_src_in, ¶ms.wf_pf_udp_dst_in,
|
||||
¶ms.wf_pf_tcp_src_out, ¶ms.wf_pf_tcp_dst_out, ¶ms.wf_pf_udp_src_out, ¶ms.wf_pf_udp_dst_out};
|
||||
for (v=0 ; v<(sizeof(wdbufs)/sizeof(*wdbufs)) ; v++)
|
||||
{
|
||||
if (!(*wdbufs[v] = malloc(WINDIVERT_PORTFILTER_MAX)))
|
||||
{
|
||||
DLOG_ERR("out of memory\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
**wdbufs[v] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
while ((v = getopt_long_only(argc, argv, "", long_options, &option_index)) != -1)
|
||||
@@ -1898,6 +2095,9 @@ int main(int argc, char **argv)
|
||||
case IDX_DRY_RUN:
|
||||
bDry = true;
|
||||
break;
|
||||
case IDX_INTERCEPT:
|
||||
params.intercept = !optarg || atoi(optarg);
|
||||
break;
|
||||
case IDX_VERSION:
|
||||
exit_clean(0);
|
||||
break;
|
||||
@@ -2289,8 +2489,10 @@ int main(int argc, char **argv)
|
||||
DLOG_ERR("Invalid port filter : %s\n", optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
// deny udp if not set
|
||||
if (!port_filters_deny_if_empty(&dp->pf_udp))
|
||||
// deny others if not set
|
||||
if (!port_filters_deny_if_empty(&dp->pf_udp) ||
|
||||
!icmp_filters_deny_if_empty(&dp->icf) ||
|
||||
!ipp_filters_deny_if_empty(&dp->ipf))
|
||||
exit_clean(1);
|
||||
break;
|
||||
case IDX_FILTER_UDP:
|
||||
@@ -2299,8 +2501,34 @@ int main(int argc, char **argv)
|
||||
DLOG_ERR("Invalid port filter : %s\n", optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
// deny tcp if not set
|
||||
if (!port_filters_deny_if_empty(&dp->pf_tcp))
|
||||
// deny others if not set
|
||||
if (!port_filters_deny_if_empty(&dp->pf_tcp) ||
|
||||
!icmp_filters_deny_if_empty(&dp->icf) ||
|
||||
!ipp_filters_deny_if_empty(&dp->ipf))
|
||||
exit_clean(1);
|
||||
break;
|
||||
case IDX_FILTER_ICMP:
|
||||
if (!parse_icf_list(optarg, &dp->icf))
|
||||
{
|
||||
DLOG_ERR("Invalid icmp filter : %s\n", optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
// deny others if not set
|
||||
if (!port_filters_deny_if_empty(&dp->pf_tcp) ||
|
||||
!port_filters_deny_if_empty(&dp->pf_udp) ||
|
||||
!ipp_filters_deny_if_empty(&dp->ipf))
|
||||
exit_clean(1);
|
||||
break;
|
||||
case IDX_FILTER_IPP:
|
||||
if (!parse_ipp_list(optarg, &dp->ipf))
|
||||
{
|
||||
DLOG_ERR("Invalid ip protocol filter : %s\n", optarg);
|
||||
exit_clean(1);
|
||||
}
|
||||
// deny others if not set
|
||||
if (!port_filters_deny_if_empty(&dp->pf_tcp) ||
|
||||
!port_filters_deny_if_empty(&dp->pf_udp) ||
|
||||
!icmp_filters_deny_if_empty(&dp->icf))
|
||||
exit_clean(1);
|
||||
break;
|
||||
case IDX_FILTER_L7:
|
||||
@@ -2415,7 +2643,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case IDX_WF_TCP_IN:
|
||||
hash_wf_tcp_in = hash_jen(optarg, strlen(optarg));
|
||||
hash_wf[WF_TCP_IN] = hash_jen(optarg, strlen(optarg));
|
||||
if (!wf_make_pf(optarg, "tcp", "SrcPort", params.wf_pf_tcp_src_in, WINDIVERT_PORTFILTER_MAX) ||
|
||||
!wf_make_pf(optarg, "tcp", "DstPort", params.wf_pf_tcp_dst_in, WINDIVERT_PORTFILTER_MAX))
|
||||
{
|
||||
@@ -2424,7 +2652,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case IDX_WF_TCP_OUT:
|
||||
hash_wf_tcp_out = hash_jen(optarg, strlen(optarg));
|
||||
hash_wf[WF_TCP_OUT] = hash_jen(optarg, strlen(optarg));
|
||||
if (!wf_make_pf(optarg, "tcp", "SrcPort", params.wf_pf_tcp_src_out, WINDIVERT_PORTFILTER_MAX) ||
|
||||
!wf_make_pf(optarg, "tcp", "DstPort", params.wf_pf_tcp_dst_out, WINDIVERT_PORTFILTER_MAX))
|
||||
{
|
||||
@@ -2433,7 +2661,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case IDX_WF_UDP_IN:
|
||||
hash_wf_udp_in = hash_jen(optarg, strlen(optarg));
|
||||
hash_wf[WF_UDP_IN] = hash_jen(optarg, strlen(optarg));
|
||||
if (!wf_make_pf(optarg, "udp", "SrcPort", params.wf_pf_udp_src_in, WINDIVERT_PORTFILTER_MAX) ||
|
||||
!wf_make_pf(optarg, "udp", "DstPort", params.wf_pf_udp_dst_in, WINDIVERT_PORTFILTER_MAX))
|
||||
{
|
||||
@@ -2442,7 +2670,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case IDX_WF_UDP_OUT:
|
||||
hash_wf_udp_out = hash_jen(optarg, strlen(optarg));
|
||||
hash_wf[WF_UDP_OUT] = hash_jen(optarg, strlen(optarg));
|
||||
if (!wf_make_pf(optarg, "udp", "SrcPort", params.wf_pf_udp_src_out, WINDIVERT_PORTFILTER_MAX) ||
|
||||
!wf_make_pf(optarg, "udp", "DstPort", params.wf_pf_udp_dst_out, WINDIVERT_PORTFILTER_MAX))
|
||||
{
|
||||
@@ -2450,8 +2678,40 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_WF_ICMP_IN:
|
||||
hash_wf[WF_ICMP_IN] = hash_jen(optarg, strlen(optarg));
|
||||
if (!wf_make_icf(optarg, params.wf_icf_in, WINDIVERT_PORTFILTER_MAX))
|
||||
{
|
||||
DLOG_ERR("bad value for --wf-icmp-in\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_WF_ICMP_OUT:
|
||||
hash_wf[WF_ICMP_OUT] = hash_jen(optarg, strlen(optarg));
|
||||
if (!wf_make_icf(optarg, params.wf_icf_out, WINDIVERT_PORTFILTER_MAX))
|
||||
{
|
||||
DLOG_ERR("bad value for --wf-icmp-out\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_WF_IPP_IN:
|
||||
hash_wf[WF_IPP_IN] = hash_jen(optarg, strlen(optarg));
|
||||
if (!wf_make_ipf(optarg, params.wf_ipf_in, WINDIVERT_PORTFILTER_MAX))
|
||||
{
|
||||
DLOG_ERR("bad value for --wf-ipp-in\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_WF_IPP_OUT:
|
||||
hash_wf[WF_IPP_OUT] = hash_jen(optarg, strlen(optarg));
|
||||
if (!wf_make_ipf(optarg, params.wf_ipf_out, WINDIVERT_PORTFILTER_MAX))
|
||||
{
|
||||
DLOG_ERR("bad value for --wf-ipp-out\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case IDX_WF_RAW:
|
||||
hash_wf_raw = hash_jen(optarg, strlen(optarg));
|
||||
hash_wf[WF_RAWF] = hash_jen(optarg, strlen(optarg));
|
||||
if (optarg[0] == '@')
|
||||
{
|
||||
size_t sz = WINDIVERT_MAX-1;
|
||||
@@ -2460,7 +2720,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(params.windivert_filter, optarg, WINDIVERT_MAX);
|
||||
snprintf(params.windivert_filter, WINDIVERT_MAX, "%s", optarg);
|
||||
params.windivert_filter[WINDIVERT_MAX - 1] = '\0';
|
||||
}
|
||||
break;
|
||||
@@ -2468,7 +2728,7 @@ int main(int argc, char **argv)
|
||||
wf_tcp_empty = !optarg || atoi(optarg);
|
||||
break;
|
||||
case IDX_WF_RAW_PART:
|
||||
hash_wf_raw_part ^= hash_jen(optarg, strlen(optarg));
|
||||
hash_wf[WF_RAWF_PART] ^= hash_jen(optarg, strlen(optarg));
|
||||
{
|
||||
char *wfpart = malloc(WINDIVERT_MAX);
|
||||
if (!wfpart)
|
||||
@@ -2484,7 +2744,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(wfpart, optarg, WINDIVERT_MAX);
|
||||
snprintf(wfpart, WINDIVERT_MAX, "%s", optarg);
|
||||
wfpart[WINDIVERT_MAX - 1] = '\0';
|
||||
}
|
||||
if (!strlist_add(¶ms.wf_raw_part, wfpart))
|
||||
@@ -2510,7 +2770,7 @@ int main(int argc, char **argv)
|
||||
bDupCheck = !optarg || !!atoi(optarg);
|
||||
break;
|
||||
case IDX_SSID_FILTER:
|
||||
hash_ssid_filter = hash_jen(optarg, strlen(optarg));
|
||||
hash_wf[GLOBAL_SSID_FILTER] = hash_jen(optarg, strlen(optarg));
|
||||
if (!parse_strlist(optarg, ¶ms.ssid_filter))
|
||||
{
|
||||
DLOG_ERR("strlist_add failed\n");
|
||||
@@ -2518,7 +2778,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case IDX_NLM_FILTER:
|
||||
hash_nlm_filter = hash_jen(optarg, strlen(optarg));
|
||||
hash_wf[GLOBAL_NLM_FILTER] = hash_jen(optarg, strlen(optarg));
|
||||
if (!parse_strlist(optarg, ¶ms.nlm_filter))
|
||||
{
|
||||
DLOG_ERR("strlist_add failed\n");
|
||||
@@ -2563,6 +2823,8 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
argv = NULL; argc = 0;
|
||||
|
||||
if (params.intercept)
|
||||
{
|
||||
#ifdef __linux__
|
||||
if (params.qnum < 0)
|
||||
{
|
||||
@@ -2576,6 +2838,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
DLOG("adding low-priority default empty desync profile\n");
|
||||
// add default empty profile
|
||||
@@ -2659,9 +2922,11 @@ int main(int argc, char **argv)
|
||||
dp_list_destroy(¶ms.desync_templates);
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
if (params.intercept)
|
||||
{
|
||||
if (!*params.windivert_filter)
|
||||
{
|
||||
if (!*params.wf_pf_tcp_src_in && !*params.wf_pf_udp_src_in && !*params.wf_pf_tcp_src_out && !*params.wf_pf_udp_src_out && LIST_EMPTY(¶ms.wf_raw_part))
|
||||
if (!*params.wf_pf_tcp_src_in && !*params.wf_pf_udp_src_in && !*params.wf_pf_tcp_src_out && !*params.wf_pf_udp_src_out && !*params.wf_icf_in && !*params.wf_icf_out && !*params.wf_ipf_in && !*params.wf_ipf_out && LIST_EMPTY(¶ms.wf_raw_part))
|
||||
{
|
||||
DLOG_ERR("windivert filter : must specify port or/and partial raw filter\n");
|
||||
exit_clean(1);
|
||||
@@ -2673,12 +2938,16 @@ int main(int argc, char **argv)
|
||||
params.wf_pf_tcp_dst_out, params.wf_pf_tcp_src_out,
|
||||
params.wf_pf_tcp_dst_in, params.wf_pf_tcp_src_in,
|
||||
params.wf_pf_udp_dst_in, params.wf_pf_udp_src_out,
|
||||
params.wf_icf_out, params.wf_icf_in,
|
||||
params.wf_ipf_out, params.wf_ipf_in,
|
||||
¶ms.wf_raw_part, wf_filter_lan, wf_filter_loopback) :
|
||||
wf_make_filter(params.windivert_filter, WINDIVERT_MAX, IfIdx, SubIfIdx, wf_ipv4, wf_ipv6,
|
||||
wf_tcp_empty,
|
||||
params.wf_pf_tcp_src_out, params.wf_pf_tcp_dst_out,
|
||||
params.wf_pf_tcp_src_in, params.wf_pf_tcp_dst_in,
|
||||
params.wf_pf_udp_src_in, params.wf_pf_udp_dst_out,
|
||||
params.wf_icf_out, params.wf_icf_in,
|
||||
params.wf_ipf_out, params.wf_ipf_in,
|
||||
¶ms.wf_raw_part, wf_filter_lan, wf_filter_loopback);
|
||||
cleanup_windivert_portfilters(¶ms);
|
||||
if (!b)
|
||||
@@ -2690,6 +2959,13 @@ int main(int argc, char **argv)
|
||||
char *p = realloc(params.windivert_filter, strlen(params.windivert_filter)+1);
|
||||
if (p) params.windivert_filter=p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// do not intercept anything. only required for rawsend
|
||||
snprintf(params.windivert_filter,WINDIVERT_MAX,"false");
|
||||
}
|
||||
|
||||
DLOG("windivert filter size: %zu\nwindivert filter:\n%s\n", strlen(params.windivert_filter), params.windivert_filter);
|
||||
if (*wf_save_file)
|
||||
{
|
||||
@@ -2705,11 +2981,10 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
HANDLE hMutexArg = NULL;
|
||||
if (bDupCheck)
|
||||
if (bDupCheck && params.intercept)
|
||||
{
|
||||
char mutex_name[128];
|
||||
snprintf(mutex_name, sizeof(mutex_name), "Global\\winws2_arg_%u_%u_%u_%u_%u_%u_%u_%u_%u_%u_%u_%u",
|
||||
hash_wf_tcp_in, hash_wf_udp_in, hash_wf_tcp_out, hash_wf_udp_out, hash_wf_raw, hash_wf_raw_part, hash_ssid_filter, hash_nlm_filter, IfIdx, SubIfIdx, wf_ipv4, wf_ipv6);
|
||||
char mutex_name[32];
|
||||
snprintf(mutex_name, sizeof(mutex_name), "Global\\winws2_arg_%u", hash_jen(hash_wf, sizeof(hash_wf)));
|
||||
|
||||
hMutexArg = CreateMutexA(NULL, TRUE, mutex_name);
|
||||
if (hMutexArg && GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
@@ -2768,6 +3043,7 @@ ex:
|
||||
CloseHandle(hMutexArg);
|
||||
}
|
||||
#endif
|
||||
close_std();
|
||||
return result;
|
||||
exiterr:
|
||||
result = 1;
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#define HAS_FILTER_SSID 1
|
||||
#endif
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
extern bool bQuit;
|
||||
extern volatile sig_atomic_t bQuit;
|
||||
#endif
|
||||
int main(int argc, char *argv[]);
|
||||
|
||||
// when something changes that can break LUA compatibility this version should be increased
|
||||
#define LUA_COMPAT_VER 4
|
||||
#define LUA_COMPAT_VER 5
|
||||
|
||||
@@ -337,6 +337,8 @@ void dp_init_dynamic(struct desync_profile *dp)
|
||||
LIST_INIT(&dp->ips_collection_exclude);
|
||||
LIST_INIT(&dp->pf_tcp);
|
||||
LIST_INIT(&dp->pf_udp);
|
||||
LIST_INIT(&dp->icf);
|
||||
LIST_INIT(&dp->ipf);
|
||||
LIST_INIT(&dp->lua_desync);
|
||||
#ifdef HAS_FILTER_SSID
|
||||
LIST_INIT(&dp->filter_ssid);
|
||||
@@ -368,6 +370,8 @@ static void dp_clear_dynamic(struct desync_profile *dp)
|
||||
ipset_collection_destroy(&dp->ips_collection_exclude);
|
||||
port_filters_destroy(&dp->pf_tcp);
|
||||
port_filters_destroy(&dp->pf_udp);
|
||||
icmp_filters_destroy(&dp->icf);
|
||||
ipp_filters_destroy(&dp->ipf);
|
||||
funclist_destroy(&dp->lua_desync);
|
||||
#ifdef HAS_FILTER_SSID
|
||||
strlist_destroy(&dp->filter_ssid);
|
||||
@@ -475,11 +479,30 @@ void cleanup_windivert_portfilters(struct params_s *params)
|
||||
{
|
||||
char **wdbufs[] =
|
||||
{¶ms->wf_pf_tcp_src_in, ¶ms->wf_pf_tcp_dst_in, ¶ms->wf_pf_udp_src_in, ¶ms->wf_pf_udp_dst_in,
|
||||
¶ms->wf_pf_tcp_src_out, ¶ms->wf_pf_tcp_dst_out, ¶ms->wf_pf_udp_src_out, ¶ms->wf_pf_udp_dst_out};
|
||||
¶ms->wf_pf_tcp_src_out, ¶ms->wf_pf_tcp_dst_out, ¶ms->wf_pf_udp_src_out, ¶ms->wf_pf_udp_dst_out,
|
||||
¶ms->wf_icf_in, ¶ms->wf_icf_out,
|
||||
¶ms->wf_ipf_in, ¶ms->wf_ipf_out};
|
||||
for (int i=0 ; i<(sizeof(wdbufs)/sizeof(*wdbufs)) ; i++)
|
||||
{
|
||||
free(*wdbufs[i]); *wdbufs[i] = NULL;
|
||||
free(*wdbufs[i]);
|
||||
*wdbufs[i] = NULL;
|
||||
}
|
||||
strlist_destroy(¶ms->wf_raw_part);
|
||||
}
|
||||
bool alloc_windivert_portfilters(struct params_s *params)
|
||||
{
|
||||
char **wdbufs[] =
|
||||
{¶ms->wf_pf_tcp_src_in, ¶ms->wf_pf_tcp_dst_in, ¶ms->wf_pf_udp_src_in, ¶ms->wf_pf_udp_dst_in,
|
||||
¶ms->wf_pf_tcp_src_out, ¶ms->wf_pf_tcp_dst_out, ¶ms->wf_pf_udp_src_out, ¶ms->wf_pf_udp_dst_out,
|
||||
¶ms->wf_icf_in, ¶ms->wf_icf_out,
|
||||
¶ms->wf_ipf_in, ¶ms->wf_ipf_out};
|
||||
for (int i=0 ; i<(sizeof(wdbufs)/sizeof(*wdbufs)) ; i++)
|
||||
{
|
||||
if (!(*wdbufs[i] = malloc(WINDIVERT_PORTFILTER_MAX)))
|
||||
return false;
|
||||
**wdbufs[i] = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
void cleanup_params(struct params_s *params)
|
||||
@@ -514,6 +537,7 @@ void init_params(struct params_s *params)
|
||||
{
|
||||
memset(params, 0, sizeof(*params));
|
||||
|
||||
params->intercept = true;
|
||||
#ifdef __linux__
|
||||
params->qnum = -1;
|
||||
#elif defined(BSD)
|
||||
|
||||
@@ -63,6 +63,8 @@ struct desync_profile
|
||||
|
||||
bool filter_ipv4,filter_ipv6;
|
||||
struct port_filters_head pf_tcp,pf_udp;
|
||||
struct icmp_filters_head icf;
|
||||
struct ipp_filters_head ipf;
|
||||
uint64_t filter_l7; // L7_PROTO_* bits
|
||||
|
||||
#ifdef HAS_FILTER_SSID
|
||||
@@ -125,7 +127,7 @@ struct params_s
|
||||
char debug_logfile[PATH_MAX];
|
||||
bool debug;
|
||||
|
||||
bool daemon;
|
||||
bool daemon, intercept;
|
||||
|
||||
#ifdef __linux__
|
||||
int qnum;
|
||||
@@ -144,6 +146,7 @@ struct params_s
|
||||
char *windivert_filter;
|
||||
char *wf_pf_tcp_src_in, *wf_pf_tcp_dst_in, *wf_pf_udp_src_in, *wf_pf_udp_dst_in;
|
||||
char *wf_pf_tcp_src_out, *wf_pf_tcp_dst_out, *wf_pf_udp_src_out, *wf_pf_udp_dst_out;
|
||||
char *wf_icf_in, *wf_icf_out, *wf_ipf_in, *wf_ipf_out;
|
||||
#else
|
||||
bool droproot;
|
||||
char *user;
|
||||
@@ -194,6 +197,7 @@ void init_params(struct params_s *params);
|
||||
void cleanup_args(struct params_s *params);
|
||||
#endif
|
||||
#ifdef __CYGWIN__
|
||||
bool alloc_windivert_portfilters(struct params_s *params);
|
||||
void cleanup_windivert_portfilters(struct params_s *params);
|
||||
#endif
|
||||
void cleanup_params(struct params_s *params);
|
||||
|
||||
81
nfq2/pools.c
81
nfq2/pools.c
@@ -742,14 +742,14 @@ void port_filters_destroy(struct port_filters_head *head)
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
bool port_filters_in_range(const struct port_filters_head *head, uint16_t port)
|
||||
bool port_filters_match(const struct port_filters_head *head, uint16_t port)
|
||||
{
|
||||
const struct port_filter_item *item;
|
||||
|
||||
if (LIST_EMPTY(head)) return true;
|
||||
LIST_FOREACH(item, head, next)
|
||||
{
|
||||
if (pf_in_range(port, &item->pf))
|
||||
if (pf_match(port, &item->pf))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -762,6 +762,83 @@ bool port_filters_deny_if_empty(struct port_filters_head *head)
|
||||
}
|
||||
|
||||
|
||||
bool icmp_filter_add(struct icmp_filters_head *head, const icmp_filter *icf)
|
||||
{
|
||||
struct icmp_filter_item *entry = malloc(sizeof(struct icmp_filter_item));
|
||||
if (entry)
|
||||
{
|
||||
entry->icf = *icf;
|
||||
LIST_INSERT_HEAD(head, entry, next);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
void icmp_filters_destroy(struct icmp_filters_head *head)
|
||||
{
|
||||
struct icmp_filter_item *entry;
|
||||
while ((entry = LIST_FIRST(head)))
|
||||
{
|
||||
LIST_REMOVE(entry, next);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
bool icmp_filters_match(const struct icmp_filters_head *head, uint8_t type, uint8_t code)
|
||||
{
|
||||
const struct icmp_filter_item *item;
|
||||
|
||||
if (LIST_EMPTY(head)) return true;
|
||||
LIST_FOREACH(item, head, next)
|
||||
{
|
||||
if (icf_match(type, code, &item->icf))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool icmp_filters_deny_if_empty(struct icmp_filters_head *head)
|
||||
{
|
||||
icmp_filter icf;
|
||||
if (!LIST_EMPTY(head)) return true;
|
||||
return icf_parse("-",&icf) && icmp_filter_add(head,&icf);
|
||||
}
|
||||
|
||||
|
||||
bool ipp_filter_add(struct ipp_filters_head *head, const ipp_filter *ipp)
|
||||
{
|
||||
struct ipp_filter_item *entry = malloc(sizeof(struct ipp_filter_item));
|
||||
if (entry)
|
||||
{
|
||||
entry->ipp = *ipp;
|
||||
LIST_INSERT_HEAD(head, entry, next);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
void ipp_filters_destroy(struct ipp_filters_head *head)
|
||||
{
|
||||
struct ipp_filter_item *entry;
|
||||
while ((entry = LIST_FIRST(head)))
|
||||
{
|
||||
LIST_REMOVE(entry, next);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
bool ipp_filters_match(const struct ipp_filters_head *head, uint8_t proto)
|
||||
{
|
||||
const struct ipp_filter_item *item;
|
||||
|
||||
if (LIST_EMPTY(head)) return true;
|
||||
LIST_FOREACH(item, head, next)
|
||||
{
|
||||
if (ipp_match(proto, &item->ipp))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool ipp_filters_deny_if_empty(struct ipp_filters_head *head)
|
||||
{
|
||||
ipp_filter ipp;
|
||||
if (!LIST_EMPTY(head)) return true;
|
||||
return ipp_parse("-",&ipp) && ipp_filter_add(head,&ipp);
|
||||
}
|
||||
|
||||
|
||||
struct blob_item *blob_collection_add(struct blob_collection_head *head)
|
||||
{
|
||||
|
||||
22
nfq2/pools.h
22
nfq2/pools.h
@@ -7,6 +7,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "helpers.h"
|
||||
#include "filter.h"
|
||||
|
||||
//#define HASH_BLOOM 20
|
||||
#define HASH_NONFATAL_OOM 1
|
||||
@@ -186,9 +187,28 @@ struct port_filter_item {
|
||||
LIST_HEAD(port_filters_head, port_filter_item);
|
||||
bool port_filter_add(struct port_filters_head *head, const port_filter *pf);
|
||||
void port_filters_destroy(struct port_filters_head *head);
|
||||
bool port_filters_in_range(const struct port_filters_head *head, uint16_t port);
|
||||
bool port_filters_match(const struct port_filters_head *head, uint16_t port);
|
||||
bool port_filters_deny_if_empty(struct port_filters_head *head);
|
||||
|
||||
struct icmp_filter_item {
|
||||
icmp_filter icf;
|
||||
LIST_ENTRY(icmp_filter_item) next;
|
||||
};
|
||||
LIST_HEAD(icmp_filters_head, icmp_filter_item);
|
||||
bool icmp_filter_add(struct icmp_filters_head *head, const icmp_filter *icf);
|
||||
void icmp_filters_destroy(struct icmp_filters_head *head);
|
||||
bool icmp_filters_match(const struct icmp_filters_head *head, uint8_t type, uint8_t code);
|
||||
bool icmp_filters_deny_if_empty(struct icmp_filters_head *head);
|
||||
|
||||
struct ipp_filter_item {
|
||||
ipp_filter ipp;
|
||||
LIST_ENTRY(ipp_filter_item) next;
|
||||
};
|
||||
LIST_HEAD(ipp_filters_head, ipp_filter_item);
|
||||
bool ipp_filter_add(struct ipp_filters_head *head, const ipp_filter *ipp);
|
||||
void ipp_filters_destroy(struct ipp_filters_head *head);
|
||||
bool ipp_filters_match(const struct ipp_filters_head *head, uint8_t proto);
|
||||
bool ipp_filters_deny_if_empty(struct ipp_filters_head *head);
|
||||
|
||||
struct blob_item {
|
||||
uint8_t *data; // main data blob
|
||||
|
||||
@@ -49,6 +49,7 @@ bool l7_proto_match(t_l7proto l7proto, uint64_t filter_l7)
|
||||
|
||||
static const char *l7payload_name[] = {
|
||||
"all","unknown","empty","known",
|
||||
"ipv4","ipv6",
|
||||
"http_req","http_reply",
|
||||
"tls_client_hello","tls_server_hello",
|
||||
"dtls_client_hello","dtls_server_hello",
|
||||
|
||||
@@ -31,6 +31,8 @@ typedef enum {
|
||||
L7P_UNKNOWN,
|
||||
L7P_EMPTY,
|
||||
L7P_KNOWN,
|
||||
L7P_IPV4,
|
||||
L7P_IPV6,
|
||||
L7P_HTTP_REQ,
|
||||
L7P_HTTP_REPLY,
|
||||
L7P_TLS_CLIENT_HELLO,
|
||||
|
||||
347
nfq2/windows/netinet/icmp6.h
Normal file
347
nfq2/windows/netinet/icmp6.h
Normal file
@@ -0,0 +1,347 @@
|
||||
/* Copyright (C) 1991-2025 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _NETINET_ICMP6_H
|
||||
#define _NETINET_ICMP6_H 1
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define ICMP6_FILTER 1
|
||||
|
||||
#define ICMP6_FILTER_BLOCK 1
|
||||
#define ICMP6_FILTER_PASS 2
|
||||
#define ICMP6_FILTER_BLOCKOTHERS 3
|
||||
#define ICMP6_FILTER_PASSONLY 4
|
||||
|
||||
struct icmp6_filter
|
||||
{
|
||||
uint32_t icmp6_filt[8];
|
||||
};
|
||||
|
||||
struct icmp6_hdr
|
||||
{
|
||||
uint8_t icmp6_type; /* type field */
|
||||
uint8_t icmp6_code; /* code field */
|
||||
uint16_t icmp6_cksum; /* checksum field */
|
||||
union
|
||||
{
|
||||
uint32_t icmp6_un_data32[1]; /* type-specific field */
|
||||
uint16_t icmp6_un_data16[2]; /* type-specific field */
|
||||
uint8_t icmp6_un_data8[4]; /* type-specific field */
|
||||
} icmp6_dataun;
|
||||
};
|
||||
|
||||
#define icmp6_data32 icmp6_dataun.icmp6_un_data32
|
||||
#define icmp6_data16 icmp6_dataun.icmp6_un_data16
|
||||
#define icmp6_data8 icmp6_dataun.icmp6_un_data8
|
||||
#define icmp6_pptr icmp6_data32[0] /* parameter prob */
|
||||
#define icmp6_mtu icmp6_data32[0] /* packet too big */
|
||||
#define icmp6_id icmp6_data16[0] /* echo request/reply */
|
||||
#define icmp6_seq icmp6_data16[1] /* echo request/reply */
|
||||
#define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */
|
||||
|
||||
#define ICMP6_DST_UNREACH 1
|
||||
#define ICMP6_PACKET_TOO_BIG 2
|
||||
#define ICMP6_TIME_EXCEEDED 3
|
||||
#define ICMP6_PARAM_PROB 4
|
||||
|
||||
#define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */
|
||||
|
||||
#define ICMP6_ECHO_REQUEST 128
|
||||
#define ICMP6_ECHO_REPLY 129
|
||||
#define MLD_LISTENER_QUERY 130
|
||||
#define MLD_LISTENER_REPORT 131
|
||||
#define MLD_LISTENER_REDUCTION 132
|
||||
#define ICMPV6_EXT_ECHO_REQUEST 160
|
||||
#define ICMPV6_EXT_ECHO_REPLY 161
|
||||
|
||||
#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
|
||||
#define ICMP6_DST_UNREACH_ADMIN 1 /* communication with destination */
|
||||
/* administratively prohibited */
|
||||
#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */
|
||||
#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */
|
||||
#define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */
|
||||
|
||||
#define ICMP6_TIME_EXCEED_TRANSIT 0 /* Hop Limit == 0 in transit */
|
||||
#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* Reassembly time out */
|
||||
|
||||
#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */
|
||||
#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized Next Header */
|
||||
#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */
|
||||
|
||||
#define ICMP6_FILTER_WILLPASS(type, filterp) \
|
||||
((((filterp)->icmp6_filt[(type) >> 5]) & (1U << ((type) & 31))) == 0)
|
||||
|
||||
#define ICMP6_FILTER_WILLBLOCK(type, filterp) \
|
||||
((((filterp)->icmp6_filt[(type) >> 5]) & (1U << ((type) & 31))) != 0)
|
||||
|
||||
#define ICMP6_FILTER_SETPASS(type, filterp) \
|
||||
((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1U << ((type) & 31))))
|
||||
|
||||
#define ICMP6_FILTER_SETBLOCK(type, filterp) \
|
||||
((((filterp)->icmp6_filt[(type) >> 5]) |= (1U << ((type) & 31))))
|
||||
|
||||
#define ICMP6_FILTER_SETPASSALL(filterp) \
|
||||
memset (filterp, 0, sizeof (struct icmp6_filter));
|
||||
|
||||
#define ICMP6_FILTER_SETBLOCKALL(filterp) \
|
||||
memset (filterp, 0xFF, sizeof (struct icmp6_filter));
|
||||
|
||||
#define ND_ROUTER_SOLICIT 133
|
||||
#define ND_ROUTER_ADVERT 134
|
||||
#define ND_NEIGHBOR_SOLICIT 135
|
||||
#define ND_NEIGHBOR_ADVERT 136
|
||||
#define ND_REDIRECT 137
|
||||
|
||||
struct nd_router_solicit /* router solicitation */
|
||||
{
|
||||
struct icmp6_hdr nd_rs_hdr;
|
||||
/* could be followed by options */
|
||||
};
|
||||
|
||||
#define nd_rs_type nd_rs_hdr.icmp6_type
|
||||
#define nd_rs_code nd_rs_hdr.icmp6_code
|
||||
#define nd_rs_cksum nd_rs_hdr.icmp6_cksum
|
||||
#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]
|
||||
|
||||
struct nd_router_advert /* router advertisement */
|
||||
{
|
||||
struct icmp6_hdr nd_ra_hdr;
|
||||
uint32_t nd_ra_reachable; /* reachable time */
|
||||
uint32_t nd_ra_retransmit; /* retransmit timer */
|
||||
/* could be followed by options */
|
||||
};
|
||||
|
||||
#define nd_ra_type nd_ra_hdr.icmp6_type
|
||||
#define nd_ra_code nd_ra_hdr.icmp6_code
|
||||
#define nd_ra_cksum nd_ra_hdr.icmp6_cksum
|
||||
#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
|
||||
#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
|
||||
#define ND_RA_FLAG_MANAGED 0x80
|
||||
#define ND_RA_FLAG_OTHER 0x40
|
||||
#define ND_RA_FLAG_HOME_AGENT 0x20
|
||||
#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
|
||||
|
||||
struct nd_neighbor_solicit /* neighbor solicitation */
|
||||
{
|
||||
struct icmp6_hdr nd_ns_hdr;
|
||||
struct in6_addr nd_ns_target; /* target address */
|
||||
/* could be followed by options */
|
||||
};
|
||||
|
||||
#define nd_ns_type nd_ns_hdr.icmp6_type
|
||||
#define nd_ns_code nd_ns_hdr.icmp6_code
|
||||
#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
|
||||
#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
|
||||
|
||||
struct nd_neighbor_advert /* neighbor advertisement */
|
||||
{
|
||||
struct icmp6_hdr nd_na_hdr;
|
||||
struct in6_addr nd_na_target; /* target address */
|
||||
/* could be followed by options */
|
||||
};
|
||||
|
||||
#define nd_na_type nd_na_hdr.icmp6_type
|
||||
#define nd_na_code nd_na_hdr.icmp6_code
|
||||
#define nd_na_cksum nd_na_hdr.icmp6_cksum
|
||||
#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0]
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define ND_NA_FLAG_ROUTER 0x80000000
|
||||
#define ND_NA_FLAG_SOLICITED 0x40000000
|
||||
#define ND_NA_FLAG_OVERRIDE 0x20000000
|
||||
#else /* __BYTE_ORDER == __LITTLE_ENDIAN */
|
||||
#define ND_NA_FLAG_ROUTER 0x00000080
|
||||
#define ND_NA_FLAG_SOLICITED 0x00000040
|
||||
#define ND_NA_FLAG_OVERRIDE 0x00000020
|
||||
#endif
|
||||
|
||||
struct nd_redirect /* redirect */
|
||||
{
|
||||
struct icmp6_hdr nd_rd_hdr;
|
||||
struct in6_addr nd_rd_target; /* target address */
|
||||
struct in6_addr nd_rd_dst; /* destination address */
|
||||
/* could be followed by options */
|
||||
};
|
||||
|
||||
#define nd_rd_type nd_rd_hdr.icmp6_type
|
||||
#define nd_rd_code nd_rd_hdr.icmp6_code
|
||||
#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
|
||||
#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
|
||||
|
||||
struct nd_opt_hdr /* Neighbor discovery option header */
|
||||
{
|
||||
uint8_t nd_opt_type;
|
||||
uint8_t nd_opt_len; /* in units of 8 octets */
|
||||
/* followed by option specific data */
|
||||
};
|
||||
|
||||
#define ND_OPT_SOURCE_LINKADDR 1
|
||||
#define ND_OPT_TARGET_LINKADDR 2
|
||||
#define ND_OPT_PREFIX_INFORMATION 3
|
||||
#define ND_OPT_REDIRECTED_HEADER 4
|
||||
#define ND_OPT_MTU 5
|
||||
#define ND_OPT_RTR_ADV_INTERVAL 7
|
||||
#define ND_OPT_HOME_AGENT_INFO 8
|
||||
|
||||
struct nd_opt_prefix_info /* prefix information */
|
||||
{
|
||||
uint8_t nd_opt_pi_type;
|
||||
uint8_t nd_opt_pi_len;
|
||||
uint8_t nd_opt_pi_prefix_len;
|
||||
uint8_t nd_opt_pi_flags_reserved;
|
||||
uint32_t nd_opt_pi_valid_time;
|
||||
uint32_t nd_opt_pi_preferred_time;
|
||||
uint32_t nd_opt_pi_reserved2;
|
||||
struct in6_addr nd_opt_pi_prefix;
|
||||
};
|
||||
|
||||
#define ND_OPT_PI_FLAG_ONLINK 0x80
|
||||
#define ND_OPT_PI_FLAG_AUTO 0x40
|
||||
#define ND_OPT_PI_FLAG_RADDR 0x20
|
||||
|
||||
struct nd_opt_rd_hdr /* redirected header */
|
||||
{
|
||||
uint8_t nd_opt_rh_type;
|
||||
uint8_t nd_opt_rh_len;
|
||||
uint16_t nd_opt_rh_reserved1;
|
||||
uint32_t nd_opt_rh_reserved2;
|
||||
/* followed by IP header and data */
|
||||
};
|
||||
|
||||
struct nd_opt_mtu /* MTU option */
|
||||
{
|
||||
uint8_t nd_opt_mtu_type;
|
||||
uint8_t nd_opt_mtu_len;
|
||||
uint16_t nd_opt_mtu_reserved;
|
||||
uint32_t nd_opt_mtu_mtu;
|
||||
};
|
||||
|
||||
struct mld_hdr
|
||||
{
|
||||
struct icmp6_hdr mld_icmp6_hdr;
|
||||
struct in6_addr mld_addr; /* multicast address */
|
||||
};
|
||||
|
||||
#define mld_type mld_icmp6_hdr.icmp6_type
|
||||
#define mld_code mld_icmp6_hdr.icmp6_code
|
||||
#define mld_cksum mld_icmp6_hdr.icmp6_cksum
|
||||
#define mld_maxdelay mld_icmp6_hdr.icmp6_data16[0]
|
||||
#define mld_reserved mld_icmp6_hdr.icmp6_data16[1]
|
||||
|
||||
#define ICMP6_ROUTER_RENUMBERING 138
|
||||
|
||||
struct icmp6_router_renum /* router renumbering header */
|
||||
{
|
||||
struct icmp6_hdr rr_hdr;
|
||||
uint8_t rr_segnum;
|
||||
uint8_t rr_flags;
|
||||
uint16_t rr_maxdelay;
|
||||
uint32_t rr_reserved;
|
||||
};
|
||||
|
||||
#define rr_type rr_hdr.icmp6_type
|
||||
#define rr_code rr_hdr.icmp6_code
|
||||
#define rr_cksum rr_hdr.icmp6_cksum
|
||||
#define rr_seqnum rr_hdr.icmp6_data32[0]
|
||||
|
||||
/* Router renumbering flags */
|
||||
#define ICMP6_RR_FLAGS_TEST 0x80
|
||||
#define ICMP6_RR_FLAGS_REQRESULT 0x40
|
||||
#define ICMP6_RR_FLAGS_FORCEAPPLY 0x20
|
||||
#define ICMP6_RR_FLAGS_SPECSITE 0x10
|
||||
#define ICMP6_RR_FLAGS_PREVDONE 0x08
|
||||
|
||||
struct rr_pco_match /* match prefix part */
|
||||
{
|
||||
uint8_t rpm_code;
|
||||
uint8_t rpm_len;
|
||||
uint8_t rpm_ordinal;
|
||||
uint8_t rpm_matchlen;
|
||||
uint8_t rpm_minlen;
|
||||
uint8_t rpm_maxlen;
|
||||
uint16_t rpm_reserved;
|
||||
struct in6_addr rpm_prefix;
|
||||
};
|
||||
|
||||
/* PCO code values */
|
||||
#define RPM_PCO_ADD 1
|
||||
#define RPM_PCO_CHANGE 2
|
||||
#define RPM_PCO_SETGLOBAL 3
|
||||
|
||||
struct rr_pco_use /* use prefix part */
|
||||
{
|
||||
uint8_t rpu_uselen;
|
||||
uint8_t rpu_keeplen;
|
||||
uint8_t rpu_ramask;
|
||||
uint8_t rpu_raflags;
|
||||
uint32_t rpu_vltime;
|
||||
uint32_t rpu_pltime;
|
||||
uint32_t rpu_flags;
|
||||
struct in6_addr rpu_prefix;
|
||||
};
|
||||
|
||||
#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20
|
||||
#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
|
||||
# define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
|
||||
# define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
|
||||
#endif
|
||||
|
||||
struct rr_result /* router renumbering result message */
|
||||
{
|
||||
uint16_t rrr_flags;
|
||||
uint8_t rrr_ordinal;
|
||||
uint8_t rrr_matchedlen;
|
||||
uint32_t rrr_ifid;
|
||||
struct in6_addr rrr_prefix;
|
||||
};
|
||||
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define ICMP6_RR_RESULT_FLAGS_OOB 0x0002
|
||||
# define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001
|
||||
#elif __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define ICMP6_RR_RESULT_FLAGS_OOB 0x0200
|
||||
# define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100
|
||||
#endif
|
||||
|
||||
/* Mobile IPv6 extension: Advertisement Interval. */
|
||||
struct nd_opt_adv_interval
|
||||
{
|
||||
uint8_t nd_opt_adv_interval_type;
|
||||
uint8_t nd_opt_adv_interval_len;
|
||||
uint16_t nd_opt_adv_interval_reserved;
|
||||
uint32_t nd_opt_adv_interval_ival;
|
||||
};
|
||||
|
||||
/* Mobile IPv6 extension: Home Agent Info. */
|
||||
struct nd_opt_home_agent_info
|
||||
{
|
||||
uint8_t nd_opt_home_agent_info_type;
|
||||
uint8_t nd_opt_home_agent_info_len;
|
||||
uint16_t nd_opt_home_agent_info_reserved;
|
||||
uint16_t nd_opt_home_agent_info_preference;
|
||||
uint16_t nd_opt_home_agent_info_lifetime;
|
||||
};
|
||||
|
||||
#endif /* netinet/icmpv6.h */
|
||||
298
nfq2/windows/netinet/ip_icmp.h
Normal file
298
nfq2/windows/netinet/ip_icmp.h
Normal file
@@ -0,0 +1,298 @@
|
||||
/* Copyright (C) 1991-2025 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef __NETINET_IP_ICMP_H
|
||||
#define __NETINET_IP_ICMP_H 1
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct icmphdr
|
||||
{
|
||||
uint8_t type; /* message type */
|
||||
uint8_t code; /* type sub-code */
|
||||
uint16_t checksum;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t sequence;
|
||||
} echo; /* echo datagram */
|
||||
uint32_t gateway; /* gateway address */
|
||||
struct
|
||||
{
|
||||
uint16_t __glibc_reserved;
|
||||
uint16_t mtu;
|
||||
} frag; /* path mtu discovery */
|
||||
} un;
|
||||
};
|
||||
|
||||
#define ICMP_ECHOREPLY 0 /* Echo Reply */
|
||||
#define ICMP_DEST_UNREACH 3 /* Destination Unreachable */
|
||||
#define ICMP_SOURCE_QUENCH 4 /* Source Quench */
|
||||
#define ICMP_REDIRECT 5 /* Redirect (change route) */
|
||||
#define ICMP_ECHO 8 /* Echo Request */
|
||||
#define ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
|
||||
#define ICMP_PARAMETERPROB 12 /* Parameter Problem */
|
||||
#define ICMP_TIMESTAMP 13 /* Timestamp Request */
|
||||
#define ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
|
||||
#define ICMP_INFO_REQUEST 15 /* Information Request */
|
||||
#define ICMP_INFO_REPLY 16 /* Information Reply */
|
||||
#define ICMP_ADDRESS 17 /* Address Mask Request */
|
||||
#define ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
|
||||
#define NR_ICMP_TYPES 18
|
||||
|
||||
|
||||
/* Codes for UNREACH. */
|
||||
#define ICMP_NET_UNREACH 0 /* Network Unreachable */
|
||||
#define ICMP_HOST_UNREACH 1 /* Host Unreachable */
|
||||
#define ICMP_PROT_UNREACH 2 /* Protocol Unreachable */
|
||||
#define ICMP_PORT_UNREACH 3 /* Port Unreachable */
|
||||
#define ICMP_FRAG_NEEDED 4 /* Fragmentation Needed/DF set */
|
||||
#define ICMP_SR_FAILED 5 /* Source Route failed */
|
||||
#define ICMP_NET_UNKNOWN 6
|
||||
#define ICMP_HOST_UNKNOWN 7
|
||||
#define ICMP_HOST_ISOLATED 8
|
||||
#define ICMP_NET_ANO 9
|
||||
#define ICMP_HOST_ANO 10
|
||||
#define ICMP_NET_UNR_TOS 11
|
||||
#define ICMP_HOST_UNR_TOS 12
|
||||
#define ICMP_PKT_FILTERED 13 /* Packet filtered */
|
||||
#define ICMP_PREC_VIOLATION 14 /* Precedence violation */
|
||||
#define ICMP_PREC_CUTOFF 15 /* Precedence cut off */
|
||||
#define NR_ICMP_UNREACH 15 /* instead of hardcoding immediate value */
|
||||
|
||||
/* Codes for REDIRECT. */
|
||||
#define ICMP_REDIR_NET 0 /* Redirect Net */
|
||||
#define ICMP_REDIR_HOST 1 /* Redirect Host */
|
||||
#define ICMP_REDIR_NETTOS 2 /* Redirect Net for TOS */
|
||||
#define ICMP_REDIR_HOSTTOS 3 /* Redirect Host for TOS */
|
||||
|
||||
/* Codes for TIME_EXCEEDED. */
|
||||
#define ICMP_EXC_TTL 0 /* TTL count exceeded */
|
||||
#define ICMP_EXC_FRAGTIME 1 /* Fragment Reass time exceeded */
|
||||
|
||||
/* Codes for ICMP_EXT_ECHO (PROBE) */
|
||||
#define ICMP_EXT_ECHO 42
|
||||
#define ICMP_EXT_ECHOREPLY 43
|
||||
#define ICMP_EXT_CODE_MAL_QUERY 1 /* Malformed Query */
|
||||
#define ICMP_EXT_CODE_NO_IF 2 /* No such Interface */
|
||||
#define ICMP_EXT_CODE_NO_TABLE_ENT 3 /* No table entry */
|
||||
#define ICMP_EXT_CODE_MULT_IFS 4 /* Multiple Interfaces Satisfy Query */
|
||||
|
||||
/* Constants for EXT_ECHO (PROBE) */
|
||||
#define ICMP_EXT_ECHOREPLY_ACTIVE (1 << 2)/* active bit in reply */
|
||||
#define ICMP_EXT_ECHOREPLY_IPV4 (1 << 1)/* ipv4 bit in reply */
|
||||
#define ICMP_EXT_ECHOREPLY_IPV6 1 /* ipv6 bit in reply */
|
||||
#define ICMP_EXT_ECHO_CTYPE_NAME 1
|
||||
#define ICMP_EXT_ECHO_CTYPE_INDEX 2
|
||||
#define ICMP_EXT_ECHO_CTYPE_ADDR 3
|
||||
#define ICMP_AFI_IP 1 /* Address Family Identifier for IPV4 */
|
||||
#define ICMP_AFI_IP6 2 /* Address Family Identifier for IPV6 */
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
/*
|
||||
* Internal of an ICMP Router Advertisement
|
||||
*/
|
||||
struct icmp_ra_addr
|
||||
{
|
||||
uint32_t ira_addr;
|
||||
uint32_t ira_preference;
|
||||
};
|
||||
|
||||
struct icmp
|
||||
{
|
||||
uint8_t icmp_type; /* type of message, see below */
|
||||
uint8_t icmp_code; /* type sub code */
|
||||
uint16_t icmp_cksum; /* ones complement checksum of struct */
|
||||
union
|
||||
{
|
||||
unsigned char ih_pptr; /* ICMP_PARAMPROB */
|
||||
struct in_addr ih_gwaddr; /* gateway address */
|
||||
struct ih_idseq /* echo datagram */
|
||||
{
|
||||
uint16_t icd_id;
|
||||
uint16_t icd_seq;
|
||||
} ih_idseq;
|
||||
uint32_t ih_void;
|
||||
|
||||
/* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */
|
||||
struct ih_pmtu
|
||||
{
|
||||
uint16_t ipm_void;
|
||||
uint16_t ipm_nextmtu;
|
||||
} ih_pmtu;
|
||||
|
||||
struct ih_rtradv
|
||||
{
|
||||
uint8_t irt_num_addrs;
|
||||
uint8_t irt_wpa;
|
||||
uint16_t irt_lifetime;
|
||||
} ih_rtradv;
|
||||
} icmp_hun;
|
||||
#define icmp_pptr icmp_hun.ih_pptr
|
||||
#define icmp_gwaddr icmp_hun.ih_gwaddr
|
||||
#define icmp_id icmp_hun.ih_idseq.icd_id
|
||||
#define icmp_seq icmp_hun.ih_idseq.icd_seq
|
||||
#define icmp_void icmp_hun.ih_void
|
||||
#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void
|
||||
#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu
|
||||
#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs
|
||||
#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa
|
||||
#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetime
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t its_otime;
|
||||
uint32_t its_rtime;
|
||||
uint32_t its_ttime;
|
||||
} id_ts;
|
||||
struct
|
||||
{
|
||||
struct ip idi_ip;
|
||||
/* options and then 64 bits of data */
|
||||
} id_ip;
|
||||
struct icmp_ra_addr id_radv;
|
||||
uint32_t id_mask;
|
||||
uint8_t id_data[1];
|
||||
} icmp_dun;
|
||||
#define icmp_otime icmp_dun.id_ts.its_otime
|
||||
#define icmp_rtime icmp_dun.id_ts.its_rtime
|
||||
#define icmp_ttime icmp_dun.id_ts.its_ttime
|
||||
#define icmp_ip icmp_dun.id_ip.idi_ip
|
||||
#define icmp_radv icmp_dun.id_radv
|
||||
#define icmp_mask icmp_dun.id_mask
|
||||
#define icmp_data icmp_dun.id_data
|
||||
};
|
||||
|
||||
/*
|
||||
* Lower bounds on packet lengths for various types.
|
||||
* For the error advice packets must first insure that the
|
||||
* packet is large enough to contain the returned ip header.
|
||||
* Only then can we do the check to see if 64 bits of packet
|
||||
* data have been returned, since we need to check the returned
|
||||
* ip header length.
|
||||
*/
|
||||
#define ICMP_MINLEN 8 /* abs minimum */
|
||||
#define ICMP_TSLEN (8 + 3 * sizeof (n_time)) /* timestamp */
|
||||
#define ICMP_MASKLEN 12 /* address mask */
|
||||
#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
|
||||
#ifndef _IP_VHL
|
||||
#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
|
||||
/* N.B.: must separately check that ip_hl >= 5 */
|
||||
#else
|
||||
#define ICMP_ADVLEN(p) (8 + (IP_VHL_HL((p)->icmp_ip.ip_vhl) << 2) + 8)
|
||||
/* N.B.: must separately check that header length >= 5 */
|
||||
#endif
|
||||
|
||||
/* Definition of type and code fields. */
|
||||
/* defined above: ICMP_ECHOREPLY, ICMP_REDIRECT, ICMP_ECHO */
|
||||
#define ICMP_UNREACH 3 /* dest unreachable, codes: */
|
||||
#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
|
||||
#define ICMP_ROUTERADVERT 9 /* router advertisement */
|
||||
#define ICMP_ROUTERSOLICIT 10 /* router solicitation */
|
||||
#define ICMP_TIMXCEED 11 /* time exceeded, code: */
|
||||
#define ICMP_PARAMPROB 12 /* ip header bad */
|
||||
#define ICMP_TSTAMP 13 /* timestamp request */
|
||||
#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
|
||||
#define ICMP_IREQ 15 /* information request */
|
||||
#define ICMP_IREQREPLY 16 /* information reply */
|
||||
#define ICMP_MASKREQ 17 /* address mask request */
|
||||
#define ICMP_MASKREPLY 18 /* address mask reply */
|
||||
|
||||
#define ICMP_MAXTYPE 18
|
||||
|
||||
/* UNREACH codes */
|
||||
#define ICMP_UNREACH_NET 0 /* bad net */
|
||||
#define ICMP_UNREACH_HOST 1 /* bad host */
|
||||
#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
|
||||
#define ICMP_UNREACH_PORT 3 /* bad port */
|
||||
#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
|
||||
#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
|
||||
#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
|
||||
#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
|
||||
#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
|
||||
#define ICMP_UNREACH_NET_PROHIB 9 /* net denied */
|
||||
#define ICMP_UNREACH_HOST_PROHIB 10 /* host denied */
|
||||
#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
|
||||
#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
|
||||
#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohib */
|
||||
#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host prec vio. */
|
||||
#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* prec cutoff */
|
||||
|
||||
/* REDIRECT codes */
|
||||
#define ICMP_REDIRECT_NET 0 /* for network */
|
||||
#define ICMP_REDIRECT_HOST 1 /* for host */
|
||||
#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
|
||||
#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
|
||||
|
||||
/* TIMEXCEED codes */
|
||||
#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
|
||||
#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
|
||||
|
||||
/* PARAMPROB code */
|
||||
#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */
|
||||
|
||||
#define ICMP_INFOTYPE(type) \
|
||||
((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO \
|
||||
|| (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT \
|
||||
|| (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY \
|
||||
|| (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY \
|
||||
|| (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
|
||||
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* netinet/ip_icmp.h */
|
||||
40
nfq2/windows/nthacks.h
Normal file
40
nfq2/windows/nthacks.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <winternl.h>
|
||||
|
||||
#define DIRECTORY_QUERY (0x0001)
|
||||
#define DIRECTORY_TRAVERSE (0x0002)
|
||||
#define DIRECTORY_CREATE_OBJECT (0x0004)
|
||||
#define DIRECTORY_CREATE_SUBDIRECTORY (0x0008)
|
||||
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
|
||||
|
||||
typedef struct _PROCESS_SESSION_INFORMATION {
|
||||
ULONG SessionId;
|
||||
} PROCESS_SESSION_INFORMATION, *PPROCESS_SESSION_INFORMATION;
|
||||
|
||||
typedef struct _OBJECT_DIRECTORY_INFORMATION {
|
||||
UNICODE_STRING Name;
|
||||
UNICODE_STRING TypeName;
|
||||
} OBJECT_DIRECTORY_INFORMATION, *POBJECT_DIRECTORY_INFORMATION;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
NTSTATUS NTAPI NtOpenDirectoryObject(
|
||||
_Out_ PHANDLE DirectoryHandle,
|
||||
_In_ ACCESS_MASK DesiredAccess,
|
||||
_In_ POBJECT_ATTRIBUTES ObjectAttributes
|
||||
);
|
||||
NTSTATUS NTAPI NtQueryDirectoryObject(
|
||||
_In_ HANDLE DirectoryHandle,
|
||||
_Out_opt_ PVOID Buffer,
|
||||
_In_ ULONG Length,
|
||||
_In_ BOOLEAN ReturnSingleEntry,
|
||||
_In_ BOOLEAN RestartScan,
|
||||
_Inout_ PULONG Context,
|
||||
_Out_opt_ PULONG ReturnLength
|
||||
);
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
4
nfq2/windows/res/howto.txt
Normal file
4
nfq2/windows/res/howto.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
# in 64 bit cygwin
|
||||
windres winws.rc -O coff -o winws_res64.o
|
||||
# in 32 bit cygwin
|
||||
windres winws.rc -O coff -o winws_res32.o
|
||||
BIN
nfq2/windows/res/winws.ico
Normal file
BIN
nfq2/windows/res/winws.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
24
nfq2/windows/res/winws.manifest
Normal file
24
nfq2/windows/res/winws.manifest
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="requireAdministrator"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!--The ID below indicates application support for Windows Vista -->
|
||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
|
||||
<!--The ID below indicates application support for Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
|
||||
<!--The ID below indicates application support for Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
|
||||
<!--The ID below indicates application support for Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
|
||||
<!--The ID below indicates application support for Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
||||
</application>
|
||||
</compatibility>
|
||||
</assembly>
|
||||
3
nfq2/windows/res/winws.rc
Normal file
3
nfq2/windows/res/winws.rc
Normal file
@@ -0,0 +1,3 @@
|
||||
LANGUAGE 0,0
|
||||
1 ICON "winws.ico"
|
||||
1 24 "winws.manifest"
|
||||
BIN
nfq2/windows/res/winws_res32.o
Normal file
BIN
nfq2/windows/res/winws_res32.o
Normal file
Binary file not shown.
BIN
nfq2/windows/res/winws_res64.o
Normal file
BIN
nfq2/windows/res/winws_res64.o
Normal file
Binary file not shown.
Reference in New Issue
Block a user