mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
nfqws: wssize
This commit is contained in:
@@ -648,3 +648,42 @@ bool tcp_synack_segment(const struct tcphdr *tcphdr)
|
||||
/* check for set bits in TCP hdr */
|
||||
return ((tcphdr->th_flags & (TH_URG|TH_ACK|TH_PUSH|TH_RST|TH_SYN|TH_FIN)) == (TH_ACK|TH_SYN));
|
||||
}
|
||||
bool tcp_syn_segment(const struct tcphdr *tcphdr)
|
||||
{
|
||||
/* check for set bits in TCP hdr */
|
||||
return ((tcphdr->th_flags & (TH_URG|TH_ACK|TH_PUSH|TH_RST|TH_SYN|TH_FIN)) == TH_SYN);
|
||||
}
|
||||
bool tcp_ack_segment(const struct tcphdr *tcphdr)
|
||||
{
|
||||
/* check for set bits in TCP hdr */
|
||||
return ((tcphdr->th_flags & (TH_URG|TH_ACK|TH_PUSH|TH_RST|TH_SYN|TH_FIN)) == TH_ACK);
|
||||
}
|
||||
|
||||
void tcp_rewrite_wscale(struct tcphdr *tcp, uint8_t scale_factor)
|
||||
{
|
||||
uint8_t *scale,scale_factor_old;
|
||||
|
||||
if (scale_factor!=(uint8_t)-1)
|
||||
{
|
||||
scale = tcp_find_option(tcp,3); // tcp option 3 - scale factor
|
||||
if (scale && scale[1]==3) // length should be 3
|
||||
{
|
||||
scale_factor_old=scale[2];
|
||||
scale[2]=scale_factor;
|
||||
if (scale_factor_old!=scale_factor)
|
||||
DLOG("Scale factor change %u => %u\n", scale_factor_old, scale_factor)
|
||||
}
|
||||
}
|
||||
}
|
||||
// scale_factor=-1 - do not change
|
||||
void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize, uint8_t scale_factor)
|
||||
{
|
||||
uint16_t winsize_old;
|
||||
uint8_t *scale,scale_factor_old;
|
||||
|
||||
winsize_old = htons(tcp->th_win); // << scale_factor;
|
||||
tcp->th_win = htons(winsize);
|
||||
DLOG("Window size change %u => %u\n", winsize_old, winsize)
|
||||
|
||||
tcp_rewrite_wscale(tcp, scale_factor);
|
||||
}
|
||||
|
@@ -73,4 +73,10 @@ bool proto_check_tcp(uint8_t *data, size_t len);
|
||||
void proto_skip_tcp(uint8_t **data, size_t *len);
|
||||
bool proto_check_ipv6(uint8_t *data, size_t len);
|
||||
void proto_skip_ipv6(uint8_t **data, size_t *len, uint8_t *proto_type);
|
||||
|
||||
bool tcp_synack_segment(const struct tcphdr *tcphdr);
|
||||
bool tcp_syn_segment(const struct tcphdr *tcphdr);
|
||||
bool tcp_ack_segment(const struct tcphdr *tcphdr);
|
||||
// scale_factor=-1 - do not change
|
||||
void tcp_rewrite_wscale(struct tcphdr *tcp, uint8_t scale_factor);
|
||||
void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize, uint8_t scale_factor);
|
||||
|
12
nfq/desync.c
12
nfq/desync.c
@@ -105,6 +105,18 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
packet_process_result res=pass;
|
||||
|
||||
if (!!ip == !!ip6hdr) return res; // one and only one must be present
|
||||
|
||||
if (params.wsize && tcp_synack_segment(tcphdr))
|
||||
{
|
||||
tcp_rewrite_winsize(tcphdr, params.wsize, params.wscale);
|
||||
res=modify;
|
||||
}
|
||||
if (params.wssize && !tcp_synack_segment(tcphdr))
|
||||
{
|
||||
tcp_rewrite_winsize(tcphdr, params.wssize, params.wsscale);
|
||||
res=modify;
|
||||
}
|
||||
|
||||
if (params.desync_mode==DESYNC_NONE && !params.hostcase && !params.hostnospace && !params.domcase) return res; // nothing to do. do not waste cpu
|
||||
|
||||
if (!(tcphdr->th_flags & TH_SYN) && len_payload)
|
||||
|
141
nfq/nfqws.c
141
nfq/nfqws.c
@@ -66,28 +66,6 @@ static void dohup()
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize)
|
||||
{
|
||||
uint16_t winsize_old;
|
||||
winsize_old = htons(tcp->th_win); // << scale_factor;
|
||||
tcp->th_win = htons(winsize);
|
||||
DLOG("Window size change %u => %u\n", winsize_old, winsize)
|
||||
}
|
||||
|
||||
// data/len points to data payload
|
||||
static bool modify_tcp_packet(uint8_t *data, size_t len, struct tcphdr *tcphdr)
|
||||
{
|
||||
if (tcp_synack_segment(tcphdr) && params.wsize)
|
||||
{
|
||||
tcp_rewrite_winsize(tcphdr, (uint16_t)params.wsize);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
static packet_process_result processPacketData(uint8_t *data_pkt, size_t len_pkt, uint32_t *mark)
|
||||
#else
|
||||
@@ -99,7 +77,7 @@ static packet_process_result processPacketData(uint8_t *data_pkt, size_t len_pkt
|
||||
struct tcphdr *tcphdr = NULL;
|
||||
size_t len = len_pkt, len_tcp;
|
||||
uint8_t *data = data_pkt;
|
||||
packet_process_result res = pass, res2;
|
||||
packet_process_result res = pass;
|
||||
uint8_t proto;
|
||||
|
||||
#ifdef __linux__
|
||||
@@ -152,11 +130,7 @@ static packet_process_result processPacketData(uint8_t *data_pkt, size_t len_pkt
|
||||
|
||||
if (len) { DLOG("TCP: ") hexdump_limited_dlog(data, len, 32); DLOG("\n") }
|
||||
|
||||
if (modify_tcp_packet(data, len, tcphdr))
|
||||
res = modify;
|
||||
|
||||
res2 = dpi_desync_packet(data_pkt, len_pkt, ip, ip6hdr, tcphdr, len_tcp, data, len);
|
||||
res = (res2==pass && res==modify) ? modify : res2;
|
||||
res = dpi_desync_packet(data_pkt, len_pkt, ip, ip6hdr, tcphdr, len_tcp, data, len);
|
||||
// in my FreeBSD divert tests only ipv4 packets were reinjected with correct checksum
|
||||
// ipv6 packets were with incorrect checksum
|
||||
#ifdef __FreeBSD__
|
||||
@@ -444,6 +418,33 @@ exiterr:
|
||||
|
||||
|
||||
|
||||
static bool parse_scale_factor(char *s, uint16_t *wsize, uint8_t *wscale)
|
||||
{
|
||||
int v;
|
||||
char *p;
|
||||
|
||||
if ((p = strchr(s,':'))) *p++=0;
|
||||
v = atoi(s);
|
||||
if (v < 0 || v>65535)
|
||||
{
|
||||
fprintf(stderr, "bad wsize\n");
|
||||
return false;
|
||||
}
|
||||
*wsize=(uint16_t)v;
|
||||
if (p && *p)
|
||||
{
|
||||
v = atoi(p);
|
||||
if (v < 0 || v>255)
|
||||
{
|
||||
fprintf(stderr, "bad wscale\n");
|
||||
return false;
|
||||
}
|
||||
*wscale = (uint8_t)v;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void exithelp()
|
||||
{
|
||||
printf(
|
||||
@@ -457,7 +458,8 @@ static void exithelp()
|
||||
" --pidfile=<filename>\t\t\t; write pid to file\n"
|
||||
" --user=<username>\t\t\t; drop root privs\n"
|
||||
" --uid=uid[:gid]\t\t\t; drop root privs\n"
|
||||
" --wsize=<window_size>\t\t\t; set window size. 0 = do not modify. OBSOLETE !\n"
|
||||
" --wsize=<window_size>[:<scale_factor>]\t; set window size. 0 = do not modify. OBSOLETE !\n"
|
||||
" --wssize=<window_size>[:<scale_factor>]; set window size for server. 0 = do not modify.\n"
|
||||
" --hostcase\t\t\t\t; change Host: => host:\n"
|
||||
" --hostspell\t\t\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n"
|
||||
" --hostnospace\t\t\t\t; remove space after Host: and add it to User-Agent: to preserve packet size\n"
|
||||
@@ -528,6 +530,8 @@ int main(int argc, char **argv)
|
||||
memcpy(params.fake_tls,fake_tls_clienthello_default,params.fake_tls_size);
|
||||
params.fake_http_size = strlen(fake_http_request_default);
|
||||
memcpy(params.fake_http,fake_http_request_default,params.fake_http_size);
|
||||
params.wscale=-1; // default - dont change scale factor (client)
|
||||
|
||||
if (can_drop_root()) // are we root ?
|
||||
{
|
||||
params.uid = params.gid = 0x7FFFFFFF; // default uid:gid
|
||||
@@ -548,28 +552,29 @@ int main(int argc, char **argv)
|
||||
{"user",required_argument,0,0 }, // optidx=4
|
||||
{"uid",required_argument,0,0 }, // optidx=5
|
||||
{"wsize",required_argument,0,0}, // optidx=6
|
||||
{"hostcase",no_argument,0,0}, // optidx=7
|
||||
{"hostspell",required_argument,0,0}, // optidx=8
|
||||
{"hostnospace",no_argument,0,0}, // optidx=9
|
||||
{"domcase",no_argument,0,0 }, // optidx=10
|
||||
{"dpi-desync",required_argument,0,0}, // optidx=11
|
||||
{"wssize",required_argument,0,0}, // optidx=7
|
||||
{"hostcase",no_argument,0,0}, // optidx=8
|
||||
{"hostspell",required_argument,0,0}, // optidx=9
|
||||
{"hostnospace",no_argument,0,0}, // optidx=10
|
||||
{"domcase",no_argument,0,0 }, // optidx=11
|
||||
{"dpi-desync",required_argument,0,0}, // optidx=12
|
||||
#ifdef __linux__
|
||||
{"dpi-desync-fwmark",required_argument,0,0}, // optidx=12
|
||||
{"dpi-desync-fwmark",required_argument,0,0}, // optidx=13
|
||||
#elif defined(SO_USER_COOKIE)
|
||||
{"dpi-desync-sockarg",required_argument,0,0}, // optidx=12
|
||||
{"dpi-desync-sockarg",required_argument,0,0}, // optidx=13
|
||||
#else
|
||||
{"disabled_argument_2",no_argument,0,0}, // optidx=12
|
||||
{"disabled_argument_2",no_argument,0,0}, // optidx=13
|
||||
#endif
|
||||
{"dpi-desync-ttl",required_argument,0,0}, // optidx=13
|
||||
{"dpi-desync-fooling",required_argument,0,0}, // optidx=14
|
||||
{"dpi-desync-retrans",optional_argument,0,0}, // optidx=15
|
||||
{"dpi-desync-repeats",required_argument,0,0}, // optidx=16
|
||||
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=17
|
||||
{"dpi-desync-split-pos",required_argument,0,0},// optidx=18
|
||||
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=19
|
||||
{"dpi-desync-fake-http",required_argument,0,0},// optidx=20
|
||||
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=21
|
||||
{"hostlist",required_argument,0,0}, // optidx=22
|
||||
{"dpi-desync-ttl",required_argument,0,0}, // optidx=14
|
||||
{"dpi-desync-fooling",required_argument,0,0}, // optidx=15
|
||||
{"dpi-desync-retrans",optional_argument,0,0}, // optidx=16
|
||||
{"dpi-desync-repeats",required_argument,0,0}, // optidx=17
|
||||
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=18
|
||||
{"dpi-desync-split-pos",required_argument,0,0},// optidx=19
|
||||
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=20
|
||||
{"dpi-desync-fake-http",required_argument,0,0},// optidx=21
|
||||
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=22
|
||||
{"hostlist",required_argument,0,0}, // optidx=23
|
||||
{NULL,0,NULL,0}
|
||||
};
|
||||
if (argc < 2) exithelp();
|
||||
@@ -631,17 +636,17 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
case 6: /* wsize */
|
||||
params.wsize = atoi(optarg);
|
||||
if (params.wsize < 0 || params.wsize>65535)
|
||||
{
|
||||
fprintf(stderr, "bad wsize\n");
|
||||
if (!parse_scale_factor(optarg,¶ms.wsize,¶ms.wscale))
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 7: /* hostcase */
|
||||
case 7: /* wssize */
|
||||
if (!parse_scale_factor(optarg,¶ms.wssize,¶ms.wsscale))
|
||||
exit_clean(1);
|
||||
break;
|
||||
case 8: /* hostcase */
|
||||
params.hostcase = true;
|
||||
break;
|
||||
case 8: /* hostspell */
|
||||
case 9: /* hostspell */
|
||||
if (strlen(optarg) != 4)
|
||||
{
|
||||
fprintf(stderr, "hostspell must be exactly 4 chars long\n");
|
||||
@@ -650,13 +655,13 @@ int main(int argc, char **argv)
|
||||
params.hostcase = true;
|
||||
memcpy(params.hostspell, optarg, 4);
|
||||
break;
|
||||
case 9: /* hostnospace */
|
||||
case 10: /* hostnospace */
|
||||
params.hostnospace = true;
|
||||
break;
|
||||
case 10: /* domcase */
|
||||
case 11: /* domcase */
|
||||
params.domcase = true;
|
||||
break;
|
||||
case 11: /* dpi-desync */
|
||||
case 12: /* dpi-desync */
|
||||
{
|
||||
char *mode2;
|
||||
mode2 = optarg ? strchr(optarg,',') : NULL;
|
||||
@@ -676,7 +681,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 12: /* dpi-desync-fwmark/dpi-desync-sockarg */
|
||||
case 13: /* dpi-desync-fwmark/dpi-desync-sockarg */
|
||||
#if defined(__linux__) || defined(SO_USER_COOKIE)
|
||||
params.desync_fwmark = 0;
|
||||
if (!sscanf(optarg, "0x%X", ¶ms.desync_fwmark)) sscanf(optarg, "%u", ¶ms.desync_fwmark);
|
||||
@@ -690,10 +695,10 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
#endif
|
||||
break;
|
||||
case 13: /* dpi-desync-ttl */
|
||||
case 14: /* dpi-desync-ttl */
|
||||
params.desync_ttl = (uint8_t)atoi(optarg);
|
||||
break;
|
||||
case 14: /* dpi-desync-fooling */
|
||||
case 15: /* dpi-desync-fooling */
|
||||
{
|
||||
char *e,*p = optarg;
|
||||
while (p)
|
||||
@@ -722,7 +727,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 15: /* dpi-desync-retrans */
|
||||
case 16: /* dpi-desync-retrans */
|
||||
#ifdef __linux__
|
||||
params.desync_retrans = !optarg || atoi(optarg);
|
||||
#else
|
||||
@@ -730,7 +735,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
#endif
|
||||
break;
|
||||
case 16: /* dpi-desync-repeats */
|
||||
case 17: /* dpi-desync-repeats */
|
||||
params.desync_repeats = atoi(optarg);
|
||||
if (params.desync_repeats<=0 || params.desync_repeats>20)
|
||||
{
|
||||
@@ -738,10 +743,10 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 17: /* dpi-desync-skip-nosni */
|
||||
case 18: /* dpi-desync-skip-nosni */
|
||||
params.desync_skip_nosni = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 18: /* dpi-desync-split-pos */
|
||||
case 19: /* dpi-desync-split-pos */
|
||||
params.desync_split_pos = atoi(optarg);
|
||||
if (params.desync_split_pos<1 || params.desync_split_pos>DPI_DESYNC_MAX_FAKE_LEN)
|
||||
{
|
||||
@@ -749,10 +754,10 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 19: /* dpi-desync-any-protocol */
|
||||
case 20: /* dpi-desync-any-protocol */
|
||||
params.desync_any_proto = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 20: /* dpi-desync-fake-http */
|
||||
case 21: /* dpi-desync-fake-http */
|
||||
params.fake_http_size = sizeof(params.fake_http);
|
||||
if (!load_file_nonempty(optarg,params.fake_http,¶ms.fake_http_size))
|
||||
{
|
||||
@@ -760,7 +765,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 21: /* dpi-desync-fake-tls */
|
||||
case 22: /* dpi-desync-fake-tls */
|
||||
params.fake_tls_size = sizeof(params.fake_tls);
|
||||
if (!load_file_nonempty(optarg,params.fake_tls,¶ms.fake_tls_size))
|
||||
{
|
||||
@@ -768,7 +773,7 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 22: /* hostlist */
|
||||
case 23: /* hostlist */
|
||||
if (!LoadHostList(¶ms.hostlist, optarg))
|
||||
exit_clean(1);
|
||||
strncpy(params.hostfile,optarg,sizeof(params.hostfile));
|
||||
|
@@ -26,7 +26,8 @@
|
||||
struct params_s
|
||||
{
|
||||
bool debug;
|
||||
int wsize;
|
||||
uint16_t wsize,wssize;
|
||||
uint8_t wscale,wsscale;
|
||||
#ifdef __linux__
|
||||
int qnum;
|
||||
#elif defined(BSD)
|
||||
|
Reference in New Issue
Block a user