diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index 286c656..eeeed60 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/arm/nfqws b/binaries/arm/nfqws index 19b57c1..b437cec 100755 Binary files a/binaries/arm/nfqws and b/binaries/arm/nfqws differ diff --git a/binaries/mips32r1-lsb/nfqws b/binaries/mips32r1-lsb/nfqws index bdd16af..c8047e1 100755 Binary files a/binaries/mips32r1-lsb/nfqws and b/binaries/mips32r1-lsb/nfqws differ diff --git a/binaries/mips32r1-msb/nfqws b/binaries/mips32r1-msb/nfqws index b0318a2..353f02f 100755 Binary files a/binaries/mips32r1-msb/nfqws and b/binaries/mips32r1-msb/nfqws differ diff --git a/binaries/mips64r2-msb/nfqws b/binaries/mips64r2-msb/nfqws index 6194b85..2fb2b75 100755 Binary files a/binaries/mips64r2-msb/nfqws and b/binaries/mips64r2-msb/nfqws differ diff --git a/binaries/ppc/nfqws b/binaries/ppc/nfqws index 31f3b00..4355b1c 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index 53958b1..6b65c3b 100755 Binary files a/binaries/x86/nfqws and b/binaries/x86/nfqws differ diff --git a/binaries/x86_64/nfqws b/binaries/x86_64/nfqws index 1a4f607..3ff23de 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/docs/readme.eng.txt b/docs/readme.eng.txt index f47fbca..712a611 100644 --- a/docs/readme.eng.txt +++ b/docs/readme.eng.txt @@ -90,10 +90,10 @@ iptables -t mangle -I POSTROUTING -o -p tcp --dport 80 -m s Some DPIs catch only the first http request, ignoring subsequent requests in a keep-alive session. Then we can reduce CPU load, refusing to process unnecessary packets. -iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 80 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4 -m mark ! --mark 0x40000000/0x40000000 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass +iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 80 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4 -m mark ! --mark 0x40000000/0x40000000 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass Mark filter does not allow nfqws-generated packets to enter the queue again. -Its necessary to use this filter when also using "connbytes 2:4". Without it packet ordering can be changed breaking the whole idea. +Its necessary to use this filter when also using "connbytes 1:4". Without it packet ordering can be changed breaking the whole idea. ip6tables @@ -134,6 +134,8 @@ nfqws takes the following parameters: --debug=0|1 ; 1=print debug info --qnum= --wsize= ; set window size. 0 = do not modify (obsolete !) + --wsize=[:] ; change window size in SYN,ACK packets. default is not to change scale factor (OBSOLETE !) + --wssize=[:] ; change window size in all packets except SYN,ACK. default scale factor is 0. --hostcase ; change Host: => host: --hostspell=HoSt ; exact spelling of the "Host" header. must be 4 chars. default is "host" --hostnospace ; remove space after Host: and add it to User-Agent: to preserve packet size @@ -228,12 +230,12 @@ Subdomains are applied automatically. gzip lists are supported. iptables for performing the attack on the first packet : -iptables -t mangle -I POSTROUTING -o -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass +iptables -t mangle -I POSTROUTING -o -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass This is good if DPI does not track all requests in http keep-alive session. If it does, then pass all outgoing packets for http and only first data packet for https : -iptables -t mangle -I POSTROUTING -o -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass +iptables -t mangle -I POSTROUTING -o -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass iptables -t mangle -I POSTROUTING -o -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass mark is needed to keep away generated packets from NFQUEUE. nfqws sets fwmark when it sends generated packets. diff --git a/docs/readme.txt b/docs/readme.txt index 487fb5c..9811e8d 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -110,10 +110,10 @@ iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp DPI может ловить только первый http запрос, игнорируя последующие запросы в keep-alive сессии. Тогда можем уменьшить нагрузку на проц, отказавшись от процессинга ненужных пакетов. -iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 80 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4 -m mark ! --mark 0x40000000/0x40000000 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass +iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 80 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4 -m mark ! --mark 0x40000000/0x40000000 -m set --match-set zapret dst -j NFQUEUE --queue-num 200 --queue-bypass Фильтр по mark нужен для отсечения от очереди пакетов, сгенерированных внутри nfqws. -Если применяется фильтр по connbytes 2:4, то обязательно добавлять в iptables и фильтр по mark. Иначе возможно +Если применяется фильтр по connbytes 1:4, то обязательно добавлять в iptables и фильтр по mark. Иначе возможно перепутывания порядка следования пакетов, что приведет к неработоспособности метода. @@ -177,8 +177,9 @@ nfqws --pidfile= ; сохранить PID в файл --user= ; менять uid процесса --uid=uid[:gid] ; менять uid процесса - --qnum=200 ; номер очереди - --wsize=4 ; менять tcp window size на указанный размер (устарело !) + --qnum=N ; номер очереди N + --wsize=[:] ; менять tcp window size на указанный размер в SYN,ACK. если не задан scale_factor, то он не меняется (устарело !) + --wssize=[:] ; менять tcp window size на указанный размер во всех пакетах, кроме SYN,ACK. scale_factor по умолчанию 0. --hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:". --hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета --hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase @@ -274,12 +275,12 @@ DPI может отстать от потока, если ClientHello его у iptables для задействования атаки на первый пакет данных : -iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass +iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp -m multiport --dports 80,443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass Этот вариант применяем, когда DPI не следит за всеми запросами http внутри keep-alive сессии. Если следит, направляем только первый пакет от https и все пакеты от http : -iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass +iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 443 -m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass iptables -t mangle -I POSTROUTING -o <внешний_интерфейс> -p tcp --dport 80 -m mark ! --mark 0x40000000/0x40000000 -j NFQUEUE --queue-num 200 --queue-bypass mark нужен, чтобы сгенерированный поддельный пакет не попал опять к нам на обработку. nfqws выставляет fwmark при его отсылке. @@ -290,7 +291,11 @@ mark нужен, чтобы сгенерированный поддельный При отсутствии ограничения на connbytes, атака будет работать и без фильтра по mark. Но лучше его все же оставить для увеличения скорости. -Почему --connbytes 2:4 : 2 - иногда данные идут в 3-м пакете 3-way handshake. 3 - стандартная ситуация. 4 - для надежности. на случай, если выполнялась одна ретрансмиссия +Почему --connbytes 1:4 : +1 - для работы параметра wssize. scaling factor обычно устанавливается инициатором соединения в SYN пакете +2 - иногда данные идут в 3-м пакете 3-way handshake +3 - стандартная ситуация +4 - для надежности. на случай, если выполнялась одна ретрансмиссия КОМБИНИРОВАНИЕ МЕТОДОВ ДЕСИНХРОНИЗАЦИИ В параметре dpi-desync можно указать 2 режима через запятую. diff --git a/init.d/openwrt/custom-2nfqws b/init.d/openwrt/custom-2nfqws index b875c7b..f184ae3 100644 --- a/init.d/openwrt/custom-2nfqws +++ b/init.d/openwrt/custom-2nfqws @@ -24,7 +24,7 @@ zapret_custom_daemons() zapret_custom_firewall() { local f4 f6 - local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4" + local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" [ "$MODE_HTTP" = "1" ] && { diff --git a/init.d/openwrt/custom-tpws4http-nfqws4https b/init.d/openwrt/custom-tpws4http-nfqws4https index 8526840..3c043e8 100644 --- a/init.d/openwrt/custom-tpws4http-nfqws4https +++ b/init.d/openwrt/custom-tpws4http-nfqws4https @@ -20,7 +20,7 @@ zapret_custom_daemons() zapret_custom_firewall() { local f4 f6 - local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4" + local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" [ "$MODE_HTTP" = "1" ] && { diff --git a/init.d/openwrt/functions b/init.d/openwrt/functions index f2d4397..6449644 100644 --- a/init.d/openwrt/functions +++ b/init.d/openwrt/functions @@ -371,7 +371,7 @@ flow_offloading_exempt() zapret_apply_firewall() { - local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4" + local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" local f4 f6 diff --git a/init.d/sysv/custom-2nfqws b/init.d/sysv/custom-2nfqws index 2f942a4..c7fd0b8 100644 --- a/init.d/sysv/custom-2nfqws +++ b/init.d/sysv/custom-2nfqws @@ -24,7 +24,7 @@ zapret_custom_daemons() zapret_custom_firewall() { local f4 f6 - local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4" + local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" [ "$MODE_HTTP" = "1" ] && { diff --git a/init.d/sysv/custom-tpws4http-nfqws4https b/init.d/sysv/custom-tpws4http-nfqws4https index 411b8fe..1667b33 100644 --- a/init.d/sysv/custom-tpws4http-nfqws4https +++ b/init.d/sysv/custom-tpws4http-nfqws4https @@ -20,7 +20,7 @@ zapret_custom_daemons() zapret_custom_firewall() { local f4 f6 - local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4" + local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" [ "$MODE_HTTP" = "1" ] && { diff --git a/init.d/sysv/functions b/init.d/sysv/functions index ac63f92..5722398 100644 --- a/init.d/sysv/functions +++ b/init.d/sysv/functions @@ -455,7 +455,7 @@ zapret_do_firewall() { # $1 - 1 - add, 0 - del - local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 2:4" + local first_packet_only="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes 1:4" local desync="-m mark ! --mark $DESYNC_MARK/$DESYNC_MARK" local f4 f6 diff --git a/nfq/darkmagic.c b/nfq/darkmagic.c index 2a1170f..054de60 100644 --- a/nfq/darkmagic.c +++ b/nfq/darkmagic.c @@ -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); +} diff --git a/nfq/darkmagic.h b/nfq/darkmagic.h index 2a39b93..1f0338e 100644 --- a/nfq/darkmagic.h +++ b/nfq/darkmagic.h @@ -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); diff --git a/nfq/desync.c b/nfq/desync.c index d6c6f59..315abb2 100644 --- a/nfq/desync.c +++ b/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) diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 3648800..9efbc37 100644 --- a/nfq/nfqws.c +++ b/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=\t\t\t; write pid to file\n" " --user=\t\t\t; drop root privs\n" " --uid=uid[:gid]\t\t\t; drop root privs\n" - " --wsize=\t\t\t; set window size. 0 = do not modify. OBSOLETE !\n" + " --wsize=[:]\t; set window size. 0 = do not modify. OBSOLETE !\n" + " --wssize=[:]; 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)); diff --git a/nfq/params.h b/nfq/params.h index 688c5ac..97cfd8d 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -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)