mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-22 01:05:48 +00:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
927cca3d44 | ||
|
|
162e8906a6 | ||
|
|
3f7180379b | ||
|
|
5d0af6b058 | ||
|
|
392e1cc1ef | ||
|
|
8a5643851d | ||
|
|
6299a46ab7 | ||
|
|
c5ecc0493d | ||
|
|
7bb8b1d7b3 | ||
|
|
401bd83f82 | ||
|
|
c117c30849 | ||
|
|
6828e7352c | ||
|
|
943e548f93 | ||
|
|
539c329da3 | ||
|
|
4c6902c17c | ||
|
|
9121d949f6 | ||
|
|
64c1f96f80 | ||
|
|
3334786fe3 | ||
|
|
20a0fa671d | ||
|
|
747de07c85 | ||
|
|
6384af6607 | ||
|
|
3046dd8013 | ||
|
|
c80ae95a09 | ||
|
|
d7e5fc1a7c | ||
|
|
97a6b9dd5b | ||
|
|
cfd2df41c4 | ||
|
|
f47f4a0cae | ||
|
|
823a2e2e5d | ||
|
|
0cdbedde74 | ||
|
|
36e243863b |
2
.github/ISSUE_TEMPLATE/issue-warning.md
vendored
2
.github/ISSUE_TEMPLATE/issue-warning.md
vendored
@@ -18,5 +18,7 @@ Discussions - место для обсуждения вопросов между
|
||||
Если вы игнорируете данное требование, вы не достигните своих целей , а только добавите желания удалить ваш issue или при настойчивости забанить.
|
||||
Идите в дискуссии, не захламляйте issues.
|
||||
|
||||
Так же будут немедленно удаляться любые issue, связанные с реакцией антивирусов. При агрессии или настойчивости - бан. (подсказка : вирусов нет, удаляйте если не верите)
|
||||
|
||||
Here is the place for bugs only. All questions, especially user-like questions (non-technical) go to Discussions.
|
||||
There're also no viruses here. All virus claims and everyting non-technical and non-bugs will be instantly deleted, closed or moved to Discussions.
|
||||
|
||||
@@ -5,9 +5,9 @@ pktws_oob()
|
||||
# $1 - test function
|
||||
# $2 - domain
|
||||
|
||||
local dropacks urp
|
||||
local urp
|
||||
for urp in b 0 2 midsld; do
|
||||
pktws_curl_test_update "$1" "$2" --in-range=-s1 --lua-desync=oob:urp=$urp$dropack
|
||||
pktws_curl_test_update "$1" "$2" --in-range=-s1 --lua-desync=oob:urp=$urp
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ pktws_seqovl_tests_tls()
|
||||
for split in '1 2' 'sniext sniext+1' 'sniext+3 sniext+4' 'midsld-1 midsld' '1 2,midsld'; do
|
||||
f="$(extract_arg 1 $split)"
|
||||
f2="$(extract_arg 2 $split)"
|
||||
pktws_curl_test_update $1 $2 $PAYLOAD --lua-desync=$MULTIDISORDER:pos=$f2:seqovl=$f && ok=1
|
||||
pktws_curl_test_update $1 $2 $pre $PAYLOAD --lua-desync=$MULTIDISORDER:pos=$f2:seqovl=$f && ok=1
|
||||
pktws_curl_test_update $testf $domain ${SEQOVL_PATTERN_HTTPS:+--blob=$pat:@"$SEQOVL_PATTERN_HTTPS" }$rnd_mod $pre $PAYLOAD --lua-desync=$MULTIDISORDER:pos=$f2:seqovl=$f:seqovl_pattern=$pat && ok=1
|
||||
done
|
||||
[ "$ok" = 1 ] && ok_any=1
|
||||
|
||||
@@ -11,7 +11,7 @@ pktws_check_http()
|
||||
|
||||
for split in '' multisplit $MULTIDISORDER; do
|
||||
pktws_curl_test_update "$1" "$2" --lua-desync=syndata ${split:+$PAYLOAD --lua-desync=$split}
|
||||
pktws_curl_test_update "$1" "$2" --lua-desync=syndata:blob=fake_default_http $PAYLOAD ${split:+$PAYLOAD --lua-desync=$split}
|
||||
pktws_curl_test_update "$1" "$2" --lua-desync=syndata:blob=fake_default_http ${split:+$PAYLOAD --lua-desync=$split}
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
@@ -69,11 +69,11 @@ pktws_fake_https_vary_()
|
||||
{
|
||||
local ok_any=0 testf=$1 domain="$2" fooling="$3" pre="$4" post="$5"
|
||||
shift; shift; shift
|
||||
pktws_curl_test_update $testf $domain ${FAKE_HTTPS:+--blob=$fake:@"$FAKE_HTTPS" }${FAKED_PATTERN_HTTPS:+--blob=faked_pat:@"$FAKED_PATTERN_HTTPS" }$pre $PAYLOAD --lua-desync=fake:blob=$fake:$fooling:repeats=$FAKE_REPEATS --lua-desync=$splitf:${FAKED_PATTERN_HTTPS+pattern=faked_pat:}pos=$split:$fooling $post && ok_any=1
|
||||
pktws_curl_test_update $testf $domain ${FAKED_PATTERN_HTTPS:+--blob=faked_pat:@"$FAKED_PATTERN_HTTPS" }$pre $PAYLOAD --lua-desync=fake:blob=0x00000000:$fooling:repeats=$FAKE_REPEATS --lua-desync=$splitf:${FAKED_PATTERN_HTTPS+pattern=faked_pat:}pos=$split:$fooling $post && ok_any=1
|
||||
pktws_curl_test_update $testf $domain ${FAKE_HTTPS:+--blob=$fake:@"$FAKE_HTTPS" }${FAKED_PATTERN_HTTPS:+--blob=faked_pat:@"$FAKED_PATTERN_HTTPS" }$pre $PAYLOAD --lua-desync=fake:blob=0x00000000:$fooling:repeats=$FAKE_REPEATS --lua-desync=fake:blob=$fake:$fooling:tls_mod=rnd,dupsid:repeats=$FAKE_REPEATS --lua-desync=$splitf:${FAKED_PATTERN_HTTPS+pattern=faked_pat:}pos=$split:$fooling $post && ok_any=1
|
||||
pktws_curl_test_update $testf $domain ${FAKE_HTTPS:+--blob=$fake:@"$FAKE_HTTPS" }${FAKED_PATTERN_HTTPS:+--blob=faked_pat:@"$FAKED_PATTERN_HTTPS" }$pre $PAYLOAD --lua-desync=multisplit:blob=$fake:$fooling:pos=2:nodrop:repeats=$FAKE_REPEATS --lua-desync=$splitf:${FAKED_PATTERN_HTTPS+pattern=faked_pat:}pos=$split:$fooling $post && ok_any=1
|
||||
pktws_curl_test_update $testf $domain ${FAKE_HTTPS:+--blob=$fake:@"$FAKE_HTTPS" }${FAKED_PATTERN_HTTPS:+--blob=faked_pat:@"$FAKED_PATTERN_HTTPS" }$pre $PAYLOAD --lua-desync=fake:blob=$fake:$fooling:tls_mod=rnd,dupsid,padencap:repeats=$FAKE_REPEATS --lua-desync=$splitf:${FAKED_PATTERN_HTTPS+pattern=faked_pat:}pos=$split:$fooling $post && ok_any=1
|
||||
pktws_curl_test_update $testf $domain ${FAKE_HTTPS:+--blob=$fake:@"$FAKE_HTTPS" }${FAKED_PATTERN_HTTPS:+--blob=faked_pat:@"$FAKED_PATTERN_HTTPS" }$pre $PAYLOAD --lua-desync=fake:blob=$fake:$fooling:repeats=$FAKE_REPEATS --lua-desync=$splitf:${FAKED_PATTERN_HTTPS:+pattern=faked_pat:}pos=$split:$fooling $post && ok_any=1
|
||||
pktws_curl_test_update $testf $domain ${FAKED_PATTERN_HTTPS:+--blob=faked_pat:@"$FAKED_PATTERN_HTTPS" }$pre $PAYLOAD --lua-desync=fake:blob=0x00000000:$fooling:repeats=$FAKE_REPEATS --lua-desync=$splitf:${FAKED_PATTERN_HTTPS:+pattern=faked_pat:}pos=$split:$fooling $post && ok_any=1
|
||||
pktws_curl_test_update $testf $domain ${FAKE_HTTPS:+--blob=$fake:@"$FAKE_HTTPS" }${FAKED_PATTERN_HTTPS:+--blob=faked_pat:@"$FAKED_PATTERN_HTTPS" }$pre $PAYLOAD --lua-desync=fake:blob=0x00000000:$fooling:repeats=$FAKE_REPEATS --lua-desync=fake:blob=$fake:$fooling:tls_mod=rnd,dupsid:repeats=$FAKE_REPEATS --lua-desync=$splitf:${FAKED_PATTERN_HTTPS:+pattern=faked_pat:}pos=$split:$fooling $post && ok_any=1
|
||||
pktws_curl_test_update $testf $domain ${FAKE_HTTPS:+--blob=$fake:@"$FAKE_HTTPS" }${FAKED_PATTERN_HTTPS:+--blob=faked_pat:@"$FAKED_PATTERN_HTTPS" }$pre $PAYLOAD --lua-desync=multisplit:blob=$fake:$fooling:pos=2:nodrop:repeats=$FAKE_REPEATS --lua-desync=$splitf:${FAKED_PATTERN_HTTPS:+pattern=faked_pat:}pos=$split:$fooling $post && ok_any=1
|
||||
pktws_curl_test_update $testf $domain ${FAKE_HTTPS:+--blob=$fake:@"$FAKE_HTTPS" }${FAKED_PATTERN_HTTPS:+--blob=faked_pat:@"$FAKED_PATTERN_HTTPS" }$pre $PAYLOAD --lua-desync=fake:blob=$fake:$fooling:tls_mod=rnd,dupsid,padencap:repeats=$FAKE_REPEATS --lua-desync=$splitf:${FAKED_PATTERN_HTTPS:+pattern=faked_pat:}pos=$split:$fooling $post && ok_any=1
|
||||
[ "$ok_any" = 1 ] && ok=1
|
||||
|
||||
}
|
||||
|
||||
@@ -221,3 +221,10 @@ v0.8.1
|
||||
* nfqws2: bcryptorandom normalize behavior when system entropy is low. prevent blocks
|
||||
* nfqws2: --new[=name]
|
||||
* winws2: fix not setting signal handlers
|
||||
|
||||
0.9.2
|
||||
|
||||
nfqws2: bt and utp_bt protocol detectors
|
||||
nfqws2: localtime,gmtime,timelocal,timegm luacalls
|
||||
winws2: load wlanapi.dll dynamically only if needed
|
||||
winws2: fixed lost windivert deinit on logical network disappear
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
- [clock\_gettime](#clock_gettime)
|
||||
- [getpid](#getpid)
|
||||
- [stat](#stat)
|
||||
- [time](#time)
|
||||
- [Packet handling options](#packet-handling-options)
|
||||
- [standard reconstruct](#standard-reconstruct)
|
||||
- [standard rawsend](#standard-rawsend)
|
||||
@@ -751,9 +752,11 @@ Table of recognizable payload types and flow protocols
|
||||
| tls | tcp | tls_client_hello<br>tls_server_hello |
|
||||
| xmpp | tcp | xmpp_stream<br>xmpp_starttls<br>xmpp_proceed<br>xmpp_features |
|
||||
| mtproto | tcp | mtproto_initial |
|
||||
| bt | tcp | bt_handshake |
|
||||
| quic | udp | quic_initial |
|
||||
| wireguard | udp | wireguard_initiation<br>wireguard_response<br>wireguard_cookie<br>wireguard_keepalive |
|
||||
| dht | udp | dht |
|
||||
| utp_bt | udp | utp_bt_handshake |
|
||||
| discord | udp | discord_ip_discovery |
|
||||
| stun | udp | stun |
|
||||
| dns | udp | dns_query dns_response |
|
||||
@@ -1991,6 +1994,34 @@ If successful returns the following table :
|
||||
|
||||
In case of error returns 3 values : nil, error string, error number (errno).
|
||||
|
||||
#### time
|
||||
|
||||
```
|
||||
function localtime(unixtime)
|
||||
function gmtime(unixtime)
|
||||
function timelocal(tm)
|
||||
function timegm(tm)
|
||||
```
|
||||
|
||||
localtime and gmtime return dissected unixtime similar to C "struct tm". timelocal and timegm are reverse functions.
|
||||
|
||||
| Field | Type | Description |
|
||||
| :------- | :----- | :---------- |
|
||||
| sec* | number | second |
|
||||
| min* | number | minute |
|
||||
| hour* | number | hour |
|
||||
| mon* | number | month starting from 0 |
|
||||
| mday* | number | day of month starting from 1 |
|
||||
| year* | number | full year, not from 1900 |
|
||||
| wday | number | day of week. 0 = sunday |
|
||||
| yday | number | day of year starting from 0 |
|
||||
| isdst* | number | not zero if summer time in effect |
|
||||
| zone | string | time zone |
|
||||
| str | string | formatted string: "dd.mm.yyyy hh:mi:ss" |
|
||||
|
||||
Fields marked with `*` are required for reverse translation.
|
||||
|
||||
|
||||
### Packet handling options
|
||||
|
||||
The following functions use standard sets of options: `rawsend` and `reconstruct`.
|
||||
@@ -5044,7 +5075,7 @@ filter_apply_hostlist_target()
|
||||
# $1 - name of the variable containing nfqws2 options
|
||||
```
|
||||
|
||||
Replaces the `<HOSTLIST>` and `<HOSTLIST_AUTO>` markers in $1 depending on the [MODE_FILTER](#config-file) and the presence of list files in ipset.
|
||||
Replaces the `<HOSTLIST>` and `<HOSTLIST_NOAUTO>` markers in $1 depending on the [MODE_FILTER](#config-file) and the presence of list files in ipset.
|
||||
|
||||
```
|
||||
standard_mode_daemons()
|
||||
@@ -5424,8 +5455,8 @@ There are several options :
|
||||
|
||||
## Windows Server
|
||||
|
||||
winws2 is linked against wlanapi.dll which is absent by default.
|
||||
To solve this problem run power shell as administrator and execute command `Install-WindowsFeature -Name Wireless-Networking`.
|
||||
To use `--ssid-filter` install wireless networking feature.
|
||||
Run power shell as administrator and execute command `Install-WindowsFeature -Name Wireless-Networking`.
|
||||
Then reboot the system.
|
||||
|
||||
## Windows ARM64
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
- [Структура track](#структура-track)
|
||||
- [Особенности обработки icmp](#особенности-обработки-icmp)
|
||||
- [Особенности обработки raw ip](#особенности-обработки-raw-ip)
|
||||
- [C интерфейс nfqws2](#c-интерфейс-nfqws2)
|
||||
- [С интерфейс nfqws2](#с-интерфейс-nfqws2)
|
||||
- [Базовые константы](#базовые-константы)
|
||||
- [Стандартные блобы](#стандартные-блобы)
|
||||
- [Переменные окружения](#переменные-окружения)
|
||||
@@ -73,6 +73,7 @@
|
||||
- [clock\_gettime](#clock_gettime)
|
||||
- [getpid](#getpid)
|
||||
- [stat](#stat)
|
||||
- [time](#time)
|
||||
- [Опции по работе с пакетами](#опции-по-работе-с-пакетами)
|
||||
- [standard reconstruct](#standard-reconstruct)
|
||||
- [standard rawsend](#standard-rawsend)
|
||||
@@ -150,7 +151,7 @@
|
||||
- [rawsend\_dissect\_segmented](#rawsend_dissect_segmented)
|
||||
- [rawsend\_payload\_segmented](#rawsend_payload_segmented)
|
||||
- [Стандартные фильтры direction и payload](#стандартные-фильтры-direction-и-payload)
|
||||
- [Работа с многопакетными пейлоадами](#работа-с-многопакетными-пейлоадами)
|
||||
- [Работа с многопакетными пейлоадам](#работа-с-многопакетными-пейлоадам)
|
||||
- [Оркестрация](#оркестрация)
|
||||
- [instance\_cutoff\_shim](#instance_cutoff_shim)
|
||||
- [cutoff\_shim\_check](#cutoff_shim_check)
|
||||
@@ -725,9 +726,9 @@ MULTI-STRATEGY:
|
||||
--ipset-exclude=<filename> ; фильтр профиля : исключающий список ip адресов или подсетей из файла. может быть смешанным ipv4+ipv6.
|
||||
--ipset-exclude-ip=<ip_list> ; фильтр профиля : исключающий фиксированный список ip адресов или подсетей через запятую
|
||||
--hostlist=<filename> ; фильтр профиля : включающий список доменов из файла
|
||||
--hostlist-domains=<domain_list> ; фильтр профиля : включающий фиксированный список доменов из файла
|
||||
--hostlist-domains=<domain_list> ; фильтр профиля : включающий фиксированный список доменов через запятую
|
||||
--hostlist-exclude=<filename> ; фильтр профиля : исключающий список доменов из файла
|
||||
--hostlist-exclude-domains=<domain_list> ; фильтр профиля : исключающий фиксированный список доменов из файла
|
||||
--hostlist-exclude-domains=<domain_list> ; фильтр профиля : исключающий фиксированный список доменов через запятую
|
||||
--hostlist-auto=<filename> ; фильтр профиля : автоматически пополняемый по обратной связи включающий фильтр доменов
|
||||
--hostlist-auto-fail-threshold=<int> ; параметр автолиста : количество неудач подряд для занесения в лист. по умолчанию 3
|
||||
--hostlist-auto-fail-time=<int> ; параметр автолиста : максимальное время между неудачами без сброса счетчика. по умолчанию 60 секунд
|
||||
@@ -810,9 +811,11 @@ nfqws2 сигнатурно распознает типы пейлоадов о
|
||||
| tls | tcp | tls_client_hello<br>tls_server_hello |
|
||||
| xmpp | tcp | xmpp_stream<br>xmpp_starttls<br>xmpp_proceed<br>xmpp_features |
|
||||
| mtproto | tcp | mtproto_initial |
|
||||
| bt | tcp | bt_handshake |
|
||||
| quic | udp | quic_initial |
|
||||
| wireguard | udp | wireguard_initiation<br>wireguard_response<br>wireguard_cookie<br>wireguard_keepalive |
|
||||
| dht | udp | dht |
|
||||
| utp_bt | udp | utp_bt_handshake |
|
||||
| discord | udp | discord_ip_discovery |
|
||||
| stun | udp | stun |
|
||||
| dns | udp | dns_query<br>dns_response |
|
||||
@@ -2137,6 +2140,32 @@ function stat(filename)
|
||||
|
||||
В случае неудачи возвращает 3 значения : nil, строка ошибки, код ошибки errno.
|
||||
|
||||
#### time
|
||||
|
||||
```
|
||||
function localtime(unixtime)
|
||||
function gmtime(unixtime)
|
||||
function timelocal(tm)
|
||||
function timegm(tm)
|
||||
```
|
||||
|
||||
Функции localtime и gmtime возвращают таблицу, аналогичную struct tm в C. timelocal и timegm - обратные функции.
|
||||
|
||||
| Поле | Тип | Описание |
|
||||
| :------- | :----- | :---------- |
|
||||
| sec* | number | секунды |
|
||||
| min* | number | минуты |
|
||||
| hour* | number | часы |
|
||||
| mon* | number | месяц, начиная с 0 |
|
||||
| mday* | number | день месяца |
|
||||
| year* | number | год - полный, не с 1900 года |
|
||||
| wday | number | день недели. 0 - воскресенье, 6 - суббота |
|
||||
| yday | number | номер дня в году, начиная с 0 |
|
||||
| isdst* | number | не 0, если включен переход на летнее/зимнее время |
|
||||
| zone | string | часовой пояс (timezone) |
|
||||
| str | string | отформатированная строка dd.mm.yyyy hh:mi:ss |
|
||||
|
||||
Поля, помеченные `*`, нужны для обратного перевода. Остальные не учитываются.
|
||||
|
||||
### Опции по работе с пакетами
|
||||
|
||||
@@ -4734,7 +4763,7 @@ blockcheck2 способен определить подменяется ли DN
|
||||
|
||||
Ситуация нестабильности стратегий - явление частое. Бывает у провайдера балансировка нагрузки , и разные запросы проходят через разные DPI. То работает, то не работает. Стабильность стратегий тестируется за счет множественных повторений - попыток. Количество попыток задается в диалоге или через [shell переменные](#shell-переменные).
|
||||
|
||||
[Поддерживается](#shell-переменные) параллельный режим. В нем каждая попытка выполняется в отдельном дочернем процессе, а потом собираются результаты со всех процессов. Режим включается только через (переменную PARALLEL](#shell-переменные). Может значительно ускорить тестирование, но так же может и нарваться на rate limit - ситуацию, когда сервер вас ограничивает или банит из-за слишком частой долбежки.
|
||||
[Поддерживается](#shell-переменные) параллельный режим. В нем каждая попытка выполняется в отдельном дочернем процессе, а потом собираются результаты со всех процессов. Режим включается только через [переменную PARALLEL](#shell-переменные). Может значительно ускорить тестирование, но так же может и нарваться на rate limit - ситуацию, когда сервер вас ограничивает или банит из-за слишком частой долбежки.
|
||||
|
||||
### Уровни сканирования
|
||||
|
||||
@@ -5226,7 +5255,7 @@ filter_apply_hostlist_target()
|
||||
# $1 - имя переменной с опциями nfqws2
|
||||
```
|
||||
|
||||
Осуществляет замену маркеров `<HOSTLIST>` и `<HOSTLIST_AUTO>` в $1 зависимости от режима фильтрации [MODE_FILTER](#файл-config) и наличия файлов листов в ipset.
|
||||
Осуществляет замену маркеров `<HOSTLIST>` и `<HOSTLIST_NOAUTO>` в $1 зависимости от режима фильтрации [MODE_FILTER](#файл-config) и наличия файлов листов в ipset.
|
||||
|
||||
```
|
||||
standard_mode_daemons()
|
||||
@@ -5634,8 +5663,8 @@ WinDivert 2.2.2-A, который идет в поставке zapret.
|
||||
|
||||
## Windows Server
|
||||
|
||||
winws2 слинкован с wlanapi.dll, который по умолчанию не установлен в Windows Server.
|
||||
Для решения этой проблемы запустите power shell под администратором и выполните команду `Install-WindowsFeature -Name Wireless-Networking`.
|
||||
Для работы `--ssid-filter` необходимо установить поддержку беспроводных сетей.
|
||||
Запустите power shell под администратором и выполните команду `Install-WindowsFeature -Name Wireless-Networking`.
|
||||
После чего перезагрузите систему.
|
||||
|
||||
## Windows ARM64
|
||||
|
||||
@@ -107,10 +107,10 @@ end
|
||||
-- hostname is original hostname
|
||||
function is_dpi_redirect(hostname, location)
|
||||
local ds = dissect_url(location)
|
||||
if ds.domain then
|
||||
if ds and ds.domain then
|
||||
local sld1 = dissect_nld(hostname,2)
|
||||
local sld2 = dissect_nld(ds.domain,2)
|
||||
return sld2 and sld1~=sld2
|
||||
return sld2 and sld1~=sld2 and true or false
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
@@ -14,7 +14,7 @@ end
|
||||
|
||||
function test_all(...)
|
||||
test_run({
|
||||
test_crypto, test_bin, test_gzip, test_ipstr, test_dissect, test_csum, test_resolve,
|
||||
test_crypto, test_bin, test_time, test_gzip, test_ipstr, test_dissect, test_csum, test_resolve,
|
||||
test_get_source_ip, test_ifaddrs, test_rawsend},...)
|
||||
end
|
||||
|
||||
@@ -415,6 +415,33 @@ function test_bin(...)
|
||||
test_run({test_ub, test_bit, test_swap, test_ux},...)
|
||||
end
|
||||
|
||||
function test_time(...)
|
||||
print("* time")
|
||||
|
||||
local unixtime=os.time()
|
||||
local tm = localtime(unixtime);
|
||||
print()
|
||||
print("now: "..tm.str.." "..tm.zone.." = "..unixtime)
|
||||
local tm = gmtime(unixtime);
|
||||
print("gmt: "..tm.str.." "..tm.zone.." = "..unixtime)
|
||||
print()
|
||||
for i=1,20 do
|
||||
unixtime = math.random(0,10000000000);
|
||||
tm = localtime(unixtime);
|
||||
local t = timelocal(tm)
|
||||
print("timelocal: "..tm.str.." "..tm.zone.." = "..t)
|
||||
print( t==unixtime and "LOCALTIME OK" or "LOCALTIME FAILED" )
|
||||
test_assert(t==unixtime)
|
||||
|
||||
unixtime = math.random(0,10000000000);
|
||||
tm = gmtime(unixtime);
|
||||
t = timegm(tm)
|
||||
print("timegm: "..tm.str.." "..tm.zone.." = "..t)
|
||||
print( t==unixtime and "GMTIME OK" or "GMTIME FAILED" )
|
||||
test_assert(t==unixtime)
|
||||
end
|
||||
end
|
||||
|
||||
function test_gzip()
|
||||
print("* gzip")
|
||||
|
||||
@@ -695,6 +722,8 @@ function test_csum()
|
||||
|
||||
raw = reconstruct_dissect({ip=ip, tcp=tcp, payload=payload})
|
||||
dis1 = dissect(raw)
|
||||
ip.ip_len = IP_BASE_LEN + #ip.options + #tcpb + #payload
|
||||
ip4b = reconstruct_iphdr(ip)
|
||||
tcpb = csum_tcp_fix(ip4b,tcpb,payload)
|
||||
dis2 = dissect(ip4b..tcpb..payload)
|
||||
print( dis1.tcp.th_sum==dis2.tcp.th_sum and "TCP+IP4 CSUM OK" or "TCP+IP4 CSUM FAILED" )
|
||||
@@ -751,6 +780,8 @@ function test_csum()
|
||||
|
||||
raw = reconstruct_dissect({ip=ip, udp=udp, payload=payload})
|
||||
dis1 = dissect(raw)
|
||||
ip.ip_len = IP_BASE_LEN + #ip.options + #udpb + #payload
|
||||
ip4b = reconstruct_iphdr(ip)
|
||||
udpb = csum_udp_fix(ip4b,udpb,payload)
|
||||
dis2 = dissect(ip4b..udpb..payload)
|
||||
print( dis1.udp.uh_sum==dis2.udp.uh_sum and "UDP+IP4 CSUM OK" or "UDP+IP4 CSUM FAILED" )
|
||||
|
||||
@@ -220,7 +220,7 @@ static void *t_resolver(void *arg)
|
||||
{
|
||||
if ((family == AF_INET && (glob.family & FAMILY4)) || (family == AF_INET6 && (glob.family & FAMILY6)))
|
||||
{
|
||||
unsigned int mask;
|
||||
unsigned int mask=0;
|
||||
bool mask_needed = false;
|
||||
if (s_mask)
|
||||
{
|
||||
|
||||
@@ -6,12 +6,13 @@ CFLAGS_LINUX = -Wno-alloc-size-larger-than
|
||||
CFLAGS_SYSTEMD = -DUSE_SYSTEMD
|
||||
CFLAGS_BSD = -Wno-address-of-packed-member
|
||||
CFLAGS_CYGWIN = -Wno-address-of-packed-member -static
|
||||
CFLAGS_UBSAN = -fsanitize=undefined,alignment -fno-sanitize-recover=undefined,alignment
|
||||
LDFLAGS_ANDROID = -llog
|
||||
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 -liphlpapi -lntdll
|
||||
LIBS_CYGWIN = -lz -Lwindows/windivert -Iwindows -lole32 -loleaut32 -liphlpapi -lntdll
|
||||
LIBS_CYGWIN32 = -lwindivert32
|
||||
LIBS_CYGWIN64 = -lwindivert64
|
||||
RES_CYGWIN32 = windows/res/winws_res32.o
|
||||
@@ -135,6 +136,9 @@ all: nfqws2
|
||||
nfqws2: $(SRC_FILES)
|
||||
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_LINUX) -o nfqws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LDFLAGS)
|
||||
|
||||
ubsan: $(SRC_FILES)
|
||||
$(CC) $(CFLAGS_UBSAN) $(CFLAGS) $(LUA_CFL) $(CFLAGS_LINUX) -o nfqws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LDFLAGS)
|
||||
|
||||
systemd: $(SRC_FILES)
|
||||
$(CC) -s $(CFLAGS) $(LUA_CFL) $(CFLAGS_LINUX) $(CFLAGS_SYSTEMD) -o nfqws2 $(SRC_FILES) $(LIBS) $(LUA_LIB) $(LIBS_LINUX) $(LIBS_SYSTEMD) $(LDFLAGS)
|
||||
|
||||
|
||||
@@ -258,6 +258,8 @@ int gcm_start(gcm_context *ctx, // pointer to user-provided GCM context
|
||||
size_t use_len; // byte count to process, up to 16 bytes
|
||||
size_t i; // local loop iterator
|
||||
|
||||
if (iv_len!=12) return -1;
|
||||
|
||||
// since the context might be reused under the same key
|
||||
// we zero the working buffers for this next new process
|
||||
memset(ctx->y, 0x00, sizeof(ctx->y));
|
||||
@@ -391,7 +393,9 @@ int gcm_finish(gcm_context *ctx, // pointer to user-provided GCM context
|
||||
uint64_t orig_add_len = ctx->add_len * 8;
|
||||
size_t i;
|
||||
|
||||
if (tag_len != 0) memcpy(tag, ctx->base_ectr, tag_len);
|
||||
if (tag_len>16) return -1;
|
||||
|
||||
if (tag_len) memcpy(tag, ctx->base_ectr, tag_len);
|
||||
|
||||
if (orig_len || orig_add_len) {
|
||||
memset(work_buf, 0x00, 16);
|
||||
@@ -443,10 +447,12 @@ int gcm_crypt_and_tag(
|
||||
prepare the gcm context with the keying material, we simply
|
||||
invoke each of the three GCM sub-functions in turn...
|
||||
*/
|
||||
gcm_start(ctx, mode, iv, iv_len, add, add_len);
|
||||
gcm_update(ctx, length, input, output);
|
||||
gcm_finish(ctx, tag, tag_len);
|
||||
return(0);
|
||||
if (iv_len!=12 || tag_len>16) return -1;
|
||||
|
||||
int ret;
|
||||
if ((ret=gcm_start(ctx, mode, iv, iv_len, add, add_len))) return ret;
|
||||
if ((ret=gcm_update(ctx, length, input, output))) return ret;
|
||||
return gcm_finish(ctx, tag, tag_len);
|
||||
}
|
||||
|
||||
|
||||
@@ -477,6 +483,9 @@ int gcm_auth_decrypt(
|
||||
uchar check_tag[16]; // the tag generated and returned by decryption
|
||||
int diff; // an ORed flag to detect authentication errors
|
||||
size_t i; // our local iterator
|
||||
|
||||
if (iv_len!=12 || tag_len>16) return -1;
|
||||
|
||||
/*
|
||||
we use GCM_DECRYPT_AND_TAG (above) to perform our decryption
|
||||
(which is an identical XORing to reverse the previous one)
|
||||
|
||||
100
nfq2/darkmagic.c
100
nfq2/darkmagic.c
@@ -102,8 +102,8 @@ bool tcp_syn_segment(const struct tcphdr *tcphdr)
|
||||
|
||||
void extract_ports(const struct tcphdr *tcphdr, const struct udphdr *udphdr,uint8_t *proto, uint16_t *sport, uint16_t *dport)
|
||||
{
|
||||
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 (sport) *sport = ntohs(tcphdr ? tcphdr->th_sport : udphdr ? udphdr->uh_sport : 0);
|
||||
if (dport) *dport = ntohs(tcphdr ? tcphdr->th_dport : udphdr ? udphdr->uh_dport : 0);
|
||||
if (proto) *proto = tcphdr ? IPPROTO_TCP : udphdr ? IPPROTO_UDP : IPPROTO_NONE;
|
||||
}
|
||||
|
||||
@@ -178,8 +178,8 @@ void extract_endpoints(const struct ip *ip,const struct ip6_hdr *ip6hdr,const st
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(src,0,sizeof(*src));
|
||||
memset(dst,0,sizeof(*dst));
|
||||
if (src) memset(src,0,sizeof(*src));
|
||||
if (dst) memset(dst,0,sizeof(*dst));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -378,6 +378,10 @@ bool proto_check_ipv4(const uint8_t *data, size_t len)
|
||||
uint8_t off = ((struct ip*)data)->ip_hl << 2;
|
||||
return off>=sizeof(struct ip) && len>=off;
|
||||
}
|
||||
bool proto_check_ipv4_payload(const uint8_t *data, size_t len)
|
||||
{
|
||||
return len >= ntohs(((struct ip*)data)->ip_len);
|
||||
}
|
||||
// move to transport protocol
|
||||
void proto_skip_ipv4(const uint8_t **data, size_t *len)
|
||||
{
|
||||
@@ -537,7 +541,7 @@ void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis, bo
|
||||
dis->data_pkt = data;
|
||||
dis->len_pkt = len;
|
||||
|
||||
if (proto_check_ipv4(data, len))
|
||||
if (proto_check_ipv4(data, len) && (no_payload_check || proto_check_ipv4_payload(data, len)))
|
||||
{
|
||||
dis->ip = (const struct ip *) data;
|
||||
dis->proto = dis->ip->ip_p;
|
||||
@@ -1148,6 +1152,42 @@ static bool AdapterID2Name(const GUID *guid,char *name,DWORD name_len)
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
typedef DWORD (WINAPI *t_WlanOpenHandle)(
|
||||
DWORD dwClientVersion,
|
||||
PVOID pReserved,
|
||||
PDWORD pdwNegotiatedVersion,
|
||||
PHANDLE phClientHandle
|
||||
);
|
||||
typedef DWORD (WINAPI *t_WlanCloseHandle)(
|
||||
HANDLE hClientHandle,
|
||||
PVOID pReserved
|
||||
);
|
||||
typedef DWORD (WINAPI *t_WlanEnumInterfaces)(
|
||||
HANDLE hClientHandle,
|
||||
PVOID pReserved,
|
||||
PWLAN_INTERFACE_INFO_LIST *ppInterfaceList
|
||||
);
|
||||
typedef DWORD (WINAPI *t_WlanQueryInterface)(
|
||||
HANDLE hClientHandle,
|
||||
const GUID *pInterfaceGuid,
|
||||
WLAN_INTF_OPCODE OpCode,
|
||||
PVOID pReserved,
|
||||
PDWORD pdwDataSize,
|
||||
PVOID *ppData,
|
||||
PWLAN_OPCODE_VALUE_TYPE pWlanOpcodeValueType
|
||||
);
|
||||
typedef DWORD (WINAPI *t_WlanFreeMemory)(
|
||||
PVOID pMemory
|
||||
);
|
||||
|
||||
t_WlanOpenHandle f_WlanOpenHandle = NULL;
|
||||
t_WlanCloseHandle f_WlanCloseHandle = NULL;
|
||||
t_WlanEnumInterfaces f_WlanEnumInterfaces = NULL;
|
||||
t_WlanQueryInterface f_WlanQueryInterface = NULL;
|
||||
t_WlanFreeMemory f_WlanFreeMemory = NULL;
|
||||
HMODULE hdll_wlanapi = NULL;
|
||||
|
||||
bool win_dark_init(const struct str_list_head *ssid_filter, const struct str_list_head *nlm_filter)
|
||||
{
|
||||
win_dark_deinit();
|
||||
@@ -1161,12 +1201,38 @@ bool win_dark_init(const struct str_list_head *ssid_filter, const struct str_lis
|
||||
if (FAILED(w_win32_error = CoCreateInstance(&CLSID_NetworkListManager, NULL, CLSCTX_ALL, &IID_INetworkListManager, (LPVOID*)&pNetworkListManager)))
|
||||
{
|
||||
CoUninitialize();
|
||||
DLOG_ERR("could not create CLSID_NetworkListManager. win32 error %u\n", w_win32_error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
if (ssid_filter)
|
||||
{
|
||||
// dont load any crap from current dir
|
||||
hdll_wlanapi = LoadLibraryExW(L"wlanapi.dll",NULL,LOAD_LIBRARY_SEARCH_SYSTEM32);
|
||||
if (!hdll_wlanapi)
|
||||
{
|
||||
w_win32_error = GetLastError();
|
||||
DLOG_ERR("could not load wlanapi.dll. win32 error %u\n", w_win32_error);
|
||||
win_dark_deinit();
|
||||
return false;
|
||||
}
|
||||
f_WlanOpenHandle = (t_WlanOpenHandle)GetProcAddress(hdll_wlanapi,"WlanOpenHandle");
|
||||
f_WlanCloseHandle = (t_WlanCloseHandle)GetProcAddress(hdll_wlanapi,"WlanCloseHandle");
|
||||
f_WlanEnumInterfaces = (t_WlanEnumInterfaces)GetProcAddress(hdll_wlanapi,"WlanEnumInterfaces");
|
||||
f_WlanQueryInterface = (t_WlanQueryInterface)GetProcAddress(hdll_wlanapi,"WlanQueryInterface");
|
||||
f_WlanFreeMemory = (t_WlanFreeMemory)GetProcAddress(hdll_wlanapi,"WlanFreeMemory");
|
||||
if (!f_WlanOpenHandle || !f_WlanCloseHandle || !f_WlanEnumInterfaces || !f_WlanQueryInterface || !f_WlanFreeMemory)
|
||||
{
|
||||
w_win32_error = GetLastError();
|
||||
DLOG_ERR("could not import all required functions from wlanapi.dll\n");
|
||||
win_dark_deinit();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nlm_filter_net = nlm_filter;
|
||||
wlan_filter_ssid = ssid_filter;
|
||||
return true;
|
||||
@@ -1180,6 +1246,16 @@ void win_dark_deinit(void)
|
||||
}
|
||||
if (nlm_filter_net) CoUninitialize();
|
||||
wlan_filter_ssid = nlm_filter_net = NULL;
|
||||
if (hdll_wlanapi)
|
||||
{
|
||||
FreeLibrary(hdll_wlanapi);
|
||||
hdll_wlanapi = NULL;
|
||||
f_WlanOpenHandle = NULL;
|
||||
f_WlanCloseHandle = NULL;
|
||||
f_WlanEnumInterfaces = NULL;
|
||||
f_WlanQueryInterface = NULL;
|
||||
f_WlanFreeMemory = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1361,16 +1437,16 @@ static bool wlan_filter_match(const struct str_list_head *ssid_list)
|
||||
return true;
|
||||
}
|
||||
|
||||
w_win32_error = WlanOpenHandle(2, NULL, &dwCurVersion, &hClient);
|
||||
w_win32_error = f_WlanOpenHandle(2, NULL, &dwCurVersion, &hClient);
|
||||
if (w_win32_error != ERROR_SUCCESS) goto fail;
|
||||
w_win32_error = WlanEnumInterfaces(hClient, NULL, &pIfList);
|
||||
w_win32_error = f_WlanEnumInterfaces(hClient, NULL, &pIfList);
|
||||
if (w_win32_error != ERROR_SUCCESS) goto fail;
|
||||
for (k = 0; k < pIfList->dwNumberOfItems; k++)
|
||||
{
|
||||
pIfInfo = pIfList->InterfaceInfo + k;
|
||||
if (pIfInfo->isState == wlan_interface_state_connected)
|
||||
{
|
||||
w_win32_error = WlanQueryInterface(hClient,
|
||||
w_win32_error = f_WlanQueryInterface(hClient,
|
||||
&pIfInfo->InterfaceGuid,
|
||||
wlan_intf_opcode_current_connection,
|
||||
NULL,
|
||||
@@ -1386,20 +1462,20 @@ static bool wlan_filter_match(const struct str_list_head *ssid_list)
|
||||
len = strlen(ssid->str);
|
||||
if (len==pConnectInfo->wlanAssociationAttributes.dot11Ssid.uSSIDLength && !memcmp(ssid->str,pConnectInfo->wlanAssociationAttributes.dot11Ssid.ucSSID,len))
|
||||
{
|
||||
WlanFreeMemory(pConnectInfo);
|
||||
f_WlanFreeMemory(pConnectInfo);
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
WlanFreeMemory(pConnectInfo);
|
||||
f_WlanFreeMemory(pConnectInfo);
|
||||
}
|
||||
}
|
||||
w_win32_error = 0;
|
||||
fail:
|
||||
bRes = false;
|
||||
ex:
|
||||
if (pIfList) WlanFreeMemory(pIfList);
|
||||
if (hClient) WlanCloseHandle(hClient, 0);
|
||||
if (pIfList) f_WlanFreeMemory(pIfList);
|
||||
if (hClient) f_WlanCloseHandle(hClient, 0);
|
||||
return bRes;
|
||||
found:
|
||||
w_win32_error = 0;
|
||||
|
||||
@@ -174,6 +174,7 @@ 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);
|
||||
bool proto_check_ipv4_payload(const uint8_t *data, size_t len);
|
||||
void proto_skip_ipv4(const uint8_t **data, size_t *len);
|
||||
bool proto_check_ipv6(const uint8_t *data, size_t len);
|
||||
bool proto_check_ipv6_payload(const uint8_t *data, size_t len);
|
||||
|
||||
@@ -609,7 +609,8 @@ static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, const struct dissect *
|
||||
// if used in postnat chain, dropping initial packet will cause conntrack connection teardown
|
||||
// so we need to workaround this.
|
||||
// SYN and SYN,ACK checks are for conntrack-less mode
|
||||
if (ctrack && (params.server ? ctrack->pos.server.pcounter : ctrack->pos.client.pcounter) == 1 || dis->tcp && (tcp_syn_segment(dis->tcp) || tcp_synack_segment(dis->tcp)))
|
||||
if (ctrack && (params.server ? ctrack->pos.server.pcounter : ctrack->pos.client.pcounter) == 1 ||
|
||||
!ctrack && dis->tcp && (tcp_syn_segment(dis->tcp) || tcp_synack_segment(dis->tcp)))
|
||||
{
|
||||
if (dis->len_pkt > *len_mod_pkt)
|
||||
DLOG_ERR("linux postnat conntrack workaround cannot be applied\n");
|
||||
@@ -729,7 +730,7 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr
|
||||
if (!params.cache_hostname)
|
||||
{
|
||||
*hostname = 0;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
if (params.debug)
|
||||
{
|
||||
@@ -737,13 +738,8 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr
|
||||
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)
|
||||
{
|
||||
DLOG_ERR("ipcache_get_hostname: out of memory\n");
|
||||
return false;
|
||||
}
|
||||
if (ipc->hostname)
|
||||
ip_cache_item *ipc = ipcacheFind(¶ms.ipcache, a4, a6, NULL);
|
||||
if (ipc && ipc->hostname)
|
||||
{
|
||||
if (params.debug)
|
||||
{
|
||||
@@ -756,31 +752,36 @@ static bool ipcache_get_hostname(const struct in_addr *a4, const struct in6_addr
|
||||
}
|
||||
else
|
||||
*hostname = 0;
|
||||
return true;
|
||||
return *hostname;
|
||||
}
|
||||
static void ipcache_update_ttl(t_ctrack *ctrack, const struct in_addr *a4, const struct in6_addr *a6, const char *iface)
|
||||
{
|
||||
// no need to cache ttl in server mode because first packet is incoming
|
||||
if (ctrack && !params.server)
|
||||
{
|
||||
ip_cache_item *ipc = ipcacheTouch(¶ms.ipcache, a4, a6, iface);
|
||||
if (!ipc)
|
||||
{
|
||||
DLOG_ERR("ipcache: out of memory\n");
|
||||
return;
|
||||
}
|
||||
ip_cache_item *ipc;
|
||||
if (ctrack->incoming_ttl)
|
||||
{
|
||||
ipc = ipcacheTouch(¶ms.ipcache, a4, a6, iface);
|
||||
if (!ipc)
|
||||
{
|
||||
DLOG_ERR("ipcache: out of memory\n");
|
||||
return;
|
||||
}
|
||||
if (ipc->ttl != ctrack->incoming_ttl)
|
||||
{
|
||||
DLOG("updated ttl cache\n");
|
||||
ipc->ttl = ctrack->incoming_ttl;
|
||||
}
|
||||
}
|
||||
else if (ipc->ttl)
|
||||
else
|
||||
{
|
||||
DLOG("got cached ttl %u\n", ipc->ttl);
|
||||
ctrack->incoming_ttl = ipc->ttl;
|
||||
ipc = ipcacheFind(¶ms.ipcache, a4, a6, iface);
|
||||
if (ipc && ipc->ttl)
|
||||
{
|
||||
DLOG("got cached ttl %u\n", ipc->ttl);
|
||||
ctrack->incoming_ttl = ipc->ttl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -789,10 +790,8 @@ static void ipcache_get_ttl(t_ctrack *ctrack, const struct in_addr *a4, const st
|
||||
// no need to cache ttl in server mode because first packet is incoming
|
||||
if (ctrack && !ctrack->incoming_ttl && !params.server)
|
||||
{
|
||||
ip_cache_item *ipc = ipcacheTouch(¶ms.ipcache, a4, a6, iface);
|
||||
if (!ipc)
|
||||
DLOG_ERR("ipcache: out of memory\n");
|
||||
else if (ipc->ttl)
|
||||
ip_cache_item *ipc = ipcacheFind(¶ms.ipcache, a4, a6, iface);
|
||||
if (ipc && ipc->ttl)
|
||||
{
|
||||
DLOG("got cached ttl %u\n", ipc->ttl);
|
||||
ctrack->incoming_ttl = ipc->ttl;
|
||||
@@ -896,7 +895,7 @@ static uint8_t desync(
|
||||
if (LIST_FIRST(&dp->lua_desync))
|
||||
{
|
||||
lua_rawgeti(params.L, LUA_REGISTRYINDEX, params.ref_desync_ctx);
|
||||
t_lua_desync_context *ctx = (t_lua_desync_context *)luaL_checkudata(params.L, 1, "desync_ctx");
|
||||
t_lua_desync_context *ctx = (t_lua_desync_context *)luaL_checkudata(params.L, -1, "desync_ctx");
|
||||
// this is singleton stored in the registry. safe to pop
|
||||
lua_pop(params.L,1);
|
||||
|
||||
@@ -1263,7 +1262,7 @@ static bool play_prolog(
|
||||
hostname_is_ip = ps->ctrack->hostname_is_ip;
|
||||
if (!hostname && !ps->bReverse)
|
||||
{
|
||||
if (ipcache_get_hostname(ps->sdip4, ps->sdip6, ps->host, sizeof(ps->host), &hostname_is_ip) && *ps->host)
|
||||
if (ipcache_get_hostname(ps->sdip4, ps->sdip6, ps->host, sizeof(ps->host), &hostname_is_ip))
|
||||
if (!(hostname = ps->ctrack->hostname = strdup(ps->host)))
|
||||
DLOG_ERR("strdup(host): out of memory\n");
|
||||
}
|
||||
@@ -1451,7 +1450,8 @@ static uint8_t dpi_desync_tcp_packet_play(
|
||||
{L7P_HTTP_REPLY,L7_HTTP,IsHttpReply,false},
|
||||
{L7P_XMPP_STREAM,L7_XMPP,IsXMPPStream,false},
|
||||
{L7P_XMPP_PROCEED,L7_XMPP,IsXMPPProceedTLS,false},
|
||||
{L7P_XMPP_FEATURES,L7_XMPP,IsXMPPFeatures,false}
|
||||
{L7P_XMPP_FEATURES,L7_XMPP,IsXMPPFeatures,false},
|
||||
{L7P_BT_HANDSHAKE,L7_BT,IsBTHandshake,false}
|
||||
};
|
||||
protocol_probe(testers, sizeof(testers) / sizeof(*testers), dis->data_payload, dis->len_payload, ps.ctrack, &ps.l7proto, &ps.l7payload);
|
||||
|
||||
@@ -1531,10 +1531,11 @@ static uint8_t dpi_desync_tcp_packet_play(
|
||||
if (!ps.ctrack_replay || ReasmIsEmpty(&ps.ctrack_replay->reasm_client))
|
||||
{
|
||||
t_protocol_probe testers[] = {
|
||||
{L7P_TLS_CLIENT_HELLO,L7_TLS,IsTLSClientHelloPartial},
|
||||
{L7P_TLS_CLIENT_HELLO,L7_TLS,IsTLSClientHelloPartial,false},
|
||||
{L7P_HTTP_REQ,L7_HTTP,IsHttp,false},
|
||||
{L7P_XMPP_STREAM,L7_XMPP,IsXMPPStream,false},
|
||||
{L7P_XMPP_STARTTLS,L7_XMPP,IsXMPPStartTLS,false}
|
||||
{L7P_XMPP_STARTTLS,L7_XMPP,IsXMPPStartTLS,false},
|
||||
{L7P_BT_HANDSHAKE,L7_BT,IsBTHandshake,false}
|
||||
};
|
||||
protocol_probe(testers, sizeof(testers) / sizeof(*testers), rdata_payload, rlen_payload, ps.ctrack_replay, &ps.l7proto, &ps.l7payload);
|
||||
|
||||
@@ -1544,7 +1545,7 @@ static uint8_t dpi_desync_tcp_packet_play(
|
||||
if (ps.tpos && (ps.tpos->client.seq_last - ps.tpos->client.seq0)==1)
|
||||
{
|
||||
t_protocol_probe testers[] = {
|
||||
{L7P_MTPROTO_INITIAL,L7_MTPROTO,IsMTProto}
|
||||
{L7P_MTPROTO_INITIAL,L7_MTPROTO,IsMTProto,false}
|
||||
};
|
||||
protocol_probe(testers, sizeof(testers) / sizeof(*testers), rdata_payload, rlen_payload, ps.ctrack_replay, &ps.l7proto, &ps.l7payload);
|
||||
}
|
||||
@@ -1627,6 +1628,7 @@ static void udp_standard_protocol_probe(const uint8_t *data_payload, size_t len_
|
||||
{L7P_DHT,L7_DHT,IsDht,false},
|
||||
{L7P_DTLS_CLIENT_HELLO,L7_DTLS,IsDTLSClientHello,false},
|
||||
{L7P_DTLS_SERVER_HELLO,L7_DTLS,IsDTLSServerHello,false},
|
||||
{L7P_UTP_BT_HANDSHAKE,L7_UTP_BT,IsUTP_BTHandshake,false},
|
||||
{L7P_WIREGUARD_INITIATION,L7_WIREGUARD,IsWireguardHandshakeInitiation,false},
|
||||
{L7P_WIREGUARD_RESPONSE,L7_WIREGUARD,IsWireguardHandshakeResponse,false},
|
||||
{L7P_WIREGUARD_COOKIE,L7_WIREGUARD,IsWireguardHandshakeCookie,false},
|
||||
@@ -1644,7 +1646,7 @@ static const uint8_t *dns_extract_name(const uint8_t *a, const uint8_t *b, const
|
||||
|
||||
if (bptr)
|
||||
{
|
||||
if (a>=e) return NULL;
|
||||
if (a+1>=e) return NULL;
|
||||
// name pointer
|
||||
off = (*a & 0x3F)<<8 | a[1];
|
||||
p = b + off;
|
||||
@@ -1981,8 +1983,8 @@ static uint8_t dpi_desync_icmp_packet(
|
||||
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)
|
||||
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) ||
|
||||
ipcache_get_hostname(dis->ip ? &dis->ip->ip_src : NULL, dis->ip6 ? &dis->ip6->ip6_src : NULL, host, sizeof(host), &hostname_is_ip))
|
||||
{
|
||||
hostname = host;
|
||||
}
|
||||
@@ -2029,7 +2031,7 @@ static uint8_t dpi_desync_ip_packet(
|
||||
if (!!dis->ip == !!dis->ip6) return verdict;
|
||||
|
||||
struct sockaddr_storage src, dst;
|
||||
const char *ssid;
|
||||
const char *ssid = NULL;
|
||||
struct desync_profile *dp;
|
||||
|
||||
extract_endpoints(dis->ip, dis->ip6, NULL, NULL, &src, &dst);
|
||||
@@ -2048,8 +2050,8 @@ static uint8_t dpi_desync_ip_packet(
|
||||
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)
|
||||
if (ipcache_get_hostname(dis->ip ? &dis->ip->ip_dst : NULL, dis->ip6 ? &dis->ip6->ip6_dst : NULL, host, sizeof(host), &hostname_is_ip) ||
|
||||
ipcache_get_hostname(dis->ip ? &dis->ip->ip_src : NULL, dis->ip6 ? &dis->ip6->ip6_src : NULL, host, sizeof(host), &hostname_is_ip))
|
||||
{
|
||||
hostname = host;
|
||||
}
|
||||
@@ -2128,6 +2130,8 @@ static uint8_t dpi_desync_packet_play(
|
||||
verdict = dpi_desync_ip_packet(fwmark, ifin, ifout, &dis, mod_pkt, len_mod_pkt);
|
||||
}
|
||||
}
|
||||
else
|
||||
DLOG("invalid packet - neither ipv4 or ipv6\n");
|
||||
return verdict;
|
||||
}
|
||||
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifin, const char *ifout, const uint8_t *data_pkt, size_t len_pkt, uint8_t *mod_pkt, size_t *len_mod_pkt)
|
||||
|
||||
@@ -18,6 +18,7 @@ bool pf_parse(const char *s, port_filter *pf)
|
||||
if (*s=='*' && s[1]==0)
|
||||
{
|
||||
pf->from=1; pf->to=0xFFFF;
|
||||
pf->neg=false;
|
||||
return true;
|
||||
}
|
||||
if (*s=='~')
|
||||
|
||||
@@ -456,8 +456,14 @@ bool file_open_test(const char *filename, int flags)
|
||||
void fill_random_bytes(uint8_t *p,size_t sz)
|
||||
{
|
||||
size_t k;
|
||||
for (k=0 ; (k+1)<sz ; k+=2) phton16(p+k, (uint16_t)random());
|
||||
if (sz & 1) p[sz-1]=(uint8_t)random();
|
||||
if (sz)
|
||||
{
|
||||
// alignment
|
||||
if ((size_t)p & 1) { *p=(uint8_t)random(); sz--; p++; }
|
||||
// random has only 31 bits of entropy. not 32 bits
|
||||
for (k=0 ; (k+1)<sz ; k+=2) *(uint16_t*)(p+k) = (uint16_t)random();
|
||||
if (sz & 1) p[sz-1]=(uint8_t)random();
|
||||
}
|
||||
}
|
||||
void fill_random_az(uint8_t *p,size_t sz)
|
||||
{
|
||||
|
||||
94
nfq2/lua.c
94
nfq2/lua.c
@@ -1053,7 +1053,7 @@ static int luacall_execution_plan(lua_State *L)
|
||||
{
|
||||
for (pl=0 ; pl<L7P_LAST ; pl++)
|
||||
{
|
||||
if (func->payload_type & (1<<pl))
|
||||
if (func->payload_type & (1ULL<<pl))
|
||||
{
|
||||
if ((pls = l7payload_str(pl)))
|
||||
{
|
||||
@@ -3614,6 +3614,90 @@ static int luacall_stat(lua_State *L)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void lua_xtime(lua_State *L, struct tm *(*timefunc)(const time_t *,struct tm *))
|
||||
{
|
||||
struct tm t;
|
||||
|
||||
time_t unixtime = (time_t)luaL_checklint(L,1);
|
||||
if (!timefunc(&unixtime, &t))
|
||||
{
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_createtable(L, 0, 11);
|
||||
lua_pushf_int(L,"sec", t.tm_sec);
|
||||
lua_pushf_int(L,"min", t.tm_min);
|
||||
lua_pushf_int(L,"hour", t.tm_hour);
|
||||
lua_pushf_int(L,"mday", t.tm_mday);
|
||||
lua_pushf_int(L,"mon", t.tm_mon);
|
||||
lua_pushf_int(L,"year", t.tm_year+1900);
|
||||
lua_pushf_int(L,"wday", t.tm_wday);
|
||||
lua_pushf_int(L,"yday", t.tm_yday);
|
||||
lua_pushf_int(L,"isdst", t.tm_isdst);
|
||||
lua_pushf_str(L,"zone", t.tm_zone);
|
||||
|
||||
char s[24];
|
||||
snprintf(s,sizeof(s),"%02d.%02d.%04d %02d:%02d:%02d", t.tm_mday, t.tm_mon + 1, t.tm_year + 1900, t.tm_hour, t.tm_min, t.tm_sec);
|
||||
lua_pushf_str(L,"str", s);
|
||||
}
|
||||
}
|
||||
static int luacall_localtime(lua_State *L)
|
||||
{
|
||||
// localtime(unixtime)
|
||||
lua_check_argc(L,"localtime",1);
|
||||
lua_xtime(L, localtime_r);
|
||||
return 1;
|
||||
}
|
||||
static int luacall_gmtime(lua_State *L)
|
||||
{
|
||||
// gmtime(unixtime)
|
||||
lua_check_argc(L,"gmtime",1);
|
||||
lua_xtime(L, gmtime_r);
|
||||
return 1;
|
||||
}
|
||||
#define TIMEX_VAL(v) \
|
||||
lua_getfield(L,1,#v); \
|
||||
if (lua_type(L,-1)!=LUA_TNUMBER) luaL_error(L,"invalid tm." #v); \
|
||||
t.tm_##v = lua_tointeger(L,-1); \
|
||||
lua_pop(L,1);
|
||||
static void lua_timex(lua_State *L, time_t (*timefunc)(struct tm *))
|
||||
{
|
||||
if (lua_type(L,1)!=LUA_TTABLE) luaL_error(L,"invalid tm structure");
|
||||
|
||||
struct tm t;
|
||||
TIMEX_VAL(sec)
|
||||
TIMEX_VAL(min)
|
||||
TIMEX_VAL(hour)
|
||||
TIMEX_VAL(mday)
|
||||
TIMEX_VAL(mon)
|
||||
TIMEX_VAL(year)
|
||||
t.tm_year-=1900;
|
||||
TIMEX_VAL(isdst)
|
||||
|
||||
time_t unixtime = timefunc(&t);
|
||||
if (unixtime==(time_t)-1)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else
|
||||
lua_pushlint(L,unixtime);
|
||||
}
|
||||
static int luacall_timelocal(lua_State *L)
|
||||
{
|
||||
// timelocal(tm)
|
||||
lua_check_argc(L,"timelocal",1);
|
||||
lua_timex(L, mktime);
|
||||
return 1;
|
||||
}
|
||||
static int luacall_timegm(lua_State *L)
|
||||
{
|
||||
// timegm(tm)
|
||||
lua_check_argc(L,"timegm",1);
|
||||
lua_timex(L, timegm);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ----------------------------------------
|
||||
|
||||
void lua_cleanup(lua_State *L)
|
||||
@@ -4258,7 +4342,13 @@ static void lua_init_functions(void)
|
||||
{"gzip_deflate",luacall_gzip_deflate},
|
||||
|
||||
// stat() - file size, mod time
|
||||
{"stat",luacall_stat}
|
||||
{"stat",luacall_stat},
|
||||
|
||||
// time
|
||||
{"localtime",luacall_localtime},
|
||||
{"gmtime",luacall_gmtime},
|
||||
{"timelocal",luacall_timelocal},
|
||||
{"timegm",luacall_timegm}
|
||||
};
|
||||
for(int i=0;i<(sizeof(lfunc)/sizeof(*lfunc));i++)
|
||||
lua_register(params.L,lfunc[i].name,lfunc[i].f);
|
||||
|
||||
57
nfq2/nfqws.c
57
nfq2/nfqws.c
@@ -156,6 +156,40 @@ static uint8_t processPacketData(uint32_t *mark, const char *ifin, const char *i
|
||||
return dpi_desync_packet(*mark, ifin, ifout, data_pkt, len_pkt, mod_pkt, len_mod_pkt);
|
||||
}
|
||||
|
||||
#define FUZZ_MAX_PACKET_SIZE (RECONSTRUCT_MAX_SIZE+4096)
|
||||
static void fuzzPacketData(unsigned int count)
|
||||
{
|
||||
uint8_t *packet,mod[RECONSTRUCT_MAX_SIZE+4096];
|
||||
size_t len, modlen;
|
||||
unsigned int k;
|
||||
uint32_t mark=0;
|
||||
uint8_t verdict;
|
||||
|
||||
for(k=0;k<count;k++)
|
||||
{
|
||||
if (bQuit) break;
|
||||
if (!(k%1000)) DLOG_CONDUP("fuzz ct=%u\n",k);
|
||||
len = random()%(FUZZ_MAX_PACKET_SIZE+1);
|
||||
if (!(packet = malloc(len))) return; // alloc every time to catch uninitialized reads
|
||||
fill_random_bytes(packet,len);
|
||||
if (len)
|
||||
{
|
||||
// simulate ipv4 or ipv6 and invalid packet with low probability
|
||||
*packet = *packet ? (*packet & 1) ? 0x40 : 0x60 | (*packet & 0x0F) : (uint8_t)random();
|
||||
}
|
||||
modlen = random()%(sizeof(mod)+1);
|
||||
verdict = processPacketData(&mark,random()%1 ? "ifin" : NULL,random()%1 ? "ifout" : NULL,packet,len,mod,&modlen);
|
||||
free(packet);
|
||||
}
|
||||
}
|
||||
static void do_fuzz(void)
|
||||
{
|
||||
if (params.fuzz)
|
||||
{
|
||||
DLOG_CONDUP("fuzz packet data count=%u\n",params.fuzz);
|
||||
fuzzPacketData(params.fuzz);
|
||||
}
|
||||
}
|
||||
|
||||
static bool test_list_files()
|
||||
{
|
||||
@@ -381,9 +415,11 @@ static int nfq_main(void)
|
||||
if (!lua_init())
|
||||
goto err;
|
||||
|
||||
do_fuzz();
|
||||
|
||||
if (!params.intercept)
|
||||
{
|
||||
DLOG("no intercept quit\n");
|
||||
DLOG_CONDUP("no intercept quit\n");
|
||||
goto exok;
|
||||
}
|
||||
|
||||
@@ -548,6 +584,8 @@ static int dvt_main(void)
|
||||
if (!lua_init())
|
||||
goto exiterr;
|
||||
|
||||
do_fuzz();
|
||||
|
||||
if (!params.intercept)
|
||||
{
|
||||
DLOG("no intercept quit\n");
|
||||
@@ -737,6 +775,8 @@ static int win_main()
|
||||
res=ERROR_INVALID_PARAMETER; goto ex;
|
||||
}
|
||||
|
||||
do_fuzz();
|
||||
|
||||
if (!params.intercept)
|
||||
{
|
||||
DLOG("no intercept quit\n");
|
||||
@@ -756,7 +796,8 @@ static int win_main()
|
||||
}
|
||||
else if (errno == ENODEV)
|
||||
{
|
||||
DLOG_CONDUP("logical network disappeared. deinitializing windivert.\n");
|
||||
DLOG_CONDUP("\nlogical network disappeared. deinitializing windivert.\n");
|
||||
rawsend_cleanup();
|
||||
break;
|
||||
}
|
||||
else if (errno == EINTR)
|
||||
@@ -1057,7 +1098,7 @@ static bool parse_l7_list(char *opt, uint64_t *l7)
|
||||
break;
|
||||
}
|
||||
else
|
||||
*l7 |= 1<<proto;
|
||||
*l7 |= 1ULL<<proto;
|
||||
|
||||
if (e) *e++ = c;
|
||||
p = e;
|
||||
@@ -1085,7 +1126,7 @@ static bool parse_l7p_list(char *opt, uint64_t *l7p)
|
||||
break;
|
||||
}
|
||||
else
|
||||
*l7p |= 1<<payload;
|
||||
*l7p |= 1ULL<<payload;
|
||||
|
||||
if (e) *e++ = c;
|
||||
p = e;
|
||||
@@ -1339,7 +1380,7 @@ static void LuaDesyncDebug(struct desync_profile *dp, const char *entity)
|
||||
if (func->payload_type)
|
||||
{
|
||||
for(i=0;i<L7P_LAST;i++)
|
||||
if (func->payload_type & (1<<i))
|
||||
if (func->payload_type & (1ULL<<i))
|
||||
DLOG(" %s", l7payload_str(i));
|
||||
}
|
||||
else
|
||||
@@ -1783,6 +1824,7 @@ enum opt_indices {
|
||||
IDX_DEBUG,
|
||||
IDX_DRY_RUN,
|
||||
IDX_INTERCEPT,
|
||||
IDX_FUZZ,
|
||||
IDX_VERSION,
|
||||
IDX_COMMENT,
|
||||
#ifdef __linux__
|
||||
@@ -1886,6 +1928,7 @@ 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_FUZZ] = {"fuzz", required_argument, 0, 0},
|
||||
[IDX_VERSION] = {"version", no_argument, 0, 0},
|
||||
[IDX_COMMENT] = {"comment", optional_argument, 0, 0},
|
||||
#ifdef __linux__
|
||||
@@ -2161,6 +2204,10 @@ int main(int argc, char **argv)
|
||||
case IDX_INTERCEPT:
|
||||
params.intercept = !optarg || atoi(optarg);
|
||||
break;
|
||||
case IDX_FUZZ:
|
||||
params.fuzz = atoi(optarg);
|
||||
params.intercept = false;
|
||||
break;
|
||||
case IDX_VERSION:
|
||||
exit_clean(0);
|
||||
break;
|
||||
|
||||
@@ -532,14 +532,15 @@ bool alloc_windivert_portfilters(struct params_s *params)
|
||||
¶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;
|
||||
if (!(*wdbufs[i] = malloc(WINDIVERT_PORTFILTER_MAX))) goto err;
|
||||
**wdbufs[i] = 0;
|
||||
}
|
||||
if (!(params->wf_raw_filter = malloc(WINDIVERT_MAX)))
|
||||
return false;
|
||||
if (!(params->wf_raw_filter = malloc(WINDIVERT_MAX))) goto err;
|
||||
*params->wf_raw_filter = 0;
|
||||
return true;
|
||||
err:
|
||||
cleanup_windivert_portfilters(params);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
void cleanup_params(struct params_s *params)
|
||||
@@ -593,7 +594,7 @@ void init_params(struct params_s *params)
|
||||
LIST_INIT(¶ms->blobs);
|
||||
LIST_INIT(¶ms->lua_init_scripts);
|
||||
|
||||
params->reasm_payload_disable = params->payload_disable = 1<<L7P_NONE;
|
||||
params->reasm_payload_disable = params->payload_disable = 1ULL<<L7P_NONE;
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
LIST_INIT(¶ms->ssid_filter);
|
||||
@@ -607,5 +608,4 @@ void init_params(struct params_s *params)
|
||||
params->droproot = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ struct params_s
|
||||
bool debug;
|
||||
|
||||
bool daemon, intercept;
|
||||
unsigned int fuzz;
|
||||
|
||||
#ifdef __linux__
|
||||
int qnum;
|
||||
|
||||
40
nfq2/pools.c
40
nfq2/pools.c
@@ -524,10 +524,15 @@ struct kavl_bit_elem *kavl_bit_get(const struct kavl_bit_elem *hdr, const void *
|
||||
|
||||
static bool ipset_kavl_add(struct kavl_bit_elem **ipset, const void *a, uint8_t preflen)
|
||||
{
|
||||
uint8_t bytelen = (preflen+7)>>3;
|
||||
uint8_t *abuf = malloc(bytelen);
|
||||
if (!abuf) return false;
|
||||
memcpy(abuf,a,bytelen);
|
||||
uint8_t *abuf, bytelen = (preflen+7)>>3;
|
||||
if (bytelen)
|
||||
{
|
||||
abuf = malloc(bytelen);
|
||||
if (!abuf) return false;
|
||||
memcpy(abuf,a,bytelen);
|
||||
}
|
||||
else
|
||||
abuf = NULL;
|
||||
if (!kavl_bit_add(ipset,abuf,preflen,0))
|
||||
{
|
||||
free(abuf);
|
||||
@@ -912,12 +917,15 @@ struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, co
|
||||
{
|
||||
struct blob_item *entry = calloc(1,sizeof(struct blob_item));
|
||||
if (!entry) return NULL;
|
||||
if (!(entry->data = malloc(size+size_reserve)))
|
||||
if (size+size_reserve)
|
||||
{
|
||||
free(entry);
|
||||
return NULL;
|
||||
if (!(entry->data = malloc(size+size_reserve)))
|
||||
{
|
||||
free(entry);
|
||||
return NULL;
|
||||
}
|
||||
if (data) memcpy(entry->data,data,size);
|
||||
}
|
||||
if (data) memcpy(entry->data,data,size);
|
||||
entry->size = size;
|
||||
entry->size_buf = size+size_reserve;
|
||||
|
||||
@@ -1107,6 +1115,22 @@ void ipcachePrint(ip_cache *ipcache)
|
||||
ipcache6Print(ipcache->ipcache6);
|
||||
}
|
||||
|
||||
ip_cache_item *ipcacheFind(ip_cache *ipcache, const struct in_addr *a4, const struct in6_addr *a6, const char *iface)
|
||||
{
|
||||
ip_cache4 *ipcache4;
|
||||
ip_cache6 *ipcache6;
|
||||
if (a4)
|
||||
{
|
||||
if ((ipcache4 = ipcache4Find(ipcache->ipcache4,a4,iface)))
|
||||
return &ipcache4->data;
|
||||
}
|
||||
else if (a6)
|
||||
{
|
||||
if ((ipcache6 = ipcache6Find(ipcache->ipcache6,a6,iface)))
|
||||
return &ipcache6->data;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4, const struct in6_addr *a6, const char *iface)
|
||||
{
|
||||
ip_cache4 *ipcache4;
|
||||
|
||||
@@ -265,6 +265,7 @@ typedef struct ip_cache
|
||||
} ip_cache;
|
||||
|
||||
ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4, const struct in6_addr *a6, const char *iface);
|
||||
ip_cache_item *ipcacheFind(ip_cache *ipcache, const struct in_addr *a4, const struct in6_addr *a6, const char *iface);
|
||||
void ipcachePurgeRateLimited(ip_cache *ipcache, time_t lifetime);
|
||||
void ipcacheDestroy(ip_cache *ipcache);
|
||||
void ipcachePrint(ip_cache *ipcache);
|
||||
|
||||
@@ -30,7 +30,7 @@ static bool FindNLD(const uint8_t *dom, size_t dlen, int level, const uint8_t **
|
||||
}
|
||||
|
||||
static const char *l7proto_name[] = {
|
||||
"all","unknown","known","http","tls","dtls","quic","wireguard","dht","discord","stun","xmpp","dns","mtproto"
|
||||
"all","unknown","known","http","tls","dtls","quic","wireguard","dht","discord","stun","xmpp","dns","mtproto","bt","utp_bt"
|
||||
};
|
||||
const char *l7proto_str(t_l7proto l7)
|
||||
{
|
||||
@@ -44,7 +44,7 @@ t_l7proto l7proto_from_name(const char *name)
|
||||
}
|
||||
bool l7_proto_match(t_l7proto l7proto, uint64_t filter_l7)
|
||||
{
|
||||
return filter_l7==L7_ALL || (filter_l7 & (1<<l7proto)) || (filter_l7 & (1<<L7_KNOWN)) && l7proto>L7_KNOWN && l7proto<L7_LAST;
|
||||
return filter_l7==L7_ALL || (filter_l7 & (1ULL<<l7proto)) || (filter_l7 & (1ULL<<L7_KNOWN)) && l7proto>L7_KNOWN && l7proto<L7_LAST;
|
||||
}
|
||||
|
||||
static const char *l7payload_name[] = {
|
||||
@@ -58,7 +58,9 @@ static const char *l7payload_name[] = {
|
||||
"dht","discord_ip_discovery","stun",
|
||||
"xmpp_stream", "xmpp_starttls", "xmpp_proceed", "xmpp_features",
|
||||
"dns_query", "dns_response",
|
||||
"mtproto_initial"};
|
||||
"mtproto_initial",
|
||||
"bt_handshake", "utp_bt_handshake"
|
||||
};
|
||||
t_l7payload l7payload_from_name(const char *name)
|
||||
{
|
||||
int idx = str_index(l7payload_name,sizeof(l7payload_name)/sizeof(*l7payload_name),name);
|
||||
@@ -71,7 +73,7 @@ const char *l7payload_str(t_l7payload l7)
|
||||
}
|
||||
bool l7_payload_match(t_l7payload l7payload, uint64_t filter_l7p)
|
||||
{
|
||||
return filter_l7p==L7P_ALL || (filter_l7p & (1<<l7payload)) || (filter_l7p & (1<<L7P_KNOWN)) && l7payload>L7P_KNOWN && l7payload<L7P_LAST;
|
||||
return filter_l7p==L7P_ALL || (filter_l7p & (1ULL<<l7payload)) || (filter_l7p & (1ULL<<L7P_KNOWN)) && l7payload>L7P_KNOWN && l7payload<L7P_LAST;
|
||||
}
|
||||
bool l7_payload_str_list(uint64_t l7p, char *buf, size_t size)
|
||||
{
|
||||
@@ -89,7 +91,7 @@ bool l7_payload_str_list(uint64_t l7p, char *buf, size_t size)
|
||||
}
|
||||
for(pl=0, p=buf, e=p+size, *buf=0 ; pl<L7P_LAST ; pl++)
|
||||
{
|
||||
if (l7p & (1<<pl))
|
||||
if (l7p & (1ULL<<pl))
|
||||
{
|
||||
pstr = l7payload_str(pl);
|
||||
lstr = strlen(pstr);
|
||||
@@ -413,7 +415,7 @@ ssize_t HttpPos(t_marker posmarker, int16_t pos, const uint8_t *data, size_t sz)
|
||||
if (*method=='\n' || *method=='\r') method++;
|
||||
if (*method=='\n' || *method=='\r') method++;
|
||||
// max length is PROPPATCH
|
||||
for (p=method,i=0;i<9;i++) if (*p>='A' && *p<='Z') p++;
|
||||
for (p=method,i=0; i<9 && *p>='A' && *p<='Z'; i++,p++);
|
||||
if (i<3 || *p!=' ') break;
|
||||
return CheckPos(sz,method-data+pos);
|
||||
case PM_HOST:
|
||||
@@ -444,6 +446,7 @@ const char *TLSVersionStr(uint16_t tlsver)
|
||||
{
|
||||
switch(tlsver)
|
||||
{
|
||||
case 0x0300: return "SSL 3.0";
|
||||
case 0x0301: return "TLS 1.0";
|
||||
case 0x0302: return "TLS 1.1";
|
||||
case 0x0303: return "TLS 1.2";
|
||||
@@ -1348,6 +1351,7 @@ bool IsQUICInitial(const uint8_t *data, size_t len)
|
||||
offset += 1 + data[offset];
|
||||
|
||||
// token length
|
||||
if (offset>=len || (offset + tvb_get_size(data[offset])) > len) return false;
|
||||
offset += tvb_get_varint(data + offset, &sz);
|
||||
offset += sz;
|
||||
if (offset >= len) return false;
|
||||
@@ -1484,3 +1488,14 @@ bool IsDTLSServerHello(const uint8_t *data, size_t len)
|
||||
{
|
||||
return IsDTLS(data,len) && data[0]==0x16 && data[13]==2;
|
||||
}
|
||||
|
||||
bool IsBTHandshake(const uint8_t *data, size_t len)
|
||||
{
|
||||
// len, pstrlen, reserved, sha1, peer id
|
||||
return len>=(1+19+8+20+20) && !memcmp(data,"\x13" "BitTorrent protocol",20);
|
||||
}
|
||||
bool IsUTP_BTHandshake(const uint8_t *data, size_t len)
|
||||
{
|
||||
// len, pstrlen, reserved, sha1, peer id
|
||||
return len>=(20+1+19+8+20+20) && data[0]==0x01 && !memcmp(data+20,"\x13" "BitTorrent protocol",20);;
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ typedef enum {
|
||||
L7_XMPP,
|
||||
L7_DNS,
|
||||
L7_MTPROTO,
|
||||
L7_BT,
|
||||
L7_UTP_BT,
|
||||
L7_LAST, L7_INVALID=L7_LAST, L7_NONE=L7_LAST
|
||||
} t_l7proto;
|
||||
const char *l7proto_str(t_l7proto l7);
|
||||
@@ -56,6 +58,8 @@ typedef enum {
|
||||
L7P_DNS_QUERY,
|
||||
L7P_DNS_RESPONSE,
|
||||
L7P_MTPROTO_INITIAL,
|
||||
L7P_BT_HANDSHAKE,
|
||||
L7P_UTP_BT_HANDSHAKE,
|
||||
L7P_LAST, L7P_INVALID=L7P_LAST, L7P_NONE=L7P_LAST
|
||||
} t_l7payload;
|
||||
t_l7payload l7payload_from_name(const char *name);
|
||||
@@ -160,7 +164,8 @@ bool IsMTProto(const uint8_t *data, size_t len);
|
||||
bool IsDTLS(const uint8_t *data, size_t len);
|
||||
bool IsDTLSClientHello(const uint8_t *data, size_t len);
|
||||
bool IsDTLSServerHello(const uint8_t *data, size_t len);
|
||||
|
||||
bool IsBTHandshake(const uint8_t *data, size_t len);
|
||||
bool IsUTP_BTHandshake(const uint8_t *data, size_t len);
|
||||
|
||||
#define QUIC_MAX_CID_LENGTH 20
|
||||
typedef struct quic_cid {
|
||||
|
||||
@@ -210,10 +210,10 @@ int getmaxcap(void)
|
||||
}
|
||||
bool dropcaps(void)
|
||||
{
|
||||
uint64_t caps = (1<<CAP_NET_ADMIN)|(1<<CAP_NET_RAW);
|
||||
uint64_t caps = (1ULL<<CAP_NET_ADMIN)|(1ULL<<CAP_NET_RAW);
|
||||
int maxcap = getmaxcap();
|
||||
|
||||
if (setpcap(caps|(1<<CAP_SETPCAP)))
|
||||
if (setpcap(caps|(1ULL<<CAP_SETPCAP)))
|
||||
{
|
||||
for (int cap = 0; cap <= maxcap; cap++)
|
||||
{
|
||||
@@ -249,7 +249,7 @@ bool can_drop_root(void)
|
||||
{
|
||||
#ifdef __linux__
|
||||
// has some caps
|
||||
return checkpcap((1<<CAP_SETUID)|(1<<CAP_SETGID));
|
||||
return checkpcap((1ULL<<CAP_SETUID)|(1ULL<<CAP_SETGID));
|
||||
#else
|
||||
// effective root
|
||||
return !geteuid();
|
||||
|
||||
Reference in New Issue
Block a user