Showing preview only (1,943K chars total). Download the full file or copy to clipboard to get everything.
Repository: bol-van/zapret
Branch: master
Commit: 363fbe6943b1
Files: 235
Total size: 1.8 MB
Directory structure:
gitextract_d8cviuz8/
├── .gitattributes
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── config.yml
│ │ └── issue-warning.md
│ └── workflows/
│ ├── build.yml
│ └── libnetfilter_queue-android.patch
├── .gitignore
├── Makefile
├── blockcheck.sh
├── common/
│ ├── base.sh
│ ├── custom.sh
│ ├── dialog.sh
│ ├── elevate.sh
│ ├── fwtype.sh
│ ├── installer.sh
│ ├── ipt.sh
│ ├── linux_daemons.sh
│ ├── linux_fw.sh
│ ├── linux_iphelper.sh
│ ├── list.sh
│ ├── nft.sh
│ ├── pf.sh
│ └── virt.sh
├── config.default
├── docs/
│ ├── LICENSE.txt
│ ├── bsd.en.md
│ ├── bsd.md
│ ├── bsdfw.txt
│ ├── changes.txt
│ ├── compile/
│ │ ├── build_howto_openwrt.txt
│ │ ├── build_howto_unix.txt
│ │ ├── build_howto_windows.txt
│ │ └── openwrt/
│ │ └── package/
│ │ └── zapret/
│ │ ├── ip2net/
│ │ │ ├── Makefile
│ │ │ └── readme.txt
│ │ ├── mdig/
│ │ │ ├── Makefile
│ │ │ └── readme.txt
│ │ ├── nfqws/
│ │ │ ├── Makefile
│ │ │ └── readme.txt
│ │ └── tpws/
│ │ ├── Makefile
│ │ └── readme.txt
│ ├── iptables.txt
│ ├── nftables.txt
│ ├── nftables_notes.txt
│ ├── quick_start.md
│ ├── quick_start_windows.md
│ ├── readme.en.md
│ ├── readme.md
│ ├── redsocks.txt
│ ├── windows.en.md
│ ├── windows.md
│ └── wireguard_iproute_openwrt.txt
├── files/
│ └── huawei/
│ └── E8372/
│ ├── run-zapret-hostlist
│ ├── run-zapret-ip
│ ├── unfuck_nfqueue.ko
│ ├── unzapret
│ ├── unzapret-ip
│ ├── zapret
│ └── zapret-ip
├── init.d/
│ ├── custom.d.examples.linux/
│ │ ├── 10-keenetic-udp-fix
│ │ ├── 20-fw-extra
│ │ ├── 50-dht4all
│ │ ├── 50-discord-media
│ │ ├── 50-nfqws-ipset
│ │ ├── 50-quic4all
│ │ ├── 50-stun4all
│ │ ├── 50-tpws-ipset
│ │ └── 50-wg4all
│ ├── macos/
│ │ ├── custom.d/
│ │ │ └── .keep
│ │ ├── custom.d.examples/
│ │ │ └── 50-extra-tpws
│ │ ├── functions
│ │ ├── zapret
│ │ └── zapret.plist
│ ├── openrc/
│ │ └── zapret
│ ├── openwrt/
│ │ ├── 90-zapret
│ │ ├── custom.d/
│ │ │ └── .keep
│ │ ├── firewall.zapret
│ │ ├── functions
│ │ └── zapret
│ ├── openwrt-minimal/
│ │ ├── readme.txt
│ │ └── tpws/
│ │ └── etc/
│ │ ├── config/
│ │ │ └── tpws
│ │ ├── firewall.user
│ │ ├── init.d/
│ │ │ └── tpws
│ │ └── nftables.d/
│ │ └── 90-tpws.nft
│ ├── pfsense/
│ │ └── zapret.sh
│ ├── runit/
│ │ └── zapret/
│ │ ├── finish
│ │ └── run
│ ├── s6/
│ │ └── zapret/
│ │ ├── down
│ │ ├── type
│ │ └── up
│ ├── systemd/
│ │ ├── nfqws@.service
│ │ ├── tpws@.service
│ │ ├── zapret-list-update.service
│ │ ├── zapret-list-update.timer
│ │ └── zapret.service
│ ├── sysv/
│ │ ├── custom.d/
│ │ │ └── .keep
│ │ ├── functions
│ │ └── zapret
│ └── windivert.filter.examples/
│ ├── README.txt
│ ├── windivert_part.discord_media.txt
│ ├── windivert_part.quic_initial_ietf.txt
│ ├── windivert_part.stun.txt
│ └── windivert_part.wireguard.txt
├── install_bin.sh
├── install_easy.sh
├── install_prereq.sh
├── ip2net/
│ ├── Makefile
│ ├── ip2net.c
│ ├── qsort.c
│ └── qsort.h
├── ipset/
│ ├── antifilter.helper
│ ├── clear_lists.sh
│ ├── create_ipset.sh
│ ├── def.sh
│ ├── get_antifilter_allyouneed.sh
│ ├── get_antifilter_ip.sh
│ ├── get_antifilter_ipresolve.sh
│ ├── get_antifilter_ipsmart.sh
│ ├── get_antifilter_ipsum.sh
│ ├── get_antizapret_domains.sh
│ ├── get_config.sh
│ ├── get_exclude.sh
│ ├── get_ipban.sh
│ ├── get_reestr_preresolved.sh
│ ├── get_reestr_preresolved_smart.sh
│ ├── get_reestr_resolvable_domains.sh
│ ├── get_refilter_domains.sh
│ ├── get_refilter_ipsum.sh
│ ├── get_user.sh
│ └── zapret-hosts-user-exclude.txt.default
├── mdig/
│ ├── Makefile
│ └── mdig.c
├── nfq/
│ ├── BSDmakefile
│ ├── Makefile
│ ├── checksum.c
│ ├── checksum.h
│ ├── conntrack.c
│ ├── conntrack.h
│ ├── crypto/
│ │ ├── aes-gcm.c
│ │ ├── aes-gcm.h
│ │ ├── aes.c
│ │ ├── aes.h
│ │ ├── gcm.c
│ │ ├── gcm.h
│ │ ├── hkdf.c
│ │ ├── hmac.c
│ │ ├── sha-private.h
│ │ ├── sha.h
│ │ ├── sha224-256.c
│ │ └── usha.c
│ ├── darkmagic.c
│ ├── darkmagic.h
│ ├── desync.c
│ ├── desync.h
│ ├── gzip.c
│ ├── gzip.h
│ ├── helpers.c
│ ├── helpers.h
│ ├── hostlist.c
│ ├── hostlist.h
│ ├── ipset.c
│ ├── ipset.h
│ ├── kavl.h
│ ├── nfqws.c
│ ├── nfqws.h
│ ├── packet_queue.c
│ ├── packet_queue.h
│ ├── params.c
│ ├── params.h
│ ├── pools.c
│ ├── pools.h
│ ├── protocol.c
│ ├── protocol.h
│ ├── sec.c
│ ├── sec.h
│ ├── uthash.h
│ ├── win.c
│ ├── win.h
│ └── windows/
│ ├── res/
│ │ ├── 32/
│ │ │ ├── winicon.o
│ │ │ └── winmanifest.o
│ │ └── 64/
│ │ ├── winicon.o
│ │ └── winmanifest.o
│ └── windivert/
│ ├── libwindivert32.a
│ ├── libwindivert64.a
│ └── windivert.h
├── tmp/
│ └── .keep
├── tpws/
│ ├── BSDmakefile
│ ├── Makefile
│ ├── andr/
│ │ ├── _musl_license.txt
│ │ ├── getifaddrs.c
│ │ ├── ifaddrs.h
│ │ ├── netlink.c
│ │ └── netlink.h
│ ├── epoll-shim/
│ │ ├── include/
│ │ │ └── sys/
│ │ │ └── epoll.h
│ │ └── src/
│ │ ├── epoll.c
│ │ ├── epoll_shim_ctx.c
│ │ ├── epoll_shim_ctx.h
│ │ ├── epollfd_ctx.c
│ │ ├── epollfd_ctx.h
│ │ ├── eventfd_ctx.h
│ │ ├── fix.c
│ │ ├── fix.h
│ │ ├── signalfd_ctx.h
│ │ └── timerfd_ctx.h
│ ├── gzip.c
│ ├── gzip.h
│ ├── helpers.c
│ ├── helpers.h
│ ├── hostlist.c
│ ├── hostlist.h
│ ├── ipset.c
│ ├── ipset.h
│ ├── kavl.h
│ ├── linux_compat.h
│ ├── macos/
│ │ ├── net/
│ │ │ └── pfvar.h
│ │ └── sys/
│ │ └── tree.h
│ ├── params.c
│ ├── params.h
│ ├── pools.c
│ ├── pools.h
│ ├── protocol.c
│ ├── protocol.h
│ ├── redirect.c
│ ├── redirect.h
│ ├── resolver.c
│ ├── resolver.h
│ ├── sec.c
│ ├── sec.h
│ ├── socks.h
│ ├── tamper.c
│ ├── tamper.h
│ ├── tpws.c
│ ├── tpws.h
│ ├── tpws_conn.c
│ ├── tpws_conn.h
│ └── uthash.h
└── uninstall_easy.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
*.cmd eol=crlf
*.bat eol=crlf
init.d/windivert.filter.examples/** eol=crlf
files/** binary
================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
================================================
FILE: .github/ISSUE_TEMPLATE/issue-warning.md
================================================
---
name: bugs
about: do not write lame questions
title: ''
labels: ''
assignees: ''
---
Issues - это место для обращений к разработчику.
Discussions - место для обсуждения вопросов между пользователями.
Не тратьте время разработчика на ерунду. Вам не будут здесь объяснять как скопировать, что "писать в", почему сразу же закрывается окно, почему не открывается сайт или госуслуги. Здесь не место обсуждению любых шаманств, т.е. манипуляций без понимания, в стиле 4pda.
Пишите только конкретные проблемы на техническом уровне в оригинальном zapret (не в сборках), которые вы заметили, и которые являются или могут являться багами в софте.
Или если вы считаете, что ваше обращение обосновано, технически грамотно и по адресу.
Все, что будет нарушать эти критерии, может быть молча удалено, закрыто или перенесено в дискуссии на усмотрение разработчика.
Если сомневаетесь - пишите лучше сразу в дискуссии.
Прочитайте для начала docs/quick_start.md или docs/quick_start_windows.md.
Там объясняется для кого этот софт, какие требуются знания, почему это не простая волшебная таблетка.
Вирусов здесь нет. У вас либо чья-то сборка, либо ваш антивирус давно пора отправить на покой. Антивирусы в основном жалуются на upx и windivert, которые убраны НЕ будут. upx - это паковщик для сокращения требуемого места на openwrt, windivert - замена iptables для windows, потенциальный инструмент хакера или компонент зловредной программы, но сам по себе вирусом не является. Не согласны - удаляйте софт. За агрессивные наезды "почему автор распространяет вирусы" молча схватите бан.
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.
================================================
FILE: .github/workflows/build.yml
================================================
name: build
run-name: ${{ startsWith(github.ref, 'refs/tags/v') && format('Release {0}', github.ref_name) || null }}
on:
workflow_dispatch:
push:
tags:
- v[0-9]+*
# branches:
# - master
# paths:
# - 'ip2net/**'
# - 'mdig/**'
# - 'nfq/**'
# - 'tpws/**'
jobs:
build-linux:
name: Linux ${{ matrix.arch }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- arch: arm64
tool: aarch64-unknown-linux-musl
- arch: arm
tool: armv6-unknown-linux-musleabi
- arch: mips64
tool: mips64-unknown-linux-musl
- arch: mipselsf
tool: mipsel-unknown-linux-muslsf
- arch: mipssf
tool: mips-unknown-linux-muslsf
- arch: ppc
tool: powerpc-unknown-linux-musl
- arch: x86
tool: i586-unknown-linux-musl
- arch: x86_64
tool: x86_64-unknown-linux-musl
- arch: lexra
tool: mips-linux
dir: rsdk-4.6.4-5281-EB-3.10-0.9.33-m32ub-20141001
env:
CFLAGS: '-march=5281'
LDFLAGS: '-lgcc_eh'
repo: 'bol-van/build'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: zapret
- name: Set up build tools
env:
ARCH: ${{ matrix.arch }}
TOOL: ${{ matrix.tool }}
REPO: ${{ matrix.arch == 'lexra' && matrix.repo || 'bol-van/musl-cross' }}
DIR: ${{ matrix.arch == 'lexra' && matrix.dir || matrix.tool }}
run: |
if [[ "$ARCH" == lexra ]]; then
sudo dpkg --add-architecture i386
sudo apt update -qq
sudo apt install -y libcap-dev libc6:i386 zlib1g:i386
URL=https://github.com/$REPO/raw/refs/heads/master/$DIR.txz
else
sudo apt update -qq
sudo apt install -y libcap-dev
URL=https://github.com/$REPO/releases/download/latest/$TOOL.tar.xz
fi
mkdir -p $HOME/tools
wget -qO- $URL | tar -C $HOME/tools -xJ || exit 1
[[ -d "$HOME/tools/$DIR/bin" ]] && echo "$HOME/tools/$DIR/bin" >> $GITHUB_PATH
- name: Build
env:
ARCH: ${{ matrix.arch }}
TARGET: ${{ matrix.tool }}
CFLAGS: ${{ matrix.env.CFLAGS != '' && matrix.env.CFLAGS || null }}
LDFLAGS: ${{ matrix.env.LDFLAGS != '' && matrix.env.LDFLAGS || null }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
DEPS_DIR=$GITHUB_WORKSPACE/deps
export CC="$TARGET-gcc"
export LD=$TARGET-ld
export AR=$TARGET-ar
export NM=$TARGET-nm
export STRIP=$TARGET-strip
export PKG_CONFIG_PATH=$DEPS_DIR/lib/pkgconfig
export STAGING_DIR=$RUNNER_TEMP
OPTIMIZE=-Oz
case "$ARCH" in
lexra)
OPTIMIZE=-Os
;;
arm)
CPU="-mcpu=arm1176jzf-s -mthumb"
;;
esac
# netfilter libs
wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
wget -qO- https://www.netfilter.org/pub/libmnl/libmnl-1.0.5.tar.bz2 | tar -xj
wget -qO- https://www.netfilter.org/pub/libnetfilter_queue/libnetfilter_queue-1.0.5.tar.bz2 | tar -xj
for i in libmnl libnfnetlink libnetfilter_queue ; do
(
cd $i-*
CFLAGS="$OPTIMIZE $CPU -flto=auto $CFLAGS" \
./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking
make install -j$(nproc) DESTDIR=$DEPS_DIR
)
sed -i "s|^prefix=.*|prefix=$DEPS_DIR|g" $DEPS_DIR/lib/pkgconfig/$i.pc
done
# zlib
gh api repos/madler/zlib/releases/latest --jq '.tag_name' |\
xargs -I{} wget -qO- https://github.com/madler/zlib/archive/refs/tags/{}.tar.gz | tar -xz
(
cd zlib-*
CFLAGS="$OPTIMIZE $CPU -flto=auto $CFLAGS" \
./configure --prefix= --static
make install -j$(nproc) DESTDIR=$DEPS_DIR
)
# headers
# wget https://git.alpinelinux.org/aports/plain/main/bsd-compat-headers/queue.h && \
# wget https://git.kernel.org/pub/scm/libs/libcap/libcap.git/plain/libcap/include/sys/capability.h && \
install -Dm644 -t $DEPS_DIR/include/sys /usr/include/x86_64-linux-gnu/sys/queue.h /usr/include/sys/capability.h
# zapret
OPTIMIZE=$OPTIMIZE \
CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -static-libgcc -static $CPU -I$DEPS_DIR/include $CFLAGS" \
LDFLAGS="-L$DEPS_DIR/lib $LDFLAGS" \
make -C zapret -j$(nproc)
tar -C zapret/binaries/my -cJf zapret-linux-$ARCH.tar.xz .
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: zapret-linux-${{ matrix.arch }}
path: zapret-*.tar.xz
if-no-files-found: error
build-macos:
name: macOS
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build zapret
run: |
export CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }}"
make mac -j$(sysctl -n hw.logicalcpu)
tar -C binaries/my -cJf zapret-mac-x64.tar.xz .
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: zapret-mac-x64
path: zapret-*.tar.xz
if-no-files-found: error
build-freebsd:
name: FreeBSD ${{ matrix.arch }}
runs-on: ubuntu-latest
strategy:
matrix:
include:
- target: x86_64
arch: x86_64
# - target: i386
# arch: x86
container:
image: empterdose/freebsd-cross-build:11.4
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install packages
run: apk add tar xz
- name: Build zapret
env:
TARGET: ${{ matrix.target }}
ARCH: ${{ matrix.arch }}
run: |
export CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }}"
settarget $TARGET-freebsd11 make bsd -j$(nproc)
tar -C binaries/my -cJf zapret-freebsd-$ARCH.tar.xz .
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: zapret-freebsd-${{ matrix.arch }}
path: zapret-*.tar.xz
if-no-files-found: error
build-windows:
name: Windows ${{ matrix.arch }}
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
arch: [ x86_64, x86 ]
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: zapret
- name: Set up MinGW
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.arch == 'x86_64' && 'MINGW64' || 'MINGW32' }}
install: >-
${{ matrix.arch == 'x86_64' && 'mingw-w64-x86_64-toolchain' || 'mingw-w64-i686-toolchain' }}
- name: Build ip2net, mdig
shell: msys2 {0}
run: |
export CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }}"
mkdir -p output
cd zapret
mingw32-make -C ip2net win
mingw32-make -C mdig win
cp -a {ip2net/ip2net,mdig/mdig}.exe ../output
- name: Restore psmisc from cache
id: cache-restore-psmisc
uses: actions/cache/restore@v4
with:
path: ${{ github.workspace }}/psmisc
key: psmisc-${{ matrix.arch }}
- name: Set up Cygwin
env:
PACKAGES: ${{ steps.cache-restore-psmisc.outputs.cache-hit != 'true' && 'cygport gettext-devel libiconv-devel libncurses-devel' || null }}
uses: cygwin/cygwin-install-action@v4
with:
platform: ${{ matrix.arch }}
site: ${{ matrix.arch == 'x86_64' && 'http://ctm.crouchingtigerhiddenfruitbat.org/pub/cygwin/circa/64bit/2024/01/30/231215' || null }}
check-sig: ${{ matrix.arch == 'x86_64' && 'false' || null }}
packages: >-
gcc-core
make
zlib-devel
zip
unzip
wget
${{ env.PACKAGES }}
- name: Build psmisc
if: steps.cache-restore-psmisc.outputs.cache-hit != 'true'
env:
URL: https://mirrors.kernel.org/sourceware/cygwin/x86_64/release/psmisc
shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}'
run: >-
export MAKEFLAGS=-j$(nproc) &&
mkdir -p psmisc && cd psmisc &&
wget -qO- ${URL} | grep -Po 'href=\"\Kpsmisc-(\d+\.)+\d+.+src\.tar\.xz(?=\")' | xargs -I{} wget -O- ${URL}/{} | tar -xJ &&
cd psmisc-*.src &&
echo CYGCONF_ARGS+=\" --disable-dependency-tracking --disable-nls\" >> psmisc.cygport &&
cygport psmisc.cygport prep compile install
- name: Save psmisc to cache
if: steps.cache-restore-psmisc.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ${{ github.workspace }}/psmisc
key: psmisc-${{ matrix.arch }}
- name: Build winws
env:
TARGET: ${{ matrix.arch == 'x86_64' && 'cygwin' || 'cygwin32' }}
shell: C:\cygwin\bin\bash.exe -eo pipefail '{0}'
run: >-
export MAKEFLAGS=-j$(nproc) &&
export CFLAGS="-DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }}" &&
cd zapret &&
make -C nfq ${TARGET} &&
cp -a nfq/winws.exe ../output
- name: Create zip
env:
BITS: ${{ matrix.arch == 'x86_64' && '64' || '32' }}
DIR: ${{ matrix.arch == 'x86_64' && 'x64' || 'x86' }}
shell: C:\cygwin\bin\bash.exe -e '{0}'
run: >-
cp -a -t output psmisc/psmisc-*.src/psmisc-*/inst/usr/bin/killall.exe /usr/bin/cygwin1.dll &&
wget -O WinDivert.zip https://github.com/basil00/WinDivert/releases/download/v2.2.2/WinDivert-2.2.2-A.zip &&
unzip -j WinDivert.zip "*/${DIR}/WinDivert.dll" "*/${DIR}/WinDivert${BITS}.sys" -d output &&
zip zapret-win-${{ matrix.arch }}.zip -j output/*
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: zapret-win-${{ matrix.arch }}
path: zapret-*.zip
if-no-files-found: error
build-android:
name: Android ${{ matrix.abi }}
runs-on: ubuntu-latest
strategy:
matrix:
include:
- abi: armeabi-v7a
target: armv7a-linux-androideabi
- abi: arm64-v8a
target: aarch64-linux-android
- abi: x86
target: i686-linux-android
- abi: x86_64
target: x86_64-linux-android
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: zapret
- name: Build
env:
ABI: ${{ matrix.abi }}
API: 21
TARGET: ${{ matrix.target }}
GH_TOKEN: ${{ github.token }}
run: |
DEPS_DIR=$GITHUB_WORKSPACE/deps
export TOOLCHAIN=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64
export CC="$TOOLCHAIN/bin/clang --target=$TARGET$API"
export AR=$TOOLCHAIN/bin/llvm-ar
export AS=$CC
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
export PKG_CONFIG_PATH=$DEPS_DIR/lib/pkgconfig
case "$ABI" in
armeabi-v7a)
CPU="-mthumb"
;;
arm64-v8a)
PAGESIZE="-Wl,-z,max-page-size=16384"
;;
esac
# netfilter libs
wget -qO- https://www.netfilter.org/pub/libnfnetlink/libnfnetlink-1.0.2.tar.bz2 | tar -xj
wget -qO- https://www.netfilter.org/pub/libmnl/libmnl-1.0.5.tar.bz2 | tar -xj
wget -qO- https://www.netfilter.org/pub/libnetfilter_queue/libnetfilter_queue-1.0.5.tar.bz2 | tar -xj
patch -p1 -d libnetfilter_queue-* -i ../zapret/.github/workflows/libnetfilter_queue-android.patch
for i in libmnl libnfnetlink libnetfilter_queue ; do
(
cd $i-*
CFLAGS="$CPU -Os -flto=auto -Wno-implicit-function-declaration" \
./configure --prefix= --host=$TARGET --enable-static --disable-shared --disable-dependency-tracking
make install -j$(nproc) DESTDIR=$DEPS_DIR
)
sed -i "s|^prefix=.*|prefix=$DEPS_DIR|g" $DEPS_DIR/lib/pkgconfig/$i.pc
done
# zapret
CFLAGS="$CPU -DZAPRET_GH_VER=${{ github.ref_name }} -DZAPRET_GH_HASH=${{ github.sha }} -I$DEPS_DIR/include" \
LDFLAGS="-L$DEPS_DIR/lib $PAGESIZE" \
make -C zapret android -j$(nproc)
# strip unwanted ELF sections to prevent warnings on old Android versions
gh api repos/termux/termux-elf-cleaner/releases/latest --jq '.tag_name' |\
xargs -I{} wget -O elf-cleaner https://github.com/termux/termux-elf-cleaner/releases/download/{}/termux-elf-cleaner
chmod +x elf-cleaner
./elf-cleaner --api-level $API zapret/binaries/my/*
zip zapret-android-$ABI.zip -j zapret/binaries/my/*
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: zapret-android-${{ matrix.abi }}
path: zapret-*.zip
if-no-files-found: error
release:
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
needs: [ build-linux, build-windows, build-macos, build-freebsd, build-android ]
permissions:
contents: write
runs-on: ubuntu-latest
env:
repo_dir: zapret-${{ github.ref_name }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: ${{ env.repo_dir }}
- name: Download artifacts
uses: actions/download-artifact@v4
id: bins
with:
path: ${{ env.repo_dir }}/binaries
pattern: zapret-*
- name: Install upx
uses: crazy-max/ghaction-upx@v3
with:
install-only: true
version: v4.2.4
- name: Prepare binaries
shell: bash
run: |
cd ${{ steps.bins.outputs.download-path }}
run_upx() {
upx --best --lzma $@ || true
}
run_dir() {
for f in $dir/* ; do
# extract binaries
case $f in
*.tar.xz )
tar -C $dir -xvf $f && rm $f
if [[ $dir == *-linux-x86_64 ]]; then
tar -C $dir -czvf $dir/tpws_wsl.tgz tpws
run_upx $dir/*
elif [[ $dir =~ linux ]] && [[ $dir != *-linux-mips64 ]] && [[ $dir != *-linux-lexra ]]; then
run_upx $dir/*
fi
;;
*.zip )
unzip $f -d $dir && rm $f
if [[ $dir =~ win ]]; then
chmod -x $dir/*
fi
;;
esac
done
mv $dir $1
}
for dir in * ; do
if [ -d $dir ]; then
echo "Processing $dir"
case $dir in
*-android-arm64-v8a ) run_dir android-arm64 ;;
*-android-armeabi-v7a ) run_dir android-arm ;;
*-android-x86 ) run_dir android-x86 ;;
*-android-x86_64 ) run_dir android-x86_64 ;;
*-freebsd-x86_64 ) run_dir freebsd-x86_64 ;;
*-linux-arm ) run_dir linux-arm ;;
*-linux-arm64 ) run_dir linux-arm64 ;;
*-linux-mips64 ) run_dir linux-mips64 ;;
*-linux-mipselsf ) run_dir linux-mipsel ;;
*-linux-mipssf ) run_dir linux-mips ;;
*-linux-ppc ) run_dir linux-ppc ;;
*-linux-x86 ) run_dir linux-x86 ;;
*-linux-x86_64 ) run_dir linux-x86_64 ;;
*-linux-lexra ) run_dir linux-lexra ;;
*-mac-x64 ) run_dir mac64 ;;
*-win-x86 ) run_dir windows-x86 ;;
*-win-x86_64 ) run_dir windows-x86_64 ;;
esac
fi
done
ls -lhR
- name: Create release bundles
run: |
rm -rf ${{ env.repo_dir }}/.git*
find ${{ env.repo_dir }}/binaries -type f -exec sha256sum {} \; >sha256sum.txt
tar --owner=0 --group=0 -czf ${{ env.repo_dir }}.tar.gz ${{ env.repo_dir }}
zip -qr ${{ env.repo_dir }}.zip ${{ env.repo_dir }}
(
cd ${{ env.repo_dir }}
rm -rf binaries/{android*,freebsd*,mac*,win*,x86_64/tpws_wsl.tgz} \
init.d/{openrc,macos,pfsense,runit,s6,systemd,windivert.filter.examples} \
tpws nfq ip2net mdig docs files/huawei Makefile
)
tar --owner=0 --group=0 -czf ${{ env.repo_dir }}-openwrt-embedded.tar.gz ${{ env.repo_dir }}
- name: Upload release assets
uses: softprops/action-gh-release@v2
with:
fail_on_unmatched_files: true
prerelease: false
draft: false
body: |
### zapret ${{ github.ref_name }}
files: |
zapret*.tar.gz
zapret*.zip
sha256sum.txt
================================================
FILE: .github/workflows/libnetfilter_queue-android.patch
================================================
--- a/src/extra/pktbuff.c
+++ b/src/extra/pktbuff.c
@@ -14,7 +14,7 @@
#include <string.h> /* for memcpy */
#include <stdbool.h>
-#include <netinet/if_ether.h>
+#include <linux/if_ether.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
--- a/src/nlmsg.c
+++ b/src/nlmsg.c
@@ -21,7 +21,7 @@
#include <linux/netfilter/nfnetlink_queue.h>
-#include <libnetfilter_queue/libnetfilter_queue.h>
+// #include <libnetfilter_queue/libnetfilter_queue.h>
#include "internal.h"
--- a/src/extra/tcp.c
+++ b/src/extra/tcp.c
@@ -139,12 +139,16 @@ void nfq_tcp_compute_checksum_ipv6(struc
* (union is compatible to any of its members)
* This means this part of the code is -fstrict-aliasing safe now.
*/
+#ifndef __ANDROID__
union tcp_word_hdr {
struct tcphdr hdr;
uint32_t words[5];
};
+#endif
+#ifndef tcp_flag_word
#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words[3])
+#endif
/**
* nfq_pkt_snprintf_tcp_hdr - print tcp header into one buffer in a humnan
================================================
FILE: .gitignore
================================================
/config
ip2net/ip2net
mdig/mdig
nfq/dvtws
nfq/nfqws
nfq/winws.exe
nfq/WinDivert*
tpws/tpws
binaries/my/
ipset/zapret-ip*.txt
ipset/zapret-ip*.gz
ipset/zapret-hosts*.txt
ipset/zapret-hosts*.gz
================================================
FILE: Makefile
================================================
DIRS := nfq tpws ip2net mdig
DIRS_MAC := tpws ip2net mdig
TGT := binaries/my
all: clean
@mkdir -p "$(TGT)"; \
for dir in $(DIRS); do \
find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \
$(MAKE) -C "$$dir" || exit; \
for exe in "$$dir/"*; do \
if [ -f "$$exe" ] && [ -x "$$exe" ]; then \
mv -f "$$exe" "${TGT}" ; \
ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \
fi \
done \
done
systemd: clean
@mkdir -p "$(TGT)"; \
for dir in $(DIRS); do \
find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \
$(MAKE) -C "$$dir" systemd || exit; \
for exe in "$$dir/"*; do \
if [ -f "$$exe" ] && [ -x "$$exe" ]; then \
mv -f "$$exe" "${TGT}" ; \
ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \
fi \
done \
done
android: clean
@mkdir -p "$(TGT)"; \
for dir in $(DIRS); do \
find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \
$(MAKE) -C "$$dir" android || exit; \
for exe in "$$dir/"*; do \
if [ -f "$$exe" ] && [ -x "$$exe" ]; then \
mv -f "$$exe" "${TGT}" ; \
ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \
fi \
done \
done
bsd: clean
@mkdir -p "$(TGT)"; \
for dir in $(DIRS); do \
find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \
$(MAKE) -C "$$dir" bsd || exit; \
for exe in "$$dir/"*; do \
if [ -f "$$exe" ] && [ -x "$$exe" ]; then \
mv -f "$$exe" "${TGT}" ; \
ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \
fi \
done \
done
mac: clean
@mkdir -p "$(TGT)"; \
for dir in $(DIRS_MAC); do \
find "$$dir" -type f \( -name "*.c" -o -name "*.h" -o -name "*akefile" \) -exec chmod -x {} \; ; \
$(MAKE) -C "$$dir" mac || exit; \
for exe in "$$dir/"*; do \
if [ -f "$$exe" ] && [ -x "$$exe" ]; then \
mv -f "$$exe" "${TGT}" ; \
ln -fs "../${TGT}/$$(basename "$$exe")" "$$exe" ; \
fi \
done \
done
clean:
@[ -d "$(TGT)" ] && rm -rf "$(TGT)" ; \
for dir in $(DIRS); do \
$(MAKE) -C "$$dir" clean; \
done
================================================
FILE: blockcheck.sh
================================================
#!/bin/sh
EXEDIR="$(dirname "$0")"
EXEDIR="$(cd "$EXEDIR"; pwd)"
ZAPRET_BASE=${ZAPRET_BASE:-"$EXEDIR"}
ZAPRET_RW=${ZAPRET_RW:-"$ZAPRET_BASE"}
ZAPRET_CONFIG=${ZAPRET_CONFIG:-"$ZAPRET_RW/config"}
ZAPRET_CONFIG_DEFAULT="$ZAPRET_BASE/config.default"
CURL=${CURL:-curl}
[ -f "$ZAPRET_CONFIG" ] || {
[ -f "$ZAPRET_CONFIG_DEFAULT" ] && {
ZAPRET_CONFIG_DIR="$(dirname "$ZAPRET_CONFIG")"
[ -d "$ZAPRET_CONFIG_DIR" ] || mkdir -p "$ZAPRET_CONFIG_DIR"
cp "$ZAPRET_CONFIG_DEFAULT" "$ZAPRET_CONFIG"
}
}
[ -f "$ZAPRET_CONFIG" ] && . "$ZAPRET_CONFIG"
. "$ZAPRET_BASE/common/base.sh"
. "$ZAPRET_BASE/common/dialog.sh"
. "$ZAPRET_BASE/common/elevate.sh"
. "$ZAPRET_BASE/common/fwtype.sh"
. "$ZAPRET_BASE/common/virt.sh"
DOMAINS_DEFAULT=${DOMAINS_DEFAULT:-rutracker.org}
QNUM=${QNUM:-59780}
SOCKS_PORT=${SOCKS_PORT:-1993}
TPWS_UID=${TPWS_UID:-1}
TPWS_GID=${TPWS_GID:-3003}
NFQWS=${NFQWS:-${ZAPRET_BASE}/nfq/nfqws}
DVTWS=${DVTWS:-${ZAPRET_BASE}/nfq/dvtws}
WINWS=${WINWS:-${ZAPRET_BASE}/nfq/winws}
TPWS=${TPWS:-${ZAPRET_BASE}/tpws/tpws}
MDIG=${MDIG:-${ZAPRET_BASE}/mdig/mdig}
DESYNC_MARK=0x10000000
IPFW_RULE_NUM=${IPFW_RULE_NUM:-1}
IPFW_DIVERT_PORT=${IPFW_DIVERT_PORT:-59780}
CURL_MAX_TIME=${CURL_MAX_TIME:-2}
CURL_MAX_TIME_QUIC=${CURL_MAX_TIME_QUIC:-$CURL_MAX_TIME}
CURL_MAX_TIME_DOH=${CURL_MAX_TIME_DOH:-2}
MIN_TTL=${MIN_TTL:-1}
MAX_TTL=${MAX_TTL:-12}
MIN_AUTOTTL_DELTA=${MIN_AUTOTTL_DELTA:-1}
MAX_AUTOTTL_DELTA=${MAX_AUTOTTL_DELTA:-5}
USER_AGENT=${USER_AGENT:-Mozilla}
HTTP_PORT=${HTTP_PORT:-80}
HTTPS_PORT=${HTTPS_PORT:-443}
QUIC_PORT=${QUIC_PORT:-443}
UNBLOCKED_DOM=${UNBLOCKED_DOM:-iana.org}
PARALLEL_OUT=/tmp/zapret_parallel
SIM_SUCCESS_RATE=${SIM_SUCCESS_RATE:-10}
HDRTEMP=/tmp/zapret-hdr
NFT_TABLE=blockcheck
DNSCHECK_DNS=${DNSCHECK_DNS:-8.8.8.8 1.1.1.1 77.88.8.1}
DNSCHECK_DOM=${DNSCHECK_DOM:-pornhub.com ej.ru rutracker.org www.torproject.org bbc.com}
DOH_SERVERS=${DOH_SERVERS:-"https://cloudflare-dns.com/dns-query https://dns.google/dns-query https://dns.quad9.net/dns-query https://dns.adguard.com/dns-query https://common.dot.dns.yandex.net/dns-query"}
DNSCHECK_DIG1=/tmp/dig1.txt
DNSCHECK_DIG2=/tmp/dig2.txt
DNSCHECK_DIGS=/tmp/digs.txt
IPSET_FILE=/tmp/blockcheck_ipset.txt
unset PF_STATUS
PF_RULES_SAVE=/tmp/pf-zapret-save.conf
unset ALL_PROXY
killwait()
{
# $1 - signal (-9, -2, ...)
# $2 - pid
kill $1 $2
# suppress job kill message
wait $2 2>/dev/null
}
exitp()
{
local A
[ "$BATCH" = 1 ] || {
echo
echo press enter to continue
read A
}
exit $1
}
pf_is_avail()
{
[ -c /dev/pf ]
}
pf_status()
{
pfctl -qsi | sed -nre "s/^Status: ([^ ]+).*$/\1/p"
}
pf_is_enabled()
{
[ "$(pf_status)" = Enabled ]
}
pf_save()
{
PF_STATUS=0
pf_is_enabled && PF_STATUS=1
[ "$UNAME" = "OpenBSD" ] && pfctl -sr >"$PF_RULES_SAVE"
}
pf_restore()
{
[ -n "$PF_STATUS" ] || return
case "$UNAME" in
OpenBSD)
if [ -f "$PF_RULES_SAVE" ]; then
pfctl -qf "$PF_RULES_SAVE"
else
echo | pfctl -qf -
fi
;;
Darwin)
# it's not possible to save all rules in the right order. hard to reorder. if not ordered pf will refuse to load conf.
pfctl -qf /etc/pf.conf
;;
esac
if [ "$PF_STATUS" = 1 ]; then
pfctl -qe
else
pfctl -qd
fi
}
pf_clean()
{
rm -f "$PF_RULES_SAVE"
}
opf_dvtws_anchor()
{
# $1 - tcp/udp
# $2 - port
# $3 - ip list
local iplist family=inet
[ "$IPV" = 6 ] && family=inet6
make_comma_list iplist "$3"
echo "set reassemble no"
[ "$1" = tcp ] && echo "pass in quick $family proto $1 from {$iplist} port $2 flags SA/SA divert-packet port $IPFW_DIVERT_PORT no state"
echo "pass in quick $family proto $1 from {$iplist} port $2 no state"
echo "pass out quick $family proto $1 to {$iplist} port $2 divert-packet port $IPFW_DIVERT_PORT no state"
echo "pass"
}
opf_prepare_dvtws()
{
# $1 - tcp/udp
# $2 - port
# $3 - ip list
opf_dvtws_anchor $1 $2 "$3" | pfctl -qf -
pfctl -qe
}
cleanup()
{
case "$UNAME" in
OpenBSD)
pf_clean
;;
esac
}
IPT()
{
$IPTABLES -C "$@" >/dev/null 2>/dev/null || $IPTABLES -I "$@"
}
IPT_DEL()
{
$IPTABLES -C "$@" >/dev/null 2>/dev/null && $IPTABLES -D "$@"
}
IPT_ADD_DEL()
{
on_off_function IPT IPT_DEL "$@"
}
IPFW_ADD()
{
ipfw -qf add $IPFW_RULE_NUM "$@"
}
IPFW_DEL()
{
ipfw -qf delete $IPFW_RULE_NUM 2>/dev/null
}
ipt6_has_raw()
{
ip6tables -nL -t raw >/dev/null 2>/dev/null
}
ipt6_has_frag()
{
ip6tables -A OUTPUT -m frag 2>/dev/null || return 1
ip6tables -D OUTPUT -m frag 2>/dev/null
}
ipt_has_nfq()
{
# cannot just check /proc/net/ip_tables_targets because of iptables-nft or modules not loaded yet
iptables -A OUTPUT -t mangle -p 255 -j NFQUEUE --queue-num $QNUM --queue-bypass 2>/dev/null || return 1
iptables -D OUTPUT -t mangle -p 255 -j NFQUEUE --queue-num $QNUM --queue-bypass 2>/dev/null
return 0
}
nft_has_nfq()
{
local res=1
nft delete table ${NFT_TABLE}_test 2>/dev/null
nft add table ${NFT_TABLE}_test 2>/dev/null && {
nft add chain ${NFT_TABLE}_test test
nft add rule ${NFT_TABLE}_test test queue num $QNUM bypass 2>/dev/null && res=0
nft delete table ${NFT_TABLE}_test
}
return $res
}
doh_resolve()
{
# $1 - ip version 4/6
# $2 - hostname
# $3 - doh server URL. use $DOH_SERVER if empty
"$MDIG" --family=$1 --dns-make-query=$2 | "$CURL" --max-time $CURL_MAX_TIME_DOH -s --data-binary @- -H "Content-Type: application/dns-message" "${3:-$DOH_SERVER}" | "$MDIG" --dns-parse-query
}
doh_find_working()
{
local doh
[ -n "$DOH_SERVER" ] && return 0
echo "* searching working DoH server"
DOH_SERVER=
for doh in $DOH_SERVERS; do
echo -n "$doh : "
if doh_resolve 4 iana.org $doh >/dev/null 2>/dev/null; then
echo OK
DOH_SERVER="$doh"
return 0
else
echo FAIL
fi
done
echo all DoH servers failed
return 1
}
mdig_vars()
{
# $1 - ip version 4/6
# $2 - hostname
hostvar=$(echo $2 | sed -e 's/[\./?&#@%*$^:~=!()+-]/_/g')
cachevar=DNSCACHE_${hostvar}_$1
countvar=${cachevar}_COUNT
eval count=\$${countvar}
}
mdig_cache()
{
# $1 - ip version 4/6
# $2 - hostname
local hostvar cachevar countvar count ip ips
mdig_vars "$@"
[ -n "$count" ] || {
# windows version of mdig outputs 0D0A line ending. remove 0D.
if [ "$SECURE_DNS" = 1 ]; then
ips="$(echo $2 | doh_resolve $1 $2 | tr -d '\r' | xargs)"
else
ips="$(echo $2 | "$MDIG" --family=$1 | tr -d '\r' | xargs)"
fi
[ -n "$ips" ] || return 1
count=0
for ip in $ips; do
eval ${cachevar}_$count=$ip
count=$(($count+1))
done
eval $countvar=$count
}
return 0
}
mdig_resolve()
{
# $1 - ip version 4/6
# $2 - var to receive result
# $3 - hostname, possibly with uri : rutracker.org/xxx/xxxx
local hostvar cachevar countvar count n sdom
split_by_separator "$3" / sdom
mdig_vars "$1" "$sdom"
if [ -n "$count" ]; then
n=$(random 0 $(($count-1)))
eval $2=\$${cachevar}_$n
return 0
else
mdig_cache "$1" "$sdom" && mdig_resolve "$1" "$2" "$sdom"
fi
}
mdig_resolve_all()
{
# $1 - ip version 4/6
# $2 - var to receive result
# $3 - hostname
local hostvar cachevar countvar count ip__ ips__ n sdom
split_by_separator "$3" / sdom
mdig_vars "$1" "$sdom"
if [ -n "$count" ]; then
n=0
while [ "$n" -le $count ]; do
eval ip__=\$${cachevar}_$n
if [ -n "$ips__" ]; then
ips__="$ips__ $ip__"
else
ips__="$ip__"
fi
n=$(($n + 1))
done
eval $2="\$ips__"
return 0
else
mdig_cache "$1" "$sdom" && mdig_resolve_all "$1" "$2" "$sdom"
fi
}
netcat_setup()
{
[ -n "$NCAT" ] || {
if exists ncat; then
NCAT=ncat
elif exists nc; then
# busybox netcat does not support any required options
is_linked_to_busybox nc && return 1
NCAT=nc
else
return 1
fi
}
return 0
}
netcat_test()
{
# $1 - ip
# $2 - port
local cmd
netcat_setup && {
cmd="$NCAT -z -w 2 $1 $2"
echo $cmd
$cmd 2>&1
}
}
tpws_can_fix_seg()
{
# fix-seg requires kernel 4.6+
"$TPWS" --port 1 --dry-run --fix-seg >/dev/null 2>/dev/null
}
check_system()
{
echo \* checking system
UNAME=$(uname)
SUBSYS=
FIX_SEG=
local s
# can be passed FWTYPE=iptables to override default nftables preference
case "$UNAME" in
Linux)
PKTWS="$NFQWS"
PKTWSD=nfqws
if [ -x "$TPWS" ] ; then
if tpws_can_fix_seg ; then
echo tpws supports --fix-seg on this system
FIX_SEG='--fix-seg'
else
echo tpws does not support --fix-seg on this system
fi
fi
linux_fwtype
[ "$FWTYPE" = iptables -o "$FWTYPE" = nftables ] || {
echo firewall type $FWTYPE not supported in $UNAME
exitp 5
}
;;
FreeBSD)
PKTWS="$DVTWS"
PKTWSD=dvtws
FWTYPE=ipfw
[ -f /etc/platform ] && read SUBSYS </etc/platform
;;
OpenBSD)
PKTWS="$DVTWS"
PKTWSD=dvtws
FWTYPE=opf
;;
Darwin)
PKTWS="$DVTWS"
PKTWSD=dvtws
FWTYPE=mpf
;;
CYGWIN*)
UNAME=CYGWIN
PKTWS="$WINWS"
PKTWSD=winws
FWTYPE=windivert
# ts fooling requires timestamps. they are disabled by default in windows.
echo enabling tcp timestamps
netsh interface tcp set global timestamps=enabled >/dev/null
;;
*)
echo $UNAME not supported
exitp 5
esac
echo $UNAME${SUBSYS:+/$SUBSYS} detected
echo -n 'kernel: '
if [ -f "/proc/version" ]; then
cat /proc/version
else
uname -a
fi
[ -f /etc/os-release ] && {
. /etc/os-release
[ -n "$PRETTY_NAME" ] && echo "distro: $PRETTY_NAME"
[ -n "$OPENWRT_RELEASE" ] && echo "openwrt release: $OPENWRT_RELEASE"
[ -n "$OPENWRT_BOARD" ] && echo "openwrt board: $OPENWRT_BOARD"
[ -n "$OPENWRT_ARCH" ] && echo "openwrt arch: $OPENWRT_ARCH"
}
echo firewall type is $FWTYPE
echo CURL=$CURL
"$CURL" --version
}
zp_already_running()
{
case "$UNAME" in
CYGWIN)
win_process_exists $PKTWSD || win_process_exists goodbyedpi
;;
*)
process_exists $PKTWSD || process_exists tpws
esac
}
check_already()
{
echo \* checking already running DPI bypass processes
if zp_already_running; then
echo "!!! WARNING. some dpi bypass processes already running !!!"
echo "!!! WARNING. blockcheck requires all DPI bypass methods disabled !!!"
echo "!!! WARNING. pls stop all dpi bypass instances that may interfere with blockcheck !!!"
fi
}
freebsd_module_loaded()
{
# $1 - module name
kldstat -qm "${1}"
}
freebsd_modules_loaded()
{
# $1,$2,$3, ... - module names
while [ -n "$1" ]; do
freebsd_module_loaded $1 || return 1
shift
done
return 0
}
check_prerequisites()
{
echo \* checking prerequisites
[ "$SKIP_PKTWS" = 1 -o "$UNAME" = Darwin -o -x "$PKTWS" ] && [ "$SKIP_TPWS" = 1 -o "$UNAME" = CYGWIN -o -x "$TPWS" ] && [ -x "$MDIG" ] || {
local target
case $UNAME in
Darwin)
target="mac"
;;
OpenBSD)
target="bsd"
;;
esac
echo $PKTWS or $TPWS or $MDIG is not available. run \"$ZAPRET_BASE/install_bin.sh\" or \`make -C \"$ZAPRET_BASE\" $target\`
exitp 6
}
local prog progs="$CURL"
[ "$SKIP_PKTWS" = 1 ] || {
case "$UNAME" in
Linux)
case "$FWTYPE" in
iptables)
ipt_has_nfq || {
echo NFQUEUE iptables or ip6tables target is missing. pls install modules.
exitp 6
}
progs="$progs iptables ip6tables"
;;
nftables)
nft_has_nfq || {
echo nftables queue support is not available. pls install modules.
exitp 6
}
progs="$progs nft"
;;
esac
;;
FreeBSD)
freebsd_modules_loaded ipfw ipdivert || {
echo ipfw or ipdivert kernel module not loaded
exitp 6
}
[ "$(sysctl -qn net.inet.ip.fw.enable)" = 0 -o "$(sysctl -qn net.inet6.ip6.fw.enable)" = 0 ] && {
echo ipfw is disabled. use : ipfw enable firewall
exitp 6
}
pf_is_avail && {
pf_save
[ "$SUBSYS" = "pfSense" ] && {
# pfsense's ipfw may not work without these workarounds
sysctl net.inet.ip.pfil.outbound=ipfw,pf 2>/dev/null
sysctl net.inet.ip.pfil.inbound=ipfw,pf 2>/dev/null
sysctl net.inet6.ip6.pfil.outbound=ipfw,pf 2>/dev/null
sysctl net.inet6.ip6.pfil.inbound=ipfw,pf 2>/dev/null
pfctl -qd
pfctl -qe
pf_restore
}
}
progs="$progs ipfw"
;;
OpenBSD|Darwin)
pf_is_avail || {
echo pf is not available
exitp 6
}
pf_save
progs="$progs pfctl"
;;
esac
}
case "$UNAME" in
CYGWIN)
SKIP_TPWS=1
;;
esac
for prog in $progs; do
exists $prog || {
echo $prog does not exist. please install
exitp 6
}
done
if exists nslookup; then
LOOKUP=nslookup
elif exists host; then
LOOKUP=host
else
echo nslookup or host does not exist. please install
exitp 6
fi
}
curl_translate_code()
{
# $1 - code
printf $1
case $1 in
0) printf ": ok"
;;
1) printf ": unsupported protocol"
;;
2) printf ": early initialization code failed"
;;
3) printf ": the URL was not properly formatted"
;;
4) printf ": feature not supported by libcurl"
;;
5) printf ": could not resolve proxy"
;;
6) printf ": could not resolve host"
;;
7) printf ": could not connect"
;;
8) printf ": invalid server reply"
;;
9) printf ": remote access denied"
;;
27) printf ": out of memory"
;;
28) printf ": operation timed out"
;;
35) printf ": SSL connect error"
;;
esac
}
curl_supports_tls13()
{
local r
"$CURL" --tlsv1.3 -Is -o /dev/null --max-time 1 http://127.0.0.1:65535 2>/dev/null
# return code 2 = init failed. likely bad command line options
[ $? = 2 ] && return 1
# curl can have tlsv1.3 key present but ssl library without TLS 1.3 support
# this is online test because there's no other way to trigger library incompatibility case
"$CURL" --tlsv1.3 --max-time 1 -Is -o /dev/null https://iana.org 2>/dev/null
r=$?
[ $r != 4 -a $r != 35 ]
}
curl_supports_tlsmax()
{
# supported only in OpenSSL and LibreSSL
"$CURL" --version | grep -Fq -e OpenSSL -e LibreSSL -e BoringSSL -e GnuTLS -e quictls || return 1
# supported since curl 7.54
"$CURL" --tls-max 1.2 -Is -o /dev/null --max-time 1 http://127.0.0.1:65535 2>/dev/null
# return code 2 = init failed. likely bad command line options
[ $? != 2 ]
}
curl_supports_connect_to()
{
"$CURL" --connect-to 127.0.0.1:: -o /dev/null --max-time 1 http://127.0.0.1:65535 2>/dev/null
[ "$?" != 2 ]
}
curl_supports_http3()
{
# if it has http3 : curl: (3) HTTP/3 requested for non-HTTPS URL
# otherwise : curl: (2) option --http3-only: is unknown
"$CURL" --connect-to 127.0.0.1:: -o /dev/null --max-time 1 --http3-only http://127.0.0.1:65535 2>/dev/null
[ "$?" != 2 ]
}
hdrfile_http_code()
{
# $1 - hdr file
sed -nre '1,1 s/^HTTP\/1\.[0,1] ([0-9]+) .*$/\1/p' "$1"
}
hdrfile_location()
{
# $1 - hdr file
# some DPIs return CRLF line ending
tr -d '\015' <"$1" | sed -nre 's/^[Ll][Oo][Cc][Aa][Tt][Ii][Oo][Nn]:[ ]*([^ ]*)[ ]*$/\1/p'
}
curl_with_subst_ip()
{
# $1 - domain
# $2 - port
# $3 - ip
# $4+ - curl params
local ip="$3"
case "$ip" in
*:*) ip="[$ip]" ;;
esac
local connect_to="--connect-to $1::$ip${2:+:$2}" arg
shift ; shift ; shift;
[ "$CURL_VERBOSE" = 1 ] && arg="-v"
[ "$CURL_CMD" = 1 ] && echo $CURL ${arg:+$arg }$connect_to "$@"
ALL_PROXY="$ALL_PROXY" "$CURL" ${arg:+$arg }$connect_to "$@"
}
curl_with_dig()
{
# $1 - ip version : 4/6
# $2 - domain name
# $3 - port
# $4+ - curl params
local dom="$2" port=$3
local sdom suri ip
split_by_separator "$dom" / sdom suri
mdig_resolve $1 ip $sdom
shift ; shift ; shift
if [ -n "$ip" ]; then
curl_with_subst_ip "$sdom" "$port" "$ip" "$@"
else
return 6
fi
}
curl_probe()
{
# $1 - ip version : 4/6
# $2 - domain name
# $3 - port
# $4 - subst ip
# $5+ - curl params
local ipv=$1 dom="$2" port=$3 subst=$4
shift; shift; shift; shift
if [ -n "$subst" ]; then
curl_with_subst_ip "$dom" $port $subst "$@"
else
curl_with_dig $ipv "$dom" $port "$@"
fi
}
curl_test_http()
{
# $1 - ip version : 4/6
# $2 - domain name
# $3 - subst ip
# $4 - "detail" - detail info
local code loc hdrt="${HDRTEMP}_${!:-$$}.txt" dom="$(tolower "$2")"
curl_probe $1 "$2" $HTTP_PORT "$3" -SsD "$hdrt" -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT "http://$2" -o /dev/null 2>&1 || {
code=$?
rm -f "$hdrt"
return $code
}
if [ "$4" = "detail" ] ; then
head -n 1 "$hdrt"
grep "^[lL]ocation:" "$hdrt"
else
code=$(hdrfile_http_code "$hdrt")
[ "$code" = 301 -o "$code" = 302 -o "$code" = 307 -o "$code" = 308 ] && {
loc=$(hdrfile_location "$hdrt")
split_by_separator "$dom" / dom
tolower "$loc" | grep -qE "^https?://.*$dom(/|$)" ||
tolower "$loc" | grep -vqE '^https?://' || {
echo suspicious redirection $code to : $loc
rm -f "$hdrt"
return 254
}
}
fi
rm -f "$hdrt"
[ "$code" = 400 ] && {
# this can often happen if the server receives fake packets it should not receive
echo http code $code. likely the server receives fakes.
return 254
}
return 0
}
curl_test_https_tls12()
{
# $1 - ip version : 4/6
# $2 - domain name
# $3 - subst ip
# do not use tls 1.3 to make sure server certificate is not encrypted
curl_probe $1 $2 $HTTPS_PORT "$3" $HTTPS_HEAD -Ss -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.2 $TLSMAX12 "https://$2" -o /dev/null 2>&1
}
curl_test_https_tls13()
{
# $1 - ip version : 4/6
# $2 - domain name
# $3 - subst ip
# force TLS1.3 mode
curl_probe $1 $2 $HTTPS_PORT "$3" $HTTPS_HEAD -Ss -A "$USER_AGENT" --max-time $CURL_MAX_TIME $CURL_OPT --tlsv1.3 $TLSMAX13 "https://$2" -o /dev/null 2>&1
}
curl_test_http3()
{
# $1 - ip version : 4/6
# $2 - domain name
# force QUIC only mode without tcp
curl_with_dig $1 $2 $QUIC_PORT $HTTPS_HEAD -Ss -A "$USER_AGENT" --max-time $CURL_MAX_TIME_QUIC --http3-only $CURL_OPT "https://$2" -o /dev/null 2>&1
}
ipt_aux_scheme()
{
# $1 - 1 - add , 0 - del
# $2 - tcp/udp
# $3 - port
# to avoid possible INVALID state drop
[ "$2" = tcp ] && IPT_ADD_DEL $1 INPUT -p $2 --sport $3 ! --syn -j ACCEPT
local icmp_filter="-p icmp -m icmp --icmp-type"
[ "$IPV" = 6 ] && icmp_filter="-p icmpv6 -m icmp6 --icmpv6-type"
IPT_ADD_DEL $1 INPUT $icmp_filter time-exceeded -m connmark --mark $DESYNC_MARK/$DESYNC_MARK -j DROP
# for strategies with incoming packets involved (autottl)
IPT_ADD_DEL $1 OUTPUT -p $2 --dport $3 -m conntrack --ctstate INVALID -j ACCEPT
if [ "$IPV" = 6 -a -n "$IP6_DEFRAG_DISABLE" ]; then
# the only way to reliable disable ipv6 defrag. works only in 4.16+ kernels
IPT_ADD_DEL $1 OUTPUT -t raw -p $2 -m frag -j CT --notrack
elif [ "$IPV" = 4 ]; then
# enable fragments
IPT_ADD_DEL $1 OUTPUT -f -j ACCEPT
fi
# enable everything generated by nfqws (works only in OUTPUT, not in FORWARD)
# raw table may not be present
IPT_ADD_DEL $1 OUTPUT -t raw -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CT --notrack
}
ipt_scheme()
{
# $1 - tcp/udp
# $2 - port
# $3 - ip list
local ip
$IPTABLES -t mangle -N blockcheck_output 2>/dev/null
$IPTABLES -t mangle -F blockcheck_output
IPT OUTPUT -t mangle -j blockcheck_output
# prevent loop
$IPTABLES -t mangle -A blockcheck_output -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j RETURN
$IPTABLES -t mangle -A blockcheck_output ! -p $1 -j RETURN
$IPTABLES -t mangle -A blockcheck_output -p $1 ! --dport $2 -j RETURN
for ip in $3; do
$IPTABLES -t mangle -A blockcheck_output -d $ip -j CONNMARK --or-mark $DESYNC_MARK
$IPTABLES -t mangle -A blockcheck_output -d $ip -j NFQUEUE --queue-num $QNUM
done
ipt_aux_scheme 1 $1 $2
}
nft_scheme()
{
# $1 - tcp/udp
# $2 - port
# $3 - ip list
local iplist ipver=$IPV
[ "$IPV" = 6 ] || ipver=
make_comma_list iplist $3
nft add table inet $NFT_TABLE
nft "add chain inet $NFT_TABLE postnat { type filter hook postrouting priority 102; }"
nft "add rule inet $NFT_TABLE postnat meta nfproto ipv${IPV} $1 dport $2 mark and $DESYNC_MARK == 0 ip${ipver} daddr {$iplist} ct mark set ct mark or $DESYNC_MARK queue num $QNUM"
# for strategies with incoming packets involved (autottl)
nft "add chain inet $NFT_TABLE prenat { type filter hook prerouting priority -102; }"
# enable everything generated by nfqws (works only in OUTPUT, not in FORWARD)
nft "add chain inet $NFT_TABLE predefrag { type filter hook output priority -402; }"
nft "add rule inet $NFT_TABLE predefrag meta nfproto ipv${IPV} mark and $DESYNC_MARK !=0 notrack"
[ "$IPV" = 4 ] && {
nft "add rule inet $NFT_TABLE prenat icmp type time-exceeded ct mark and $DESYNC_MARK != 0 drop"
nft "add rule inet $NFT_TABLE prenat icmp type time-exceeded ct state invalid drop"
}
[ "$IPV" = 6 ] && {
nft "add rule inet $NFT_TABLE prenat icmpv6 type time-exceeded ct mark and $DESYNC_MARK != 0 drop"
nft "add rule inet $NFT_TABLE prenat icmpv6 type time-exceeded ct state invalid drop"
}
}
pktws_ipt_prepare()
{
# $1 - tcp/udp
# $2 - port
# $3 - ip list
local ip
case "$FWTYPE" in
iptables)
ipt_scheme $1 $2 "$3"
;;
nftables)
nft_scheme $1 $2 "$3"
;;
ipfw)
# disable PF to avoid interferences
pf_is_avail && pfctl -qd
for ip in $3; do
IPFW_ADD divert $IPFW_DIVERT_PORT $1 from me to $ip $2 proto ip${IPV} out not diverted
done
;;
opf)
opf_prepare_dvtws $1 $2 "$3"
;;
windivert)
WF="--wf-l3=ipv${IPV} --wf-${1}=$2"
rm -f "$IPSET_FILE"
for ip in $3; do
echo $ip >>"$IPSET_FILE"
done
;;
esac
}
pktws_ipt_unprepare()
{
# $1 - tcp/udp
# $2 - port
case "$FWTYPE" in
iptables)
ipt_aux_scheme 0 $1 $2
IPT_DEL OUTPUT -t mangle -j blockcheck_output
$IPTABLES -t mangle -F blockcheck_output 2>/dev/null
$IPTABLES -t mangle -X blockcheck_output 2>/dev/null
;;
nftables)
nft delete table inet $NFT_TABLE 2>/dev/null
;;
ipfw)
IPFW_DEL
pf_is_avail && pf_restore
;;
opf)
pf_restore
;;
windivert)
unset WF
rm -f "$IPSET_FILE"
;;
esac
}
pktws_ipt_prepare_tcp()
{
# $1 - port
# $2 - ip list
local ip iplist ipver
pktws_ipt_prepare tcp $1 "$2"
# for autottl mode
case "$FWTYPE" in
iptables)
$IPTABLES -N blockcheck_input -t mangle 2>/dev/null
$IPTABLES -F blockcheck_input -t mangle 2>/dev/null
IPT INPUT -t mangle -j blockcheck_input
$IPTABLES -t mangle -A blockcheck_input ! -p tcp -j RETURN
$IPTABLES -t mangle -A blockcheck_input -p tcp ! --sport $1 -j RETURN
$IPTABLES -t mangle -A blockcheck_input -p tcp ! --tcp-flags SYN,ACK SYN,ACK -j RETURN
for ip in $2; do
$IPTABLES -A blockcheck_input -t mangle -s $ip -j NFQUEUE --queue-num $QNUM
done
;;
nftables)
ipver=$IPV
[ "$IPV" = 6 ] || ipver=
make_comma_list iplist $2
nft "add rule inet $NFT_TABLE prenat meta nfproto ipv${IPV} tcp sport $1 tcp flags & (syn | ack) == (syn | ack) ip${ipver} saddr {$iplist} queue num $QNUM"
;;
ipfw)
for ip in $2; do
IPFW_ADD divert $IPFW_DIVERT_PORT tcp from $ip $1 to me proto ip${IPV} tcpflags syn,ack in not diverted
done
;;
esac
}
pktws_ipt_unprepare_tcp()
{
# $1 - port
pktws_ipt_unprepare tcp $1
case "$FWTYPE" in
iptables)
IPT_DEL INPUT -t mangle -j blockcheck_input
$IPTABLES -t mangle -F blockcheck_input 2>/dev/null
$IPTABLES -t mangle -X blockcheck_input 2>/dev/null
;;
esac
}
pktws_ipt_prepare_udp()
{
# $1 - port
# $2 - ip list
pktws_ipt_prepare udp $1 "$2"
}
pktws_ipt_unprepare_udp()
{
# $1 - port
pktws_ipt_unprepare udp $1
}
pktws_start()
{
case "$UNAME" in
Linux)
"$NFQWS" --uid $TPWS_UID:$TPWS_GID --dpi-desync-fwmark=$DESYNC_MARK --qnum=$QNUM "$@" >/dev/null &
;;
FreeBSD|OpenBSD)
"$DVTWS" --port=$IPFW_DIVERT_PORT "$@" >/dev/null &
;;
CYGWIN)
"$WINWS" $WF --ipset="$IPSET_FILE" "$@" >/dev/null &
;;
esac
PID=$!
# give some time to initialize
minsleep
}
tpws_start()
{
local uid
[ -n "$HAVE_ROOT" ] && uid="--uid $TPWS_UID:$TPWS_GID"
"$TPWS" $uid --socks --bind-addr=127.0.0.1 --port=$SOCKS_PORT "$@" >/dev/null &
PID=$!
# give some time to initialize
minsleep
}
ws_kill()
{
[ -z "$PID" ] || {
killwait -9 $PID 2>/dev/null
PID=
}
}
check_domain_port_block()
{
# $1 - domain
# $2 - port
local ip ips
echo
echo \* port block tests ipv$IPV $1:$2
if netcat_setup; then
mdig_resolve_all $IPV ips $1
if [ -n "$ips" ]; then
for ip in $ips; do
if netcat_test $ip $2; then
echo $ip connects
else
echo $ip does not connect. netcat code $?
fi
done
else
echo "ipv${IPV} $1 does not resolve"
fi
else
echo suitable netcat not found. busybox nc is not supported. pls install nmap ncat or openbsd netcat.
fi
}
curl_test()
{
# $1 - test function
# $2 - domain
# $3 - subst ip
# $4 - param of test function
local code=0 n=0 p pids
if [ "$PARALLEL" = 1 ]; then
rm -f "${PARALLEL_OUT}"*
for n in $(seq -s ' ' 1 $REPEATS); do
$1 "$IPV" $2 $3 "$4" >"${PARALLEL_OUT}_$n" &
pids="${pids:+$pids }$!"
done
n=1
for p in $pids; do
[ $REPEATS -gt 1 ] && printf "[attempt $n] "
if wait $p; then
[ $REPEATS -gt 1 ] && echo 'AVAILABLE'
else
code=$?
cat "${PARALLEL_OUT}_$n"
fi
n=$(($n+1))
done
rm -f "${PARALLEL_OUT}"*
else
while [ $n -lt $REPEATS ]; do
n=$(($n+1))
[ $REPEATS -gt 1 ] && printf "[attempt $n] "
if $1 "$IPV" $2 $3 "$4" ; then
[ $REPEATS -gt 1 ] && echo 'AVAILABLE'
else
code=$?
[ "$SCANLEVEL" = quick ] && break
fi
done
fi
[ "$4" = detail ] || {
if [ $code = 254 ]; then
echo "UNAVAILABLE"
elif [ $code = 0 ]; then
echo '!!!!! AVAILABLE !!!!!'
else
echo "UNAVAILABLE code=$code"
fi
}
return $code
}
ws_curl_test()
{
# $1 - ws start function
# $2 - test function
# $3 - domain
# $4,$5,$6, ... - ws params
local code ws_start=$1 testf=$2 dom="$3"
[ "$SIMULATE" = 1 ] && {
n=$(random 0 99)
if [ "$n" -lt "$SIM_SUCCESS_RATE" ]; then
echo "SUCCESS"
return 0
else
echo "FAILED"
return 7
fi
}
shift
shift
shift
$ws_start "$@"
curl_test $testf "$dom"
code=$?
ws_kill
return $code
}
tpws_curl_test()
{
# $1 - test function
# $2 - domain
# $3,$4,$5, ... - tpws params
echo - $1 ipv$IPV $2 : tpws $3 $4 $5 $6 $7 $8 $9${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
local ALL_PROXY="socks5://127.0.0.1:$SOCKS_PORT"
ws_curl_test tpws_start "$@"${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}
local testf=$1 dom="$2" strategy code=$?
[ "$code" = 0 ] && {
shift; shift;
strategy="$@"
strategy_append_extra_tpws
report_append "$dom" "$testf ipv${IPV}" "tpws ${WF:+$WF }$strategy"
}
return $code
}
pktws_curl_test()
{
# $1 - test function
# $2 - domain
# $3,$4,$5, ... - nfqws/dvtws params
local testf=$1 dom="$2" strategy code
shift; shift;
echo - $testf ipv$IPV $dom : $PKTWSD ${WF:+$WF }${PKTWS_EXTRA_PRE:+$PKTWS_EXTRA_PRE }${PKTWS_EXTRA_PRE_1:+"$PKTWS_EXTRA_PRE_1" }${PKTWS_EXTRA_PRE_2:+"$PKTWS_EXTRA_PRE_2" }${PKTWS_EXTRA_PRE_3:+"$PKTWS_EXTRA_PRE_3" }${PKTWS_EXTRA_PRE_4:+"$PKTWS_EXTRA_PRE_4" }${PKTWS_EXTRA_PRE_5:+"$PKTWS_EXTRA_PRE_5" }${PKTWS_EXTRA_PRE_6:+"$PKTWS_EXTRA_PRE_6" }${PKTWS_EXTRA_PRE_7:+"$PKTWS_EXTRA_PRE_7" }${PKTWS_EXTRA_PRE_8:+"$PKTWS_EXTRA_PRE_8" }${PKTWS_EXTRA_PRE_9:+"$PKTWS_EXTRA_PRE_9" }$@${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
ws_curl_test pktws_start $testf "$dom" ${PKTWS_EXTRA_PRE:+$PKTWS_EXTRA_PRE }${PKTWS_EXTRA_PRE_1:+"$PKTWS_EXTRA_PRE_1" }${PKTWS_EXTRA_PRE_2:+"$PKTWS_EXTRA_PRE_2" }${PKTWS_EXTRA_PRE_3:+"$PKTWS_EXTRA_PRE_3" }${PKTWS_EXTRA_PRE_4:+"$PKTWS_EXTRA_PRE_4" }${PKTWS_EXTRA_PRE_5:+"$PKTWS_EXTRA_PRE_5" }${PKTWS_EXTRA_PRE_6:+"$PKTWS_EXTRA_PRE_6" }${PKTWS_EXTRA_PRE_7:+"$PKTWS_EXTRA_PRE_7" }${PKTWS_EXTRA_PRE_8:+"$PKTWS_EXTRA_PRE_8" }${PKTWS_EXTRA_PRE_9:+"$PKTWS_EXTRA_PRE_9" }"$@"${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}
code=$?
[ "$code" = 0 ] && {
strategy="$@"
strategy_append_extra_pktws
report_append "$dom" "$testf ipv${IPV}" "$PKTWSD ${WF:+$WF }$strategy"
}
return $code
}
strategy_append_extra_pktws()
{
strategy="${strategy:+${PKTWS_EXTRA_PRE:+$PKTWS_EXTRA_PRE }${PKTWS_EXTRA_PRE_1:+"$PKTWS_EXTRA_PRE_1" }${PKTWS_EXTRA_PRE_2:+"$PKTWS_EXTRA_PRE_2" }${PKTWS_EXTRA_PRE_3:+"$PKTWS_EXTRA_PRE_3" }${PKTWS_EXTRA_PRE_4:+"$PKTWS_EXTRA_PRE_4" }${PKTWS_EXTRA_PRE_5:+"$PKTWS_EXTRA_PRE_5" }${PKTWS_EXTRA_PRE_6:+"$PKTWS_EXTRA_PRE_6" }${PKTWS_EXTRA_PRE_7:+"$PKTWS_EXTRA_PRE_7" }${PKTWS_EXTRA_PRE_8:+"$PKTWS_EXTRA_PRE_8" }${PKTWS_EXTRA_PRE_9:+"$PKTWS_EXTRA_PRE_9" }$strategy${PKTWS_EXTRA:+ $PKTWS_EXTRA}${PKTWS_EXTRA_1:+ "$PKTWS_EXTRA_1"}${PKTWS_EXTRA_2:+ "$PKTWS_EXTRA_2"}${PKTWS_EXTRA_3:+ "$PKTWS_EXTRA_3"}${PKTWS_EXTRA_4:+ "$PKTWS_EXTRA_4"}${PKTWS_EXTRA_5:+ "$PKTWS_EXTRA_5"}${PKTWS_EXTRA_6:+ "$PKTWS_EXTRA_6"}${PKTWS_EXTRA_7:+ "$PKTWS_EXTRA_7"}${PKTWS_EXTRA_8:+ "$PKTWS_EXTRA_8"}${PKTWS_EXTRA_9:+ "$PKTWS_EXTRA_9"}}"
}
strategy_append_extra_tpws()
{
strategy="${strategy:+${PKTWS_EXTRA_PRE:+$PKTWS_EXTRA_PRE }${PKTWS_EXTRA_PRE_1:+"$PKTWS_EXTRA_PRE_1" }${PKTWS_EXTRA_PRE_2:+"$PKTWS_EXTRA_PRE_2" }${PKTWS_EXTRA_PRE_3:+"$PKTWS_EXTRA_PRE_3" }${PKTWS_EXTRA_PRE_4:+"$PKTWS_EXTRA_PRE_4" }${PKTWS_EXTRA_PRE_5:+"$PKTWS_EXTRA_PRE_5" }${PKTWS_EXTRA_PRE_6:+"$PKTWS_EXTRA_PRE_6" }${PKTWS_EXTRA_PRE_7:+"$PKTWS_EXTRA_PRE_7" }${PKTWS_EXTRA_PRE_8:+"$PKTWS_EXTRA_PRE_8" }${PKTWS_EXTRA_PRE_9:+"$PKTWS_EXTRA_PRE_9" }$strategy${TPWS_EXTRA:+ $TPWS_EXTRA}${TPWS_EXTRA_1:+ "$TPWS_EXTRA_1"}${TPWS_EXTRA_2:+ "$TPWS_EXTRA_2"}${TPWS_EXTRA_3:+ "$TPWS_EXTRA_3"}${TPWS_EXTRA_4:+ "$TPWS_EXTRA_4"}${TPWS_EXTRA_5:+ "$TPWS_EXTRA_5"}${TPWS_EXTRA_6:+ "$TPWS_EXTRA_6"}${TPWS_EXTRA_7:+ "$TPWS_EXTRA_7"}${TPWS_EXTRA_8:+ "$TPWS_EXTRA_8"}${TPWS_EXTRA_9:+ "$TPWS_EXTRA_9"}}"
}
xxxws_curl_test_update()
{
# $1 - xxx_curl_test function
# $2 - test function
# $3 - domain
# $4,$5,$6, ... - nfqws/dvtws params
local code xxxf=$1 testf=$2 dom="$3"
shift
shift
shift
$xxxf $testf "$dom" "$@"
code=$?
[ $code = 0 ] && strategy="${strategy:-$@}"
return $code
}
pktws_curl_test_update()
{
xxxws_curl_test_update pktws_curl_test "$@"
}
tpws_curl_test_update()
{
xxxws_curl_test_update tpws_curl_test "$@"
}
report_append()
{
# $1 - domain
# $2 - test function + ipver
# $3 - value
local hashstr hash hashvar hashcountvar val ct
# save resources if only one domain
[ "$DOMAINS_COUNT" -gt 1 ] && {
hashstr="$2 : $3"
hash="$(echo -n "$hashstr" | md5f)"
hashvar=RESHASH_${hash}
hashcountvar=${hashvar}_COUNTER
NRESHASH=${NRESHASH:-0}
eval val="\$$hashvar"
if [ -n "$val" ]; then
eval ct="\$$hashcountvar"
ct=$(($ct + 1))
eval $hashcountvar="\$ct"
else
eval $hashvar=\"$hashstr\"
eval $hashcountvar=1
eval RES_$NRESHASH="\$hash"
NRESHASH=$(($NRESHASH+1))
fi
}
NREPORT=${NREPORT:-0}
eval REPORT_${NREPORT}=\"$2 $1 : $3\"
NREPORT=$(($NREPORT+1))
}
report_print()
{
local n=0 s
NREPORT=${NREPORT:-0}
while [ $n -lt $NREPORT ]; do
eval s=\"\${REPORT_$n}\"
echo $s
n=$(($n+1))
done
}
result_intersection_print()
{
local n=0 hash hashvar hashcountvar ct val
while : ; do
eval hash=\"\$RES_$n\"
[ -n "$hash" ] || break
hashvar=RESHASH_${hash}
hashcountvar=${hashvar}_COUNTER
eval ct=\"\$$hashcountvar\"
[ "$ct" = "$DOMAINS_COUNT" ] && {
eval val=\"\$$hashvar\"
echo "$val"
}
n=$(($n + 1))
done
}
report_strategy()
{
# $1 - test function
# $2 - domain
# $3 - daemon
echo
if [ -n "$strategy" ]; then
# trim spaces at the end
strategy="$(echo "$strategy" | xargs)"
echo "!!!!! $1: working strategy found for ipv${IPV} $2 : $3 $strategy !!!!!"
echo
return 0
else
echo "$1: $3 strategy for ipv${IPV} $2 not found"
echo
report_append "$2" "$1 ipv${IPV}" "$3 not working"
return 1
fi
}
test_has_fakedsplit()
{
contains "$1" fakedsplit || contains "$1" fakeddisorder
}
test_has_split()
{
contains "$1" multisplit || contains "$1" multidisorder || test_has_fakedsplit "$1"
}
test_has_hostfakesplit()
{
contains "$1" hostfakesplit
}
test_has_fake()
{
[ "$1" = fake ] || starts_with "$1" fake,
}
warn_fool()
{
case "$1" in
md5sig) echo 'WARNING ! although md5sig fooling worked it will not work on all sites. it typically works only on linux servers.'
[ "$2" = "fakedsplit" -o "$2" = "fakeddisorder" ] && \
echo "WARNING ! fakedsplit/fakeddisorder with md5sig fooling and low split position causes MTU overflow with multi-segment TLS (kyber)"
;;
datanoack) echo 'WARNING ! although datanoack fooling worked it may break NAT and may only work with external IP. Additionally it may require nftables to work correctly.' ;;
ts) echo 'WARNING ! although ts fooling worked it will not work without timestamps being enabled in the client OS. In windows timestamps are DISABLED by default.'
esac
}
pktws_curl_test_update_vary()
{
# $1 - test function
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
# $3 - domain
# $4 - desync mode
# $5,$6,... - strategy
local testf=$1 sec=$2 domain=$3 desync=$4 proto splits= pos fake ret=1
local fake1=- fake2=- fake3=- fake4=-
shift; shift; shift; shift
proto=http
[ "$sec" = 0 ] || proto=tls
test_has_fake $desync && {
fake1="--dpi-desync-fake-$proto=0x00000000"
[ "$sec" = 0 ] || {
fake2='--dpi-desync-fake-tls=0x00000000 --dpi-desync-fake-tls=! --dpi-desync-fake-tls-mod=rnd,rndsni,dupsid'
# this splits actual fake to '1603' and modified standard fake from offset 2
fake3='--dpi-desync-fake-tls=0x1603 --dpi-desync-fake-tls=!+2 --dpi-desync-fake-tls-mod=rnd,dupsid,rndsni --dpi-desync-fake-tcp-mod=seq'
fake4='--dpi-desync-fake-tls-mod=rnd,dupsid,rndsni,padencap'
}
}
if test_has_fakedsplit $desync ; then
splits="method+2 midsld"
[ "$sec" = 0 ] || splits="1 midsld"
# do not send fake first
fake1='--dpi-desync-fakedsplit-mod=altorder=1'
elif test_has_split $desync ; then
splits="method+2 midsld"
[ "$sec" = 0 ] || splits="1 midsld 1,midsld"
fi
test_has_hostfakesplit $desync && {
fake1="--dpi-desync-hostfakesplit-mod=altorder=1"
fake2="--dpi-desync-hostfakesplit-midhost=midsld"
fake3="--dpi-desync-hostfakesplit-mod=altorder=1 --dpi-desync-hostfakesplit-midhost=midsld"
}
for fake in '' "$fake1" "$fake2" "$fake3" "$fake4" ; do
[ "$fake" = "-" ] && continue
if [ -n "$splits" ]; then
for pos in $splits ; do
pktws_curl_test_update $testf "$domain" --dpi-desync=$desync "$@" --dpi-desync-split-pos=$pos $fake && {
[ "$SCANLEVEL" = force ] || return 0
ret=0
}
done
else
pktws_curl_test_update $testf "$domain" --dpi-desync=$desync "$@" $fake && {
[ "$SCANLEVEL" = force ] || return 0
ret=0
}
fi
done
return $ret
}
pktws_check_domain_http_bypass_()
{
# $1 - test function
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
# $3 - domain
local ok ttls attls s f f2 e desync pos fooling frag sec="$2" delta orig splits
local need_split need_disorder need_fakedsplit need_hostfakesplit need_fakeddisorder need_fake need_wssize
local splits_http='method+2 midsld method+2,midsld'
local splits_tls='2 1 sniext+1 sniext+4 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld-2,midsld,midsld+2,endhost-1'
[ "$sec" = 0 ] && {
for s in '--hostcase' '--hostspell=hoSt' '--hostnospace' '--domcase' '--methodeol'; do
pktws_curl_test_update $1 $3 $s && [ "$SCANLEVEL" = quick ] && return
done
}
ttls=$(seq -s ' ' $MIN_TTL $MAX_TTL)
attls=$(seq -s ' ' $MIN_AUTOTTL_DELTA $MAX_AUTOTTL_DELTA)
need_wssize=1
for e in '' '--wssize 1:6'; do
need_split=
need_disorder=
[ -n "$e" ] && {
pktws_curl_test_update $1 $3 $e && [ "$SCANLEVEL" = quick ] && return
}
for desync in multisplit multidisorder; do
ok=0
splits="$splits_http"
[ "$sec" = 0 ] || splits="$splits_tls"
for pos in $splits; do
pktws_curl_test_update $1 $3 --dpi-desync=$desync --dpi-desync-split-pos=$pos $e && {
[ "$SCANLEVEL" = quick ] && return
ok=1
need_wssize=0
[ "$SCANLEVEL" = force ] || break
}
done
[ "$ok" = 1 -a "$SCANLEVEL" != force ] || {
case $desync in
multisplit)
need_split=1
;;
multidisorder)
need_disorder=1
;;
esac
}
done
need_fakedsplit=1
need_hostfakesplit=1
need_fakeddisorder=1
need_fake=1
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit hostfakesplit fake,hostfakesplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
[ "$need_fake" = 0 ] && test_has_fake "$desync" && continue
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
[ "$need_hostfakesplit" = 0 ] && contains "$desync" hostfakesplit && continue
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
ok=0
for ttl in $ttls; do
# orig-ttl=1 with start/cutoff limiter drops empty ACK packet in response to SYN,ACK. it does not reach DPI or server.
# missing ACK is transmitted in the first data packet of TLS/HTTP proto
for f in '' '--orig-ttl=1 --orig-mod-start=s1 --orig-mod-cutoff=d1'; do
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=$ttl $f $e && {
[ "$SCANLEVEL" = quick ] && return
ok=1
need_wssize=0
[ "$SCANLEVEL" = force ] || break
}
done
[ "$ok" = 1 ] && break
done
# only skip tests if TTL succeeded. do not skip if TTL failed but fooling succeeded
[ $ok = 1 -a "$SCANLEVEL" != force ] && {
[ "$desync" = fake ] && need_fake=0
[ "$desync" = fakedsplit ] && need_fakedsplit=0
[ "$desync" = hostfakesplit ] && need_hostfakesplit=0
[ "$desync" = fakeddisorder ] && need_fakeddisorder=0
}
f=
[ "$UNAME" = "OpenBSD" ] || f="badsum"
f="$f badseq datanoack ts md5sig"
[ "$IPV" = 6 ] && f="$f hopbyhop hopbyhop2"
for fooling in $f; do
ok=0
f2=
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling $e && {
warn_fool $fooling $desync
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
ok=1
}
[ "$fooling" = badseq ] && {
[ "$ok" = 1 -a "$SCANLEVEL" != force ] && continue
# --dpi-desync-badseq-increment=0 leaves modified by default ack increment
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling --dpi-desync-badseq-increment=0 $e && {
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
}
[ "$fooling" = md5sig ] && {
[ "$ok" = 1 -a "$SCANLEVEL" != force ] && continue
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fooling=$fooling --dup=1 --dup-cutoff=n2 --dup-fooling=md5sig $e && {
warn_fool $fooling $desync
echo "HINT ! To avoid possible 1 sec server response delay use --dup-ttl or --dup-autottl and block ICMP time exceeded"
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
}
done
done
[ "$IPV" = 6 ] && {
f="hopbyhop ${need_split:+hopbyhop,multisplit} ${need_disorder:+hopbyhop,multidisorder} destopt ${need_split:+destopt,multisplit} ${need_disorder:+destopt,multidisorder}"
[ -n "$IP6_DEFRAG_DISABLE" ] && f="$f ipfrag1 ${need_split:+ ipfrag1,multisplit} ${need_disorder:+ ipfrag1,multidisorder}"
for desync in $f; do
pktws_curl_test_update_vary $1 $2 $3 $desync $e && {
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
done
}
[ "$need_split" = 1 ] && {
# relative markers can be anywhere, even in subsequent packets. first packet can be MTU-full.
# make additional split pos "10" to guarantee enough space for seqovl and likely to be before midsld,sniext,...
# method is always expected in the beginning of the first packet
f="method+2 method+2,midsld"
[ "$sec" = 0 ] || f="10 10,sniext+1 10,sniext+4 10,midsld"
for pos in $f; do
pktws_curl_test_update $1 $3 --dpi-desync=multisplit --dpi-desync-split-pos=$pos --dpi-desync-split-seqovl=1 $e && {
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
done
[ "$sec" != 0 ] && pktws_curl_test_update $1 $3 --dpi-desync=multisplit --dpi-desync-split-pos=2 --dpi-desync-split-seqovl=336 --dpi-desync-split-seqovl-pattern="$ZAPRET_BASE/files/fake/tls_clienthello_iana_org.bin" $e && {
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
}
[ "$need_disorder" = 1 ] && {
if [ "$sec" = 0 ]; then
for pos in 'method+1 method+2' 'midsld-1 midsld' 'method+1 method+2,midsld'; do
f="$(extract_arg 1 $pos)"
f2="$(extract_arg 2 $pos)"
pktws_curl_test_update $1 $3 --dpi-desync=multidisorder --dpi-desync-split-pos=$f2 --dpi-desync-split-seqovl=$f $e && {
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
done
else
for pos in '1 2' 'sniext sniext+1' 'sniext+3 sniext+4' 'midsld-1 midsld' '1 2,midsld'; do
f=$(extract_arg 1 $pos)
f2=$(extract_arg 2 $pos)
pktws_curl_test_update $1 $3 --dpi-desync=multidisorder --dpi-desync-split-pos=$f2 --dpi-desync-split-seqovl=$f $e && {
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
}
done
fi
}
need_fakedsplit=1
need_fakeddisorder=1
need_hostfakesplit=1
need_fake=1
for desync in fake ${need_split:+fakedsplit fake,multisplit fake,fakedsplit hostfakesplit fake,hostfakesplit} ${need_disorder:+fakeddisorder fake,multidisorder fake,fakeddisorder}; do
[ "$need_fake" = 0 ] && test_has_fake "$desync" && continue
[ "$need_fakedsplit" = 0 ] && contains "$desync" fakedsplit && continue
[ "$need_hostfakesplit" = 0 ] && contains "$desync" hostfakesplit && continue
[ "$need_fakeddisorder" = 0 ] && contains "$desync" fakeddisorder && continue
ok=0
# orig-ttl=1 with start/cutoff limiter drops empty ACK packet in response to SYN,ACK. it does not reach DPI or server.
# missing ACK is transmitted in the first data packet of TLS/HTTP proto
for delta in $attls; do
for f in '' '--orig-ttl=1 --orig-mod-start=s1 --orig-mod-cutoff=d1'; do
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-ttl=1 --dpi-desync-autottl=-$delta $f $e && ok=1
[ "$ok" = 1 -a "$SCANLEVEL" != force ] && break
done
done
[ "$SCANLEVEL" = force ] && {
for orig in 1 2 3; do
for delta in $attls; do
pktws_curl_test_update_vary $1 $2 $3 $desync ${orig:+--orig-autottl=+$orig} --dpi-desync-ttl=1 --dpi-desync-autottl=-$delta $e && ok=1
done
[ "$ok" = 1 -a "$SCANLEVEL" != force ] && break
done
}
[ "$ok" = 1 ] &&
{
echo "WARNING ! although autottl worked it requires testing on multiple domains to find out reliable delta"
echo "WARNING ! if a reliable delta cannot be found it's a good idea not to use autottl"
[ "$SCANLEVEL" = quick ] && return
need_wssize=0
[ "$SCANLEVEL" = force ] || {
[ "$desync" = fake ] && need_fake=0
[ "$desync" = fakedsplit ] && need_fakedsplit=0
[ "$desync" = hostfakesplit ] && need_hostfakesplit=0
[ "$desync" = fakeddisorder ] && need_fakeddisorder=0
}
}
done
s="http_iana_org.bin"
[ "$sec" = 0 ] || s="tls_clienthello_iana_org.bin"
for desync in syndata ${need_split:+syndata,multisplit} ${need_disorder:+syndata,multidisorder} ; do
pktws_curl_test_update_vary $1 $2 $3 $desync $e && [ "$SCANLEVEL" = quick ] && return
pktws_curl_test_update_vary $1 $2 $3 $desync --dpi-desync-fake-syndata="$ZAPRET_BASE/files/fake/$s" $e && [ "$SCANLEVEL" = quick ] && return
done
# do not do wssize test for http and TLS 1.3. it's useless
[ "$sec" = 1 ] || break
[ "$SCANLEVEL" = force -o "$need_wssize" = 1 ] || break
done
}
pktws_check_domain_http_bypass()
{
# $1 - test function
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
# $3 - domain
local strategy
pktws_check_domain_http_bypass_ "$@"
strategy_append_extra_pktws
report_strategy $1 $3 $PKTWSD
}
pktws_check_domain_http3_bypass_()
{
# $1 - test function
# $2 - domain
local f desync frag tests rep fake
for fake in '' "--dpi-desync-fake-quic=$ZAPRET_BASE/files/fake/quic_initial_www_google_com.bin"; do
for rep in '' 2 5 10 20; do
pktws_curl_test_update $1 $2 --dpi-desync=fake ${fake:+"$fake" }${rep:+--dpi-desync-repeats=$rep} && [ "$SCANLEVEL" != force ] && {
[ "$SCANLEVEL" = quick ] && return
break
}
done
done
[ "$IPV" = 6 ] && {
f="hopbyhop destopt"
[ -n "$IP6_DEFRAG_DISABLE" ] && f="$f ipfrag1"
for desync in $f; do
pktws_curl_test_update $1 $2 --dpi-desync=$desync && [ "$SCANLEVEL" = quick ] && return
done
}
# OpenBSD has checksum issues with fragmented packets
[ "$UNAME" != "OpenBSD" ] && [ "$IPV" = 4 -o -n "$IP6_DEFRAG_DISABLE" ] && {
for frag in 8 16 24 32 40 64; do
tests="ipfrag2"
[ "$IPV" = 6 ] && tests="$tests hopbyhop,ipfrag2 destopt,ipfrag2"
for desync in $tests; do
pktws_curl_test_update $1 $2 --dpi-desync=$desync --dpi-desync-ipfrag-pos-udp=$frag && [ "$SCANLEVEL" = quick ] && return
done
done
}
}
pktws_check_domain_http3_bypass()
{
# $1 - test function
# $2 - domain
local strategy
pktws_check_domain_http3_bypass_ "$@"
strategy_append_extra_pktws
report_strategy $1 $2 $PKTWSD
}
warn_mss()
{
[ -n "$1" ] && echo 'WARNING ! although mss worked it may not work on all sites and will likely cause significant slowdown. it may only be required for TLS1.2, not TLS1.3'
return 0
}
fix_seg()
{
# $1 - split-pos
[ -n "$FIX_SEG" ] && contains "$1" , && echo "$FIX_SEG"
}
tpws_check_domain_http_bypass_()
{
# $1 - test function
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
# $3 - domain
local s mss s2 s3 oobdis pos sec="$2"
local splits_tls='2 1 sniext+1 sniext+4 host+1 midsld 1,midsld 1,sniext+1,host+1,midsld,endhost-1'
local splits_http='method+2 midsld method+2,midsld'
# simulteneous oob and disorder works properly only in linux. other systems retransmit oob byte without URG tcp flag and poison tcp stream.
[ "$UNAME" = Linux ] && oobdis='--oob --disorder'
if [ "$sec" = 0 ]; then
for s in '--hostcase' '--hostspell=hoSt' '--hostdot' '--hosttab' '--hostnospace' '--domcase' ; do
tpws_curl_test_update $1 $3 $s && [ "$SCANLEVEL" = quick ] && return
done
for s in 1024 2048 4096 8192 16384 ; do
tpws_curl_test_update $1 $3 --hostpad=$s && [ "$SCANLEVEL" != force ] && {
[ "$SCANLEVEL" = quick ] && return
break
}
done
for s2 in '' '--hostcase' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
for s in $splits_http ; do
tpws_curl_test_update $1 $3 --split-pos=$s $(fix_seg $s) $s2 && [ "$SCANLEVEL" != force ] && {
[ "$SCANLEVEL" = quick ] && return
break
}
done
done
for s in '--methodspace' '--unixeol' '--methodeol'; do
tpws_curl_test_update $1 $3 $s && [ "$SCANLEVEL" = quick ] && return
done
else
local need_mss=1
for mss in '' 88; do
s3=${mss:+--mss=$mss}
for s2 in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
for pos in $splits_tls; do
tpws_curl_test_update $1 $3 --split-pos=$pos $(fix_seg $pos) $s2 $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
[ "$SCANLEVEL" = quick ] && return
need_mss=0
break
}
done
done
for s in '' '--oob' '--disorder' ${oobdis:+"$oobdis"}; do
for s2 in '--tlsrec=midsld' '--tlsrec=sniext+1 --split-pos=midsld' '--tlsrec=sniext+4 --split-pos=midsld' "--tlsrec=sniext+1 --split-pos=1,midsld $FIX_SEG" "--tlsrec=sniext+4 --split-pos=1,midsld $FIX_SEG" ; do
tpws_curl_test_update $1 $3 $s2 $s $s3 && warn_mss $s3 && [ "$SCANLEVEL" != force ] && {
[ "$SCANLEVEL" = quick ] && return
need_mss=0
break
}
done
done
# only linux supports mss
[ "$UNAME" = Linux -a "$sec" = 1 ] || break
[ "$SCANLEVEL" = force -o "$need_mss" = 1 ] || break
done
fi
}
tpws_check_domain_http_bypass()
{
# $1 - test function
# $2 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
# $3 - domain
local strategy
tpws_check_domain_http_bypass_ "$@"
strategy_append_extra_tpws
report_strategy $1 $3 tpws
}
check_dpi_ip_block()
{
# $1 - test function
# $2 - domain
local blocked_dom="$2"
local blocked_ip blocked_ips unblocked_ip
echo
echo "- IP block tests (requires manual interpretation)"
echo "> testing $UNBLOCKED_DOM on it's original ip"
if curl_test $1 $UNBLOCKED_DOM; then
mdig_resolve $IPV unblocked_ip $UNBLOCKED_DOM
[ -n "$unblocked_ip" ] || {
echo $UNBLOCKED_DOM does not resolve. tests not possible.
return 1
}
echo "> testing $blocked_dom on $unblocked_ip ($UNBLOCKED_DOM)"
curl_test $1 $blocked_dom $unblocked_ip detail
mdig_resolve_all $IPV blocked_ips $blocked_dom
for blocked_ip in $blocked_ips; do
echo "> testing $UNBLOCKED_DOM on $blocked_ip ($blocked_dom)"
curl_test $1 $UNBLOCKED_DOM $blocked_ip detail
done
else
echo $UNBLOCKED_DOM is not available. skipping this test.
fi
}
curl_has_reason_to_continue()
{
# $1 - curl return code
for c in 1 2 3 4 6 27 ; do
[ $1 = $c ] && return 1
done
return 0
}
check_domain_prolog()
{
# $1 - test function
# $2 - port
# $3 - domain
local code
[ "$SIMULATE" = 1 ] && return 0
echo
echo \* $1 ipv$IPV $3
echo "- checking without DPI bypass"
curl_test $1 $3 && {
report_append "$3" "$1 ipv${IPV}" "working without bypass"
[ "$SCANLEVEL" = force ] || return 1
}
code=$?
curl_has_reason_to_continue $code || {
report_append "$3" "$1 ipv${IPV}" "test aborted, no reason to continue. curl code $(curl_translate_code $code)"
return 1
}
return 0
}
check_domain_http_tcp()
{
# $1 - test function
# $2 - port
# $3 - encrypted test : 0 = plain, 1 - encrypted with server reply risk, 2 - encrypted without server reply risk
# $4 - domain
local ips
# in case was interrupted before
pktws_ipt_unprepare_tcp $2
ws_kill
check_domain_prolog $1 $2 $4 || return
[ "$SKIP_IPBLOCK" = 1 ] || check_dpi_ip_block $1 $4
[ "$SKIP_TPWS" = 1 ] || {
echo
tpws_check_domain_http_bypass $1 $3 $4
}
[ "$SKIP_PKTWS" = 1 ] || {
echo
echo preparing $PKTWSD redirection
mdig_resolve_all $IPV ips $4
pktws_ipt_prepare_tcp $2 "$ips"
pktws_check_domain_http_bypass $1 $3 $4
echo clearing $PKTWSD redirection
pktws_ipt_unprepare_tcp $2
}
}
check_domain_http_udp()
{
# $1 - test function
# $2 - port
# $3 - domain
local ips
# in case was interrupted before
pktws_ipt_unprepare_udp $2
ws_kill
check_domain_prolog $1 $2 $3 || return
[ "$SKIP_PKTWS" = 1 ] || {
echo
echo preparing $PKTWSD redirection
mdig_resolve_all $IPV ips $3
pktws_ipt_prepare_udp $2 "$ips"
pktws_check_domain_http3_bypass $1 $3
echo clearing $PKTWSD redirection
pktws_ipt_unprepare_udp $2
}
}
check_domain_http()
{
# $1 - domain
check_domain_http_tcp curl_test_http $HTTP_PORT 0 $1
}
check_domain_https_tls12()
{
# $1 - domain
check_domain_http_tcp curl_test_https_tls12 $HTTPS_PORT 1 $1
}
check_domain_https_tls13()
{
# $1 - domain
check_domain_http_tcp curl_test_https_tls13 $HTTPS_PORT 2 $1
}
check_domain_http3()
{
# $1 - domain
check_domain_http_udp curl_test_http3 $QUIC_PORT $1
}
configure_ip_version()
{
if [ "$IPV" = 6 ]; then
LOCALHOST=::1
LOCALHOST_IPT=[${LOCALHOST}]
IPVV=6
else
IPTABLES=iptables
LOCALHOST=127.0.0.1
LOCALHOST_IPT=$LOCALHOST
IPVV=
fi
IPTABLES=ip${IPVV}tables
}
configure_curl_opt()
{
# wolfssl : --tlsv1.x mandates exact ssl version, tls-max not supported
# openssl : --tlsv1.x means "version equal or greater", tls-max supported
TLSMAX12=
TLSMAX13=
curl_supports_tlsmax && {
TLSMAX12="--tls-max 1.2"
TLSMAX13="--tls-max 1.3"
}
TLS13=
curl_supports_tls13 && TLS13=1
HTTP3=
curl_supports_http3 && HTTP3=1
HTTPS_HEAD=-I
[ "$CURL_HTTPS_GET" = 1 ] && HTTPS_HEAD=
}
linux_ipv6_defrag_can_be_disabled()
{
linux_min_version 4 16
}
configure_defrag()
{
IP6_DEFRAG_DISABLE=
[ "$IPVS" = 4 ] && return
[ "$UNAME" = "Linux" ] && {
linux_ipv6_defrag_can_be_disabled || {
echo "WARNING ! ipv6 defrag can only be effectively disabled in linux kernel 4.16+"
echo "WARNING ! ipv6 ipfrag tests are disabled"
echo
return
}
}
case "$FWTYPE" in
iptables)
if ipt6_has_raw ; then
if ipt6_has_frag; then
IP6_DEFRAG_DISABLE=1
else
echo "WARNING ! ip6tables does not have '-m frag' module, ipv6 ipfrag tests are disabled"
echo
fi
else
echo "WARNING ! ip6tables raw table is not available, ipv6 ipfrag tests are disabled"
echo
fi
[ -n "$IP6_DEFRAG_DISABLE" ] && {
local ipexe="$(readlink -f $(whichq ip6tables))"
if contains "$ipexe" nft; then
echo "WARNING ! ipv6 ipfrag tests may have no effect if ip6tables-nft is used. current ip6tables point to : $ipexe"
else
echo "WARNING ! ipv6 ipfrag tests may have no effect if ip6table_raw kernel module is not loaded with parameter : raw_before_defrag=1"
fi
echo
}
;;
*)
IP6_DEFRAG_DISABLE=1
;;
esac
}
ask_params()
{
echo
echo NOTE ! this test should be run with zapret or any other bypass software disabled, without VPN
echo
curl_supports_connect_to || {
echo "installed curl does not support --connect-to option. pls install at least curl 7.49"
echo "current curl version:"
"$CURL" --version
exitp 1
}
local dom
[ -n "$DOMAINS" ] || {
DOMAINS="$DOMAINS_DEFAULT"
[ "$BATCH" = 1 ] || {
echo "specify domain(s) to test. multiple domains are space separated. URIs are supported (rutracker.org/forum/index.php)"
printf "domain(s) (default: $DOMAINS) : "
read dom
[ -n "$dom" ] && DOMAINS="$dom"
}
}
DOMAINS_COUNT="$(echo "$DOMAINS" | wc -w | trim)"
local IPVS_def=4
[ -n "$IPVS" ] || {
# yandex public dns
pingtest 6 2a02:6b8::feed:0ff && IPVS_def=46
[ "$BATCH" = 1 ] || {
printf "ip protocol version(s) - 4, 6 or 46 for both (default: $IPVS_def) : "
read IPVS
}
[ -n "$IPVS" ] || IPVS=$IPVS_def
[ "$IPVS" = 4 -o "$IPVS" = 6 -o "$IPVS" = 46 ] || {
echo 'invalid ip version(s). should be 4, 6 or 46.'
exitp 1
}
}
[ "$IPVS" = 46 ] && IPVS="4 6"
configure_curl_opt
[ -n "$ENABLE_HTTP" ] || {
ENABLE_HTTP=1
[ "$BATCH" = 1 ] || {
echo
ask_yes_no_var ENABLE_HTTP "check http"
}
}
[ -n "$ENABLE_HTTPS_TLS12" ] || {
ENABLE_HTTPS_TLS12=1
[ "$BATCH" = 1 ] || {
echo
ask_yes_no_var ENABLE_HTTPS_TLS12 "check https tls 1.2"
}
}
[ -n "$ENABLE_HTTPS_TLS13" ] || {
ENABLE_HTTPS_TLS13=0
if [ -n "$TLS13" ]; then
[ "$BATCH" = 1 ] || {
echo
echo "TLS 1.3 uses encrypted ServerHello. DPI cannot check domain name in server response."
echo "This can allow more bypass strategies to work."
echo "What works for TLS 1.2 will also work for TLS 1.3 but not vice versa."
echo "Most sites nowadays support TLS 1.3 but not all. If you can't find a strategy for TLS 1.2 use this test."
echo "TLS 1.3 only strategy is better than nothing."
ask_yes_no_var ENABLE_HTTPS_TLS13 "check https tls 1.3"
}
else
echo
echo "installed curl version does not support TLS 1.3 . tests disabled."
fi
}
[ -n "$ENABLE_HTTP3" ] || {
ENABLE_HTTP3=0
if [ -n "$HTTP3" ]; then
ENABLE_HTTP3=1
[ "$BATCH" = 1 ] || {
echo
echo "make sure target domain(s) support QUIC or result will be negative in any case"
ask_yes_no_var ENABLE_HTTP3 "check http3 QUIC"
}
else
echo
echo "installed curl version does not support http3 QUIC. tests disabled."
fi
}
[ -n "$REPEATS" ] || {
[ "$BATCH" = 1 ] || {
echo
echo "sometimes ISPs use multiple DPIs or load balancing. bypass strategies may work unstable."
printf "how many times to repeat each test (default: 1) : "
read REPEATS
}
REPEATS=$((0+${REPEATS:-1}))
[ "$REPEATS" = 0 ] && {
echo invalid repeat count
exitp 1
}
}
[ -z "$PARALLEL" -a $REPEATS -gt 1 ] && {
PARALLEL=0
[ "$BATCH" = 1 ] || {
echo
echo "parallel scan can greatly increase speed but may also trigger DDoS protection and cause false result"
ask_yes_no_var PARALLEL "enable parallel scan"
}
}
PARALLEL=${PARALLEL:-0}
[ -n "$SCANLEVEL" ] || {
SCANLEVEL=standard
[ "$BATCH" = 1 ] || {
echo
echo quick - scan as fast as possible to reveal any working strategy
echo standard - do investigation what works on your DPI
echo force - scan maximum despite of result
ask_list SCANLEVEL "quick standard force" "$SCANLEVEL"
# disable tpws checks by default in quick mode
[ "$SCANLEVEL" = quick -a -z "$SKIP_TPWS" -a "$UNAME" != Darwin ] && SKIP_TPWS=1
}
}
echo
configure_defrag
}
ping_with_fix()
{
local ret
$PING $2 $1 >/dev/null 2>/dev/null
ret=$?
# can be because of unsupported -4 option
if [ "$ret" = 2 -o "$ret" = 64 ]; then
ping $2 $1 >/dev/null
else
return $ret
fi
}
pingtest()
{
# $1 - ip version : 4 or 6
# $2 - domain or ip
# ping command can vary a lot. some implementations have -4/-6 options. others don.t
# WARNING ! macos ping6 command does not have timeout option. ping6 will fail
local PING=ping ret
if [ "$1" = 6 ]; then
if exists ping6; then
PING=ping6
else
PING="ping -6"
fi
else
if [ "$UNAME" = Darwin -o "$UNAME" = FreeBSD -o "$UNAME" = OpenBSD ]; then
# ping by default pings ipv4, ping6 only pings ipv6
# in FreeBSD -4/-6 options are supported, in others not
PING=ping
else
# this can be linux or cygwin
# in linux it's not possible for sure to figure out if it supports -4/-6. only try and check for result code=2 (invalid option)
PING="ping -4"
fi
fi
case "$UNAME" in
Darwin)
$PING -c 1 -t 1 $2 >/dev/null 2>/dev/null
# WARNING ! macos ping6 command does not have timeout option. ping6 will fail. but without timeout is not an option.
;;
OpenBSD)
$PING -c 1 -w 1 $2 >/dev/null
;;
CYGWIN)
if starts_with "$(which ping)" /cygdrive; then
# cygwin does not have own ping by default. use windows PING.
$PING -n 1 -w 1000 $2 >/dev/null
else
ping_with_fix $2 '-c 1 -w 1'
fi
;;
*)
ping_with_fix $2 '-c 1 -W 1'
;;
esac
}
dnstest()
{
# $1 - dns server. empty for system resolver
"$LOOKUP" iana.org $1 >/dev/null 2>/dev/null
}
find_working_public_dns()
{
local dns
for dns in $DNSCHECK_DNS; do
pingtest 4 $dns && dnstest $dns && {
PUBDNS=$dns
return 0
}
done
return 1
}
lookup4()
{
# $1 - domain
# $2 - DNS
case "$LOOKUP" in
nslookup)
if is_linked_to_busybox nslookup; then
nslookup $1 $2 2>/dev/null | sed -e '1,3d' -nre 's/^.*:[^0-9]*(([0-9]{1,3}\.){3}[0-9]{1,3}).*$/\1/p'
else
nslookup $1 $2 2>/dev/null | sed -e '1,3d' -nre 's/^[^0-9]*(([0-9]{1,3}\.){3}[0-9]{1,3}).*$/\1/p'
fi
;;
host)
host -t A $1 $2 | grep "has address" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}'
;;
esac
}
check_dns_spoof()
{
# $1 - domain
# $2 - public DNS
# windows version of mdig outputs 0D0A line ending. remove 0D.
echo $1 | "$MDIG" --family=4 | tr -d '\r' >"$DNSCHECK_DIG1"
lookup4 $1 $2 >"$DNSCHECK_DIG2"
# check whether system resolver returns anything other than public DNS
grep -qvFf "$DNSCHECK_DIG2" "$DNSCHECK_DIG1"
}
check_dns_cleanup()
{
rm -f "$DNSCHECK_DIG1" "$DNSCHECK_DIG2" "$DNSCHECK_DIGS" 2>/dev/null
}
check_dns_()
{
local C1 C2 dom
DNS_IS_SPOOFED=0
[ "$SKIP_DNSCHECK" = 1 ] && return 0
echo \* checking DNS
[ -f "$DNSCHECK_DIGS" ] && rm -f "$DNSCHECK_DIGS"
dnstest || {
echo -- DNS is not working. It's either misconfigured or blocked or you don't have inet access.
return 1
}
echo system DNS is working
if find_working_public_dns ; then
echo comparing system resolver to public DNS : $PUBDNS
for dom in $DNSCHECK_DOM; do
if check_dns_spoof "$dom" $PUBDNS ; then
echo $dom : MISMATCH
echo -- system resolver :
cat "$DNSCHECK_DIG1"
echo -- $PUBDNS :
cat "$DNSCHECK_DIG2"
check_dns_cleanup
echo -- POSSIBLE DNS HIJACK DETECTED. ZAPRET WILL NOT HELP YOU IN CASE DNS IS SPOOFED !!!
echo -- DNS CHANGE OR DNSCRYPT MAY BE REQUIRED
DNS_IS_SPOOFED=1
return 1
else
echo $dom : OK
cat "$DNSCHECK_DIG1" >>"$DNSCHECK_DIGS"
fi
done
else
echo no working public DNS was found. looks like public DNS blocked.
for dom in $DNSCHECK_DOM; do echo $dom; done | "$MDIG" --threads=10 --family=4 >"$DNSCHECK_DIGS"
fi
echo "checking resolved IP uniqueness for : $DNSCHECK_DOM"
echo "censor's DNS can return equal result for multiple blocked domains."
C1=$(wc -l <"$DNSCHECK_DIGS")
C2=$(sort -u "$DNSCHECK_DIGS" | wc -l)
[ "$C1" -eq 0 ] &&
{
echo -- DNS is not working. It's either misconfigured or blocked or you don't have inet access.
check_dns_cleanup
return 1
}
[ "$C1" = "$C2" ] ||
{
echo system dns resolver has returned equal IPs for some domains checked above \($C1 total, $C2 unique\)
echo non-unique IPs :
sort "$DNSCHECK_DIGS" | uniq -d
echo -- POSSIBLE DNS HIJACK DETECTED. ZAPRET WILL NOT HELP YOU IN CASE DNS IS SPOOFED !!!
echo -- DNSCRYPT MAY BE REQUIRED
check_dns_cleanup
DNS_IS_SPOOFED=1
return 1
}
echo all resolved IPs are unique
echo -- DNS looks good
echo -- NOTE this check is Russia targeted. In your country other domains may be blocked.
check_dns_cleanup
return 0
}
check_dns()
{
local r
check_dns_
r=$?
[ "$DNS_IS_SPOOFED" = 1 ] && SECURE_DNS=${SECURE_DNS:-1}
[ "$SECURE_DNS" = 1 ] && {
doh_find_working || {
echo could not find working DoH server. exiting.
exitp 7
}
}
return $r
}
unprepare_all()
{
# make sure we are not in a middle state that impacts connectivity
ws_kill
wait
[ -n "$IPV" ] && {
pktws_ipt_unprepare_tcp $HTTP_PORT
pktws_ipt_unprepare_tcp $HTTPS_PORT
pktws_ipt_unprepare_udp $QUIC_PORT
}
cleanup
rm -f "${HDRTEMP}"* "${PARALLEL_OUT}"*
}
sigint()
{
echo
echo terminating...
unprepare_all
exitp 1
}
sigint_cleanup()
{
cleanup
exit 1
}
sigsilent()
{
# must not write anything here to stdout
unprepare_all
exit 1
}
fsleep_setup
fix_sbin_path
check_system
check_already
# no divert sockets in MacOS
[ "$UNAME" = "Darwin" ] && SKIP_PKTWS=1
[ "$UNAME" != CYGWIN -a "$SKIP_PKTWS" != 1 ] && require_root
check_prerequisites
trap sigint_cleanup INT
check_dns
check_virt
ask_params
trap - INT
PID=
NREPORT=
unset WF
trap sigint INT
trap sigsilent PIPE
trap sigsilent HUP
for dom in $DOMAINS; do
for IPV in $IPVS; do
configure_ip_version
[ "$ENABLE_HTTP" = 1 ] && {
[ "$SKIP_IPBLOCK" = 1 ] || check_domain_port_block $dom $HTTP_PORT
check_domain_http $dom
}
[ "$ENABLE_HTTPS_TLS12" = 1 -o "$ENABLE_HTTPS_TLS13" = 1 ] && [ "$SKIP_IPBLOCK" != 1 ] && check_domain_port_block $dom $HTTPS_PORT
[ "$ENABLE_HTTPS_TLS12" = 1 ] && check_domain_https_tls12 $dom
[ "$ENABLE_HTTPS_TLS13" = 1 ] && check_domain_https_tls13 $dom
[ "$ENABLE_HTTP3" = 1 ] && check_domain_http3 $dom
done
done
trap - HUP
trap - PIPE
trap - INT
cleanup
echo
echo \* SUMMARY
report_print
[ "$DOMAINS_COUNT" -gt 1 ] && {
echo
echo \* COMMON
result_intersection_print
echo
[ "$SCANLEVEL" = force ] || {
echo "blockcheck optimizes test sequence. To save time some strategies can be skipped if their test is considered useless."
echo "That's why COMMON intersection can miss strategies that would work for all domains."
echo "Use \"force\" scan level to test all strategies and generate trustable intersection."
echo "Current scan level was \"$SCANLEVEL\"".
}
}
echo
echo "Please note this SUMMARY does not guarantee a magic pill for you to copy/paste and be happy."
echo "Understanding how strategies work is very desirable."
echo "This knowledge allows to understand better which strategies to prefer and which to avoid if possible, how to combine strategies."
echo "Blockcheck does it's best to prioritize good strategies but it's not bullet-proof."
echo "It was designed not as magic pill maker but as a DPI bypass test tool."
exitp 0
================================================
FILE: common/base.sh
================================================
which()
{
# on some systems 'which' command is considered deprecated and not installed by default
# 'command -v' replacement does not work exactly the same way. it outputs shell aliases if present
# $1 - executable name
local IFS=:
[ "$1" != "${1#/}" ] && [ -x "$1" ] && {
echo "$1"
return 0
}
for p in $PATH; do
[ -x "$p/$1" ] && {
echo "$p/$1"
return 0
}
done
return 1
}
exists()
{
which "$1" >/dev/null 2>/dev/null
}
existf()
{
type "$1" >/dev/null 2>/dev/null
}
whichq()
{
which $1 2>/dev/null
}
exist_all()
{
while [ -n "$1" ]; do
exists "$1" || return 1
shift
done
return 0
}
on_off_function()
{
# $1 : function name on
# $2 : function name off
# $3 : 0 - off, 1 - on
local F="$1"
[ "$3" = "1" ] || F="$2"
shift
shift
shift
"$F" "$@"
}
contains()
{
# check if substring $2 contains in $1
[ "${1#*$2}" != "$1" ]
}
starts_with()
{
# $1 : what
# $2 : starts with
case "$1" in
"$2"*)
return 0
;;
esac
return 1
}
extract_arg()
{
# $1 - arg number
# $2,$3,... - args
local n=$1
while [ -n "$1" ]; do
shift
[ $n -eq 1 ] && { echo "$1"; return 0; }
n=$(($n-1))
done
return 1
}
find_str_in_list()
{
# $1 - string
# $2 - space separated values
local v
[ -n "$1" ] && {
for v in $2; do
[ "$v" = "$1" ] && return 0
done
}
return 1
}
end_with_newline()
{
local c="$(tail -c 1)"
[ "$c" = "" ]
}
trim()
{
awk '{gsub(/^ +| +$/,"")}1'
}
split_by_separator()
{
# $1 - string
# $2 - separator
# $3 - var name to get "before" part
# $4 - var name to get "after" part
local before="${1%%$2*}"
local after="${1#*$2}"
[ "$after" = "$1" ] && after=
[ -n "$3" ] && eval $3="\$before"
[ -n "$4" ] && eval $4="\$after"
}
tolower()
{
echo "$@" | tr 'A-Z' 'a-z'
}
dir_is_not_empty()
{
# $1 - directory
local n
[ -d "$1" ] || return 1
n=$(ls "$1" | wc -c | xargs)
[ "$n" != 0 ]
}
append_separator_list()
{
# $1 - var name to receive result
# $2 - separator
# $3 - quoter
# $4,$5,... - elements
local _var="$1" sep="$2" quo="$3" i
eval i="\$$_var"
shift; shift; shift
while [ -n "$1" ]; do
if [ -n "$i" ] ; then
i="$i$sep$quo$1$quo"
else
i="$quo$1$quo"
fi
shift
done
eval $_var="\$i"
}
make_separator_list()
{
eval $1=''
append_separator_list "$@"
}
make_comma_list()
{
# $1 - var name to receive result
# $2,$3,... - elements
local var="$1"
shift
make_separator_list $var , '' "$@"
}
make_quoted_comma_list()
{
# $1 - var name to receive result
# $2,$3,... - elements
local var="$1"
shift
make_separator_list $var , '"' "$@"
}
unique()
{
local i
for i in "$@"; do echo $i; done | sort -u | xargs
}
is_linked_to_busybox()
{
local IFS F P
IFS=:
for path in $PATH; do
F=$path/$1
P="$(readlink $F)"
if [ -z "$P" ] && [ -x $F ] && [ ! -L $F ]; then return 1; fi
[ "${P%busybox*}" != "$P" ] && return
done
}
get_dir_inode()
{
local dir="$1"
[ -L "$dir" ] && dir=$(readlink "$dir")
ls -id "$dir" | awk '{print $1}'
}
linux_min_version()
{
# $1 - major ver
# $2 - minor ver
local V1=$(sed -nre 's/^Linux version ([0-9]+)\.[0-9]+.*$/\1/p' /proc/version)
local V2=$(sed -nre 's/^Linux version [0-9]+\.([0-9]+).*$/\1/p' /proc/version)
[ -n "$V1" -a -n "$V2" ] && [ "$V1" -gt "$1" -o "$V1" -eq "$1" -a "$V2" -ge "$2" ]
}
linux_get_subsys()
{
local INIT="$(sed 's/\x0/\n/g' /proc/1/cmdline | head -n 1)"
[ -L "$INIT" ] && INIT=$(readlink "$INIT")
INIT="$(basename "$INIT")"
if [ -f "/etc/openwrt_release" ] && [ "$INIT" = "procd" ] ; then
SUBSYS=openwrt
elif [ -x "/bin/ndm" ] ; then
SUBSYS=keenetic
else
# generic linux
SUBSYS=
fi
}
openwrt_fw3()
{
[ ! -x /sbin/fw4 -a -x /sbin/fw3 ]
}
openwrt_fw4()
{
[ -x /sbin/fw4 ]
}
openwrt_fw3_integration()
{
[ "$FWTYPE" = iptables ] && openwrt_fw3
}
create_dev_stdin()
{
[ -e /dev/stdin ] || ln -s /proc/self/fd/0 /dev/stdin
}
call_for_multiple_items()
{
# $1 - function to get an item
# $2 - variable name to put result into
# $3 - space separated parameters to function $1
local i item items
for i in $3; do
$1 item $i
[ -n "$item" ] && {
if [ -n "$items" ]; then
items="$items $item"
else
items="$item"
fi
}
done
eval $2=\"$items\"
}
fix_sbin_path()
{
local IFS=':'
printf "%s\n" $PATH | grep -Fxq '/usr/sbin' || PATH="/usr/sbin:$PATH"
printf "%s\n" $PATH | grep -Fxq '/sbin' || PATH="/sbin:$PATH"
export PATH
}
# it can calculate floating point expr
calc()
{
LC_ALL=C awk "BEGIN { print $*}";
}
fsleep_setup()
{
[ -n "$FSLEEP" ] || {
if sleep 0.001 2>/dev/null; then
FSLEEP=1
elif busybox usleep 1 2>/dev/null; then
FSLEEP=2
else
local errtext="$(read -t 0.001 2>&1)"
if [ -z "$errtext" ]; then
FSLEEP=3
# newer openwrt has ucode with system function that supports timeout in ms
elif ucode -e "system(['sleep','1'], 1)" 2>/dev/null; then
FSLEEP=4
# older openwrt may have lua and nixio lua module
elif lua -e 'require "nixio".nanosleep(0,1)' 2>/dev/null ; then
FSLEEP=5
else
FSLEEP=0
fi
fi
}
}
msleep()
{
# $1 - milliseconds
case "$FSLEEP" in
1)
sleep $(calc $1/1000)
;;
2)
busybox usleep $(calc $1*1000)
;;
3)
read -t $(calc $1/1000)
;;
4)
ucode -e "system(['sleep','2147483647'], $1)"
;;
5)
lua -e "require 'nixio'.nanosleep($(($1/1000)),$(calc $1%1000*1000000))"
;;
*)
sleep $((($1+999)/1000))
esac
}
minsleep()
{
msleep 100
}
replace_char()
{
local a="$1"
local b="$2"
shift; shift
echo "$@" | tr "$a" "$b"
}
replace_str()
{
local a=$(echo "$1" | sed 's/\//\\\//g')
local b=$(echo "$2" | sed 's/\//\\\//g')
shift; shift
echo "$@" | sed "s/$a/$b/g"
}
setup_md5()
{
[ -n "$MD5" ] && return
MD5=md5sum
exists $MD5 || MD5=md5
}
md5f()
{
setup_md5
$MD5 | cut -d ' ' -f1
}
setup_random()
{
[ -n "$RCUT" ] && return
RCUT="cut -c 1-17"
# some shells can operate with 32 bit signed int
[ $((0x100000000)) = 0 ] && RCUT="cut -c 1-9"
}
random()
{
# $1 - min, $2 - max
local r rs
setup_random
if [ -c /dev/urandom ]; then
read rs </dev/urandom
else
rs="$RANDOM$RANDOM$(date)"
fi
# shells use signed int64
r=1$(echo $rs | md5f | sed 's/[^0-9]//g' | $RCUT)
echo $(( ($r % ($2-$1+1)) + $1 ))
}
shell_name()
{
[ -n "$SHELL_NAME" ] || {
[ -n "$UNAME" ] || UNAME="$(uname)"
if [ "$UNAME" = "Linux" ]; then
SHELL_NAME="$(readlink /proc/$$/exe)"
SHELL_NAME="$(basename "$SHELL_NAME")"
else
SHELL_NAME=$(ps -p $$ -o comm=)
fi
[ -n "$SHELL_NAME" ] || SHELL_NAME="$(basename "$SHELL")"
}
}
process_exists()
{
if exists pgrep; then
pgrep ^$1$ >/dev/null
elif exists pidof; then
pidof $1 >/dev/null
else
return 1
fi
}
win_process_exists()
{
tasklist /NH /FI "IMAGENAME eq ${1}.exe" | grep -q "^${1}.exe"
}
alloc_num()
{
# $1 - source var name
# $2 - target var name
# $3 - min
# $4 - max
local v
eval v="\$$2"
# do not replace existing value
[ -n "$v" ] && return
eval v="\$$1"
[ -n "$v" ] || v=$3
eval $2="$v"
v=$((v + 1))
[ $v -gt $4 ] && v=$3
eval $1="$v"
}
std_ports()
{
TPWS_PORTS_IPT=$(replace_char - : $TPWS_PORTS)
NFQWS_PORTS_TCP_IPT=$(replace_char - : $NFQWS_PORTS_TCP)
NFQWS_PORTS_TCP_KEEPALIVE_IPT=$(replace_char - : $NFQWS_PORTS_TCP_KEEPALIVE)
NFQWS_PORTS_UDP_IPT=$(replace_char - : $NFQWS_PORTS_UDP)
NFQWS_PORTS_UDP_KEEPALIVE_IPT=$(replace_char - : $NFQWS_PORTS_UDP_KEEPALIVE)
}
has_bad_ws_options()
{
# $1 - nfqws/tpws opts
contains "$1" "--ipset" && {
echo
echo "WARNING !!! --ipset parameter is present"
echo "It's OK if you only specialize already redirected traffic and also process the rest."
echo "If you redirect port X to process several IPs from the list and do nothing with the rest - IT'S VERY INEFFECTIVE !"
echo "Kernel ipsets should be used instead. Write custom scripts and filter IPs in kernel."
echo
}
return 1
}
check_bad_ws_options()
{
# $1 - 0 = stop, 1 = start
# $2 - nfqws/tpws options
if [ "$1" = 1 ] && has_bad_ws_options "$2"; then
echo "!!! REFUSING TO USE BAD OPTIONS : $2"
help_bad_ws_options
return 1
else
return 0
fi
}
help_bad_ws_options()
{
echo "WARNING ! BAD options detected"
}
================================================
FILE: common/custom.sh
================================================
custom_runner()
{
# $1 - function name
# $2+ - params
[ "$DISABLE_CUSTOM" = 1 ] && return 0
local n script FUNC=$1
shift
[ -d "$CUSTOM_DIR/custom.d" ] && {
dir_is_not_empty "$CUSTOM_DIR/custom.d" && {
for script in "$CUSTOM_DIR/custom.d/"*; do
[ -f "$script" ] || continue
unset -f $FUNC
. "$script"
existf $FUNC && $FUNC "$@"
done
}
}
}
alloc_tpws_port()
{
# $1 - target var name
alloc_num NUMPOOL_TPWS_PORT $1 910 979
}
alloc_qnum()
{
# $1 - target var name
alloc_num NUMPOOL_QNUM $1 65400 65499
}
alloc_dnum()
{
# alloc daemon number
# $1 - target var name
alloc_num NUMPOOL_DNUM $1 1000 1999
}
================================================
FILE: common/dialog.sh
================================================
read_yes_no()
{
# $1 - default (Y/N)
local A
read A
[ -z "$A" ] || ([ "$A" != "Y" ] && [ "$A" != "y" ] && [ "$A" != "N" ] && [ "$A" != "n" ]) && A=$1
[ "$A" = "Y" ] || [ "$A" = "y" ] || [ "$A" = "1" ]
}
ask_yes_no()
{
# $1 - default (Y/N or 0/1)
# $2 - text
local DEFAULT=$1
[ "$1" = "1" ] && DEFAULT=Y
[ "$1" = "0" ] && DEFAULT=N
[ -z "$DEFAULT" ] && DEFAULT=N
printf "$2 (default : $DEFAULT) (Y/N) ? "
read_yes_no $DEFAULT
}
ask_yes_no_var()
{
# $1 - variable name for answer : 0/1
# $2 - text
local DEFAULT
eval DEFAULT="\$$1"
if ask_yes_no "$DEFAULT" "$2"; then
eval $1=1
else
eval $1=0
fi
}
ask_list()
{
# $1 - mode var
# $2 - space separated value list
# $3 - (optional) default value
local M_DEFAULT
eval M_DEFAULT="\$$1"
local M_DEFAULT_VAR="$M_DEFAULT"
local M="" m
[ -n "$3" ] && { find_str_in_list "$M_DEFAULT" "$2" || M_DEFAULT="$3" ;}
n=1
for m in $2; do
echo $n : $m
n=$(($n+1))
done
printf "your choice (default : $M_DEFAULT) : "
read m
[ -n "$m" ] && M=$(echo $2 | cut -d ' ' -f$m 2>/dev/null)
[ -z "$M" ] && M="$M_DEFAULT"
echo selected : $M
eval $1="\"$M\""
[ "$M" != "$M_DEFAULT_VAR" ]
}
================================================
FILE: common/elevate.sh
================================================
require_root()
{
local exe preserve_env
echo \* checking privileges
[ $(id -u) -ne "0" ] && {
echo root is required
exe="$EXEDIR/$(basename "$0")"
exists sudo && {
echo elevating with sudo
exec sudo -E sh "$exe"
}
exists su && {
echo elevating with su
case "$UNAME" in
Linux)
preserve_env="--preserve-environment"
;;
FreeBSD|OpenBSD|Darwin)
preserve_env="-m"
;;
esac
exec su $preserve_env root -c "sh \"$exe\""
}
echo su or sudo not found
exitp 2
}
HAVE_ROOT=1
}
================================================
FILE: common/fwtype.sh
================================================
linux_ipt_avail()
{
exists iptables && exists ip6tables
}
linux_maybe_iptables_fwtype()
{
linux_ipt_avail && FWTYPE=iptables
}
linux_nft_avail()
{
exists nft
}
linux_fwtype()
{
[ -n "$FWTYPE" ] && return
FWTYPE=unsupported
linux_get_subsys
if [ "$SUBSYS" = openwrt ] ; then
# linux kernel is new enough if fw4 is there
if [ -x /sbin/fw4 ] && linux_nft_avail ; then
FWTYPE=nftables
else
linux_maybe_iptables_fwtype
fi
else
SUBSYS=
# generic linux
# flowtable is implemented since kernel 4.16
if linux_nft_avail && linux_min_version 4 16; then
FWTYPE=nftables
else
linux_maybe_iptables_fwtype
fi
fi
export FWTYPE
}
get_fwtype()
{
[ -n "$FWTYPE" ] && return
local UNAME="$(uname)"
case "$UNAME" in
Linux)
linux_fwtype
;;
FreeBSD)
if exists ipfw ; then
FWTYPE=ipfw
else
FWTYPE=unsupported
fi
;;
*)
FWTYPE=unsupported
;;
esac
export FWTYPE
}
================================================
FILE: common/installer.sh
================================================
GET_LIST_PREFIX=/ipset/get_
SYSTEMD_DIR=/lib/systemd
[ -d "$SYSTEMD_DIR" ] || SYSTEMD_DIR=/usr/lib/systemd
[ -d "$SYSTEMD_DIR" ] && SYSTEMD_SYSTEM_DIR="$SYSTEMD_DIR/system"
INIT_SCRIPT=/etc/init.d/zapret
exitp()
{
echo
echo press enter to continue
read A
exit $1
}
extract_var_def()
{
# $1 - var name
# this sed script parses single or multi line shell var assignments with optional ' or " enclosure
sed -n \
"/^$1=\"/ {
:s1
/\".*\"/ {
p
b
}
N
t c1
b s1
:c1
}
/^$1='/ {
:s2
/'.*'/ {
p
b
}
N
t c2
b s2
:c2
}
/^$1=/p
"
}
replace_var_def()
{
# $1 - var name
# $2 - new val
# $3 - conf file
# this sed script replaces single or multi line shell var assignments with optional ' or " enclosure
local repl
if [ -z "$2" ]; then
repl="#$1="
elif contains "$2" " "; then
repl="$1=\"$2\""
else
repl="$1=$2"
fi
local script=\
"/^#*[[:space:]]*$1=\"/ {
:s1
/\".*\"/ {
c\\
$repl
b
}
N
t c1
b s1
:c1
}
/^#*[[:space:]]*$1='/ {
:s2
/'.*'/ {
c\\
$repl
b
}
N
t c2
b s2
:c2
}
/^#*[[:space:]]*$1=/c\\
$repl"
# there's incompatibility with -i option on MacOS/BSD and busybox/GNU
if [ "$UNAME" = "Linux" ]; then
sed -i -e "$script" "$3"
else
sed -i '' -e "$script" "$3"
fi
}
parse_var_checked()
{
# $1 - file name
# $2 - var name
local tmp="/tmp/zvar-pid-$$.sh"
local v
cat "$1" | extract_var_def "$2" >"$tmp"
. "$tmp"
rm -f "$tmp"
eval v="\$$2"
# trim
v="$(echo "$v" | trim)"
eval $2=\""$v"\"
}
parse_vars_checked()
{
# $1 - file name
# $2,$3,... - var names
local f="$1"
shift
while [ -n "$1" ]; do
parse_var_checked "$f" $1
shift
done
}
edit_file()
{
# $1 - file name
local ed="$EDITOR"
[ -n "$ed" ] || {
for e in mcedit nano vim vi; do
exists "$e" && {
ed="$e"
break
}
done
}
[ -n "$ed" ] && "$ed" "$1"
}
echo_var()
{
local v
eval v="\$$1"
if find_str_in_list $1 "$EDITVAR_NEWLINE_VARS"; then
echo "$1=\""
echo "$v\"" | tr '\n' ' ' | tr -d '\r' | sed -e 's/^ *//' -e 's/ *$//' -e "s/$EDITVAR_NEWLINE_DELIMETER /$EDITVAR_NEWLINE_DELIMETER\n/g"
else
if contains "$v" " "; then
echo $1=\"$v\"
else
echo $1=$v
fi
fi
}
edit_vars()
{
# $1,$2,... - var names
local n=1 var tmp="/tmp/zvars-pid-$$.txt"
rm -f "$tmp"
while : ; do
eval var="\${$n}"
[ -n "$var" ] || break
echo_var $var >> "$tmp"
n=$(($n+1))
done
edit_file "$tmp" && parse_vars_checked "$tmp" "$@"
rm -f "$tmp"
}
list_vars()
{
while [ -n "$1" ] ; do
echo_var $1
shift
done
echo
}
openrc_test()
{
exists rc-update || return 1
# some systems do not usse openrc-init but launch openrc from inittab
[ "$INIT" = "openrc-init" ] || grep -qE "sysinit.*openrc" /etc/inittab 2>/dev/null
}
check_system()
{
# $1 - nonempty = do not fail on unknown rc system
echo \* checking system
SYSTEM=
SUBSYS=
SYSTEMCTL="$(whichq systemctl)"
get_fwtype
OPENWRT_FW3=
OPENWRT_FW4=
local info
UNAME=$(uname)
if [ "$UNAME" = "Linux" ]; then
# do not use 'exe' because it requires root
local INIT="$(sed 's/\x0/\n/g' /proc/1/cmdline | head -n 1)"
[ -L "$INIT" ] && INIT=$(readlink "$INIT")
INIT="$(basename "$INIT")"
# some distros include systemctl without systemd
if [ -d "$SYSTEMD_DIR" ] && [ -x "$SYSTEMCTL" ] && [ "$INIT" = "systemd" ]; then
SYSTEM=systemd
[ -f "$EXEDIR/init.d/sysv/functions" ] && . "$EXEDIR/init.d/sysv/functions"
elif [ -f "/etc/openwrt_release" ] && exists opkg || exists apk && exists uci && [ "$INIT" = "procd" ] ; then
SYSTEM=openwrt
OPENWRT_PACKAGER=opkg
OPENWRT_PACKAGER_INSTALL="opkg install"
OPENWRT_PACKAGER_UPDATE="opkg update"
exists apk && {
OPENWRT_PACKAGER=apk
OPENWRT_PACKAGER_INSTALL="apk add"
OPENWRT_PACKAGER_UPDATE=
}
info="package manager $OPENWRT_PACKAGER\n"
if openwrt_fw3 ; then
OPENWRT_FW3=1
info="${info}firewall fw3"
if is_ipt_flow_offload_avail; then
info="$info. hardware flow offloading requires iptables."
else
info="$info. flow offloading unavailable."
fi
elif openwrt_fw4; then
OPENWRT_FW4=1
info="${info}firewall fw4. flow offloading requires nftables."
fi
[ -f "$EXEDIR/init.d/openwrt/functions" ] && . "$EXEDIR/init.d/openwrt/functions"
elif openrc_test; then
SYSTEM=openrc
[ -f "$EXEDIR/init.d/sysv/functions" ] && . "$EXEDIR/init.d/sysv/functions"
else
echo system is not either systemd, openrc or openwrt based
echo easy installer can set up config settings but can\'t configure auto start
echo you have to do it manually. check readme.md for manual setup info.
if [ -n "$1" ] || ask_yes_no N "do you want to continue"; then
SYSTEM=linux
else
exitp 5
fi
[ -f "$EXEDIR/init.d/sysv/functions" ] && . "$EXEDIR/init.d/sysv/functions"
fi
linux_get_subsys
elif [ "$UNAME" = "Darwin" ]; then
SYSTEM=macos
[ -f "$EXEDIR/init.d/macos/functions" ] && . "$EXEDIR/init.d/macos/functions"
else
echo easy installer only supports Linux and MacOS. check readme.md for supported systems and manual setup info.
exitp 5
fi
echo system is based on $SYSTEM
[ -n "$info" ] && printf "${info}\n"
}
get_free_space_mb()
{
df -m "$1" | awk '/[0-9]%/{print $(NF-2)}'
}
get_ram_kb()
{
grep MemTotal /proc/meminfo | awk '{print $2}'
}
get_ram_mb()
{
local R=$(get_ram_kb)
echo $(($R/1024))
}
crontab_del()
{
exists crontab || return
echo \* removing crontab entry
CRONTMP=/tmp/cron.tmp
crontab -l >$CRONTMP 2>/dev/null
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
echo removing following entries from crontab :
grep "$GET_LIST_PREFIX" $CRONTMP
grep -v "$GET_LIST_PREFIX" $CRONTMP >$CRONTMP.2
crontab $CRONTMP.2
rm -f $CRONTMP.2
fi
rm -f $CRONTMP
}
crontab_del_quiet()
{
exists crontab || return
CRONTMP=/tmp/cron.tmp
crontab -l >$CRONTMP 2>/dev/null
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
grep -v "$GET_LIST_PREFIX" $CRONTMP >$CRONTMP.2
crontab $CRONTMP.2
rm -f $CRONTMP.2
fi
rm -f $CRONTMP
}
crontab_add()
{
# $1 - hour min
# $2 - hour max
[ -x "$GET_LIST" ] && {
echo \* adding crontab entry
if exists crontab; then
CRONTMP=/tmp/cron.tmp
crontab -l >$CRONTMP 2>/dev/null
if grep -q "$GET_LIST_PREFIX" $CRONTMP; then
echo some entries already exist in crontab. check if this is corrent :
grep "$GET_LIST_PREFIX" $CRONTMP
else
end_with_newline <"$CRONTMP" || echo >>"$CRONTMP"
echo "$(random 0 59) $(random $1 $2) */2 * * $GET_LIST" >>$CRONTMP
crontab $CRONTMP
fi
rm -f $CRONTMP
else
echo '!!! CRON IS ABSENT !!! LISTS AUTO UPDATE WILL NOT WORK !!!'
fi
}
}
cron_ensure_running()
{
# if no crontabs present in /etc/cron openwrt init script does not launch crond. this is default
[ "$SYSTEM" = "openwrt" ] && {
/etc/init.d/cron enable
/etc/init.d/cron start
}
}
service_start_systemd()
{
echo \* starting zapret service
"$SYSTEMCTL" start zapret || {
echo could not start zapret service
exitp 30
}
}
service_stop_systemd()
{
echo \* stopping zapret service
"$SYSTEMCTL" daemon-reload
"$SYSTEMCTL" disable zapret
"$SYSTEMCTL" stop zapret
}
service_remove_systemd()
{
echo \* removing zapret service
rm -f "$SYSTEMD_SYSTEM_DIR/zapret.service"
"$SYSTEMCTL" daemon-reload
}
timer_remove_systemd()
{
echo \* removing zapret-list-update timer
"$SYSTEMCTL" daemon-reload
"$SYSTEMCTL" disable zapret-list-update.timer
"$SYSTEMCTL" stop zapret-list-update.timer
rm -f "$SYSTEMD_SYSTEM_DIR/zapret-list-update.service" "$SYSTEMD_SYSTEM_DIR/zapret-list-update.timer"
"$SYSTEMCTL" daemon-reload
}
install_sysv_init()
{
# $1 - "0"=disable
echo \* installing init script
[ -x "$INIT_SCRIPT" ] && {
"$INIT_SCRIPT" stop
"$INIT_SCRIPT" disable
}
ln -fs "$INIT_SCRIPT_SRC" "$INIT_SCRIPT"
[ "$1" != "0" ] && "$INIT_SCRIPT" enable
}
install_openrc_init()
{
# $1 - "0"=disable
echo \* installing init script
[ -x "$INIT_SCRIPT" ] && {
"$INIT_SCRIPT" stop
rc-update del zapret
}
ln -fs "$INIT_SCRIPT_SRC" "$INIT_SCRIPT"
[ "$1" != "0" ] && rc-update add zapret
}
service_remove_openrc()
{
echo \* removing zapret service
[ -x "$INIT_SCRIPT" ] && {
rc-update del zapret
"$INIT_SCRIPT" stop
}
rm -f "$INIT_SCRIPT"
}
service_start_sysv()
{
[ -x "$INIT_SCRIPT" ] && {
echo \* starting zapret service
"$INIT_SCRIPT" start || {
echo could not start zapret service
exitp 30
}
}
}
service_stop_sysv()
{
[ -x "$INIT_SCRIPT" ] && {
echo \* stopping zapret service
"$INIT_SCRIPT" stop
}
}
service_remove_sysv()
{
echo \* removing zapret service
[ -x "$INIT_SCRIPT" ] && {
"$INIT_SCRIPT" disable
"$INIT_SCRIPT" stop
}
rm -f "$INIT_SCRIPT"
}
check_kmod()
{
[ -f "/lib/modules/$(uname -r)/$1.ko" ]
}
check_package_exists_openwrt()
{
[ -n "$($OPENWRT_PACKAGER list $1)" ]
}
check_package_openwrt()
{
case $OPENWRT_PACKAGER in
opkg)
[ -n "$(opkg list-installed $1)" ] && return 0
local what="$(opkg whatprovides $1 | tail -n +2 | head -n 1)"
[ -n "$what" ] || return 1
[ -n "$(opkg list-installed $what)" ]
;;
apk)
apk info -e $1
;;
esac
}
check_packages_openwrt()
{
for pkg in $@; do
check_package_openwrt $pkg || return
done
}
install_openwrt_iface_hook()
{
echo \* installing ifup hook
ln -fs "$OPENWRT_IFACE_HOOK" /etc/hotplug.d/iface
}
remove_openwrt_iface_hook()
{
echo \* removing ifup hook
rm -f /etc/hotplug.d/iface/??-zapret
}
openwrt_fw_section_find()
{
# $1 - fw include postfix
# echoes section number
i=0
while true
do
path=$(uci -q get firewall.@include[$i].path)
[ -n "$path" ] || break
[ "$path" = "$OPENWRT_FW_INCLUDE$1" ] && {
echo $i
return 0
}
i=$(($i+1))
done
return 1
}
openwrt_fw_section_del()
{
# $1 - fw include postfix
local id="$(openwrt_fw_section_find $1)"
[ -n "$id" ] && {
uci delete firewall.@include[$id] && uci commit firewall
rm -f "$OPENWRT_FW_INCLUDE$1"
}
}
openwrt_fw_section_add()
{
openwrt_fw_section_find ||
{
uci add firewall include >/dev/null || return
echo -1
}
}
openwrt_fw_section_configure()
{
local id="$(openwrt_fw_section_add $1)"
[ -z "$id" ] ||
! uci set firewall.@include[$id].path="$OPENWRT_FW_INCLUDE" ||
! uci set firewall.@include[$id].reload="1" ||
! uci commit firewall &&
{
echo could not add firewall include
exitp 50
}
}
install_openwrt_firewall()
{
echo \* installing firewall script $1
echo "linking : $FW_SCRIPT_SRC => $OPENWRT_FW_INCLUDE"
ln -fs "$FW_SCRIPT_SRC" "$OPENWRT_FW_INCLUDE"
openwrt_fw_section_configure $1
}
restart_openwrt_firewall()
{
echo \* restarting firewall
local FW=fw4
[ -n "$OPENWRT_FW3" ] && FW=fw3
exists $FW && $FW -q restart || {
echo could not restart firewall $FW
}
}
remove_openwrt_firewall()
{
echo \* removing firewall script
openwrt_fw_section_del
# from old zapret versions. now we use single include
openwrt_fw_section_del 6
}
clear_ipset()
{
echo "* clearing ipset(s)"
# free some RAM
"$IPSET_DIR/create_ipset.sh" clear
}
service_install_macos()
{
echo \* installing zapret service
ln -fs "$ZAPRET_BASE/init.d/macos/zapret.plist" /Library/LaunchDaemons
}
service_start_macos()
{
echo \* starting zapret service
"$INIT_SCRIPT_SRC" start
}
service_stop_macos()
{
echo \* stopping zapret service
"$INIT_SCRIPT_SRC" stop
}
service_remove_macos()
{
echo \* removing zapret service
rm -f /Library/LaunchDaemons/zapret.plist
zapret_stop_daemons
}
remove_macos_firewall()
{
echo \* removing zapret PF hooks
pf_anchors_clear
pf_anchors_del
pf_anchor_root_del
pf_anchor_root_reload
}
sedi()
{
# MacOS doesnt support -i without parameter. busybox doesnt support -i with parameter.
# its not possible to put "sed -i ''" to a variable and then use it
if [ "$SYSTEM" = "macos" ]; then
sed -i '' "$@"
else
sed -i "$@"
fi
}
write_config_var()
{
# $1 - mode var
local M
eval M="\$$1"
# replace / => \/
#M=${M//\//\\\/}
M=$(echo $M | sed 's/\//\\\//g' | trim)
grep -q "^[[:space:]]*$1=\|^#*[[:space:]]*$1=" "$ZAPRET_CONFIG" || {
# var does not exist in config. add it
echo $1= >>"$ZAPRET_CONFIG"
}
replace_var_def $1 "$M" "$ZAPRET_CONFIG"
}
no_prereq_exit()
{
echo could not install prerequisites
exitp 6
}
check_prerequisites_linux()
{
echo \* checking prerequisites
local s cmd PKGS UTILS req="curl curl"
local APTGET DNF YUM PACMAN ZYPPER EOPKG APK
case "$FWTYPE" in
iptables)
req="$req iptables iptables ip6tables iptables ipset ipset"
;;
nftables)
req="$req nft nftables"
;;
esac
PKGS=$(for s in $req; do echo $s; done |
while read cmd; do
read pkg
exists $cmd || echo $pkg
done | sort -u | xargs)
UTILS=$(for s in $req; do echo $s; done |
while read cmd; do
read pkg
echo $cmd
done | sort -u | xargs)
if [ -z "$PKGS" ] ; then
echo required utilities exist : $UTILS
else
echo \* installing prerequisites
echo packages required : $PKGS
APTGET=$(whichq apt-get)
DNF=$(whichq dnf)
YUM=$(whichq yum)
PACMAN=$(whichq pacman)
ZYPPER=$(whichq zypper)
EOPKG=$(whichq eopkg)
APK=$(whichq apk)
if [ -x "$APTGET" ] ; then
"$APTGET" update
"$APTGET" install -y --no-install-recommends $PKGS dnsutils || no_prereq_exit
elif [ -x "$DNF" ] ; then
"$DNF" -y install $PKGS || no_prereq_exit
elif [ -x "$YUM" ] ; then
"$YUM" -y install $PKGS || no_prereq_exit
elif [ -x "$PACMAN" ] ; then
"$PACMAN" -Syy
"$PACMAN" --noconfirm -S $PKGS || no_prereq_exit
elif [ -x "$ZYPPER" ] ; then
"$ZYPPER" --non-interactive install $PKGS || no_prereq_exit
elif [ -x "$EOPKG" ] ; then
"$EOPKG" -y install $PKGS || no_prereq_exit
elif [ -x "$APK" ] ; then
"$APK" update
# for alpine
[ "$FWTYPE" = iptables ] && [ -n "$($APK list ip6tables)" ] && PKGS="$PKGS ip6tables"
"$APK" add $PKGS || no_prereq_exit
else
echo supported package manager not found
echo you must manually install : $UTILS
exitp 5
fi
fi
}
removable_pkgs_openwrt()
{
local pkg PKGS2
[ -n "$OPENWRT_FW4" ] && PKGS2="$PKGS2 iptables-zz-legacy iptables ip6tables-zz-legacy ip6tables"
[ -n "$OPENWRT_FW3" ] && PKGS2="$PKGS2 nftables-json nftables-nojson nftables"
PKGS=
for pkg in $PKGS2; do
check_package_exists_openwrt $pkg && PKGS="${PKGS:+$PKGS }$pkg"
done
PKGS="ipset iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra iptables-mod-u32 ip6tables-mod-nat ip6tables-extra kmod-nft-queue gzip coreutils-sort coreutils-sleep curl $PKGS"
}
openwrt_fix_broken_apk_uninstall_scripts()
{
# at least in early snapshots with apk removing gnu gzip, sort, ... does not restore links to busybox
# system may become unusable
exists sort || { echo fixing missing sort; ln -fs /bin/busybox /usr/bin/sort; }
exists gzip || { echo fixing missing gzip; ln -fs /bin/busybox /bin/gzip; }
exists sleep || { echo fixing missing sleep; ln -fs /bin/busybox /bin/sleep; }
}
remove_extra_pkgs_openwrt()
{
local PKGS
echo \* remove dependencies
removable_pkgs_openwrt
echo these packages may have been installed by install_easy.sh : $PKGS
ask_yes_no N "do you want to remove them" && {
case $OPENWRT_PACKAGER in
opkg)
opkg remove --autoremove $PKGS
;;
apk)
apk del $PKGS
openwrt_fix_broken_apk_uninstall_scripts
;;
esac
}
}
check_prerequisites_openwrt()
{
echo \* checking prerequisites
local PKGS="curl" UPD=0 local pkg_iptables
case "$FWTYPE" in
iptables)
pkg_iptables=iptables
check_package_exists_openwrt iptables-zz-legacy && pkg_iptables=iptables-zz-legacy
PKGS="$PKGS ipset $pkg_iptables iptables-mod-extra iptables-mod-nfqueue iptables-mod-filter iptables-mod-ipopt iptables-mod-conntrack-extra iptables-mod-u32"
check_package_exists_openwrt ip6tables-zz-legacy && pkg_iptables=ip6tables-zz-legacy
[ "$DISABLE_IPV6" = 1 ] || PKGS="$PKGS $pkg_iptables ip6tables-mod-nat ip6tables-extra"
;;
nftables)
PKGS="$PKGS nftables kmod-nft-nat kmod-nft-offload kmod-nft-queue"
;;
esac
if check_packages_openwrt $PKGS ; then
echo everything is present
else
echo \* installing prerequisites
$OPENWRT_PACKAGER_UPDATE
UPD=1
$OPENWRT_PACKAGER_INSTALL $PKGS || {
echo could not install prerequisites
exitp 6
}
fi
is_linked_to_busybox gzip && {
echo
echo your system uses default busybox gzip. its several times slower than GNU gzip.
echo ip/host list scripts will run much faster with GNU gzip
echo installer can install GNU gzip but it requires about 100 Kb space
if ask_yes_no N "do you want to install GNU gzip"; then
[ "$UPD" = "0" ] && {
$OPENWRT_PACKAGER_UPDATE
UPD=1
}
$OPENWRT_PACKAGER_INSTALL --force-overwrite gzip
fi
}
is_linked_to_busybox sort && {
echo
echo your system uses default busybox sort. its much slower and consumes much more RAM than GNU sort
echo ip/host list scripts will run much faster with GNU sort
echo installer can install GNU sort but it requires about 100 Kb space
if ask_yes_no N "do you want to install GNU sort"; then
[ "$UPD" = "0" ] && {
$OPENWRT_PACKAGER_UPDATE
UPD=1
}
$OPENWRT_PACKAGER_INSTALL --force-overwrite coreutils-sort
fi
}
[ "$FSLEEP" = 0 ] && is_linked_to_busybox sleep && {
echo
echo no methods of sub-second sleep were found.
echo if you want to speed up blockcheck install coreutils-sleep. it requires about 40 Kb space
if ask_yes_no N "do you want to install COREUTILS sleep"; then
[ "$UPD" = "0" ] && {
$OPENWRT_PACKAGER_UPDATE
UPD=1
}
$OPENWRT_PACKAGER_INSTALL --force-overwrite coreutils-sleep
fsleep_setup
fi
}
}
select_ipv6()
{
local T=N
[ "$DISABLE_IPV6" != '1' ] && T=Y
local old6=$DISABLE_IPV6
echo
if ask_yes_no $T "enable ipv6 support"; then
DISABLE_IPV6=0
else
DISABLE_IPV6=1
fi
[ "$old6" != "$DISABLE_IPV6" ] && write_config_var DISABLE_IPV6
}
select_fwtype()
{
echo
[ $(get_ram_mb) -le 400 ] && {
echo WARNING ! you are running a low RAM system
echo WARNING ! nft requires lots of RAM to load huge ip sets, much more than ipsets require
echo WARNING ! if you need large lists it may be necessary to fall back to iptables+ipset firewall
}
echo select firewall type :
ask_list FWTYPE "iptables nftables" "$FWTYPE"
# always write config var to prevent auto discovery every time
write_config_var FWTYPE
}
dry_run_tpws_()
{
local TPWS="$ZAPRET_BASE/tpws/tpws"
echo verifying tpws options
"$TPWS" --dry-run ${WS_USER:+--user=$WS_USER} "$@"
}
dry_run_nfqws_()
{
local NFQWS="$ZAPRET_BASE/nfq/nfqws"
echo verifying nfqws options
"$NFQWS" --dry-run ${WS_USER:+--user=$WS_USER} "$@"
}
dry_run_tpws()
{
[ "$TPWS_ENABLE" = 1 ] || return 0
local opt="$TPWS_OPT" port=${TPPORT_SOCKS:-988}
filter_apply_hostlist_target opt
dry_run_tpws_ --port=$port $opt
}
dry_run_tpws_socks()
{
[ "$TPWS_SOCKS_ENABLE" = 1 ] || return 0
local opt="$TPWS_SOCKS_OPT" port=${TPPORT:-987}
filter_apply_hostlist_target opt
dry_run_tpws_ --port=$port --socks $opt
}
dry_run_nfqws()
{
[ "$NFQWS_ENABLE" = 1 ] || return 0
local opt="$NFQWS_OPT" qn=${QNUM:-200}
filter_apply_hostlist_target opt
dry_run_nfqws_ --qnum=$qn $opt
}
================================================
FILE: common/ipt.sh
================================================
std_ports
ipt_connbytes="-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes"
IPSET_EXCLUDE="-m set ! --match-set nozapret"
IPSET_EXCLUDE6="-m set ! --match-set nozapret6"
IPBAN_EXCLUDE="-m set ! --match-set ipban"
IPBAN_EXCLUDE6="-m set ! --match-set ipban6"
ipt()
{
iptables $FW_EXTRA_PRE -C "$@" $FW_EXTRA_POST >/dev/null 2>/dev/null || iptables $FW_EXTRA_PRE -I "$@" $FW_EXTRA_POST
}
ipta()
{
iptables $FW_EXTRA_PRE -C "$@" $FW_EXTRA_POST >/dev/null 2>/dev/null || iptables $FW_EXTRA_PRE -A "$@" $FW_EXTRA_POST
}
ipt_del()
{
iptables $FW_EXTRA_PRE -C "$@" $FW_EXTRA_POST >/dev/null 2>/dev/null && iptables $FW_EXTRA_PRE -D "$@" $FW_EXTRA_POST
}
ipt_add_del()
{
on_off_function ipt ipt_del "$@"
}
ipta_add_del()
{
on_off_function ipta ipt_del "$@"
}
ipt6()
{
ip6tables -C "$@" >/dev/null 2>/dev/null || ip6tables -I "$@"
}
ipt6a()
{
ip6tables -C "$@" >/dev/null 2>/dev/null || ip6tables -A "$@"
}
ipt6_del()
{
ip6tables -C "$@" >/dev/null 2>/dev/null && ip6tables -D "$@"
}
ipt6_add_del()
{
on_off_function ipt6 ipt6_del "$@"
}
ipt6a_add_del()
{
on_off_function ipt6a ipt6_del "$@"
}
is_ipt_flow_offload_avail()
{
# $1 = '' for ipv4, '6' for ipv6
grep -q FLOWOFFLOAD 2>/dev/null /proc/net/ip$1_tables_targets
}
filter_apply_ipset_target4()
{
# $1 - var name of ipv4 iptables filter
if [ "$MODE_FILTER" = "ipset" ]; then
eval $1="\"\$$1 -m set --match-set zapret dst\""
fi
}
filter_apply_ipset_target6()
{
# $1 - var name of ipv6 iptables filter
if [ "$MODE_FILTER" = "ipset" ]; then
eval $1="\"\$$1 -m set --match-set zapret6 dst\""
fi
}
filter_apply_ipset_target()
{
# $1 - var name of ipv4 iptables filter
# $2 - var name of ipv6 iptables filter
filter_apply_ipset_target4 $1
filter_apply_ipset_target6 $2
}
reverse_nfqws_rule_stream()
{
sed -e 's/-o /-i /g' -e 's/--dport /--sport /g' -e 's/--dports /--sports /g' -e 's/ dst$/ src/' -e 's/ dst / src /g' -e 's/--connbytes-dir=original/--connbytes-dir=reply/g' -e "s/-m mark ! --mark $DESYNC_MARK\/$DESYNC_MARK//g"
}
reverse_nfqws_rule()
{
echo "$@" | reverse_nfqws_rule_stream
}
prepare_tpws_fw4()
{
# otherwise linux kernel will treat 127.0.0.0/8 as "martian" ip and refuse routing to it
# NOTE : kernels <3.6 do not have this feature. consider upgrading or change DNAT to REDIRECT and do not bind to 127.0.0.0/8
[ "$DISABLE_IPV4" = "1" ] || {
iptables -N input_rule_zapret 2>/dev/null
ipt input_rule_zapret -d $TPWS_LOCALHOST4 -j RETURN
ipta input_rule_zapret -d 127.0.0.0/8 -j DROP
ipt INPUT ! -i lo -j input_rule_zapret
prepare_route_localnet
}
}
unprepare_tpws_fw4()
{
[ "$DISABLE_IPV4" = "1" ] || {
unprepare_route_localnet
ipt_del INPUT ! -i lo -j input_rule_zapret
iptables -F input_rule_zapret 2>/dev/null
iptables -X input_rule_zapret 2>/dev/null
}
}
unprepare_tpws_fw()
{
unprepare_tpws_fw4
}
ipt_mark_filter()
{
[ -n "$FILTER_MARK" ] && echo "-m mark --mark $FILTER_MARK/$FILTER_MARK"
}
ipt_print_op()
{
if [ "$1" = "1" ]; then
echo "Inserting ip$4tables rule for $3 : $2"
else
echo "Deleting ip$4tables rule for $3 : $2"
fi
}
_fw_tpws4()
{
# $1 - 1 - add, 0 - del
# $2 - iptable filter for ipv4
# $3 - tpws port
# $4 - lan interface names space separated
# $5 - wan interface names space separated
[ "$DISABLE_IPV4" = "1" -o -z "$2" ] || {
local i rule
[ "$1" = 1 ] && prepare_tpws_fw4
ipt_print_op $1 "$2" "tpws (port $3)"
rule="$(ipt_mark_filter) $2 $IPSET_EXCLUDE dst $IPBAN_EXCLUDE dst -j DNAT --to $TPWS_LOCALHOST4:$3"
for i in $4 ; do
ipt_add_del $1 PREROUTING -t nat -i $i $rule
done
rule="-m owner ! --uid-owner $WS_USER $rule"
if [ -n "$5" ]; then
for i in $5; do
ipt_add_del $1 OUTPUT -t nat -o $i $rule
done
else
ipt_add_del $1 OUTPUT -t nat $rule
fi
}
}
_fw_tpws6()
{
# $1 - 1 - add, 0 - del
# $2 - iptable filter for ipv6
# $3 - tpws port
# $4 - lan interface names space separated
# $5 - wan interface names space separated
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || {
local i rule DNAT6
ipt_print_op $1 "$2" "tpws (port $3)" 6
rule="$(ipt_mark_filter) $2 $IPSET_EXCLUDE6 dst $IPBAN_EXCLUDE6 dst"
for i in $4 ; do
_dnat6_target $i DNAT6
[ -n "$DNAT6" -a "$DNAT6" != "-" ] && ipt6_add_del $1 PREROUTING -t nat -i $i $rule -j DNAT --to [$DNAT6]:$3
done
rule="-m owner ! --uid-owner $WS_USER $rule -j DNAT --to [::1]:$3"
if [ -n "$5" ]; then
for i in $5; do
ipt6_add_del $1 OUTPUT -t nat -o $i $rule
done
else
ipt6_add_del $1 OUTPUT -t nat $rule
fi
}
}
fw_tpws()
{
# $1 - 1 - add, 0 - del
# $2 - iptable filter for ipv4
# $3 - iptable filter for ipv6
# $4 - tpws port
fw_tpws4 $1 "$2" $4
fw_tpws6 $1 "$3" $4
}
_fw_nfqws_post4()
{
# $1 - 1 - add, 0 - del
# $2 - iptable filter for ipv4
# $3 - queue number
# $4 - wan interface names space separated
[ "$DISABLE_IPV4" = "1" -o -z "$2" ] || {
local i
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)"
rule="$(ipt_mark_filter) -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK $2 $IPSET_EXCLUDE dst -j NFQUEUE --queue-num $3 --queue-bypass"
if [ -n "$4" ] ; then
for i in $4; do
ipt_add_del $1 POSTROUTING -t mangle -o $i $rule
done
else
ipt_add_del $1 POSTROUTING -t mangle $rule
fi
}
}
_fw_nfqws_post6()
{
# $1 - 1 - add, 0 - del
# $2 - iptable filter for ipv6
# $3 - queue number
# $4 - wan interface names space separated
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || {
local i
ipt_print_op $1 "$2" "nfqws postrouting (qnum $3)" 6
rule="$(ipt_mark_filter) -m mark ! --mark $DESYNC_MARK/$DESYNC_MARK $2 $IPSET_EXCLUDE6 dst -j NFQUEUE --queue-num $3 --queue-bypass"
if [ -n "$4" ] ; then
for i in $4; do
ipt6_add_del $1 POSTROUTING -t mangle -o $i $rule
done
else
ipt6_add_del $1 POSTROUTING -t mangle $rule
fi
}
}
fw_nfqws_post()
{
# $1 - 1 - add, 0 - del
# $2 - iptable filter for ipv4
# $3 - iptable filter for ipv6
# $4 - queue number
fw_nfqws_post4 $1 "$2" $4
fw_nfqws_post6 $1 "$3" $4
}
_fw_nfqws_pre4()
{
# $1 - 1 - add, 0 - del
# $2 - iptable filter for ipv4
# $3 - queue number
# $4 - wan interface names space separated
[ "$DISABLE_IPV4" = "1" -o -z "$2" ] || {
local i
ipt_print_op $1 "$2" "nfqws input+forward (qnum $3)"
rule="$2 $IPSET_EXCLUDE src -j NFQUEUE --queue-num $3 --queue-bypass"
if [ -n "$4" ] ; then
for i in $4; do
# iptables PREROUTING chain is before NAT. not possible to have DNATed ip's there
ipt_add_del $1 INPUT -t mangle -i $i $rule
ipt_add_del $1 FORWARD -t mangle -i $i $rule
done
else
ipt_add_del $1 INPUT -t mangle $rule
ipt_add_del $1 FORWARD -t mangle $rule
fi
}
}
_fw_nfqws_pre6()
{
# $1 - 1 - add, 0 - del
# $2 - iptable filter for ipv6
# $3 - queue number
# $4 - wan interface names space separated
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || {
local i
ipt_print_op $1 "$2" "nfqws input+forward (qnum $3)" 6
rule="$2 $IPSET_EXCLUDE6 src -j NFQUEUE --queue-num $3 --queue-bypass"
if [ -n "$4" ] ; then
for i in $4; do
# iptables PREROUTING chain is before NAT. not possible to have DNATed ip's there
ipt6_add_del $1 INPUT -t mangle -i $i $rule
ipt6_add_del $1 FORWARD -t mangle -i $i $rule
done
else
ipt6_add_del $1 INPUT -t mangle $rule
ipt6_add_del $1 FORWARD -t mangle $rule
fi
}
}
fw_nfqws_pre()
{
# $1 - 1 - add, 0 - del
# $2 - iptable filter for ipv4
# $3 - iptable filter for ipv6
# $4 - queue number
fw_nfqws_pre4 $1 "$2" $4
fw_nfqws_pre6 $1 "$3" $4
}
fw_reverse_nfqws_rule4()
{
fw_nfqws_pre4 $1 "$(reverse_nfqws_rule "$2")" $3
}
fw_reverse_nfqws_rule6()
{
fw_nfqws_pre6 $1 "$(reverse_nfqws_rule "$2")" $3
}
fw_reverse_nfqws_rule()
{
# ensure that modes relying on incoming traffic work
# $1 - 1 - add, 0 - del
# $2 - rule4
# $3 - rule6
# $4 - queue number
fw_reverse_nfqws_rule4 $1 "$2" $4
fw_reverse_nfqws_rule6 $1 "$3" $4
}
ipt_first_packets()
{
# $1 - packet count
[ -n "$1" -a "$1" != keepalive ] && [ "$1" -ge 1 ] && echo "$ipt_connbytes 1:$1"
}
ipt_do_nfqws_in_out()
{
# $1 - 1 - add, 0 - del
# $2 - tcp,udp
# $3 - ports
# $4 - PKT_OUT. special value : 'keepalive'
# $5 - PKT_IN
local f4 f6 first_packets_only
[ -n "$3" ] || return
[ -n "$4" -a "$4" != 0 ] &&
{
first_packets_only="$(ipt_first_packets $4)"
f4="-p $2 -m multiport --dports $3 $first_packets_only"
f6=$f4
filter_apply_ipset_target f4 f6
fw_nfqws_post $1 "$f4" "$f6" $QNUM
}
[ -n "$5" -a "$5" != 0 ] &&
{
first_packets_only="$(ipt_first_packets $5)"
f4="-p $2 -m multiport --dports $3 $first_packets_only"
f6=$f4
filter_apply_ipset_target f4 f6
fw_reverse_nfqws_rule $1 "$f4" "$f6" $QNUM
}
}
zapret_do_firewall_standard_tpws_rules_ipt()
{
# $1 - 1 - add, 0 - del
local f4 f6
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && {
f4="-p tcp -m multiport --dports $TPWS_PORTS_IPT"
f6=$f4
filter_apply_ipset_target f4 f6
fw_tpws $1 "$f4" "$f6" $TPPORT
}
}
zapret_do_firewall_standard_nfqws_rules_ipt()
{
# $1 - 1 - add, 0 - del
[ "$NFQWS_ENABLE" = 1 ] && {
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_IPT" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
ipt_do_nfqws_in_out $1 tcp "$NFQWS_PORTS_TCP_KEEPALIVE_IPT" keepalive "$NFQWS_TCP_PKT_IN"
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_IPT" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
ipt_do_nfqws_in_out $1 udp "$NFQWS_PORTS_UDP_KEEPALIVE_IPT" keepalive "$NFQWS_UDP_PKT_IN"
}
}
zapret_do_firewall_standard_rules_ipt()
{
# $1 - 1 - add, 0 - del
zapret_do_firewall_standard_tpws_rules_ipt $1
zapret_do_firewall_standard_nfqws_rules_ipt $1
}
zapret_do_firewall_rules_ipt()
{
# $1 - 1 - add, 0 - del
zapret_do_firewall_standard_rules_ipt $1
custom_runner zapret_custom_firewall $1
zapret_do_icmp_filter $1
}
zapret_do_icmp_filter()
{
# $1 - 1 - add, 0 - del
local FW_EXTRA_PRE= FW_EXTRA_POST=
[ "$FILTER_TTL_EXPIRED_ICMP" = 1 ] && {
[ "$DISABLE_IPV4" = 1 ] || {
ipt_add_del $1 POSTROUTING -t mangle -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CONNMARK --or-mark $DESYNC_MARK
ipt_add_del $1 INPUT -p icmp -m icmp --icmp-type time-exceeded -m connmark --mark $DESYNC_MARK/$DESYNC_MARK -j DROP
ipt_add_del $1 FORWARD -p icmp -m icmp --icmp-type time-exceeded -m connmark --mark $DESYNC_MARK/$DESYNC_MARK -j DROP
}
[ "$DISABLE_IPV6" = 1 ] || {
ipt6_add_del $1 POSTROUTING -t mangle -m mark --mark $DESYNC_MARK/$DESYNC_MARK -j CONNMARK --or-mark $DESYNC_MARK
ipt6_add_del $1 INPUT -p icmpv6 -m icmp6 --icmpv6-type time-exceeded -m connmark --mark $DESYNC_MARK/$DESYNC_MARK -j DROP
ipt6_add_del $1 FORWARD -p icmpv6 -m icmp6 --icmpv6-type time-exceeded -m connmark --mark $DESYNC_MARK/$DESYNC_MARK -j DROP
}
}
}
zapret_do_firewall_ipt()
{
# $1 - 1 - add, 0 - del
if [ "$1" = 1 ]; then
echo Applying iptables
else
echo Clearing iptables
fi
# always create ipsets. ip_exclude ipset is required
[ "$1" = 1 ] && create_ipset no-update
zapret_do_firewall_rules_ipt "$@"
if [ "$1" = 1 ] ; then
existf flow_offloading_exempt && flow_offloading_exempt
else
existf flow_offloading_unexempt && flow_offloading_unexempt
unprepare_tpws_fw
fi
return 0
}
================================================
FILE: common/linux_daemons.sh
================================================
standard_mode_tpws_socks()
{
# $1 - 1 - run, 0 - stop
local opt
[ "$TPWS_SOCKS_ENABLE" = 1 ] && {
opt="--port=$TPPORT_SOCKS $TPWS_SOCKS_OPT"
filter_apply_hostlist_target opt
do_tpws_socks $1 2 "$opt"
}
}
standard_mode_tpws()
{
# $1 - 1 - run, 0 - stop
local opt
[ "$TPWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$TPWS_OPT" && {
opt="--port=$TPPORT $TPWS_OPT"
filter_apply_hostlist_target opt
do_tpws $1 1 "$opt"
}
}
standard_mode_nfqws()
{
# $1 - 1 - run, 0 - stop
local opt
[ "$NFQWS_ENABLE" = 1 ] && check_bad_ws_options $1 "$NFQWS_OPT" && {
opt="--qnum=$QNUM $NFQWS_OPT"
filter_apply_hostlist_target opt
do_nfqws $1 3 "$opt"
}
}
standard_mode_daemons()
{
# $1 - 1 - run, 0 - stop
standard_mode_tpws_socks $1
standard_mode_tpws $1
standard_mode_nfqws $1
}
zapret_do_daemons()
{
# $1 - 1 - run, 0 - stop
standard_mode_daemons $1
custom_runner zapret_custom_daemons $1
return 0
}
zapret_run_daemons()
{
zapret_do_daemons 1 "$@"
}
zapret_stop_daemons()
{
zapret_do_daemons 0 "$@"
}
================================================
FILE: common/linux_fw.sh
================================================
set_conntrack_liberal_mode()
{
[ -n "$SKIP_CONNTRACK_LIBERAL_MODE" ] || sysctl -w net.netfilter.nf_conntrack_tcp_be_liberal=$1
}
zapret_do_firewall()
{
linux_fwtype
[ "$1" = 1 -a -n "$INIT_FW_PRE_UP_HOOK" ] && $INIT_FW_PRE_UP_HOOK
[ "$1" = 0 -a -n "$INIT_FW_PRE_DOWN_HOOK" ] && $INIT_FW_PRE_DOWN_HOOK
case "$FWTYPE" in
iptables)
zapret_do_firewall_ipt "$@"
;;
nftables)
zapret_do_firewall_nft "$@"
;;
esac
# russian DPI sends RST,ACK with wrong ACK.
# this is sometimes treated by conntrack as invalid and connbytes fw rules do not pass RST packet to nfqws.
# switch on liberal mode on zapret firewall start and switch off on zapret firewall stop
# this is only required for processing incoming bad RSTs. incoming rules are only applied in autohostlist mode
# calling this after firewall because conntrack module can be not loaded before applying conntrack firewall rules
[ "$MODE_FILTER" = "autohostlist" ] && set_conntrack_liberal_mode $1
[ "$1" = 1 -a -n "$INIT_FW_POST_UP_HOOK" ] && $INIT_FW_POST_UP_HOOK
[ "$1" = 0 -a -n "$INIT_FW_POST_DOWN_HOOK" ] && $INIT_FW_POST_DOWN_HOOK
return 0
}
zapret_apply_firewall()
{
zapret_do_firewall 1 "$@"
}
zapret_unapply_firewall()
{
zapret_do_firewall 0 "$@"
}
================================================
FILE: common/linux_iphelper.sh
================================================
# there's no route_localnet for ipv6
# the best we can is to route to link local of the incoming interface
# OUTPUT - can DNAT to ::1
# PREROUTING - can't DNAT to ::1. can DNAT to link local of -i interface or to any global addr
# not a good idea to expose tpws to the world (bind to ::)
# max wait time for the link local ipv6 on the LAN interface
LINKLOCAL_WAIT_SEC=${LINKLOCAL_WAIT_SEC:-5}
get_ipv6_linklocal()
{
# $1 - interface name. if empty - any interface
if exists ip ; then
local dev
[ -n "$1" ] && dev="dev $1"
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope link.*$/\1/;t;d' | head -n 1
else
ifconfig $1 | sed -re 's/^.*inet6 addr: ([^ ]*)\/[0-9]* Scope:Link.*$/\1/;t;d' | head -n 1
fi
}
get_ipv6_global()
{
# $1 - interface name. if empty - any interface
if exists ip ; then
local dev
[ -n "$1" ] && dev="dev $1"
ip addr show $dev | sed -e 's/^.*inet6 \([^ ]*\)\/[0-9]* scope global.*$/\1/;t;d' | head -n 1
else
ifconfig $1 | sed -re 's/^.*inet6 addr: ([^ ]*)\/[0-9]* Scope:Global.*$/\1/;t;d' | head -n 1
fi
}
iface_is_up()
{
# $1 - interface name
[ -f /sys/class/net/$1/operstate ] || return
local state
read state </sys/class/net/$1/operstate
[ "$state" != "down" ]
}
wait_ifup()
{
# $1 - interface name
local ct=0
while
iface_is_up $1 && return
[ "$ct" -ge "$IFUP_WAIT_SEC" ] && break
echo waiting for ifup of $1 for another $(($IFUP_WAIT_SEC - $ct)) seconds ...
ct=$(($ct+1))
sleep 1
do :; done
false
}
_dnat6_target()
{
# $1 - interface name
# $2 - var to store target ip6
# get target ip address for DNAT. prefer link locals
# tpws should be as inaccessible from outside as possible
# link local address can appear not immediately after ifup
# DNAT6_TARGET=- means attempt was made but address was not found (to avoid multiple re-attempts)
local DNAT6_TARGET DVAR=DNAT6_TARGET_$1
DVAR=$(echo $DVAR | sed 's/[^a-zA-Z0-9_]/_/g')
eval DNAT6_TARGET="\$$DVAR"
[ -n "$2" ] && eval $2=''
[ -n "$DNAT6_TARGET" ] || {
local ct=0
while
DNAT6_TARGET=$(get_ipv6_linklocal $1)
[ -n "$DNAT6_TARGET" ] && break
[ "$ct" -ge "$LINKLOCAL_WAIT_SEC" ] && break
echo $1: waiting for the link local for another $(($LINKLOCAL_WAIT_SEC - $ct)) seconds ...
ct=$(($ct+1))
sleep 1
do :; done
[ -n "$DNAT6_TARGET" ] || {
echo $1: no link local. getting global
DNAT6_TARGET=$(get_ipv6_global $1)
[ -n "$DNAT6_TARGET" ] || {
echo $1: could not get any address
DNAT6_TARGET=-
}
}
eval $DVAR="$DNAT6_TARGET"
}
[ -n "$2" ] && eval $2="$DNAT6_TARGET"
}
_set_route_localnet()
{
# $1 - 1 = enable, 0 = disable
# $2,$3,... - interface names
[ "$DISABLE_IPV4" = "1" ] || {
local enable="$1"
shift
while [ -n "$1" ]; do
sysctl -q -w net.ipv4.conf.$1.route_localnet="$enable"
shift
done
}
}
prepare_route_localnet()
{
set_route_localnet 1 "$@"
}
unprepare_route_localnet()
{
set_route_localnet 0 "$@"
}
get_uevent_devtype()
{
local DEVTYPE INTERFACE IFINDEX OF_NAME OF_FULLNAME OF_COMPATIBLE_N
[ -f "/sys/class/net/$1/uevent" ] && {
. "/sys/class/net/$1/uevent"
echo -n $DEVTYPE
}
}
resolve_lower_devices()
{
# $1 - bridge interface name
[ -d "/sys/class/net/$1" ] && {
find "/sys/class/net/$1" -follow -maxdepth 1 -name "lower_*" |
{
local l lower lowers
while read lower; do
lower="$(basename "$lower")"
l="${lower#lower_*}"
[ "$l" != "$lower" ] && append_separator_list lowers ' ' '' "$l"
done
printf "$lowers"
}
}
}
default_route_interfaces6()
{
sed -nre 's/^00000000000000000000000000000000 00 [0-9a-f]{32} [0-9a-f]{2} [0-9a-f]{32} [0-9a-f]{8} [0-9a-f]{8} [0-9a-f]{8} [0-9a-f]{8} +(.*)$/\1/p' /proc/net/ipv6_route | grep -v '^lo$' | sort -u | xargs
}
default_route_interfaces4()
{
sed -nre 's/^([^\t]+)\t00000000\t[0-9A-F]{8}\t[0-9A-F]{4}\t[0-9]+\t[0-9]+\t[0-9]+\t00000000.*$/\1/p' /proc/net/route | sort -u | xargs
}
================================================
FILE: common/list.sh
================================================
HOSTLIST_MARKER="<HOSTLIST>"
HOSTLIST_NOAUTO_MARKER="<HOSTLIST_NOAUTO>"
find_hostlists()
{
[ -n "$HOSTLIST_BASE" ] || HOSTLIST_BASE="$ZAPRET_BASE/ipset"
HOSTLIST="$HOSTLIST_BASE/zapret-hosts.txt.gz"
[ -f "$HOSTLIST" ] || HOSTLIST="$HOSTLIST_BASE/zapret-hosts.txt"
[ -f "$HOSTLIST" ] || HOSTLIST=
HOSTLIST_USER="$HOSTLIST_BASE/zapret-hosts-user.txt.gz"
[ -f "$HOSTLIST_USER" ] || HOSTLIST_USER="$HOSTLIST_BASE/zapret-hosts-user.txt"
[ -f "$HOSTLIST_USER" ] || HOSTLIST_USER=
HOSTLIST_EXCLUDE="$HOSTLIST_BASE/zapret-hosts-user-exclude.txt.gz"
[ -f "$HOSTLIST_EXCLUDE" ] || HOSTLIST_EXCLUDE="$HOSTLIST_BASE/zapret-hosts-user-exclude.txt"
[ -f "$HOSTLIST_EXCLUDE" ] || HOSTLIST_EXCLUDE=
HOSTLIST_AUTO="$HOSTLIST_BASE/zapret-hosts-auto.txt"
HOSTLIST_AUTO_DEBUGLOG="$HOSTLIST_BASE/zapret-hosts-auto-debug.log"
}
filter_apply_hostlist_target()
{
# $1 - var name of tpws or nfqws params
local v parm parm1 parm2 parm3 parm4 parm5 parm6 parm7 parm8 parmNA
eval v="\$$1"
if contains "$v" "$HOSTLIST_MARKER" || contains "$v" "$HOSTLIST_NOAUTO_MARKER"; then
[ "$MODE_FILTER" = hostlist -o "$MODE_FILTER" = autohostlist ] &&
{
find_hostlists
parm1="${HOSTLIST_USER:+--hostlist=$HOSTLIST_USER}"
parm2="${HOSTLIST:+--hostlist=$HOSTLIST}"
parm3="${HOSTLIST_EXCLUDE:+--hostlist-exclude=$HOSTLIST_EXCLUDE}"
[ "$MODE_FILTER" = autohostlist ] &&
{
parm4="--hostlist-auto=$HOSTLIST_AUTO"
parm5="${AUTOHOSTLIST_FAIL_THRESHOLD:+--hostlist-auto-fail-threshold=$AUTOHOSTLIST_FAIL_THRESHOLD}"
parm6="${AUTOHOSTLIST_FAIL_TIME:+--hostlist-auto-fail-time=$AUTOHOSTLIST_FAIL_TIME}"
parm7="${AUTOHOSTLIST_RETRANS_THRESHOLD:+--hostlist-auto-retrans-threshold=$AUTOHOSTLIST_RETRANS_THRESHOLD}"
parm8="--hostlist=$HOSTLIST_AUTO"
}
parm="$parm1${parm2:+ $parm2}${parm3:+ $parm3}${parm4:+ $parm4}${parm5:+ $parm5}${parm6:+ $parm6}${parm7:+ $parm7}"
parmNA="$parm1${parm2:+ $parm2}${parm3:+ $parm3}${parm8:+ $parm8}"
}
v="$(replace_str $HOSTLIST_NOAUTO_MARKER "$parmNA" "$v")"
v="$(replace_str $HOSTLIST_MARKER "$parm" "$v")"
[ "$MODE_FILTER" = autohostlist -a "$AUTOHOSTLIST_DEBUGLOG" = 1 ] && {
v="$v --hostlist-auto-debug=$HOSTLIST_AUTO_DEBUGLOG"
}
eval $1=\""$v"\"
fi
}
================================================
FILE: common/nft.sh
================================================
[ -n "$ZAPRET_NFT_TABLE" ] || ZAPRET_NFT_TABLE=zapret
nft_connbytes="ct original packets"
# required for : nft -f -
create_dev_stdin
std_ports
nft_create_table()
{
nft add table inet $ZAPRET_NFT_TABLE
}
nft_del_table()
{
nft delete table inet $ZAPRET_NFT_TABLE 2>/dev/null
}
nft_list_table()
{
nft -t list table inet $ZAPRET_NFT_TABLE
}
nft_create_set()
{
# $1 - set name
# $2 - params
nft create set inet $ZAPRET_NFT_TABLE $1 "{ $2 }" 2>/dev/null
}
nft_del_set()
{
# $1 - set name
nft delete set inet $ZAPRET_NFT_TABLE $1
}
nft_flush_set()
{
# $1 - set name
nft flush set inet $ZAPRET_NFT_TABLE $1
}
nft_set_exists()
{
# $1 - set name
nft -t list set inet $ZAPRET_NFT_TABLE $1 2>/dev/null >/dev/null
}
nft_flush_chain()
{
# $1 - chain name
nft flush chain inet $ZAPRET_NFT_TABLE $1
}
nft_del_all_chains_from_table()
{
# $1 - table_name with or without family
# delete all chains with possible references to each other
# cannot just delete all in the list because of references
# avoid infinite loops
local chains deleted=1 error=1
while [ -n "$deleted" -a -n "$error" ]; do
chains=$(nft -t list table $1 2>/dev/null | sed -nre "s/^[ ]*chain ([^ ]+) \{/\1/p" | xargs)
[ -n "$chains" ] || break
deleted=
error=
for chain in $chains; do
if nft delete chain $1 $chain 2>/dev/null; then
deleted=1
else
error=1
fi
done
done
}
nft_create_chains()
{
cat << EOF | nft -f -
add chain inet $ZAPRET_NFT_TABLE dnat_output { type nat hook output priority -101; }
flush chain inet $ZAPRET_NFT_TABLE dnat_output
add chain inet $ZAPRET_NFT_TABLE dnat_pre { type nat hook prerouting priority -101; }
flush chain inet $ZAPRET_NFT_TABLE dnat_pre
add chain inet $ZAPRET_NFT_TABLE forward { type filter hook forward priority -1; }
flush chain inet $ZAPRET_NFT_TABLE forward
add chain inet $ZAPRET_NFT_TABLE input { type filter hook input priority -1; }
flush chain inet $ZAPRET_NFT_TABLE input
add chain inet $ZAPRET_NFT_TABLE flow_offload
flush chain inet $ZAPRET_NFT_TABLE flow_offload
add chain inet $ZAPRET_NFT_TABLE localnet_protect
flush chain inet $ZAPRET_NFT_TABLE localnet_protect
add rule inet $ZAPRET_NFT_TABLE localnet_protect ip daddr $TPWS_LOCALHOST4 return comment "route_localnet allow access to tpws"
add rule inet $ZAPRET_NFT_TABLE localnet_protect ip daddr 127.0.0.0/8 drop comment "route_localnet remote access protection"
add rule inet $ZAPRET_NFT_TABLE input iif != lo jump localnet_protect
add chain inet $ZAPRET_NFT_TABLE postrouting
flush chain inet $ZAPRET_NFT_TABLE postrouting
add chain inet $ZAPRET_NFT_TABLE postrouting_hook { type filter hook postrouting priority 99; }
flush chain inet $ZAPRET_NFT_TABLE postrouting_hook
add rule inet $ZAPRET_NFT_TABLE postrouting_hook mark and $DESYNC_MARK == 0 jump postrouting
add chain inet $ZAPRET_NFT_TABLE postnat
flush chain inet $ZAPRET_NFT_TABLE postnat
add chain inet $ZAPRET_NFT_TABLE postnat_hook { type filter hook postrouting priority 101; }
flush chain inet $ZAPRET_NFT_TABLE postnat_hook
add rule inet $ZAPRET_NFT_TABLE postnat_hook mark and $DESYNC_MARK == 0 jump postnat
add chain inet $ZAPRET_NFT_TABLE prerouting { type filter hook prerouting priority -99; }
flush chain inet $ZAPRET_NFT_TABLE prerouting
add chain inet $ZAPRET_NFT_TABLE prenat { type filter hook prerouting priority -101; }
flush chain inet $ZAPRET_NFT_TABLE prenat
add chain inet $ZAPRET_NFT_TABLE predefrag { type filter hook output priority -401; }
flush chain inet $ZAPRET_NFT_TABLE predefrag
add chain inet $ZAPRET_NFT_TABLE predefrag_nfqws
flush chain inet $ZAPRET_NFT_TABLE predefrag_nfqws
add rule inet $ZAPRET_NFT_TABLE predefrag mark and $DESYNC_MARK !=0 jump predefrag_nfqws comment "nfqws generated : avoid drop by INVALID conntrack state"
add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws mark and $DESYNC_MARK_POSTNAT !=0 notrack comment "postnat traffic"
add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws ip frag-off & 0x1fff != 0 notrack comment "ipfrag"
add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws exthdr frag exists notrack comment "ipfrag"
add rule inet $ZAPRET_NFT_TABLE predefrag_nfqws tcp flags ! syn,rst,ack notrack comment "datanoack"
add set inet $ZAPRET_NFT_TABLE lanif { type ifname; }
add set inet $ZAPRET_NFT_TABLE wanif { type ifname; }
add set inet $ZAPRET_NFT_TABLE wanif6 { type ifname; }
add map inet $ZAPRET_NFT_TABLE link_local { type ifname : ipv6_addr; }
EOF
[ -n "$POSTNAT_ALL" ] && {
nft_flush_chain predefrag_nfqws
nft_add_rule predefrag_nfqws notrack comment \"do not track nfqws generated packets to avoid nat tampering and defragmentation\"
}
[ "$FILTER_TTL_EXPIRED_ICMP" = 1 ] && {
if is_postnat; then
# can be caused by untracked nfqws-generated packets
nft_add_rule prerouting icmp type time-exceeded ct state invalid drop
else
nft_add_rule postrouting_hook mark and $DESYNC_MARK != 0 ct mark set ct mark or $DESYNC_MARK comment \"nfqws related : prevent ttl expired socket errors\"
fi
[ "$DISABLE_IPV4" = "1" ] || {
nft_add_rule prerouting icmp type time-exceeded ct mark and $DESYNC_MARK != 0 drop comment \"nfqws related : prevent ttl expired socket errors\"
}
[ "$DISABLE_IPV6" = "1" ] || {
nft_add_rule prerouting icmpv6 type time-exceeded ct mark and $DESYNC_MARK != 0 drop comment \"nfqws related : prevent ttl expired socket errors\"
}
}
}
nft_del_chains()
{
# do not delete all chains because of additional user hooks
# they must be inside zapret table to use nfsets
# these chains are newer. do not fail all because chains are not present
cat << EOF | nft -f - 2>/dev/null
delete chain inet $ZAPRET_NFT_TABLE postrouting_hook
delete chain inet $ZAPRET_NFT_TABLE postnat_hook
EOF
cat << EOF | nft -f - 2>/dev/null
delete chain inet $ZAPRET_NFT_TABLE dnat_output
delete chain inet $ZAPRET_NFT_TABLE dnat_pre
delete chain inet $ZAPRET_NFT_TABLE forward
delete chain inet $ZAPRET_NFT_TABLE input
delete chain inet $ZAPRET_NFT_TABLE postrouting
delete chain inet $ZAPRET_NFT_TABLE postnat
delete chain inet $ZAPRET_NFT_TABLE prerouting
delete chain inet $ZAPRET_NFT_TABLE prenat
delete chain inet $ZAPRET_NFT_TABLE predefrag
delete chain inet $ZAPRET_NFT_TABLE predefrag_nfqws
delete chain inet $ZAPRET_NFT_TABLE flow_offload
delete chain inet $ZAPRET_NFT_TABLE localnet_protect
EOF
# unfortunately this approach breaks udp desync of the connection initiating packet (new, first one)
# delete chain inet $ZAPRET_NFT_TABLE predefrag
}
nft_del_flowtable()
{
nft delete flowtable inet $ZAPRET_NFT_TABLE ft 2>/dev/null
}
nft_create_or_update_flowtable()
{
# $1 = flags ('offload' for hw offload)
# $2,$3,$4,... - interfaces
# can be called multiple times to add interfaces. interfaces can only be added , not removed
local flags=$1 devices makelist
shift
# warning ! nft versions at least up to 1.0.1 do not allow interface names starting with digit in flowtable and do not allow quoting
# warning ! openwrt fixes this in post-21.x snapshots with special nft patch
# warning ! in traditional linux distros nft is unpatched and will fail with quoted interface definitions if unfixed
[ -n "$flags" ] && flags="flags $flags;"
for makelist in make_quoted_comma_list make_comma_list; do
$makelist devices "$@"
[ -n "$devices" ] && devices="devices={$devices};"
nft add flowtable inet $ZAPRET_NFT_TABLE ft "{ hook ingress priority -1; $flags $devices }" && break
done
}
nft_flush_ifsets()
{
cat << EOF | nft -f - 2>/dev/null
flush set inet $ZAPRET_NFT_TABLE lanif
flush set inet $ZAPRET_NFT_TABLE wanif
flush set inet $ZAPRET_NFT_TABLE wanif6
flush map inet $ZAPRET_NFT_TABLE link_local
EOF
}
nft_flush_link_local()
{
nft flush map inet $ZAPRET_NFT_TABLE link_local 2>/dev/null
}
nft_list_ifsets()
{
nft list set inet $ZAPRET_NFT_TABLE lanif
nft list set inet $ZAPRET_NFT_TABLE wanif
nft list set inet $ZAPRET_NFT_TABLE wanif6
nft list map inet $ZAPRET_NFT_TABLE link_local
nft list flowtable inet $ZAPRET_NFT_TABLE ft 2>/dev/null
}
nft_create_firewall()
{
nft_create_table
nft_del_flowtable
nft_flush_link_local
nft_create_chains
}
nft_del_firewall()
{
nft_del_chains
nft_del_flowtable
nft_flush_link_local
# leave ifsets and ipsets because they may be used by custom rules
}
nft_add_rule()
{
# $1 - chain
# $2,$3,... - rule(s)
local chain="$1"
shift
nft add rule inet $ZAPRET_NFT_TABLE $chain $FW_EXTRA_PRE "$@"
}
nft_insert_rule()
{
# $1 - chain
# $2,$3,... - rule(s)
local chain="$1"
shift
nft insert rule inet $ZAPRET_NFT_TABLE $chain $FW_EXTRA_PRE "$@"
}
nft_add_set_element()
{
# $1 - set or map name
# $2 - element
[ -z "$2" ] || nft add element inet $ZAPRET_NFT_TABLE $1 "{ $2 }"
}
nft_add_set_elements()
{
# $1 - set or map name
# $2,$3,... - element(s)
local set="$1" elements
shift
make_comma_list elements "$@"
nft_add_set_element $set "$elements"
}
nft_reverse_nfqws_rule()
{
echo "$@" | sed -e 's/oifname /iifname /g' -e 's/dport /sport /g' -e 's/daddr /saddr /g' -e 's/ct original /ct reply /g' -e "s/mark and $DESYNC_MARK == 0//g"
}
nft_clean_nfqws_rule()
{
echo "$@" | sed -e "s/mark and $DESYNC_MARK == 0//g" -e "s/oifname @wanif6//g" -e "s/oifname @wanif//g"
}
nft_add_nfqws_flow_exempt_rule()
{
# $1 - rule (must be all filters in one var)
local FW_EXTRA_POST= FW_EXTRA_PRE=
nft_add_rule flow_offload $(nft_clean_nfqws_rule $1) return comment \"direct flow offloading exemption\"
# do not need this because of oifname @wanif/@wanif6 filter in forward chain
#nft_add_rule flow_offload $(nft_reverse_nfqws_rule $1) return comment \"reverse flow offloading exemption\"
}
nft_add_flow_offload_exemption()
{
# "$1" - rule for ipv4
# "$2" - rule for ipv6
# "$3" - comment
local FW_EXTRA_POST= FW_EXTRA_PRE=
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || nft_add_rule flow_offload oifname @wanif $1 ip daddr != @nozapret return comment \"$3\"
[ "$DISABLE_IPV6" = "1" -o -z "$2" ] || nft_add_rule flow_offload oifname @wanif6 $2 ip6 daddr != @nozapret6 return comment \"$3\"
}
nft_apply_flow_offloading()
{
# ft can be absent
nft_add_rule flow_offload meta l4proto "{ tcp, udp }" flow add @ft 2>/dev/null && {
nft_add_rule flow_offload meta l4proto "{ tcp, udp }" counter comment \"if offload works here must not be too much traffic\"
# allow only outgoing packets to initiate flow offload
nft_add_rule forward oifname @wanif jump flow_offload
nft_add_rule forward oifname @wanif6 jump flow_offload
}
}
nft_filter_apply_ipset_target4()
{
# $1 - var name of ipv4 nftables filter
if [ "$MODE_FILTER" = "ipset" ]; then
eval $1="\"\$$1 ip daddr @zapret\""
fi
}
nft_filter_apply_ipset_target6()
{
# $1 - var name of ipv6 nftables filter
if [ "$MODE_FILTER" = "ipset" ]; then
eval $1="\"\$$1 ip6 daddr @zapret6\""
fi
}
nft_filter_apply_ipset_target()
{
# $1 - var name of ipv4 nftables filter
# $2 - var name of ipv6 nftables filter
nft_filter_apply_ipset_target4 $1
nft_filter_apply_ipset_target6 $2
}
nft_mark_filter()
{
[ -n "$FILTER_MARK" ] && echo "mark and $FILTER_MARK != 0"
}
nft_script_add_ifset_element()
{
# $1 - set name
# $2 - space separated elements
local elements
[ -n "$2" ] && {
make_quoted_comma_list elements $2
script="${script}
add element inet $ZAPRET_NFT_TABLE $1 { $elements }"
}
}
nft_fill_ifsets()
{
# $1 - space separated lan interface names
# $2 - space separated wan interface names
# $3 - space separated wan6 interface names
# 4,5,6 is needed for pppoe+openwrt case. looks like it's not easily possible to resolve ethernet device behind a pppoe interface
# $4 - space separated lan physical interface names (optional)
# $5 - space separated wan physical interface names (optional)
# $6 - space separated wan6 physical interface names (optional)
local script i j ALLDEVS devs b
# if large sets exist nft works very ineffectively
# looks like it analyzes the whole table blob to find required data pieces
# calling all in one shot helps not to waste cpu time many times
script="flush set inet $ZAPRET_NFT_TABLE wanif
flush set inet $ZAPRET_NFT_TABLE wanif6
flush set inet $ZAPRET_NFT_TABLE lanif"
[ "$DISABLE_IPV4" = "1" ] || nft_script_add_ifset_element wanif "$2"
[ "$DISABLE_IPV6" = "1" ] || nft_script_add_ifset_element wanif6 "$3"
nft_script_add_ifset_element lanif "$1"
echo "$script" | nft -f -
case "$FLOWOFFLOAD" in
software)
ALLDEVS=$(unique $1 $2 $3)
# unbound flowtable may cause error in older nft version
nft_create_or_update_flowtable '' $ALLDEVS 2>/dev/null
;;
hardware)
ALLDEVS=$(unique $1 $2 $3 $4 $5 $6)
# first create unbound flowtable. may cause error in older nft version
nft_create_or_update_flowtable 'offload' 2>/dev/null
# then add elements. some of them can cause error because unsupported
for i in $ALLDEVS; do
# bridge members must be added instead of the bridge itself
# some members may not support hw offload. example : lan1 lan2 lan3 support, wlan0 wlan1 - not
b=
devs=$(resolve_lower_devices $i)
for j in $devs; do
# do not display error if addition failed
nft_create_or_update_flowtable 'offload' $j && b=1 2>/dev/null
done
[ -n "$b" ] || {
# no lower devices added ? try to add interface itself
nft_create_or_update_flowtable 'offload' $i 2>/dev/null
}
done
;;
esac
}
nft_only()
{
linux_fwtype
case "$FWTYPE" in
nftables)
"$@"
;;
esac
}
nft_print_op()
{
echo "Inserting nftables ipv$3 rule for $2 : $1"
}
_nft_fw_tpws4()
{
# $1 - filter ipv4
# $2 - tpws port
# $3 - not-empty if wan interface filtering required
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
local filter="$1" port="$2"
local mark_filter=$(nft_mark_filter)
nft_print_op "$filter" "tpws (port $2)" 4
nft_insert_rule dnat_output skuid != $WS_USER ${3:+oifname @wanif} $mark_filter $filter ip daddr != @nozapret ip daddr != @ipban $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
nft_insert_rule dnat_pre iifname @lanif $mark_filter $filter ip daddr != @nozapret ip daddr != @ipban $FW_EXTRA_POST dnat ip to $TPWS_LOCALHOST4:$port
prepare_route_localnet
}
}
_nft_fw_tpws6()
{
# $1 - filter ipv6
# $2 - tpws port
# $3 - lan interface names space separated
# $4 - not-empty if wan interface filtering required
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
local filter="$1" port="$2" DNAT6 i
local mark_filter=$(nft_mark_filter)
nft_print_op "$filter" "tpws (port $port)" 6
nft_insert_rule dnat_output skuid != $WS_USER ${4:+oifname @wanif6} $mark_filter $filter ip6 daddr != @nozapret6 ip6 daddr != @ipban6 $FW_EXTRA_POST dnat ip6 to [::1]:$port
[ -n "$3" ] && {
nft_insert_rule dnat_pre $mark_filter $filter ip6 daddr != @nozapret6 ip6 daddr != @ipban6 $FW_EXTRA_POST dnat ip6 to iifname map @link_local:$port
for i in $3; do
_dnat6_target $i DNAT6
# can be multiple tpws processes on different ports
[ -n "$DNAT6" -a "$DNAT6" != '-' ] && nft_add_set_element link_local "$i : $DNAT6"
done
}
}
}
nft_fw_tpws()
{
# $1 - filter ipv4
# $2 - filter ipv6
# $3 - tpws port
nft_fw_tpws4 "$1" $3
nft_fw_tpws6 "$2" $3
}
is_postnat()
{
[ "$POSTNAT" != 0 -o "$POSTNAT_ALL" = 1 ]
}
get_postchain()
{
if is_postnat ; then
echo -n postnat
else
echo -n postrouting
fi
}
get_prechain()
{
if is_postnat ; then
echo -n prenat
else
echo -n prerouting
fi
}
_nft_fw_nfqws_post4()
{
# $1 - filter ipv4
# $2 - queue number
# $3 - not-empty if wan interface filtering required
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
local filter="$1" port="$2" rule chain=$(get_postchain) setmark
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 4
rule="${3:+oifname @wanif} $(nft_mark_filter) $filter ip daddr != @nozapret"
is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT"
nft_insert_rule $chain $rule $setmark $CONNMARKER $FW_EXTRA_POST queue num $port bypass
nft_add_nfqws_flow_exempt_rule "$rule"
}
}
_nft_fw_nfqws_post6()
{
# $1 - filter ipv6
# $2 - queue number
# $3 - not-empty if wan interface filtering required
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
local filter="$1" port="$2" rule chain=$(get_postchain) setmark
nft_print_op "$filter" "nfqws postrouting (qnum $port)" 6
rule="${3:+oifname @wanif6} $(nft_mark_filter) $filter ip6 daddr != @nozapret6"
is_postnat && setmark="meta mark set meta mark or $DESYNC_MARK_POSTNAT"
nft_insert_rule $chain $rule $setmark $CONNMARKER $FW_EXTRA_POST queue num $port bypass
nft_add_nfqws_flow_exempt_rule "$rule"
}
}
nft_fw_nfqws_post()
{
# $1 - filter ipv4
# $2 - filter ipv6
# $3 - queue number
nft_fw_nfqws_post4 "$1" $3
nft_fw_nfqws_post6 "$2" $3
}
_nft_fw_nfqws_pre4()
{
# $1 - filter ipv4
# $2 - queue number
# $3 - not-empty if wan interface filtering required
[ "$DISABLE_IPV4" = "1" -o -z "$1" ] || {
local filter="$1" port="$2" rule
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 4
rule="${3:+iifname @wanif} $filter ip saddr != @nozapret"
nft_insert_rule $(get_prechain) $rule $CONNMARKER $FW_EXTRA_POST queue num $port bypass
}
}
_nft_fw_nfqws_pre6()
{
# $1 - filter ipv6
# $2 - queue number
# $3 - not-empty if wan interface filtering required
[ "$DISABLE_IPV6" = "1" -o -z "$1" ] || {
local filter="$1" port="$2" rule
nft_print_op "$filter" "nfqws prerouting (qnum $port)" 6
rule="${3:+iifname @wanif6} $filter ip6 saddr != @nozapret6"
nft_insert_rule $(get_prechain) $rule $CONNMARKER $FW_EXTRA_POST queue num $port bypass
}
}
nft_fw_nfqws_pre()
{
# $1 - filter ipv4
# $2 - filter ipv6
# $3 - queue number
nft_fw_nfqws_pre4 "$1" $3
nft_fw_nfqws_pre6 "$2" $3
}
nft_fw_nfqws_both4()
{
# $1 - filter ipv4
# $2 - queue number
nft_fw_nfqws_post4 "$@"
nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule $1)" $2
}
nft_fw_nfqws_both6()
{
# $1 - filter ipv6
# $2 - queue number
nft_fw_nfqws_post6 "$@"
nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule $1)" $2
}
nft_fw_nfqws_both()
{
# $1 - filter ipv4
# $2 - filter ipv6
# $3 - queue number
nft_fw_nfqws_both4 "$1" "$3"
nft_fw_nfqws_both6 "$2" "$3"
}
zapret_reload_ifsets()
{
nft_only nft_create_table ; nft_fill_ifsets_overload
return 0
}
zapret_list_ifsets()
{
nft_only nft_list_ifsets
return 0
}
zapret_list_table()
{
nft_only nft_list_table
return 0
}
nft_fw_reverse_nfqws_rule4()
{
nft_fw_nfqws_pre4 "$(nft_reverse_nfqws_rule "$1")" $2
}
nft_fw_reverse_nfqws_rule6()
{
nft_fw_nfqws_pre6 "$(nft_reverse_nfqws_rule "$1")" $2
}
nft_fw_reverse_nfqws_rule()
{
# ensure that modes relying on incoming traffic work
# $1 - rule4
# $2 - rule6
# $3 - queue number
nft_fw_reverse_nfqws_rule4 "$1" $3
nft_fw_reverse_nfqws_rule6 "$2" $3
}
nft_first_packets()
{
# $1 - packet count
[ -n "$1" -a "$1" != keepalive ] && [ "$1" -ge 1 ] &&
{
if [ "$1" = 1 ] ; then
echo "$nft_connbytes 1"
else
echo "$nft_connbytes 1-$1"
fi
}
}
nft_apply_nfqws_in_out()
{
# $1 - tcp,udp
# $2 - ports
# $3 - PKT_OUT. special value : 'keepalive'
# $4 - PKT_IN
local f4 f6 first_packets_only
[ -n "$2" ] || return
[ -n "$3" -a "$3" != 0 ] &&
{
first_packets_only="$(nft_first_packets $3)"
f4="$1 dport {$2} $first_packets_only"
f6=$f4
nft_filter_apply_ipset_target f4 f6
nft_fw_nfqws_post "$f4" "$f6" $QNUM
}
[ -n "$4" -a "$4" != 0 ] &&
{
first_packets_only="$(nft_first_packets $4)"
f4="$1 dport {$2} $first_packets_only"
f6=$f4
nft_filter_apply_ipset_target f4 f6
nft_fw_reverse_nfqws_rule "$f4" "$f6" $QNUM
}
}
zapret_apply_firewall_standard_tpws_rules_nft()
{
local f4 f6
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && {
f4="tcp dport {$TPWS_PORTS}"
f6=$f4
nft_filter_apply_ipset_target f4 f6
nft_fw_tpws "$f4" "$f6" $TPPORT
}
}
zapret_apply_firewall_standard_nfqws_rules_nft()
{
[ "$NFQWS_ENABLE" = 1 ] && {
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP" "$NFQWS_TCP_PKT_OUT" "$NFQWS_TCP_PKT_IN"
nft_apply_nfqws_in_out tcp "$NFQWS_PORTS_TCP_KEEPALIVE" keepalive "$NFQWS_TCP_PKT_IN"
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP" "$NFQWS_UDP_PKT_OUT" "$NFQWS_UDP_PKT_IN"
nft_apply_nfqws_in_out udp "$NFQWS_PORTS_UDP_KEEPALIVE" keepalive "$NFQWS_UDP_PKT_IN"
}
}
zapret_apply_firewall_standard_rules_nft()
{
zapret_apply_firewall_standard_tpws_rules_nft
zapret_apply_firewall_standard_nfqws_rules_nft
}
zapret_apply_firewall_rules_nft()
{
zapret_apply_firewall_standard_rules_nft
custom_runner zapret_custom_firewall_nft
}
zapret_apply_firewall_nft()
{
echo Applying nftables
create_ipset no-update
nft_create_firewall
nft_fill_ifsets_overload
zapret_apply_firewall_rules_nft
[ "$FLOWOFFLOAD" = 'software' -o "$FLOWOFFLOAD" = 'hardware' ] && nft_apply_flow_offloading
return 0
}
zapret_unapply_firewall_nft()
{
echo Clearing nftables
unprepare_route_localnet
nft_del_firewall
custom_runner zapret_custom_firewall_nft_flush
return 0
}
zapret_do_firewall_nft()
{
# $1 - 1 - add, 0 - del
if [ "$1" = 0 ] ; then
zapret_unapply_firewall_nft
else
zapret_apply_firewall_nft
fi
return 0
}
# ctmark is not available in POSTNAT mode
CONNMARKER=
[ "$FILTER_TTL_EXPIRED_ICMP" = 1 ] && is_postnat && CONNMARKER="ct mark set ct mark or $DESYNC_MARK"
================================================
FILE: common/pf.sh
================================================
PF_MAIN="/etc/pf.conf"
PF_ANCHOR_DIR="/etc/pf.anchors"
PF_ANCHOR_ZAPRET="$PF_ANCHOR_DIR/zapret"
PF_ANCHOR_ZAPRET_V4="$PF_ANCHOR_DIR/zapret-v4"
PF_ANCHOR_ZAPRET_V6="$PF_ANCHOR_DIR/zapret-v6"
std_ports
pf_anchor_root_reload()
{
echo reloading PF root anchor
pfctl -qf "$PF_MAIN"
}
pf_anchor_root()
{
local patch
[ -f "$PF_MAIN" ] && {
grep -q '^rdr-anchor "zapret"$' "$PF_MAIN" || {
echo patching rdr-anchor in $PF_MAIN
patch=1
sed -i '' -e '/^rdr-anchor "com\.apple\/\*"$/i \
rdr-anchor "zapret"
' $PF_MAIN
}
grep -q '^anchor "zapret"$' "$PF_MAIN" || {
echo patching anchor in $PF_MAIN
patch=1
sed -i '' -e '/^anchor "com\.apple\/\*"$/i \
anchor "zapret"
' $PF_MAIN
}
grep -q "^set limit table-entries" "$PF_MAIN" || {
echo patching table-entries limit
patch=1
sed -i '' -e '/^scrub-anchor "com\.apple\/\*"$/i \
set limit table-entries 5000000
' $PF_MAIN
}
grep -q '^anchor "zapret"$' "$PF_MAIN" &&
grep -q '^rdr-anchor "zapret"$' "$PF_MAIN" &&
grep -q '^set limit table-entries' "$PF_MAIN" && {
if [ -n "$patch" ]; then
echo successfully patched $PF_MAIN
pf_anchor_root_reload
else
echo successfully checked zapret anchors in $PF_MAIN
fi
return 0
}
}
echo ----------------------------------
echo Automatic $PF_MAIN patching failed. You must apply root anchors manually in your PF config.
echo rdr-anchor \"zapret\"
echo anchor \"zapret\"
echo ----------------------------------
return 1
}
pf_anchor_root_del()
{
sed -i '' -e '/^anchor "zapret"$/d' -e '/^rdr-anchor "zapret"$/d' -e '/^set limit table-entries/d' "$PF_MAIN"
}
pf_anchor_zapret()
{
[ "$DISABLE_IPV4" = "1" ] || {
if [ -f "$ZIPLIST_EXCLUDE" ]; then
echo "table <nozapret> persist file \"$ZIPLIST_EXCLUDE\""
else
echo "table <nozapret> persist"
fi
}
[ "$DISABLE_IPV6" = "1" ] || {
if [ -f "$ZIPLIST_EXCLUDE6" ]; then
echo "table <nozapret6> persist file \"$ZIPLIST_EXCLUDE6\""
else
echo "table <nozapret6> persist"
fi
}
[ "$DISABLE_IPV4" = "1" ] || echo "rdr-anchor \"/zapret-v4\" inet to !<nozapret>"
[ "$DISABLE_IPV6" = "1" ] || echo "rdr-anchor \"/zapret-v6\" inet6 to !<nozapret6>"
[ "$DISABLE_IPV4" = "1" ] || echo "anchor \"/zapret-v4\" inet to !<nozapret>"
[ "$DISABLE_IPV6" = "1" ] || echo "anchor \"/zapret-v6\" inet6 to !<nozapret6>"
}
pf_anchor_zapret_tables()
{
# $1 - variable to receive applied table names
# $2/$3 $4/$5 ... table_name/table_file
local tblv=$1
local _tbl
shift
[ "$MODE_FILTER" = "ipset" ] &&
{
while [ -n "$1" ] && [ -n "$2" ] ; do
[ -f "$2" ] && {
echo "table <$1> file \"$2\""
_tbl="$_tbl<$1> "
}
shift
shift
done
}
[ -n "$_tbl" ] || _tbl="any"
eval $tblv="\"\$_tbl\""
}
pf_nat_reorder_rules()
{
# this is dirty hack to move rdr above route-to
# use only first word as a key and preserve order within a single key
sort -srfk 1,1
}
pf_anchor_zapret_v4_tpws()
{
# $1 - tpws listen port
# $2 - rdr ports
local rule port="{$2}"
for lan in $IFACE_LAN; do
for t in $tbl; do
echo "rdr on $lan inet proto tcp from any to $t port $port -> 127.0.0.1 port $1"
done
done
echo "rdr on lo0 inet proto tcp from !127.0.0.0/8 to any port $port -> 127.0.0.1 port $1"
for t in $tbl; do
rule="route-to (lo0 127.0.0.1) inet proto tcp from !127.0.0.0/8 to $t port $port user { >root }"
if [ -n "$IFACE_WAN" ] ; then
for wan in $IFACE_WAN; do
echo "pass out on $wan $rule"
done
else
echo "pass out $rule"
fi
done
}
pf_anchor_zapret_v4()
{
local tbl port
[ "$DISABLE_IPV4" = "1" ] || {
{
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
custom_runner zapret_custom_firewall_v4
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS" ] && pf_anchor_zapret_v4_tpws $TPPORT "$TPWS_PORTS_IPT"
} | pf_nat_reorder_rules
}
}
pf_anchor_zapret_v6_tpws()
{
# $1 - tpws listen port
# $2 - rdr ports
local rule LL_LAN port="{$2}"
# LAN link local is only for router
for lan in $IFACE_LAN; do
LL_LAN=$(get_ipv6_linklocal $lan)
[ -n "$LL_LAN" ] && {
for t in $tbl; do
echo "rdr on $lan inet6 proto tcp from any to $t port $port -> $LL_LAN port $1"
done
}
done
echo "rdr on lo0 inet6 proto tcp from !::1 to any port $port -> fe80::1 port $1"
for t in $tbl; do
rule="route-to (lo0 fe80::1) inet6 proto tcp from !::1 to $t port $port user { >root }"
if [ -n "${IFACE_WAN6:-$IFACE_WAN}" ] ; then
for wan in ${IFACE_WAN6:-$IFACE_WAN}; do
echo "pass out on $wan $rule"
done
else
echo "pass out $rule"
fi
done
}
pf_anchor_zapret_v6()
{
local tbl port
[ "$DISABLE_IPV6" = "1" ] || {
{
pf_anchor_zapret_tables tbl zapret-user "$ZIPLIST_USER" zapret "$ZIPLIST"
custom_runner zapret_custom_firewall_v6
[ "$TPWS_ENABLE" = 1 -a -n "$TPWS_PORTS_IPT" ] && pf_anchor_zapret_v6_tpws $TPPORT "$TPWS_PORTS_IPT"
} | pf_nat_reorder_rules
}
}
pf_anchors_create()
{
wait_lan_ll
pf_anchor_zapret >"$PF_ANCHOR_ZAPRET"
pf_anchor_zapret_v4 >"$PF_ANCHOR_ZAPRET_V4"
pf_anchor_zapret_v6 >"$PF_ANCHOR_ZAPRET_V6"
}
pf_anchors_del()
{
rm -f "$PF_ANCHOR_ZAPRET" "$PF_ANCHOR_ZAPRET_V4" "$PF_ANCHOR_ZAPRET_V6"
}
pf_anchors_load()
{
echo loading zapret anchor from "$PF_ANCHOR_ZAPRET"
pfctl -qa zapret -f "$PF_ANCHOR_ZAPRET" || {
echo error loading zapret anchor
return 1
}
if [ "$DISABLE_IPV4" = "1" ]; then
echo clearing zapret-v4 anchor
pfctl -qa zapret-v4 -F all 2>/dev/null
else
echo loading zapret-v4 anchor from "$PF_ANCHOR_ZAPRET_V4"
pfctl -qa zapret-v4 -f "$PF_ANCHOR_ZAPRET_V4" || {
echo error loading zapret-v4 anchor
return 1
}
fi
if [ "$DISABLE_IPV6" = "1" ]; then
echo clearing zapret-v6 anchor
pfctl -qa zapret-v6 -F all 2>/dev/null
else
echo loading zapret-v6 anchor from "$PF_ANCHOR_ZAPRET_V6"
pfctl -qa zapret-v6 -f "$PF_ANCHOR_ZAPRET_V6" || {
echo error loading zapret-v6 anchor
return 1
}
fi
echo successfully loaded PF anchors
return 0
}
pf_anchors_clear()
{
echo clearing zapret anchors
pfctl -qa zapret-v4 -F all 2>/dev/null
pfctl -qa zapret-v6 -F all 2>/dev/null
pfctl -qa zapret -F all 2>/dev/null
}
pf_enable()
{
echo enabling PF
pfctl -qe
}
pf_table_reload()
{
echo reloading zapret tables
[ "$DISABLE_IPV4" = "1" ] || pfctl -qTl -a zapret-v4 -f "$PF_ANCHOR_ZAPRET_V4"
[ "$DISABLE_IPV6" = "1" ] || pfctl -qTl -a zapret-v6 -f "$PF_ANCHOR_ZAPRET_V6"
pfctl -qTl -a zapret -f "$PF_ANCHOR_ZAPRET"
}
================================================
FILE: common/virt.sh
================================================
get_virt()
{
local vm s v UNAME
UNAME=$(uname)
case "$UNAME" in
Linux)
if exists systemd-detect-virt; then
vm=$(systemd-detect-virt --vm)
elif [ -f /sys/class/dmi/id/product_name ]; then
read s </sys/class/dmi/id/product_name
for v in KVM QEMU VMware VMW VirtualBox Xen Bochs Parallels BHYVE Hyper-V; do
case "$s" in
"$v"*)
vm=$v
break
;;
esac
done
fi
;;
esac
echo "$vm" | awk '{print tolower($0)}'
}
check_virt()
{
echo \* checking virtualization
local vm="$(get_virt)"
if [ -n "$vm" ]; then
if [ "$vm" = "none" ]; then
echo running on bare metal
else
echo "!!! WARNING. $vm virtualization detected !!!"
echo '!!! WARNING. vmware and virtualbox are known to break most of the DPI bypass techniques when network is NATed using internal hypervisor NAT !!!'
echo '!!! WARNING. if this is your case make sure you are bridged not NATed !!!'
fi
else
echo cannot detect
fi
}
================================================
FILE: config.default
================================================
# this file is included from init scripts
# change values here
# can help in case /tmp has not enough space
#TMPDIR=/opt/zapret/tmp
# redefine user for zapret daemons. required on Keenetic
#WS_USER=nobody
# override firewall type : iptables,nftables,ipfw
#FWTYPE=iptables
# nftables only : set this to 0 to use pre-nat mode. default is post-nat.
# pre-nat mode disables some bypass techniques for forwarded traffic but allows to see client IP addresses in debug log
#POSTNAT=0
# options for ipsets
# maximum number of elements in sets. also used for nft sets
SET_MAXELEM=522288
# too low hashsize can cause memory allocation errors on low RAM systems , even if RAM is enough
# too large hashsize will waste lots of RAM
IPSET_OPT="hashsize 262144 maxelem $SET_MAXELEM"
# dynamically generate additional ip. $1 = ipset/nfset/table name
#IPSET_HOOK="/etc/zapret.ipset.hook"
# options for ip2net. "-4" or "-6" auto added by ipset create script
IP2NET_OPT4="--prefix-length=22-30 --v4-threshold=3/4"
IP2NET_OPT6="--prefix-length=56-64 --v6-threshold=5"
# options for auto hostlist
AUTOHOSTLIST_RETRANS_THRESHOLD=3
AUTOHOSTLIST_FAIL_THRESHOLD=3
AUTOHOSTLIST_FAIL_TIME=60
# 1 = debug autohostlist positives to ipset/zapret-hosts-auto-debug.log
AUTOHOSTLIST_DEBUGLOG=0
# number of parallel threads for domain list resolves
MDIG_THREADS=30
# ipset/*.sh can compress large lists
GZIP_LISTS=1
# command to reload ip/host lists after update
# comment or leave empty for auto backend selection : ipset or ipfw if present
# on BSD systems with PF no auto reloading happens. you must provide your own command
# set to "-" to disable reload
#LISTS_RELOAD="pfctl -f /etc/pf.conf"
# mark bit used by nfqws to prevent loop
DESYNC_MARK=0x40000000
DESYNC_MARK_POSTNAT=0x20000000
# do not pass outgoing traffic to tpws/nfqws not marked with this bit
# this setting allows to write your own rules to limit traffic that should be fooled
# for example based on source IP or incoming interface name
# no filter if not defined
#FILTER_MARK=0x10000000
TPWS_SOCKS_ENABLE=0
# tpws socks listens on this port on localhost and LAN interfaces
TPPORT_SOCKS=987
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
TPWS_SOCKS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-pos=1,midsld --disorder <HOSTLIST>
"
TPWS_ENABLE=0
TPWS_PORTS=80,443
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
TPWS_OPT="
--filter-tcp=80 --methodeol <HOSTLIST> --new
--filter-tcp=443 --split-pos=1,midsld --disorder <HOSTLIST>
"
NFQWS_ENABLE=0
# redirect outgoing traffic with connbytes limiter applied in both directions.
NFQWS_PORTS_TCP=80,443
NFQWS_PORTS_UDP=443
# PKT_OUT means connbytes dir original
# PKT_IN means connbytes dir reply
# this is --dpi-desync-cutoff=nX kernel mode implementation for linux. it saves a lot of CPU.
NFQWS_TCP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
NFQWS_TCP_PKT_IN=3
NFQWS_UDP_PKT_OUT=$((6+$AUTOHOSTLIST_RETRANS_THRESHOLD))
NFQWS_UDP_PKT_IN=0
# redirect outgoing traffic without connbytes limiter and incoming with connbytes limiter
# normally it's needed only for stateless DPI that matches every packet in a single TCP session
# typical example are plain HTTP keep alives
# this mode can be very CPU consuming. enable with care !
#NFQWS_PORTS_TCP_KEEPALIVE=80
#NFQWS_PORTS_UDP_KEEPALIVE=
# use <HOSTLIST> and <HOSTLIST_NOAUTO> placeholders to engage standard hostlists and autohostlist in ipset dir
# hostlist markers are replaced to empty string if MODE_FILTER does not satisfy
# <HOSTLIST_NOAUTO> appends ipset/zapret-hosts-auto.txt as normal list
NFQWS_OPT="
--filter-tcp=80 --dpi-desync=fake,multisplit --dpi-desync-split-pos=method+2 --dpi-desync-fooling=md5sig <HOSTLIST> --new
--filter-tcp=443 --dpi-desync=fake,multidisorder --dpi-desync-split-pos=1,midsld --dpi-desync-fooling=badseq,md5sig <HOSTLIST> --new
--filter-udp=443 --dpi-desync=fake --dpi-desync-repeats=6 <HOSTLIST_NOAUTO>
"
# none,ipset,hostlist,autohostlist
MODE_FILTER=none
# donttouch,none,software,hardware
FLOWOFFLOAD=donttouch
# openwrt: specify networks to be treated as LAN. default is "lan"
#OPENWRT_LAN="lan lan2 lan3"
# openwrt: specify networks to be treated as WAN. default wans are interfaces with default route
#OPENWRT_WAN4="wan vpn"
#OPENWRT_WAN6="wan6 vpn6"
# for routers based on desktop linux and macos. has no effect in openwrt.
# CHOOSE LAN and optinally WAN/WAN6 NETWORK INTERFACES
# or leave them commented if its not router
# it's possible to specify multiple interfaces like this : IFACE_LAN="eth0 eth1 eth2"
# if IFACE_WAN6 is not defined it take the value of IFACE_WAN
#IFACE_LAN=eth0
#IFACE_WAN=eth1
#IFACE_WAN6="ipsec0 wireguard0 he_net"
# should start/stop command of init scripts apply firewall rules ?
# not applicable to openwrt with firewall3+iptables
INIT_APPLY_FW=1
# firewall apply hooks
#INIT_FW_PRE_UP_HOOK="/etc/firewall.zapret.hook.pre_up"
#INIT_FW_POST_UP_HOOK="/etc/firewall.zapret.hook.post_up"
#INIT_FW_PRE_DOWN_HOOK="/etc/firewall.zapret.hook.pre_down"
#INIT_FW_POST_DOWN_HOOK="/etc/firewall.zapret.hook.post_down"
# do not work with ipv4
#DISABLE_IPV4=1
# do not work with ipv6
DISABLE_IPV6=1
# drop icmp time exceeded messages for nfqws tampered connections
# in POSTNAT mode this can interfere with default mtr/traceroute in tcp or udp mode. use source port not redirected to nfqws
# set to 0 if you are not expecting connection breakage due to icmp in response to TCP SYN or UDP
FILTER_TTL_EXPIRED_ICMP=1
# select which init script will be used to get ip or host list
# possible values : get_user.sh get_antizapret.sh get_combined.sh get_reestr.sh get_hostlist.sh
# comment if not required
#GETLIST=
================================================
FILE: docs/LICENSE.txt
================================================
MIT License
Copyright (c) 2016-2024 bol-van
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: docs/bsd.en.md
================================================
## Table of contents
- [Table of contents](#table-of-contents)
- [Supported versions](#supported-versions)
- [BSD features](#bsd-features)
- [FreeBSD](#freebsd)
- [`dvtws` quick start](#dvtws-quick-start)
- [PF in FreeBSD](#pf-in-freebsd)
- [`pfsense`](#pfsense)
- [OpenBSD](#openbsd)
- [MacOS](#macos)
- [MacOS easy install](#macos-easy-install)
## Supported versions
FreeBSD 11.x+ , OpenBSD 6.x+, partially MacOS Sierra+
Older versions may work or not.
## BSD features
BSD does not have NFQUEUE. Similar mechanism - divert sockets. In BSD compiling
the source from nfq directory result in `dvtws` binary instead of `nfqws`.
`dvtws` shares most of the code with `nfqws` and offers almost identical
parameters.
FreeBSD has 3 firewalls: IPFilter, ipfw and Packet Filter (PF). OpenBSD has
only PF.
To compile sources:
- FreeBSD: `make`
- OpenBSD: `make bsd`
- MacOS: `make mac`
Compile all programs:
```
make -C /opt/zapret
```
Divert sockets are internal type sockets in the BSD kernel. They have no
relation to network addresses or network packet exchange. They are identified
by a port number `1..65535`. Its like queue number in NFQUEUE. Traffic can be
diverted to a divert socket using firewall rule. If nobody listens on the
specified divert port packets are dropped. Its similar to NFQUEUE without
`--queue-bypass`.
`ipset/*.sh` scripts work with ipfw lookup tables if ipfw is present.
ipfw table is analog to linux `ipset`. Unlike ipsets ipfw tables share v4 an v6
addresses and subnets.
- If ipfw is absent scripts check LISTS_RELOAD config variable.
- If its present then scripts execute a command from LISTS_RELOAD.
- If LISTS_RELOAD=- scripts do not load tables even if ipfw exists.
PF can load ip tables from a file. To use this feature with `ipset/*.sh` scripts disable gzip file creation
using `GZIP_LISTS=0` directive in the `/opt/zapret/config` file.
BSD kernel doesn't implement splice syscall. tpws uses regular recv/send
operations with data copying to user space. Its slower but not critical.
`tpws` uses nonblocking sockets with linux specific epoll feature. In BSD systems
epoll is emulated by epoll-shim library on top of kqueue.
`dvtws` uses some programming HACKs, assumptions and knowledge of discovered
bugs and limitations. BSD systems have many limitations, version specific
features and bugs in low level networking, especially for ipv6. Many years have
passed but BSD code still has 15-20 year artificial limiters in the code. `dvtws`
uses additinal divert socket(s) for layer 3 packet injection if raw sockets do
not allow it. It works for the moment but who knows. Such a usage is not very
documented.
`mdig` and `ip2net` are fully compatible with BSD.
## FreeBSD
Divert sockets require special kernel module `ipdivert`.
Write the following to config files:
`/boot/loader.conf` (create if absent):
```
ipdivert_load="YES"
net.inet.ip.fw.default_to_accept=1
```
`/etc/rc.conf`:
```
firewall_enable="YES"
firewall_script="/etc/rc.firewall.my"
```
`/etc/rc.firewall.my`:
```
ipfw -q -f flush
```
Later you will add ipfw commands to `/etc/rc.firewall.my` to be reapplied after reboot.
You can also run zapret daemons from there. Start them with `--daemon` options, for example
```
pkill ^dvtws$
/opt/zapret/nfq/dvtws --port=989 --daemon --dpi-desync=multisplit --dpi-desync-split-pos=2
```
To restart firewall and daemons run : `/etc/rc.d/ipfw restart`
Assume `LAN="em1"`, `WAN="em0"`.
`tpws` transparent mode quick start.
For all traffic:
```
ipfw delete 100
ipfw add 100 fwd 127.0.0.1,988 tcp from me to any 80,443 proto ip4 xmit em0 not uid daemon
ipfw add 100 fwd ::1,988 tcp from me to any 80,443 proto ip6 xmit em0 not uid daemon
ipfw add 100 fwd 127.0.0.1,988 tcp from any to any 80,443 proto ip4 recv em1
ipfw add 100 fwd ::1,988 tcp from any to any 80,443 proto ip6 recv em1
/opt/zapret/tpws/tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
```
Process only table zapret with the exception of table nozapret:
```
ipfw delete 100
ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
ipfw add 100 fwd 127.0.0.1,988 tcp from me to table\(zapret\) 80,443 proto ip4 xmit em0 not uid daemon
ipfw add 100 fwd ::1,988 tcp from me to table\(zapret\) 80,443 proto ip6 xmit em0 not uid daemon
ipfw add 100 allow tcp from any to table\(nozapret\) 80,443 recv em1
ipfw add 100 fwd 127.0.0.1,988 tcp from any to any 80,443 proto ip4 recv em1
ipfw add 100 fwd ::1,988 tcp from any to any 80,443 proto ip6 recv em1
/opt/zapret/tpws/tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
```
Tables zapret, nozapret, ipban are created by `ipset/*.sh` scripts the same way as in Linux.
Its a good idea to update tables periodically:
```
crontab -e
```
Write the line:
```
0 12 */2 * * /opt/zapret/ipset/get_config.sh
```
When using `ipfw`, `tpws` does not require special permissions for transparent
mode. However without root its not possible to bind to ports less than 1024 and
change UID/GID. Without changing UID tpws will run into recursive loop, and
that's why its necessary to write ipfw rules with the right UID. Redirecting to
ports greater than or equal to 1024 is dangerous. If tpws is not running any
unprivileged process can listen to that port and intercept traffic.
### `dvtws` quick start
For all traffic:
```
ipfw delete 100
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg xmit em0
# required for autottl mode only
ipfw add 100 divert 989 tcp from any 80,443 to any tcpflags syn,ack in not diverted not sockarg recv em0
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
```
Process only table zapret with the exception of table nozapret:
```
ipfw delete 100
ipfw add 100 allow tcp from me to table\(nozapret\) 80,443
ipfw add 100 divert 989 tcp from any to table\(zapret\) 80,443 out not diverted not sockarg xmit em0
# required for autottl mode only
ipfw add 100 divert 989 tcp from table\(zapret\) 80,443 to any tcpflags syn,ack in not diverted not sockarg recv em0
/opt/zapret/nfq/dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
```
Reinjection loop avoidance. FreeBSD artificially ignores sockarg for ipv6 in
the kernel. This limitation is coming from the ipv6 early age. Code is still in
"testing" state. 10-20 years. Everybody forgot about it. `dvtws` sends ipv6
forged frames using another divert socket (HACK). they can be filtered out
using 'diverted'. ipv4 frames are filtered using 'sockarg'.
### PF in FreeBSD
The setup is similar to OpenBSD, but there are important nuances.
1. PF support is disabled by default in FreeBSD. Use parameter `--enable-pf`.
2. It's not possible to redirect to `::1`. Need to redirect to the link-local
address of the incoming interface. Look for fe80:... address in ifconfig and
use it for redirection target.
3. pf.conf syntax is a bit different from OpenBSD.
4. How to set maximum table size : sysctl net.pf.request_maxcount=2000000
5. `divert-to` is broken. Loop avoidance scheme does not work.
This makes `dvtws` unusable with pf.
Someone posted kernel patch but 14-RELEASE is still broken.
`/etc/pf.conf`:
```
rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::31c:29ff:dee2:1c4d port 988
rdr pass on em1 inet proto tcp to port {80,443} -> 127.0.0.1 port 988
```
Then:
```
/opt/zapret/tpws/tpws --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force
```
Its not clear how to do rdr-to outgoing traffic. I could not make route-to
scheme work.
### `pfsense`
`pfsense` is based on FreeBSD. Binaries from `binaries/freebsd-x64` are
compiled in FreeBSD 11 and should work. Use `install_bin.sh`. pfsense uses pf
firewall which does not support divert. Fortunately ipfw and ipdivert modules
are present and can be kldload-ed. In older versions it's also necessary to
change firewall order using sysctl commands. In newer versions those sysctl
parameters are absent but the system behaves as required without them.
Sometimes pf may limit `dvtws` abilities. It scrubs ip fragments disabling `dvtws`
ipfrag2 desync mode.
There's autostart script example in `init.d/pfsense`. It should be placed to
`/usr/local/etc/rc.d` and edited. Write your ipfw rules and daemon start
commands.
curl is present by default. You can use it to download `tar.gz` release directly from github.
Or you can copy files using sftp.
Copy zip with zapret files to `/opt` and unpack there as it's done in other
systems. In this case run `dvtws` as `/opt/zapret/nfq/dvtws`. Or just copy
`dvtws` to `/usr/local/sbin`. As you wish. `ipset` scripts are working, cron is
present. It's possible to renew lists.
If you dont like poverty of default repos its possible to enable FreeBSD repo.
Change `no` to `yes` in `/usr/local/etc/pkg/repos/FreeBSD.conf` and `/usr/local/etc/pkg/repos/pfSense.conf`.
`/usr/local/etc/rc.d/zapret.sh` (chmod 755)
```
#!/bin/sh
kldload ipfw
kldload ipdivert
# for older pfsense versions. newer do not have these sysctls
sysctl net.inet.ip.pfil.outbound=ipfw,pf
sysctl net.inet.ip.pfil.inbound=ipfw,pf
sysctl net.inet6.ip6.pfil.outbound=ipfw,pf
sysctl net.inet6.ip6.pfil.inbound=ipfw,pf
ipfw delete 100
ipfw add 100 divert 989 tcp from any to any 80,443 out not diverted not sockarg xmit em0
pkill ^dvtws$
dvtws --daemon --port 989 --dpi-desync=multisplit --dpi-desync-split-pos=2
# required for newer pfsense versions (2.6.0 tested) to return ipfw to functional state
pfctl -d ; pfctl -e
```
I could not make tpws work from ipfw. Looks like there's some conflict between
two firewalls. Only PF redirection works. PF does not allow to freely add and
delete rules. Only anchors can be reloaded. To make an anchor work it must be
referred from the main ruleset. But its managed by pfsense scripts.
One possible solution would be to modify `/etc/inc/filter.inc` as follows:
```
.................
/* MOD */
$natrules .= "# ZAPRET redirection\n";
$natrules .= "rdr-anchor \"zapret\"\n";
$natrules .= "# TFTP proxy\n";
$natrules .= "rdr-anchor \"tftp-proxy/*\"\n";
.................
```
Write the anchor code to `/etc/zapret.anchor`:
```
rdr pass on em1 inet proto tcp to port {80,443} -> 127.0.0.1 port 988
rdr pass on em1 inet6 proto tcp to port {80,443} -> fe80::20c:29ff:5ae3:4821 port 988
```
Replace `fe80::20c:29ff:5ae3:4821` with your link local address of the LAN
interface or remove the line if ipv6 is not needed.
Autostart `/usr/local/etc/rc.d/zapret.sh`:
```
pfctl -a zapret -f /etc/zapret.anchor
pkill ^tpws$
tpws --daemon --port=988 --enable-pf --bind-addr=127.0.0.1 --bind-iface6=em1 --bind-linklocal=force --split-pos=2
```
After reboot check that anchor is created and referred from the main ruleset:
```
[root@pfSense /]# pfctl -s nat
no nat proto carp all
nat-anchor "natearly/*" all
nat-anchor "natrules/*" all
...................
no rdr proto carp all
rdr-anchor "zapret" all
rdr-anchor "tftp-proxy/*" all
rdr-anchor "miniupnpd" all
[root@pfSense /]# pfctl -s nat -a zapret
rdr pass on em1 inet proto tcp from any to any port = http -> 127.0.0.1 port 988
rdr pass on em1 inet proto tcp from any to any port = https -> 127.0.0.1 port 988
rdr pass on em1 inet6 proto tcp from any to any port = http -> fe80::20c:29ff:5ae3:4821 port 988
rdr pass on em1 inet6 proto tcp from any to any port = https -> fe80::20c:29ff:5ae3:4821 port 988
```
Also there's a way to add redirect in the pfsense UI and start `tpws` from cron using `@reboot` prefix.
This way avoids modification of pfsense code.
## OpenBSD
In OpenBSD default `tpws` bind is ipv6 only. To bind to ipv4 specify
`--bind-addr=0.0.0.0`.
Use `--bind-addr=0.0.0.0 --bind-addr=::` to achieve the same default bind as in
others OSes.
`tpws` for forwarded traffic only (OLDER OS versions):
`/etc/pf.conf`:
```
pass in quick on em1 inet proto tcp to port {80,443} rdr-to 127.0.0.1 port 988
pass in quick on em1 inet6 proto tcp to port {80,443} rdr-to ::1 port 988
```
Then:
```
pfctl -f /etc/pf.conf
tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1 --enable-pf
```
Its not clear how to do rdr-to outgoing traffic. I could not make route-to
scheme work. rdr-to support is done using /dev/pf, that's why transparent mode
requires root.
`tpws` for forwarded traffic only (NEWER OS versions):
```
pass on em1 inet proto tcp to port {80,443} divert-to 127.0.0.1 port 989
pass on em1 inet6 proto tcp to port {80,443} divert-to ::1 port 989
```
Then:
```
pfctl -f /etc/pf.conf
tpws --port=988 --user=daemon --bind-addr=::1 --bind-addr=127.0.0.1
```
tpws must be bound exactly to diverted IPs, not `0.0.0.0` or `::`.
It's also not clear how to divert connections from local system.
`dvtws` for all traffic:
`/etc/pf.conf`:
```
pass in quick on em0 proto tcp from port {80,443} flags SA/SA divert-packet port 989 no state
pass in quick on em0 proto tcp from port {80,443} no state
pass out quick on em0 proto tcp to port {80,443} divert-packet port 989
```
Then:
```
pfctl -f /etc/pf.conf
./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
```
`dwtws` only for table zapret with the exception of table nozapret :
`/etc/pf.conf`:
```
set limit table-entries 2000000
table <zapret> file "/opt/zapret/ipset/zapret-ip.txt"
table <zapret-user> file "/opt/zapret/ipset/zapret-ip-user.txt"
table <nozapret> file "/opt/zapret/ipset/zapret-ip-exclude.txt"
pass out quick on em0 inet proto tcp to <nozapret> port {80,443}
pass in quick on em0 inet proto tcp from <zapret> port {80,443} flags SA/SA divert-packet port 989 no state
pass in quick on em0 inet proto tcp from <zapret> port {80,443} no state
pass out quick on em0 inet proto tcp to <zapret> port {80,443} divert-packet port 989 no state
pass in quick on em0 inet proto tcp from <zapret-user> port {80,443} flags SA/SA divert-packet port 989 no state
pass in quick on em0 inet proto tcp from <zapret-user> port {80,443} no state
pass out quick on em0 inet proto tcp to <zapret-user> port {80,443} divert-packet port 989 no state
table <zapret6> file "/opt/zapret/ipset/zapret-ip6.txt"
table <zapret6-user> file "/opt/zapret/ipset/zapret-ip-user6.txt"
table <nozapret6> file "/opt/zapret/ipset/zapret-ip-exclude6.txt"
pass out quick on em0 inet6 proto tcp to <nozapret6> port {80,443}
pass in quick on em0 inet6 proto tcp from <zapret6> port {80,443} flags SA/SA divert-packet port 989 no state
pass in quick on em0 inet6 proto tcp from <zapret6> port {80,443} no state
pass out quick on em0 inet6 proto tcp to <zapret6> port {80,443} divert-packet port 989 no state
pass in quick on em0 inet6 proto tcp from <zapret6-user> port {80,443} flags SA/SA divert-packet port 989 no state
pass in quick on em0 inet6 proto tcp from <zapret6-user> port {80,443} no state
pass out quick on em0 inet6 proto tcp to <zapret6-user> port {80,443} divert-packet port 989 no state
```
Then:
```
pfctl -f /etc/pf.conf
./dvtws --port=989 --dpi-desync=multisplit --dpi-desync-split-pos=2
```
divert-packet automatically adds the reverse rule. By default also incoming
traffic will be passwed to `dvtws`. This is highly undesired because it is waste
of cpu resources and speed limiter. The trick with "no state" and "in" rules
allows to bypass auto reverse rule.
`dvtws` in OpenBSD sends all fakes through a divert socket because raw sockets
have critical artificial limitations. Looks like pf automatically prevent
reinsertion of diverted frames. Loop problem does not exist.
OpenBSD forcibly recomputes tcp checksum after divert. Thats why most likely
dpi-desync-fooling=badsum will not work. `dvtws` will warn if you specify this
parameter.
`ipset` scripts do not reload PF by default. To enable reload specify command in
`/opt/zapret/config`:
```
LISTS_RELOAD="pfctl -f /etc/pf.conf"
```
Newer `pfctl` versions can reload tables only:
```
pfctl -Tl -f /etc/pf.conf
```
But OpenBSD 6.8 `pfctl` is old enough and does not support that. Newer FreeBSD do.
Don't forget to disable gzip compression:
```
GZIP_LISTS=0
```
If some list files do not exist and have references in pf.conf it leads to
error. You need to exclude those tables from pf.conf and referencing them
rules. After configuration is done you can put `ipset` script:
```
crontab -e
```
Then write the line:
```
0 12 */2 * * /opt/zapret/ipset/get_config.sh
```
## MacOS
Initially, the kernel of this OS was based on BSD. That's why it is still BSD
but a lot was modified by Apple. As usual a mass commercial project priorities
differ from their free counterparts. Apple guys do what they want.
MacOS used to have ipfw but it was removed later and replaced by PF. It looks
like divert sockets are internally replaced with raw. Its possible to request a
divert socket but it behaves exactly as raw socket with all its BSD inherited +
apple specific bugs and feature. The fact is that divert-packet in
`/etc/pf.conf` does not work. pfctl binary does not contain the word `divert`.
`dvtws` does compile but is useless.
After some efforts `tpws` works. Apple has removed some important stuff from
their newer SDKs (DIOCNATLOOK) making them undocumented and unsupported.
With important definitions copied from an older SDK it was possible to make
transparent mode working again. But this is not guaranteed to work in the
future versions.
Another MacOS unique feature is root requirement while polling `/dev/pf`.
By default tpws drops root. Its necessary to specify `--user=root` to stay with
root.
In other aspects PF behaves very similar to FreeBSD and shares the same pf.conf
syntax.
In MacOS redirection works both for passthrough and outgoing traffic. Outgoing
redirection requires route-to rule. Because tpws is forced to run as root to
avoid loop its necessary to exempt root from the redirection. That's why DPI
bypass will not work for local requests from root.
If you do ipv6 routing you have to get rid of "secured" ipv6 address
assignment.
"secured" addresses are designed to be permanent and not related to the MAC
address.
And they really are. Except for link-locals.
If you just reboot the system link-locals will not change. But next day they
will change.
Not necessary to wait so long. Just change the system time to tomorrow and reboot.
Link-locals will change (at least they change in vmware guest). Looks like its a kernel bug.
Link locals should not change. Its useless and can be harmful. Cant use LL as a gateway.
The easiest solution is to disable "secured" addresses.
Outgoing connections prefer randomly generated temporary addressesas like in other systems.
Put the string `net.inet6.send.opmode=0` to `/etc/sysctl.conf`. If not present
- create it.
Then reboot the system.
If you dont like this solution you can assign an additional static ipv6 address
from `fc00::/7` range with `/128` prefix to your LAN interface and use it as
the gateway address.
`tpws` transparent mode only for outgoing connections.
`/etc/pf.conf`:
```
rdr pass on lo0 inet proto tcp from !127.0.0.0/8 to any port {80,443} -> 127.0.0.1 port 988
rdr pass on lo0 inet6 proto tcp from !::1 to any port {80,443} -> fe80::1 port 988
pass out route-to (lo0 127.0.0.1) inet proto tcp from any to any port {80,443} user { >root }
pass out route-to (lo0 fe80::1) inet6 proto tcp from any to any port {80,443} user { >root }
```
Then:
```
pfctl -ef /etc/pf.conf
/opt/zapret/tpws/tpws --user=root --port=988 --bind-addr=127.0.0.1 --bind-iface6=lo0 --bind-linklocal=force
```
`tpws` transparent mode for both passthrough and outgoing connections. en1 - LAN.
```
ifconfig en1 | grep fe80
inet6 fe80::bbbb:bbbb:bbbb:bbbb%en1 prefixlen 64 scopeid 0x8
```
`/etc/pf.conf`:
```
rdr pass on en1 inet proto tcp from any to any port {80,443} -> 127.0.0.1 port 988
rdr pass on en1 inet6 proto tcp from any to any port {80,443} -> fe80::bbbb:bbbb:bbbb:bbbb port 988
rdr pass on lo0 inet proto tcp from !127.0.0.0/8 to any port {80,443} -> 127.0.0.1 port 988
rdr pass on lo0 inet6 proto tcp from !::1 to any port {80,443} -> fe80::1 port 988
pass out route-to (lo0 127.0.0.1) inet proto tcp from any to any port {80,443} user { >root }
pass out route-to (lo0 fe80::1) inet6 proto tcp from any to any port {80,443} user { >root }
```
Then:
```
pfctl -ef /etc/pf.conf
/opt/zapret/tpws/tpws --user=root --port=988 --bind-addr=127.0.0.1 --bind-iface6=lo0 --bind-linklocal=force --bind-iface6=en1 --bind-linklocal=force
```
Build from source : `make -C /opt/zapret mac`
`ipset/*.sh` scripts work.
### MacOS easy install
`install_easy.sh` supports MacOS
Shipped precompiled binaries are built for 64-bit MacOS with
`-mmacosx-version-min=10.8` option. They should run on all supported MacOS
versions. If no - its easy to build your own. Running `make` automatically
installs developer tools.
**WARNING**:
**Internet sharing is not supported!**
Routing is supported but only manually configured through PF. If you enable
internet sharing tpws stops functioning. When you disable internet sharing you
may lose web site access.
To fix:
```
pfctl -f /etc/pf.conf
```
If you need internet sharing use `tpws` socks mode.
`launchd` is used for autostart (`/Library/LaunchDaemons/zapret.plist`)
Control script: `/opt/zapret/init.d/macos/zapret`
The following commands fork with both tpws and firewall (if `INIT_APPLY_FW=1` in config)
```
/opt/zapret/init.d/macos/zapret start
/opt/zapret/init.d/macos/zapret stop
/opt/zapret/init.d/macos/zapret restart
```
Work with `tpws` only:
```
/opt/zapret/init.d/macos/zapret start-daemons
/opt/zapret/init.d/macos/zapret stop-daemons
/opt/zapret/init.d/macos/zapret restart-daemons
```
Work with PF only:
```
/opt/zapret/init.d/macos/zapret start-fw
/opt/zapret/init.d/macos/zapret stop-fw
/opt/zapret/init.d/macos/zapret restart-fw
```
Reloading PF tables:
```
/opt/zapret/init.d/macos/zapret reload-fw-tables
```
Installer configures `LISTS_RELOAD` in the config so `ipset *.sh` scripts
automatically reload PF tables. Installer creates cron job for `ipset
/get_config.sh`, as in OpenWRT.
start-fw script automatically patches `/etc/pf.conf` inserting there `zapret`
anchors. Auto patching requires pf.conf with apple anchors preserved. If your
`pf.conf` is highly customized and patching fails you will see the warning. Do
not ignore it.
In that case you need to manually insert "zapret" anchors to your `pf.conf`
(keeping the right rule type ordering):
```
rdr-anchor "zapret"
anchor "zapret"
unistall_easy.sh unpatches pf.conf
```
start-fw creates 3 anchor files in `/etc/pf.anchors` :
zapret,zapret-v4,zapret-v6.
- Last 2 are referenced by anchor `zapret`.
- Tables `nozapret`,`nozapret6` belong to anchor `zapret`.
- Tables `zapret`,`zapret-user` belong to anchor `zapret-v4`.
- Tables `zapret6`,`apret6-user` belong to anchor `zapret-v6`.
If an ip version is disabled then corresponding anchor is empty and is not
referenced from the anchor `zapret`. Tables are only created for existing list
files in the `ipset` directory.
================================================
FILE: docs/bsd.md
================================================
# Настройка BSD-подобных систем
* [Поддерживаемые версии](#поддерживаемые-версии)
* [Особенности BSD систем](#особенности-bsd-систем)
* [Отсутствие nfqueue](#отсутствие-nfqueue)
* [Типы Firewall](#типы-firewall)
* [Сборка](#сборка)
* [Divert сокеты](#divert-сокеты)
* [Lookup Tables](#lookup-tables)
* [Загрузка ip таблиц из файла](#загрузка-ip-таблиц-из-файла)
* [Отсутствие splice](#отсутствие-splice)
* [mdig и ip2net](#mdig-и-ip2net)
* [FreeBSD](#freebsd)
* [Подгрузка ipdivert](#подгрузка-ipdivert)
* [Авто-восстановление правил ipfw и работа в фоне](#авто-восстановление-правил-ipfw-и-работа-в-фоне)
* [tpws в прозрачном режиме](#tpws-в-прозрачном-режиме)
* [Запуск dvtws](#запуск-dvtws)
* [PF в FreeBSD](#pf-в-freebsd)
* [pfsense](#pfsense)
* [OpenBSD](#openbsd)
gitextract_d8cviuz8/ ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── config.yml │ │ └── issue-warning.md │ └── workflows/ │ ├── build.yml │ └── libnetfilter_queue-android.patch ├── .gitignore ├── Makefile ├── blockcheck.sh ├── common/ │ ├── base.sh │ ├── custom.sh │ ├── dialog.sh │ ├── elevate.sh │ ├── fwtype.sh │ ├── installer.sh │ ├── ipt.sh │ ├── linux_daemons.sh │ ├── linux_fw.sh │ ├── linux_iphelper.sh │ ├── list.sh │ ├── nft.sh │ ├── pf.sh │ └── virt.sh ├── config.default ├── docs/ │ ├── LICENSE.txt │ ├── bsd.en.md │ ├── bsd.md │ ├── bsdfw.txt │ ├── changes.txt │ ├── compile/ │ │ ├── build_howto_openwrt.txt │ │ ├── build_howto_unix.txt │ │ ├── build_howto_windows.txt │ │ └── openwrt/ │ │ └── package/ │ │ └── zapret/ │ │ ├── ip2net/ │ │ │ ├── Makefile │ │ │ └── readme.txt │ │ ├── mdig/ │ │ │ ├── Makefile │ │ │ └── readme.txt │ │ ├── nfqws/ │ │ │ ├── Makefile │ │ │ └── readme.txt │ │ └── tpws/ │ │ ├── Makefile │ │ └── readme.txt │ ├── iptables.txt │ ├── nftables.txt │ ├── nftables_notes.txt │ ├── quick_start.md │ ├── quick_start_windows.md │ ├── readme.en.md │ ├── readme.md │ ├── redsocks.txt │ ├── windows.en.md │ ├── windows.md │ └── wireguard_iproute_openwrt.txt ├── files/ │ └── huawei/ │ └── E8372/ │ ├── run-zapret-hostlist │ ├── run-zapret-ip │ ├── unfuck_nfqueue.ko │ ├── unzapret │ ├── unzapret-ip │ ├── zapret │ └── zapret-ip ├── init.d/ │ ├── custom.d.examples.linux/ │ │ ├── 10-keenetic-udp-fix │ │ ├── 20-fw-extra │ │ ├── 50-dht4all │ │ ├── 50-discord-media │ │ ├── 50-nfqws-ipset │ │ ├── 50-quic4all │ │ ├── 50-stun4all │ │ ├── 50-tpws-ipset │ │ └── 50-wg4all │ ├── macos/ │ │ ├── custom.d/ │ │ │ └── .keep │ │ ├── custom.d.examples/ │ │ │ └── 50-extra-tpws │ │ ├── functions │ │ ├── zapret │ │ └── zapret.plist │ ├── openrc/ │ │ └── zapret │ ├── openwrt/ │ │ ├── 90-zapret │ │ ├── custom.d/ │ │ │ └── .keep │ │ ├── firewall.zapret │ │ ├── functions │ │ └── zapret │ ├── openwrt-minimal/ │ │ ├── readme.txt │ │ └── tpws/ │ │ └── etc/ │ │ ├── config/ │ │ │ └── tpws │ │ ├── firewall.user │ │ ├── init.d/ │ │ │ └── tpws │ │ └── nftables.d/ │ │ └── 90-tpws.nft │ ├── pfsense/ │ │ └── zapret.sh │ ├── runit/ │ │ └── zapret/ │ │ ├── finish │ │ └── run │ ├── s6/ │ │ └── zapret/ │ │ ├── down │ │ ├── type │ │ └── up │ ├── systemd/ │ │ ├── nfqws@.service │ │ ├── tpws@.service │ │ ├── zapret-list-update.service │ │ ├── zapret-list-update.timer │ │ └── zapret.service │ ├── sysv/ │ │ ├── custom.d/ │ │ │ └── .keep │ │ ├── functions │ │ └── zapret │ └── windivert.filter.examples/ │ ├── README.txt │ ├── windivert_part.discord_media.txt │ ├── windivert_part.quic_initial_ietf.txt │ ├── windivert_part.stun.txt │ └── windivert_part.wireguard.txt ├── install_bin.sh ├── install_easy.sh ├── install_prereq.sh ├── ip2net/ │ ├── Makefile │ ├── ip2net.c │ ├── qsort.c │ └── qsort.h ├── ipset/ │ ├── antifilter.helper │ ├── clear_lists.sh │ ├── create_ipset.sh │ ├── def.sh │ ├── get_antifilter_allyouneed.sh │ ├── get_antifilter_ip.sh │ ├── get_antifilter_ipresolve.sh │ ├── get_antifilter_ipsmart.sh │ ├── get_antifilter_ipsum.sh │ ├── get_antizapret_domains.sh │ ├── get_config.sh │ ├── get_exclude.sh │ ├── get_ipban.sh │ ├── get_reestr_preresolved.sh │ ├── get_reestr_preresolved_smart.sh │ ├── get_reestr_resolvable_domains.sh │ ├── get_refilter_domains.sh │ ├── get_refilter_ipsum.sh │ ├── get_user.sh │ └── zapret-hosts-user-exclude.txt.default ├── mdig/ │ ├── Makefile │ └── mdig.c ├── nfq/ │ ├── BSDmakefile │ ├── Makefile │ ├── checksum.c │ ├── checksum.h │ ├── conntrack.c │ ├── conntrack.h │ ├── crypto/ │ │ ├── aes-gcm.c │ │ ├── aes-gcm.h │ │ ├── aes.c │ │ ├── aes.h │ │ ├── gcm.c │ │ ├── gcm.h │ │ ├── hkdf.c │ │ ├── hmac.c │ │ ├── sha-private.h │ │ ├── sha.h │ │ ├── sha224-256.c │ │ └── usha.c │ ├── darkmagic.c │ ├── darkmagic.h │ ├── desync.c │ ├── desync.h │ ├── gzip.c │ ├── gzip.h │ ├── helpers.c │ ├── helpers.h │ ├── hostlist.c │ ├── hostlist.h │ ├── ipset.c │ ├── ipset.h │ ├── kavl.h │ ├── nfqws.c │ ├── nfqws.h │ ├── packet_queue.c │ ├── packet_queue.h │ ├── params.c │ ├── params.h │ ├── pools.c │ ├── pools.h │ ├── protocol.c │ ├── protocol.h │ ├── sec.c │ ├── sec.h │ ├── uthash.h │ ├── win.c │ ├── win.h │ └── windows/ │ ├── res/ │ │ ├── 32/ │ │ │ ├── winicon.o │ │ │ └── winmanifest.o │ │ └── 64/ │ │ ├── winicon.o │ │ └── winmanifest.o │ └── windivert/ │ ├── libwindivert32.a │ ├── libwindivert64.a │ └── windivert.h ├── tmp/ │ └── .keep ├── tpws/ │ ├── BSDmakefile │ ├── Makefile │ ├── andr/ │ │ ├── _musl_license.txt │ │ ├── getifaddrs.c │ │ ├── ifaddrs.h │ │ ├── netlink.c │ │ └── netlink.h │ ├── epoll-shim/ │ │ ├── include/ │ │ │ └── sys/ │ │ │ └── epoll.h │ │ └── src/ │ │ ├── epoll.c │ │ ├── epoll_shim_ctx.c │ │ ├── epoll_shim_ctx.h │ │ ├── epollfd_ctx.c │ │ ├── epollfd_ctx.h │ │ ├── eventfd_ctx.h │ │ ├── fix.c │ │ ├── fix.h │ │ ├── signalfd_ctx.h │ │ └── timerfd_ctx.h │ ├── gzip.c │ ├── gzip.h │ ├── helpers.c │ ├── helpers.h │ ├── hostlist.c │ ├── hostlist.h │ ├── ipset.c │ ├── ipset.h │ ├── kavl.h │ ├── linux_compat.h │ ├── macos/ │ │ ├── net/ │ │ │ └── pfvar.h │ │ └── sys/ │ │ └── tree.h │ ├── params.c │ ├── params.h │ ├── pools.c │ ├── pools.h │ ├── protocol.c │ ├── protocol.h │ ├── redirect.c │ ├── redirect.h │ ├── resolver.c │ ├── resolver.h │ ├── sec.c │ ├── sec.h │ ├── socks.h │ ├── tamper.c │ ├── tamper.h │ ├── tpws.c │ ├── tpws.h │ ├── tpws_conn.c │ ├── tpws_conn.h │ └── uthash.h └── uninstall_easy.sh
SYMBOL INDEX (1685 symbols across 84 files)
FILE: ip2net/ip2net.c
function ucmp (line 41) | static int ucmp(const void * a, const void * b, void *arg)
function mask_from_bitcount (line 50) | static uint32_t mask_from_bitcount(uint32_t zct)
function unique (line 56) | static uint32_t unique(uint32_t *pu, uint32_t ct)
function cmp6 (line 71) | __attribute__((optimize ("no-strict-aliasing")))
function unique6 (line 122) | static uint32_t unique6(struct in6_addr *pu, uint32_t ct)
function mask_from_bitcount6_make (line 132) | static void mask_from_bitcount6_make(uint32_t zct, struct in6_addr *a)
type in6_addr (line 144) | struct in6_addr
function mask_from_bitcount6_prepare (line 145) | static void mask_from_bitcount6_prepare(void)
type in6_addr (line 149) | struct in6_addr
function ip6_and (line 179) | __attribute__((optimize ("no-strict-aliasing")))
function rtrim (line 192) | static void rtrim(char *s)
type params_s (line 199) | struct params_s
function exithelp (line 208) | static void exithelp(void)
type opt_indices (line 228) | enum opt_indices {
type option (line 239) | struct option
function parse_params (line 250) | static void parse_params(int argc, char *argv[])
function main (line 314) | int main(int argc, char **argv)
FILE: ip2net/qsort.c
type stack_node (line 48) | typedef struct
function gnu_quicksort (line 89) | void
FILE: mdig/mdig.c
function trimstr (line 36) | static void trimstr(char *s)
function dom_valid (line 79) | static bool dom_valid(char *dom)
function invalid_domain_beautify (line 88) | static void invalid_domain_beautify(char *dom)
function interlocked_get_dom (line 110) | static char interlocked_get_dom(char *dom, size_t size)
function interlocked_fprintf (line 120) | static void interlocked_fprintf(FILE *stream, const char * format, ...)
function print_addrinfo (line 136) | static void print_addrinfo(struct addrinfo *ai)
function stat_print (line 156) | static void stat_print(int ct, int ct_ok)
function stat_plus (line 165) | static void stat_plus(bool is_ok)
function GetAddrFamily (line 179) | static uint16_t GetAddrFamily(const char *saddr)
type addrinfo (line 197) | struct addrinfo
type timespec (line 198) | struct timespec
type addrinfo (line 203) | struct addrinfo
function run_threads (line 284) | static int run_threads(void)
function dns_mk_query_blob (line 330) | size_t dns_mk_query_blob(uint8_t op, const char *dname, uint8_t class, u...
function dns_make_query (line 365) | int dns_make_query(const char *dom, char family)
function dns_parse_print (line 385) | bool dns_parse_print(const uint8_t *a, size_t len)
function dns_parse_query (line 431) | int dns_parse_query()
function exithelp (line 453) | static void exithelp(void)
type opt_indices (line 480) | enum opt_indices {
type option (line 495) | struct option
function main (line 510) | int main(int argc, char **argv)
FILE: nfq/checksum.c
function from64to16 (line 8) | static uint16_t from64to16(uint64_t x)
function do_csum (line 17) | static uint16_t do_csum(const uint8_t * buff, size_t len)
function csum_partial (line 96) | uint16_t csum_partial(const void *buff, size_t len)
function csum_tcpudp_magic (line 101) | uint16_t csum_tcpudp_magic(uint32_t saddr, uint32_t daddr, size_t len, u...
function ip4_compute_csum (line 106) | uint16_t ip4_compute_csum(const void *buff, size_t len)
function ip4_fix_checksum (line 110) | void ip4_fix_checksum(struct ip *ip)
function csum_ipv6_magic (line 116) | uint16_t csum_ipv6_magic(const void *saddr, const void *daddr, size_t le...
function tcp4_fix_checksum (line 125) | void tcp4_fix_checksum(struct tcphdr *tcp,size_t len, const struct in_ad...
function tcp6_fix_checksum (line 130) | void tcp6_fix_checksum(struct tcphdr *tcp,size_t len, const struct in6_a...
function tcp_fix_checksum (line 135) | void tcp_fix_checksum(struct tcphdr *tcp,size_t len,const struct ip *ip,...
function udp4_fix_checksum (line 143) | void udp4_fix_checksum(struct udphdr *udp,size_t len, const struct in_ad...
function udp6_fix_checksum (line 148) | void udp6_fix_checksum(struct udphdr *udp,size_t len, const struct in6_a...
function udp_fix_checksum (line 153) | void udp_fix_checksum(struct udphdr *udp,size_t len,const struct ip *ip,...
FILE: nfq/checksum.h
type ip (line 19) | struct ip
type tcphdr (line 21) | struct tcphdr
type in_addr (line 21) | struct in_addr
type in_addr (line 21) | struct in_addr
type tcphdr (line 22) | struct tcphdr
type in6_addr (line 22) | struct in6_addr
type in6_addr (line 22) | struct in6_addr
type tcphdr (line 23) | struct tcphdr
type ip (line 23) | struct ip
type ip6_hdr (line 23) | struct ip6_hdr
type udphdr (line 25) | struct udphdr
type in_addr (line 25) | struct in_addr
type in_addr (line 25) | struct in_addr
type udphdr (line 26) | struct udphdr
type in6_addr (line 26) | struct in6_addr
type in6_addr (line 26) | struct in6_addr
type udphdr (line 27) | struct udphdr
type ip (line 27) | struct ip
type ip6_hdr (line 27) | struct ip6_hdr
FILE: nfq/conntrack.c
function ut_oom_recover (line 10) | static void ut_oom_recover(void *elem)
function connswap (line 17) | static void connswap(const t_conn *c, t_conn *c2)
function ConntrackClearHostname (line 28) | void ConntrackClearHostname(t_ctrack *track)
function ConntrackClearTrack (line 34) | static void ConntrackClearTrack(t_ctrack *track)
function ConntrackFreeElem (line 41) | static void ConntrackFreeElem(t_conntrack_pool *elem)
function ConntrackPoolDestroyPool (line 47) | static void ConntrackPoolDestroyPool(t_conntrack_pool **pp)
function ConntrackPoolDestroy (line 52) | void ConntrackPoolDestroy(t_conntrack *p)
function ConntrackPoolInit (line 57) | void ConntrackPoolInit(t_conntrack *p, time_t purge_interval, uint32_t t...
function ConntrackExtractConn (line 68) | void ConntrackExtractConn(t_conn *c, bool bReverse, const struct ip *ip,...
function t_conntrack_pool (line 89) | static t_conntrack_pool *ConntrackPoolSearch(t_conntrack_pool *p, const ...
function ConntrackInitTrack (line 96) | static void ConntrackInitTrack(t_ctrack *t)
function ConntrackReInitTrack (line 103) | static void ConntrackReInitTrack(t_ctrack *t)
function t_conntrack_pool (line 109) | static t_conntrack_pool *ConntrackNew(t_conntrack_pool **pp, const t_con...
function ConntrackFeedPacket (line 122) | static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct...
function ConntrackPoolDoubleSearchPool (line 202) | static bool ConntrackPoolDoubleSearchPool(t_conntrack_pool **pp, const s...
function ConntrackPoolDoubleSearch (line 226) | bool ConntrackPoolDoubleSearch(t_conntrack *p, const struct ip *ip, cons...
function ConntrackPoolFeedPool (line 231) | static bool ConntrackPoolFeedPool(t_conntrack_pool **pp, const struct ip...
function ConntrackPoolFeed (line 267) | bool ConntrackPoolFeed(t_conntrack *p, const struct ip *ip, const struct...
function ConntrackPoolDropPool (line 272) | static bool ConntrackPoolDropPool(t_conntrack_pool **pp, const struct ip...
function ConntrackPoolDrop (line 286) | bool ConntrackPoolDrop(t_conntrack *p, const struct ip *ip, const struct...
function ConntrackPoolPurge (line 291) | void ConntrackPoolPurge(t_conntrack *p)
function taddr2str (line 315) | static void taddr2str(uint8_t l3proto, const t_addr *a, char *buf, size_...
function ConntrackPoolDump (line 320) | void ConntrackPoolDump(const t_conntrack *p)
function ReasmClear (line 351) | void ReasmClear(t_reassemble *reasm)
function ReasmInit (line 357) | bool ReasmInit(t_reassemble *reasm, size_t size_requested, uint32_t seq_...
function ReasmResize (line 366) | bool ReasmResize(t_reassemble *reasm, size_t new_size)
function ReasmFeed (line 375) | bool ReasmFeed(t_reassemble *reasm, uint32_t seq, const void *payload, s...
function ReasmHasSpace (line 388) | bool ReasmHasSpace(t_reassemble *reasm, size_t len)
FILE: nfq/conntrack.h
type t_addr (line 31) | typedef union {
type t_conn (line 35) | typedef struct
type t_reassemble (line 44) | typedef struct {
type t_connstate (line 54) | typedef enum {SYN=0, ESTABLISHED, FIN} t_connstate;
type t_ctrack (line 56) | typedef struct
type t_conntrack_pool (line 99) | typedef struct
type t_conntrack (line 105) | typedef struct
type ip (line 115) | struct ip
type ip6_hdr (line 115) | struct ip6_hdr
type tcphdr (line 115) | struct tcphdr
type udphdr (line 115) | struct udphdr
type ip (line 117) | struct ip
type ip6_hdr (line 117) | struct ip6_hdr
type tcphdr (line 117) | struct tcphdr
type udphdr (line 117) | struct udphdr
type ip (line 118) | struct ip
type ip6_hdr (line 118) | struct ip6_hdr
type tcphdr (line 118) | struct tcphdr
type udphdr (line 118) | struct udphdr
type ip (line 119) | struct ip
type ip6_hdr (line 119) | struct ip6_hdr
type tcphdr (line 119) | struct tcphdr
type udphdr (line 119) | struct udphdr
function ReasmIsEmpty (line 131) | inline static bool ReasmIsEmpty(t_reassemble *reasm) {return !reasm->size;}
function ReasmIsFull (line 132) | inline static bool ReasmIsFull(t_reassemble *reasm) {return !ReasmIsEmpt...
FILE: nfq/crypto/aes-gcm.c
function aes_gcm_crypt (line 3) | int aes_gcm_crypt(int mode, uint8_t *output, const uint8_t *input, size_...
FILE: nfq/crypto/aes.c
function aes_init_keygen_tables (line 144) | void aes_init_keygen_tables(void)
function aes_set_encryption_key (line 220) | int aes_set_encryption_key(aes_context *ctx,
function aes_set_decryption_key (line 305) | int aes_set_decryption_key(aes_context *ctx,
function aes_setkey (line 347) | int aes_setkey(aes_context *ctx, // AES context provided by our caller
function aes_cipher (line 386) | int aes_cipher(aes_context *ctx,
FILE: nfq/crypto/aes.h
type UINT32 (line 36) | typedef UINT32 uint32_t;
type uchar (line 41) | typedef unsigned char uchar;
type uint (line 42) | typedef unsigned int uint;
type aes_context (line 54) | typedef struct {
FILE: nfq/crypto/gcm.c
function gcm_initialize (line 111) | int gcm_initialize(void)
function gcm_mult (line 127) | static void gcm_mult(gcm_context *ctx, // pointer to established con...
function gcm_setkey (line 174) | int gcm_setkey(gcm_context *ctx, // pointer to caller-provided gcm con...
function gcm_start (line 248) | int gcm_start(gcm_context *ctx, // pointer to user-provided GCM context
function gcm_update (line 318) | int gcm_update(gcm_context *ctx, // pointer to user-provided GCM c...
function gcm_finish (line 385) | int gcm_finish(gcm_context *ctx, // pointer to user-provided GCM context
function gcm_crypt_and_tag (line 431) | int gcm_crypt_and_tag(
function gcm_auth_decrypt (line 469) | int gcm_auth_decrypt(
function gcm_zero_ctx (line 517) | void gcm_zero_ctx(gcm_context *ctx)
FILE: nfq/crypto/gcm.h
type UINT32 (line 32) | typedef UINT32 uint32_t;
type UINT64 (line 33) | typedef UINT64 uint64_t;
type gcm_context (line 42) | typedef struct {
FILE: nfq/crypto/hkdf.c
function hkdf (line 56) | int hkdf(SHAversion whichSha,
function hkdfExtract (line 95) | int hkdfExtract(SHAversion whichSha,
function hkdfExpand (line 142) | int hkdfExpand(SHAversion whichSha, const uint8_t prk[], size_t prk_len,
function hkdfReset (line 205) | int hkdfReset(HKDFContext *context, enum SHAversion whichSha,
function hkdfInput (line 242) | int hkdfInput(HKDFContext *context, const unsigned char *ikm,
function hkdfFinalBits (line 271) | int hkdfFinalBits(HKDFContext *context, uint8_t ikm_bits,
function hkdfResult (line 310) | int hkdfResult(HKDFContext *context,
FILE: nfq/crypto/hmac.c
function hmac (line 46) | int hmac(SHAversion whichSha,
function hmacReset (line 79) | int hmacReset(HMACContext *context, enum SHAversion whichSha,
function hmacInput (line 162) | int hmacInput(HMACContext *context, const unsigned char *text,
function hmacFinalBits (line 192) | int hmacFinalBits(HMACContext *context,
function hmacResult (line 221) | int hmacResult(HMACContext *context, uint8_t *digest)
FILE: nfq/crypto/sha.h
type SHAversion (line 116) | typedef enum SHAversion {
type SHA256Context (line 124) | typedef struct SHA256Context {
type SHA224Context (line 142) | typedef struct SHA256Context SHA224Context;
type USHAContext (line 148) | typedef struct USHAContext {
type HMACContext (line 160) | typedef struct HMACContext {
type HKDFContext (line 176) | typedef struct HKDFContext {
type SHAversion (line 217) | enum SHAversion
type SHAversion (line 218) | enum SHAversion
type SHAversion (line 237) | enum SHAversion
type SHAversion (line 269) | enum SHAversion
FILE: nfq/crypto/sha224-256.c
function SHA224_256AddLength (line 67) | static int SHA224_256AddLength(SHA256Context *context, uint32_t length)
function SHA224Reset (line 110) | int SHA224Reset(SHA224Context *context)
function SHA224Input (line 135) | int SHA224Input(SHA224Context *context, const uint8_t *message_array,
function SHA224FinalBits (line 160) | int SHA224FinalBits(SHA224Context *context,
function SHA224Result (line 185) | int SHA224Result(SHA224Context *context,
function SHA256Reset (line 205) | int SHA256Reset(SHA256Context *context)
function SHA256Input (line 229) | int SHA256Input(SHA256Context *context, const uint8_t *message_array,
function SHA256FinalBits (line 272) | int SHA256FinalBits(SHA256Context *context,
function SHA256Result (line 320) | int SHA256Result(SHA256Context *context,
function SHA224_256Reset (line 342) | static int SHA224_256Reset(SHA256Context *context, uint32_t *H0)
function SHA224_256ProcessMessageBlock (line 383) | static void SHA224_256ProcessMessageBlock(SHA256Context *context)
function SHA224_256Finalize (line 470) | static void SHA224_256Finalize(SHA256Context *context,
function SHA224_256PadMessage (line 507) | static void SHA224_256PadMessage(SHA256Context *context,
function SHA224_256ResultN (line 563) | static int SHA224_256ResultN(SHA256Context *context,
FILE: nfq/crypto/usha.c
function USHAReset (line 31) | int USHAReset(USHAContext *context, enum SHAversion whichSha)
function USHAInput (line 62) | int USHAInput(USHAContext *context,
function USHAFinalBits (line 96) | int USHAFinalBits(USHAContext *context,
function USHAResult (line 130) | int USHAResult(USHAContext *context,
function USHABlockSize (line 160) | int USHABlockSize(enum SHAversion whichSha)
function USHAHashSize (line 184) | int USHAHashSize(enum SHAversion whichSha)
FILE: nfq/darkmagic.c
function net32_add (line 42) | uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment)
function net16_add (line 46) | uint32_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment)
function ip_has_df (line 51) | bool ip_has_df(const struct ip *ip)
type tcphdr (line 56) | struct tcphdr
type tcphdr (line 80) | struct tcphdr
function tcp_find_scale_factor (line 85) | uint8_t tcp_find_scale_factor(const struct tcphdr *tcp)
function tcp_has_fastopen (line 91) | bool tcp_has_fastopen(const struct tcphdr *tcp)
function tcp_find_mss (line 101) | uint16_t tcp_find_mss(struct tcphdr *tcp)
function tcp_has_sack (line 106) | bool tcp_has_sack(struct tcphdr *tcp)
function fill_tcphdr (line 113) | static void fill_tcphdr(
function tcpopt_len (line 189) | static uint16_t tcpopt_len(bool sack, bool mss, uint32_t fooling, const ...
function fill_udphdr (line 201) | static void fill_udphdr(struct udphdr *udp, uint16_t nsport, uint16_t nd...
function fill_iphdr (line 209) | static void fill_iphdr(struct ip *ip, const struct in_addr *src, const s...
function fill_ip6hdr (line 223) | static void fill_ip6hdr(struct ip6_hdr *ip6, const struct in6_addr *src,...
function prepare_tcp_segment4 (line 233) | bool prepare_tcp_segment4(
function prepare_tcp_segment6 (line 273) | bool prepare_tcp_segment6(
function prepare_tcp_segment (line 360) | bool prepare_tcp_segment(
function prepare_udp_segment4 (line 390) | bool prepare_udp_segment4(
function prepare_udp_segment6 (line 433) | bool prepare_udp_segment6(
function prepare_udp_segment (line 522) | bool prepare_udp_segment(
function ip6_insert_simple_hdr (line 542) | bool ip6_insert_simple_hdr(uint8_t type, uint8_t *data_pkt, size_t len_p...
function ip_frag4 (line 561) | bool ip_frag4(
function ip_frag6 (line 593) | bool ip_frag6(
function ip_frag (line 646) | bool ip_frag(
function rewrite_ttl (line 660) | bool rewrite_ttl(struct ip *ip, struct ip6_hdr *ip6, uint8_t ttl)
function apply_tcp_flags (line 685) | void apply_tcp_flags(struct tcphdr *tcp, uint16_t fl)
function get_tcp_flags (line 693) | uint16_t get_tcp_flags(const struct tcphdr *tcp)
function extract_ports (line 700) | void extract_ports(const struct tcphdr *tcphdr, const struct udphdr *udp...
function extract_endpoints (line 707) | void extract_endpoints(const struct ip *ip,const struct ip6_hdr *ip6hdr,...
function str_proto_name (line 789) | static void str_proto_name(char *s, size_t s_len, uint8_t proto)
function family_from_proto (line 797) | uint16_t family_from_proto(uint8_t l3proto)
function str_srcdst_ip (line 807) | static void str_srcdst_ip(char *s, size_t s_len, const void *saddr,const...
function str_ip (line 815) | void str_ip(char *s, size_t s_len, const struct ip *ip)
function print_ip (line 822) | void print_ip(const struct ip *ip)
function str_srcdst_ip6 (line 828) | void str_srcdst_ip6(char *s, size_t s_len, const void *saddr,const void ...
function str_ip6hdr (line 836) | void str_ip6hdr(char *s, size_t s_len, const struct ip6_hdr *ip6hdr, uin...
function print_ip6hdr (line 843) | void print_ip6hdr(const struct ip6_hdr *ip6hdr, uint8_t proto)
function str_tcphdr (line 849) | void str_tcphdr(char *s, size_t s_len, const struct tcphdr *tcphdr)
function print_tcphdr (line 861) | void print_tcphdr(const struct tcphdr *tcphdr)
function str_udphdr (line 867) | void str_udphdr(char *s, size_t s_len, const struct udphdr *udphdr)
function print_udphdr (line 871) | void print_udphdr(const struct udphdr *udphdr)
function proto_check_ipv4 (line 881) | bool proto_check_ipv4(const uint8_t *data, size_t len)
function proto_skip_ipv4 (line 887) | void proto_skip_ipv4(uint8_t **data, size_t *len)
function proto_check_tcp (line 895) | bool proto_check_tcp(const uint8_t *data, size_t len)
function proto_skip_tcp (line 899) | void proto_skip_tcp(uint8_t **data, size_t *len)
function proto_check_udp (line 906) | bool proto_check_udp(const uint8_t *data, size_t len)
function proto_skip_udp (line 910) | void proto_skip_udp(uint8_t **data, size_t *len)
function proto_check_ipv6 (line 916) | bool proto_check_ipv6(const uint8_t *data, size_t len)
function proto_skip_ipv6 (line 923) | void proto_skip_ipv6(uint8_t **data, size_t *len, uint8_t *proto_type, u...
function proto_dissect_l3l4 (line 972) | void proto_dissect_l3l4(uint8_t *data, size_t len,struct dissect *dis)
function tcp_synack_segment (line 1019) | bool tcp_synack_segment(const struct tcphdr *tcphdr)
function tcp_syn_segment (line 1024) | bool tcp_syn_segment(const struct tcphdr *tcphdr)
function tcp_ack_segment (line 1029) | bool tcp_ack_segment(const struct tcphdr *tcphdr)
function tcp_rewrite_wscale (line 1035) | void tcp_rewrite_wscale(struct tcphdr *tcp, uint8_t scale_factor)
function tcp_rewrite_winsize (line 1057) | void tcp_rewrite_winsize(struct tcphdr *tcp, uint16_t winsize, uint8_t s...
type str_list_head (line 1073) | struct str_list_head
function guid2str (line 1078) | static void guid2str(const GUID *guid, char *str)
function str2guid (line 1082) | static bool str2guid(const char* str, GUID *guid)
function AdapterID2Name (line 1102) | static bool AdapterID2Name(const GUID *guid,char *name,DWORD name_len)
function win_dark_init (line 1158) | bool win_dark_init(const struct str_list_head *ssid_filter, const struct...
function win_dark_deinit (line 1180) | bool win_dark_deinit(void)
function nlm_list (line 1192) | bool nlm_list(bool bAll)
function nlm_filter_match (line 1293) | static bool nlm_filter_match(const struct str_list_head *nlm_list)
function wlan_filter_match (line 1350) | static bool wlan_filter_match(const struct str_list_head *ssid_list)
function logical_net_filter_match (line 1415) | bool logical_net_filter_match(void)
function logical_net_filter_match_rate_limited (line 1420) | static bool logical_net_filter_match_rate_limited(void)
function HANDLE (line 1428) | static HANDLE windivert_init_filter(const char *filter, UINT64 flags)
function rawsend_cleanup (line 1459) | void rawsend_cleanup(void)
function windivert_init (line 1473) | bool windivert_init(const char *filter)
function windivert_recv_filter (line 1491) | static bool windivert_recv_filter(HANDLE hFilter, uint8_t *packet, size_...
function windivert_recv (line 1552) | bool windivert_recv(uint8_t *packet, size_t *len, WINDIVERT_ADDRESS *wa)
function windivert_send_filter (line 1557) | static bool windivert_send_filter(HANDLE hFilter, const uint8_t *packet,...
function windivert_send (line 1563) | bool windivert_send(const uint8_t *packet, size_t len, const WINDIVERT_A...
function rawsend (line 1568) | bool rawsend(const struct sockaddr* dst,uint32_t fwmark,const char *ifou...
function rawsend_clean_sock (line 1592) | static void rawsend_clean_sock(int *sock)
function rawsend_cleanup (line 1600) | void rawsend_cleanup(void)
function socket_divert (line 1616) | int socket_divert(sa_family_t family)
function rawsend_socket_divert (line 1630) | static int rawsend_socket_divert(sa_family_t family)
function rawsend_sendto_divert (line 1646) | static int rawsend_sendto_divert(sa_family_t family, int sock, const voi...
function rawsend_socket_raw (line 1675) | static int rawsend_socket_raw(int domain, int proto)
function set_socket_fwmark (line 1696) | static bool set_socket_fwmark(int sock, uint32_t fwmark)
function rawsend_socket (line 1717) | static int rawsend_socket(sa_family_t family)
function rawsend_preinit (line 1772) | bool rawsend_preinit(bool bind_fix4, bool bind_fix6)
function rawsend (line 1779) | bool rawsend(const struct sockaddr* dst,uint32_t fwmark,const char *ifou...
function rawsend_rp (line 1855) | bool rawsend_rp(const struct rawpacket *rp)
function rawsend_queue (line 1859) | bool rawsend_queue(struct rawpacket_tailhead *q)
type nlmsghdr (line 1874) | struct nlmsghdr
function netlink_genl_simple_transact (line 1876) | static bool netlink_genl_simple_transact(struct mnl_socket* nl, uint16_t...
function wlan_id_prepare (line 1915) | static void wlan_id_prepare(struct nlmsghdr *nlh, void *param)
function wlan_id_attr_cb (line 1919) | static int wlan_id_attr_cb(const struct nlattr *attr, void *data)
function wlan_id_cb (line 1940) | static int wlan_id_cb(const struct nlmsghdr *nlh, void *data)
function wlan_get_family_id (line 1944) | static uint16_t wlan_get_family_id(struct mnl_socket* nl)
function wlan_info_attr_cb (line 1950) | static int wlan_info_attr_cb(const struct nlattr *attr, void *data)
type wlan_info_req (line 1982) | struct wlan_info_req
function wlan_info_cb (line 1987) | static int wlan_info_cb(const struct nlmsghdr *nlh, void *data)
function wlan_info (line 1998) | static bool wlan_info(struct mnl_socket* nl, uint16_t wlan_family_id, st...
function scan_prepare (line 2005) | static void scan_prepare(struct nlmsghdr *nlh, void *param)
function scan_info_attr_cb (line 2020) | static int scan_info_attr_cb(const struct nlattr *attr, void *data)
function scan_info_cb (line 2082) | static int scan_info_cb(const struct nlmsghdr *nlh, void *data)
function scan_info (line 2093) | static bool scan_info(struct mnl_socket* nl, uint16_t wlan_family_id, st...
function wlan_init80211 (line 2107) | static bool wlan_init80211(struct mnl_socket** nl)
function wlan_deinit80211 (line 2122) | static void wlan_deinit80211(struct mnl_socket** nl)
function wlan_info_rate_limited (line 2132) | static bool wlan_info_rate_limited(struct mnl_socket* nl, uint16_t wlan_...
type mnl_socket (line 2146) | struct mnl_socket
type wlan_interface_collection (line 2148) | struct wlan_interface_collection
function wlan_info_deinit (line 2150) | void wlan_info_deinit(void)
function wlan_info_init (line 2154) | bool wlan_info_init(void)
function wlan_info_get_rate_limited (line 2166) | bool wlan_info_get_rate_limited(void)
type wlan_interface_collection (line 2175) | struct wlan_interface_collection
type wlan_interface_collection (line 2186) | struct wlan_interface_collection
function hop_count_guess (line 2207) | uint8_t hop_count_guess(uint8_t ttl)
function autottl_eval (line 2228) | uint8_t autottl_eval(uint8_t hop_count, const autottl *attl)
function do_nat (line 2244) | void do_nat(bool bOutbound, struct ip *ip, struct ip6_hdr *ip6, struct t...
function verdict_tcp_csum_fix (line 2287) | void verdict_tcp_csum_fix(uint8_t verdict, struct tcphdr *tcphdr, size_t...
function verdict_udp_csum_fix (line 2304) | void verdict_udp_csum_fix(uint8_t verdict, struct udphdr *udphdr, size_t...
function dbgprint_socket_buffers (line 2322) | void dbgprint_socket_buffers(int fd)
function set_socket_buffers (line 2336) | bool set_socket_buffers(int fd, int rcvbuf, int sndbuf)
FILE: nfq/darkmagic.h
type sockaddr_in (line 71) | struct sockaddr_in
type sockaddr_in (line 71) | struct sockaddr_in
type sockaddr_in6 (line 90) | struct sockaddr_in6
type sockaddr_in6 (line 90) | struct sockaddr_in6
type sockaddr (line 107) | struct sockaddr
type sockaddr (line 107) | struct sockaddr
type sockaddr_in (line 129) | struct sockaddr_in
type sockaddr_in (line 129) | struct sockaddr_in
type sockaddr_in6 (line 140) | struct sockaddr_in6
type sockaddr_in6 (line 140) | struct sockaddr_in6
type sockaddr (line 149) | struct sockaddr
type sockaddr (line 149) | struct sockaddr
type ip (line 180) | struct ip
type ip6_hdr (line 180) | struct ip6_hdr
type tcphdr (line 181) | struct tcphdr
type tcphdr (line 182) | struct tcphdr
type tcphdr (line 184) | struct tcphdr
type udphdr (line 184) | struct udphdr
type ip (line 185) | struct ip
type ip6_hdr (line 185) | struct ip6_hdr
type tcphdr (line 185) | struct tcphdr
type udphdr (line 185) | struct udphdr
type sockaddr_storage (line 185) | struct sockaddr_storage
type sockaddr_storage (line 185) | struct sockaddr_storage
type tcphdr (line 186) | struct tcphdr
type tcphdr (line 187) | struct tcphdr
type tcphdr (line 188) | struct tcphdr
type tcphdr (line 189) | struct tcphdr
type tcphdr (line 190) | struct tcphdr
type tcphdr (line 192) | struct tcphdr
type ip (line 194) | struct ip
type str_list_head (line 199) | struct str_list_head
type str_list_head (line 199) | struct str_list_head
type sockaddr (line 212) | struct sockaddr
type rawpacket (line 213) | struct rawpacket
type rawpacket_tailhead (line 215) | struct rawpacket_tailhead
type ip (line 225) | struct ip
type ip6_hdr (line 226) | struct ip6_hdr
type tcphdr (line 227) | struct tcphdr
type udphdr (line 228) | struct udphdr
type ip (line 229) | struct ip
type ip6_hdr (line 230) | struct ip6_hdr
type tcphdr (line 232) | struct tcphdr
type udphdr (line 233) | struct udphdr
type dissect (line 243) | struct dissect
type dissect (line 256) | struct dissect
type tcphdr (line 258) | struct tcphdr
type tcphdr (line 259) | struct tcphdr
type tcphdr (line 260) | struct tcphdr
type tcphdr (line 262) | struct tcphdr
type tcphdr (line 263) | struct tcphdr
type autottl (line 265) | typedef struct
type ip (line 274) | struct ip
type ip6_hdr (line 274) | struct ip6_hdr
type tcphdr (line 274) | struct tcphdr
type udphdr (line 274) | struct udphdr
type sockaddr_in (line 274) | struct sockaddr_in
type sockaddr_in6 (line 274) | struct sockaddr_in6
type tcphdr (line 276) | struct tcphdr
type ip (line 276) | struct ip
type ip6_hdr (line 276) | struct ip6_hdr
type udphdr (line 277) | struct udphdr
type ip (line 277) | struct ip
type ip6_hdr (line 277) | struct ip6_hdr
type wlan_interface (line 285) | struct wlan_interface
type wlan_interface_collection (line 291) | struct wlan_interface_collection
type wlan_interface_collection (line 297) | struct wlan_interface_collection
FILE: nfq/desync.c
function TLSDebugHandshake (line 86) | static void TLSDebugHandshake(const uint8_t *tls, size_t sz)
function TLSDebug (line 147) | static void TLSDebug(const uint8_t *tls, size_t sz)
function desync_valid_zero_stage (line 161) | bool desync_valid_zero_stage(enum dpi_desync_mode mode)
function desync_valid_first_stage (line 165) | bool desync_valid_first_stage(enum dpi_desync_mode mode)
function desync_only_first_stage (line 169) | bool desync_only_first_stage(enum dpi_desync_mode mode)
function desync_valid_second_stage_tcp (line 173) | bool desync_valid_second_stage_tcp(enum dpi_desync_mode mode)
function desync_valid_second_stage_udp (line 179) | bool desync_valid_second_stage_udp(enum dpi_desync_mode mode)
function desync_valid_second_stage (line 183) | bool desync_valid_second_stage(enum dpi_desync_mode mode)
function desync_mode_from_string (line 187) | enum dpi_desync_mode desync_mode_from_string(const char *s)
function dp_match (line 228) | static bool dp_match(
type desync_profile (line 281) | struct desync_profile
type desync_profile_list_head (line 282) | struct desync_profile_list_head
type sockaddr (line 283) | struct sockaddr
type desync_profile_list (line 286) | struct desync_profile_list
function rawsend_rep (line 307) | static bool rawsend_rep(int repeats, const struct sockaddr* dst, uint32_...
function cutoff_get_limit (line 316) | static uint64_t cutoff_get_limit(const t_ctrack *ctrack, char mode)
function cutoff_test (line 326) | static bool cutoff_test(const t_ctrack *ctrack, uint64_t cutoff, char mode)
function maybe_cutoff (line 330) | static void maybe_cutoff(t_ctrack *ctrack, uint8_t proto)
function wssize_cutoff (line 355) | static void wssize_cutoff(t_ctrack *ctrack)
function forced_wssize_cutoff (line 363) | static void forced_wssize_cutoff(t_ctrack *ctrack)
function ctrack_stop_retrans_counter (line 372) | static void ctrack_stop_retrans_counter(t_ctrack *ctrack)
function auto_hostlist_reset_fail_counter (line 381) | static void auto_hostlist_reset_fail_counter(struct desync_profile *dp, ...
function auto_hostlist_retrans (line 398) | static bool auto_hostlist_retrans(t_ctrack *ctrack, uint8_t l4proto, int...
function auto_hostlist_failed (line 425) | static void auto_hostlist_failed(struct desync_profile *dp, const char *...
function process_retrans_fail (line 474) | static void process_retrans_fail(t_ctrack *ctrack, uint8_t proto, const ...
function send_delayed (line 488) | static bool send_delayed(t_ctrack *ctrack)
function reasm_start (line 499) | static bool reasm_start(t_ctrack *ctrack, t_reassemble *reasm, uint8_t p...
function reasm_orig_start (line 518) | static bool reasm_orig_start(t_ctrack *ctrack, uint8_t proto, size_t sz,...
function reasm_feed (line 522) | static bool reasm_feed(t_ctrack *ctrack, t_reassemble *reasm, uint8_t pr...
function reasm_orig_feed (line 541) | static bool reasm_orig_feed(t_ctrack *ctrack, uint8_t proto, const uint8...
function reasm_orig_stop (line 545) | static void reasm_orig_stop(t_ctrack *ctrack, const char *dlog_msg)
function reasm_orig_cancel (line 557) | static void reasm_orig_cancel(t_ctrack *ctrack)
function reasm_orig_fin (line 561) | static void reasm_orig_fin(t_ctrack *ctrack)
function ct_new_postnat_fix (line 567) | static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, struct ip *ip,...
function check_desync_interval (line 595) | static bool check_desync_interval(const struct desync_profile *dp, const...
function process_desync_interval (line 636) | static bool process_desync_interval(const struct desync_profile *dp, t_c...
function check_dup_interval (line 646) | static bool check_dup_interval(const struct desync_profile *dp, const t_...
function check_orig_mod_interval (line 687) | static bool check_orig_mod_interval(const struct desync_profile *dp, con...
type rawpacket_tailhead (line 729) | struct rawpacket_tailhead
function pos_normalize (line 731) | static size_t pos_normalize(size_t split_pos, size_t reasm_offset, size_...
function autottl_guess (line 736) | static uint8_t autottl_guess(autottl *attl, uint8_t hop_count, const cha...
function autottl_discover (line 750) | static void autottl_discover(t_ctrack *ctrack, const struct in_addr *a4,...
function autottl_rediscover (line 781) | static void autottl_rediscover(t_ctrack *ctrack, const struct in_addr *a...
function ipcache_put_hostname (line 790) | static bool ipcache_put_hostname(const struct in_addr *a4, const struct ...
function ipcache_get_hostname (line 813) | static bool ipcache_get_hostname(const struct in_addr *a4, const struct ...
function IP4_IP_ID_FIX (line 838) | static uint16_t IP4_IP_ID_FIX(const struct ip *ip, t_ip_id_mode mode)
function IP4_IP_ID_ADD (line 857) | static uint16_t IP4_IP_ID_ADD(uint16_t ip_id, uint16_t inc, t_ip_id_mode...
function runtime_tls_mod (line 883) | static bool runtime_tls_mod(int fake_n, const struct fake_tls_mod_cache ...
function rewrite_tcp_flags (line 935) | static bool rewrite_tcp_flags(uint16_t *flags, uint16_t unset, uint16_t ...
function orig_mod (line 950) | static uint8_t orig_mod(const struct desync_profile *dp, const t_ctrack ...
function orig_send_rewrite (line 981) | static bool orig_send_rewrite(
function tcp_orig_send (line 1009) | static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *...
function udp_orig_send (line 1090) | static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *...
function dpi_desync_tcp_packet_play (line 1161) | static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offs...
FILE: nfq/desync.h
type dpi_desync_mode (line 22) | enum dpi_desync_mode {
type dpi_desync_mode (line 48) | enum dpi_desync_mode
type dpi_desync_mode (line 49) | enum dpi_desync_mode
type dpi_desync_mode (line 50) | enum dpi_desync_mode
type dpi_desync_mode (line 51) | enum dpi_desync_mode
type dpi_desync_mode (line 52) | enum dpi_desync_mode
type dpi_desync_mode (line 53) | enum dpi_desync_mode
type dpi_desync_mode (line 54) | enum dpi_desync_mode
FILE: nfq/gzip.c
function z_readfile (line 10) | int z_readfile(FILE *F, char **buf, size_t *size)
function is_gzip (line 73) | bool is_gzip(FILE* F)
FILE: nfq/helpers.c
function unique_size_t (line 14) | int unique_size_t(size_t *pu, int ct)
function cmp_size_t (line 25) | static int cmp_size_t(const void * a, const void * b)
function qsort_size_t (line 29) | void qsort_size_t(size_t *array,size_t ct)
function rtrim (line 35) | void rtrim(char *s)
function replace_char (line 41) | void replace_char(char *s, char from, char to)
function load_file (line 68) | bool load_file(const char *filename, void *buffer, size_t *buffer_size)
function load_file_nonempty (line 85) | bool load_file_nonempty(const char *filename, void *buffer, size_t *buff...
function save_file (line 90) | bool save_file(const char *filename, const void *buffer, size_t buffer_s...
function append_to_list_file (line 107) | bool append_to_list_file(const char *filename, const char *s)
function expand_bits (line 116) | void expand_bits(void *target, const void *source, unsigned int source_b...
function strip_host_to_ip (line 133) | bool strip_host_to_ip(char *host)
function ntop46 (line 182) | void ntop46(const struct sockaddr *sa, char *str, size_t len)
function ntop46_port (line 198) | void ntop46_port(const struct sockaddr *sa, char *str, size_t len)
function print_sockaddr (line 214) | void print_sockaddr(const struct sockaddr *sa)
function pton4_port (line 222) | bool pton4_port(const char *s, struct sockaddr_in *sa)
function pton6_port (line 242) | bool pton6_port(const char *s, struct sockaddr_in6 *sa)
function saport (line 266) | uint16_t saport(const struct sockaddr *sa)
function pntoh64 (line 273) | uint64_t pntoh64(const void *p)
function phton64 (line 284) | void phton64(uint8_t *p, uint64_t v)
function seq_within (line 296) | bool seq_within(uint32_t s, uint32_t s1, uint32_t s2)
function ipv6_addr_is_zero (line 301) | bool ipv6_addr_is_zero(const struct in6_addr *a)
function parse_hex_digit (line 308) | static inline uint8_t parse_hex_digit(char c)
function parse_hex_byte (line 312) | static inline bool parse_hex_byte(const char *s, uint8_t *pbyte)
function parse_hex_str (line 328) | bool parse_hex_str(const char *s, uint8_t *pbuf, size_t *size)
function fill_pattern (line 341) | void fill_pattern(uint8_t *buf,size_t bufsize,const void *pattern,size_t...
function fprint_localtime (line 362) | int fprint_localtime(FILE *F)
function time_t (line 372) | time_t file_mod_time(const char *filename)
function file_mod_signature (line 377) | bool file_mod_signature(const char *filename, file_mod_sig *ms)
function file_open_test (line 390) | bool file_open_test(const char *filename, int flags)
function pf_in_range (line 401) | bool pf_in_range(uint16_t port, const port_filter *pf)
function pf_parse (line 405) | bool pf_parse(const char *s, port_filter *pf)
function pf_is_empty (line 440) | bool pf_is_empty(const port_filter *pf)
function fill_random_bytes (line 445) | void fill_random_bytes(uint8_t *p,size_t sz)
function fill_random_az (line 451) | void fill_random_az(uint8_t *p,size_t sz)
function fill_random_az09 (line 456) | void fill_random_az09(uint8_t *p,size_t sz)
function set_console_io_buffering (line 467) | void set_console_io_buffering(void)
function set_env_exedir (line 473) | bool set_env_exedir(const char *argv0)
function str_cidr4 (line 487) | void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr)
function print_cidr4 (line 494) | void print_cidr4(const struct cidr4 *cidr)
function str_cidr6 (line 500) | void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr)
function print_cidr6 (line 507) | void print_cidr6(const struct cidr6 *cidr)
function parse_cidr4 (line 513) | bool parse_cidr4(char *s, struct cidr4 *cidr)
function parse_cidr6 (line 532) | bool parse_cidr6(char *s, struct cidr6 *cidr)
FILE: nfq/helpers.h
type sockaddr_in46 (line 15) | typedef union
type sockaddr (line 38) | struct sockaddr
type sockaddr (line 39) | struct sockaddr
type sockaddr (line 40) | struct sockaddr
type sockaddr_in (line 41) | struct sockaddr_in
type sockaddr_in6 (line 42) | struct sockaddr_in6
type sockaddr (line 44) | struct sockaddr
type in6_addr (line 51) | struct in6_addr
function pntoh16 (line 53) | static inline uint16_t pntoh16(const uint8_t *p) {
function phton16 (line 56) | static inline void phton16(uint8_t *p, uint16_t v) {
function pntoh24 (line 60) | static inline uint32_t pntoh24(const uint8_t *p) {
function phton24 (line 63) | static inline void phton24(uint8_t *p, uint32_t v) {
function pntoh32 (line 68) | static inline uint32_t pntoh32(const uint8_t *p) {
type file_mod_sig (line 77) | typedef struct
type port_filter (line 88) | typedef struct
type cidr4 (line 105) | struct cidr4
type cidr6 (line 110) | struct cidr6
type cidr4 (line 115) | struct cidr4
type cidr4 (line 116) | struct cidr4
type cidr6 (line 117) | struct cidr6
type cidr6 (line 118) | struct cidr6
type cidr4 (line 119) | struct cidr4
type cidr6 (line 120) | struct cidr6
FILE: nfq/hostlist.c
function addpool (line 7) | static bool addpool(hostlist_pool **hostlist, char **s, const char *end,...
function AppendHostlistItem (line 41) | bool AppendHostlistItem(hostlist_pool **hostlist, char *s)
function AppendHostList (line 46) | bool AppendHostList(hostlist_pool **hostlist, const char *filename)
function LoadHostList (line 110) | static bool LoadHostList(struct hostlist_file *hfile)
function LoadHostLists (line 133) | static bool LoadHostLists(struct hostlist_files_head *list)
function NonEmptyHostlist (line 147) | bool NonEmptyHostlist(hostlist_pool **hostlist)
function MakeAutolistsNonEmpty (line 153) | static void MakeAutolistsNonEmpty()
function LoadAllHostLists (line 163) | bool LoadAllHostLists()
function SearchHostList (line 173) | static bool SearchHostList(hostlist_pool *hostlist, const char *host, bo...
function HostlistsReloadCheck (line 208) | static bool HostlistsReloadCheck(const struct hostlist_collection_head *...
function HostlistsReloadCheckForProfile (line 219) | bool HostlistsReloadCheckForProfile(const struct desync_profile *dp)
function HostlistCheck_ (line 224) | static bool HostlistCheck_(const struct hostlist_collection_head *hostli...
function HostlistCheck (line 259) | bool HostlistCheck(const struct desync_profile *dp, const char *host, bo...
type hostlist_file (line 266) | struct hostlist_file
type hostlist_files_head (line 266) | struct hostlist_files_head
type hostlist_collection_head (line 266) | struct hostlist_collection_head
type hostlist_file (line 268) | struct hostlist_file
type hostlist_file (line 289) | struct hostlist_file
type desync_profile (line 289) | struct desync_profile
function HostlistsDebug (line 304) | void HostlistsDebug()
FILE: nfq/hostlist.h
type desync_profile (line 12) | struct desync_profile
type hostlist_file (line 13) | struct hostlist_file
type desync_profile (line 13) | struct desync_profile
type desync_profile (line 14) | struct desync_profile
FILE: nfq/ipset.c
function addpool (line 8) | static bool addpool(ipset *ips, char **s, const char *end, int *ct)
function AppendIpsetItem (line 56) | bool AppendIpsetItem(ipset *ips, char *ip)
function AppendIpset (line 61) | static bool AppendIpset(ipset *ips, const char *filename)
function LoadIpset (line 125) | static bool LoadIpset(struct ipset_file *hfile)
function LoadIpsets (line 148) | static bool LoadIpsets(struct ipset_files_head *list)
function LoadAllIpsets (line 162) | bool LoadAllIpsets()
function SearchIpset (line 167) | static bool SearchIpset(const ipset *ips, const struct in_addr *ipv4, co...
function IpsetsReloadCheck (line 193) | static bool IpsetsReloadCheck(const struct ipset_collection_head *ipsets)
function IpsetsReloadCheckForProfile (line 203) | bool IpsetsReloadCheckForProfile(const struct desync_profile *dp)
function IpsetCheck_ (line 208) | static bool IpsetCheck_(const struct ipset_collection_head *ips, const s...
function IpsetCheck (line 235) | bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *i...
type ipset_file (line 243) | struct ipset_file
type ipset_files_head (line 243) | struct ipset_files_head
type ipset_collection_head (line 243) | struct ipset_collection_head
type ipset_file (line 245) | struct ipset_file
type ipset_file (line 264) | struct ipset_file
type desync_profile (line 264) | struct desync_profile
function IpsetsDebug (line 290) | void IpsetsDebug()
FILE: nfq/ipset.h
type desync_profile (line 9) | struct desync_profile
type in_addr (line 9) | struct in_addr
type in6_addr (line 9) | struct in6_addr
type ipset_file (line 10) | struct ipset_file
type desync_profile (line 10) | struct desync_profile
FILE: nfq/nfqws.c
type params_s (line 56) | struct params_s
function onhup (line 62) | static void onhup(int sig)
function ReloadCheck (line 67) | static void ReloadCheck()
function onusr1 (line 87) | static void onusr1(int sig)
function onusr2 (line 93) | static void onusr2(int sig)
function pre_desync (line 111) | static void pre_desync(void)
function processPacketData (line 119) | static uint8_t processPacketData(uint32_t *mark, const char *ifin, const...
function test_list_files (line 132) | static bool test_list_files()
function nfq_cb (line 156) | static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struc...
function nfq_deinit (line 198) | static void nfq_deinit(struct nfq_handle **h, struct nfq_q_handle **qh)
function nfq_init (line 213) | static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh)
function notify_ready (line 278) | static void notify_ready(void)
function nfq_main (line 287) | static int nfq_main(void)
function dvt_main (line 383) | static int dvt_main(void)
function win_main (line 547) | static int win_main(const char *windivert_filter)
function exit_clean (line 673) | static void exit_clean(int code)
function parse_uid (line 680) | static bool parse_uid(const char *opt, uid_t *uid, gid_t *gid, int *gid_...
function parse_ws_scale_factor (line 708) | static bool parse_ws_scale_factor(char *s, uint16_t *wsize, uint8_t *wsc...
function parse_cutoff (line 734) | static bool parse_cutoff(const char *opt, unsigned int *value, char *mode)
function parse_net32_signed (line 739) | static bool parse_net32_signed(const char *opt, uint32_t *value)
function load_file_or_exit (line 751) | static void load_file_or_exit(const char *filename, void *buf, size_t *s...
function parse_autottl (line 804) | static bool parse_autottl(const char *s, autottl *t, int8_t def_delta, u...
function parse_l7_list (line 847) | static bool parse_l7_list(char *opt, uint32_t *l7)
function parse_pf_list (line 883) | static bool parse_pf_list(char *opt, struct port_filters_head *pfl)
function wf_make_l3 (line 906) | static bool wf_make_l3(char *opt, bool *ipv4, bool *ipv6)
function parse_httpreqpos (line 930) | static bool parse_httpreqpos(const char *s, struct proto_pos *sp)
function parse_tlspos (line 946) | static bool parse_tlspos(const char *s, struct proto_pos *sp)
function parse_int16 (line 968) | static bool parse_int16(const char *p, int16_t *v)
function parse_posmarker (line 978) | static bool parse_posmarker(const char *opt, uint8_t *posmarker)
function parse_split_pos (line 998) | static bool parse_split_pos(char *opt, struct proto_pos *split)
function parse_split_pos_list (line 1022) | static bool parse_split_pos_list(char *opt, struct proto_pos *splits, in...
function parse_domain_list (line 1041) | static bool parse_domain_list(char *opt, hostlist_pool **pp)
function parse_ip_list (line 1061) | static bool parse_ip_list(char *opt, ipset *pp)
function parse_tlsmod_list (line 1081) | static bool parse_tlsmod_list(char *opt, struct fake_tls_mod *tls_mod)
function parse_hostfakesplit_mod (line 1134) | static bool parse_hostfakesplit_mod(char *opt, struct hostfakesplit_mod ...
function parse_fakedsplit_mod (line 1183) | static bool parse_fakedsplit_mod(char *opt, struct fakedsplit_mod *fs_mod)
function parse_tcpmod (line 1226) | static bool parse_tcpmod(char *opt, struct tcp_mod *tcp_mod)
function parse_fooling (line 1266) | static bool parse_fooling(char *opt, unsigned int *fooling_mode)
function parse_strlist (line 1294) | static bool parse_strlist(char *opt, struct str_list_head *list)
function parse_tcpflags (line 1308) | static bool parse_tcpflags(char *opt, uint16_t *fl)
function split_compat (line 1365) | static void split_compat(struct desync_profile *dp)
function SplitDebug (line 1380) | static void SplitDebug(void)
function onetime_tls_mod_blob (line 1394) | static bool onetime_tls_mod_blob(int profile_n, int fake_n, const struct...
function onetime_tls_mod (line 1529) | static bool onetime_tls_mod(struct desync_profile *dp)
type blob_item (line 1566) | struct blob_item
type blob_collection_head (line 1566) | struct blob_collection_head
type blob_item (line 1568) | struct blob_item
type blob_item (line 1588) | struct blob_item
type blob_collection_head (line 1588) | struct blob_collection_head
type blob_item (line 1595) | struct blob_item
function wf_make_pf (line 1610) | static bool wf_make_pf(char *opt, const char *l4, const char *portname, ...
function wf_make_filter (line 1678) | static bool wf_make_filter(
function hash_jen (line 1744) | static unsigned int hash_jen(const void *data, unsigned int len)
function exithelp (line 1754) | static void exithelp(void)
function exithelp_clean (line 1927) | static void exithelp_clean(void)
function config_from_file (line 1935) | void config_from_file(const char *filename)
function check_dp (line 1960) | void check_dp(const struct desync_profile *dp)
type opt_indices (line 2001) | enum opt_indices {
type option (line 2142) | struct option
function main (line 2283) | int main(int argc, char **argv)
FILE: nfq/packet_queue.c
function rawpacket_queue_init (line 7) | void rawpacket_queue_init(struct rawpacket_tailhead *q)
function rawpacket_free (line 11) | void rawpacket_free(struct rawpacket *rp)
type rawpacket (line 16) | struct rawpacket
type rawpacket_tailhead (line 16) | struct rawpacket_tailhead
type rawpacket (line 18) | struct rawpacket
function rawpacket_queue_destroy (line 23) | void rawpacket_queue_destroy(struct rawpacket_tailhead *q)
type rawpacket (line 29) | struct rawpacket
type rawpacket_tailhead (line 29) | struct rawpacket_tailhead
type sockaddr_storage (line 29) | struct sockaddr_storage
type rawpacket (line 31) | struct rawpacket
type rawpacket (line 31) | struct rawpacket
function rawpacket_queue_count (line 60) | unsigned int rawpacket_queue_count(const struct rawpacket_tailhead *q)
function rawpacket_queue_empty (line 67) | bool rawpacket_queue_empty(const struct rawpacket_tailhead *q)
FILE: nfq/packet_queue.h
type rawpacket (line 9) | struct rawpacket
type rawpacket_tailhead (line 20) | struct rawpacket_tailhead
type rawpacket_tailhead (line 21) | struct rawpacket_tailhead
type rawpacket_tailhead (line 22) | struct rawpacket_tailhead
type rawpacket_tailhead (line 23) | struct rawpacket_tailhead
type rawpacket (line 24) | struct rawpacket
type rawpacket_tailhead (line 24) | struct rawpacket_tailhead
type sockaddr_storage (line 24) | struct sockaddr_storage
type rawpacket (line 25) | struct rawpacket
type rawpacket_tailhead (line 25) | struct rawpacket_tailhead
type rawpacket (line 26) | struct rawpacket
FILE: nfq/params.c
function DLOG_FILE (line 25) | int DLOG_FILE(FILE *F, const char *format, va_list args)
function DLOG_CON (line 29) | int DLOG_CON(const char *format, int syslog_priority, va_list args)
function DLOG_FILENAME (line 33) | int DLOG_FILENAME(const char *filename, const char *format, va_list args)
function syslog_log_function (line 51) | static void syslog_log_function(int priority, const char *line)
function syslog_priority_to_android (line 56) | static enum android_LogPriority syslog_priority_to_android(int priority)
function android_log_function (line 73) | static void android_log_function(int priority, const char *line)
function log_buffered (line 78) | static void log_buffered(f_log_function log_function, int syslog_priorit...
function DLOG_VA (line 92) | static int DLOG_VA(const char *format, int syslog_priority, bool condup,...
function DLOG (line 132) | int DLOG(const char *format, ...)
function DLOG_CONDUP (line 141) | int DLOG_CONDUP(const char *format, ...)
function DLOG_ERR (line 150) | int DLOG_ERR(const char *format, ...)
function DLOG_PERROR (line 159) | int DLOG_PERROR(const char *s)
function LOG_APPEND (line 165) | int LOG_APPEND(const char *filename, const char *format, va_list args)
function HOSTLIST_DEBUGLOG_APPEND (line 182) | int HOSTLIST_DEBUGLOG_APPEND(const char *format, ...)
function hexdump_limited_dlog (line 198) | void hexdump_limited_dlog(const uint8_t *data, size_t size, size_t limit)
function dp_init (line 214) | void dp_init(struct desync_profile *dp)
function dp_fake_defaults (line 245) | bool dp_fake_defaults(struct desync_profile *dp)
type desync_profile_list (line 284) | struct desync_profile_list
type desync_profile_list_head (line 284) | struct desync_profile_list_head
type desync_profile_list (line 286) | struct desync_profile_list
type desync_profile_list (line 286) | struct desync_profile_list
type desync_profile_list (line 292) | struct desync_profile_list
function dp_clear_dynamic (line 303) | static void dp_clear_dynamic(struct desync_profile *dp)
function dp_clear (line 320) | void dp_clear(struct desync_profile *dp)
function dp_entry_destroy (line 325) | void dp_entry_destroy(struct desync_profile_list *entry)
function dp_list_destroy (line 330) | void dp_list_destroy(struct desync_profile_list_head *head)
function dp_list_have_autohostlist (line 339) | bool dp_list_have_autohostlist(struct desync_profile_list_head *head)
function dp_list_need_all_out (line 348) | bool dp_list_need_all_out(struct desync_profile_list_head *head)
function cleanup_args (line 359) | void cleanup_args(struct params_s *params)
function cleanup_params (line 365) | void cleanup_params(struct params_s *params)
FILE: nfq/params.h
type log_target (line 74) | enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSL...
type fake_tls_mod_cache (line 76) | struct fake_tls_mod_cache
type fake_tls_mod (line 80) | struct fake_tls_mod
type hostfakesplit_mod (line 85) | struct hostfakesplit_mod
type fakedsplit_mod (line 91) | struct fakedsplit_mod
type tcp_mod (line 95) | struct tcp_mod
type t_synack_split (line 100) | typedef enum {SS_NONE=0,SS_SYN,SS_SYNACK,SS_ACKSYN} t_synack_split;
type t_ip_id_mode (line 101) | typedef enum {IPID_SEQ=0,IPID_SEQ_GROUP,IPID_RND,IPID_ZERO,IPID_SAME} t_...
type desync_profile (line 103) | struct desync_profile
type desync_profile_list (line 195) | struct desync_profile_list {
type desync_profile_list (line 200) | struct desync_profile_list
type desync_profile_list_head (line 200) | struct desync_profile_list_head
type desync_profile_list (line 201) | struct desync_profile_list
type desync_profile_list_head (line 202) | struct desync_profile_list_head
type desync_profile_list_head (line 203) | struct desync_profile_list_head
type desync_profile_list_head (line 204) | struct desync_profile_list_head
type desync_profile (line 205) | struct desync_profile
type desync_profile (line 206) | struct desync_profile
type desync_profile (line 207) | struct desync_profile
type params_s (line 209) | struct params_s
type params_s (line 264) | struct params_s
type params_s (line 267) | struct params_s
type params_s (line 269) | struct params_s
FILE: nfq/pools.c
function ut_oom_recover (line 46) | static void ut_oom_recover(void *elem)
function HostlistPoolAddStrLen (line 52) | bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t sle...
function HostlistPoolAddStr (line 58) | bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags)
function hostlist_pool (line 63) | hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s)
function HostlistPoolCheckStr (line 69) | bool HostlistPoolCheckStr(hostlist_pool *p, const char *s)
function HostlistPoolDestroy (line 74) | void HostlistPoolDestroy(hostlist_pool **pp)
function HostFailPoolDestroy (line 81) | void HostFailPoolDestroy(hostfail_pool **pp)
function hostfail_pool (line 85) | hostfail_pool * HostFailPoolAdd(hostfail_pool **pp,const char *s,int fai...
function hostfail_pool (line 93) | hostfail_pool *HostFailPoolFind(hostfail_pool *p,const char *s)
function HostFailPoolDel (line 99) | void HostFailPoolDel(hostfail_pool **p, hostfail_pool *elem)
function HostFailPoolPurge (line 105) | void HostFailPoolPurge(hostfail_pool **pp)
function HostFailPoolPurgeRateLimited (line 116) | void HostFailPoolPurgeRateLimited(hostfail_pool **pp)
function HostFailPoolDump (line 126) | void HostFailPoolDump(hostfail_pool *p)
function strlist_add (line 135) | bool strlist_add(struct str_list_head *head, const char *filename)
function strlist_entry_destroy (line 148) | static void strlist_entry_destroy(struct str_list *entry)
function strlist_destroy (line 153) | void strlist_destroy(struct str_list_head *head)
function strlist_search (line 162) | bool strlist_search(const struct str_list_head *head, const char *str)
type hostlist_file (line 178) | struct hostlist_file
type hostlist_files_head (line 178) | struct hostlist_files_head
type hostlist_file (line 180) | struct hostlist_file
type hostlist_file (line 180) | struct hostlist_file
function hostlist_files_entry_destroy (line 199) | static void hostlist_files_entry_destroy(struct hostlist_file *entry)
function hostlist_files_destroy (line 205) | void hostlist_files_destroy(struct hostlist_files_head *head)
type hostlist_file (line 214) | struct hostlist_file
type hostlist_files_head (line 214) | struct hostlist_files_head
type hostlist_file (line 216) | struct hostlist_file
function hostlist_files_reset_modtime (line 225) | void hostlist_files_reset_modtime(struct hostlist_files_head *list)
type hostlist_item (line 233) | struct hostlist_item
type hostlist_collection_head (line 233) | struct hostlist_collection_head
type hostlist_file (line 233) | struct hostlist_file
type hostlist_item (line 235) | struct hostlist_item
type hostlist_item (line 235) | struct hostlist_item
function hostlist_collection_destroy (line 243) | void hostlist_collection_destroy(struct hostlist_collection_head *head)
type hostlist_item (line 252) | struct hostlist_item
type hostlist_collection_head (line 252) | struct hostlist_collection_head
type hostlist_item (line 254) | struct hostlist_item
function hostlist_collection_is_empty (line 263) | bool hostlist_collection_is_empty(const struct hostlist_collection_head ...
function kavl_bit_cmp (line 276) | static int kavl_bit_cmp(const struct kavl_bit_elem *p, const struct kavl...
function kavl_bit_destroy_elem (line 289) | static void kavl_bit_destroy_elem(struct kavl_bit_elem *e)
function kavl_bit_delete (line 297) | void kavl_bit_delete(struct kavl_bit_elem **hdr, const void *data, unsig...
function kavl_bit_destroy (line 304) | void kavl_bit_destroy(struct kavl_bit_elem **hdr)
type kavl_bit_elem (line 314) | struct kavl_bit_elem
type kavl_bit_elem (line 314) | struct kavl_bit_elem
type kavl_bit_elem (line 316) | struct kavl_bit_elem
type kavl_bit_elem (line 318) | struct kavl_bit_elem
type kavl_bit_elem (line 333) | struct kavl_bit_elem
type kavl_bit_elem (line 333) | struct kavl_bit_elem
type kavl_bit_elem (line 335) | struct kavl_bit_elem
function ipset_kavl_add (line 341) | static bool ipset_kavl_add(struct kavl_bit_elem **ipset, const void *a, ...
function ipset4Check (line 356) | bool ipset4Check(const struct kavl_bit_elem *ipset, const struct in_addr...
function ipset4Add (line 360) | bool ipset4Add(struct kavl_bit_elem **ipset, const struct in_addr *a, ui...
function ipset4Print (line 365) | void ipset4Print(struct kavl_bit_elem *ipset)
function ipset6Check (line 384) | bool ipset6Check(const struct kavl_bit_elem *ipset, const struct in6_add...
function ipset6Add (line 388) | bool ipset6Add(struct kavl_bit_elem **ipset, const struct in6_addr *a, u...
function ipset6Print (line 393) | void ipset6Print(struct kavl_bit_elem *ipset)
function ipsetDestroy (line 412) | void ipsetDestroy(ipset *ipset)
function ipsetPrint (line 417) | void ipsetPrint(ipset *ipset)
type ipset_file (line 424) | struct ipset_file
type ipset_files_head (line 424) | struct ipset_files_head
type ipset_file (line 426) | struct ipset_file
type ipset_file (line 426) | struct ipset_file
function ipset_files_entry_destroy (line 445) | static void ipset_files_entry_destroy(struct ipset_file *entry)
function ipset_files_destroy (line 451) | void ipset_files_destroy(struct ipset_files_head *head)
type ipset_file (line 460) | struct ipset_file
type ipset_files_head (line 460) | struct ipset_files_head
type ipset_file (line 462) | struct ipset_file
function ipset_files_reset_modtime (line 471) | void ipset_files_reset_modtime(struct ipset_files_head *list)
type ipset_item (line 479) | struct ipset_item
type ipset_collection_head (line 479) | struct ipset_collection_head
type ipset_file (line 479) | struct ipset_file
type ipset_item (line 481) | struct ipset_item
type ipset_item (line 481) | struct ipset_item
function ipset_collection_destroy (line 489) | void ipset_collection_destroy(struct ipset_collection_head *head)
type ipset_item (line 498) | struct ipset_item
type ipset_collection_head (line 498) | struct ipset_collection_head
type ipset_item (line 500) | struct ipset_item
function ipset_collection_is_empty (line 509) | bool ipset_collection_is_empty(const struct ipset_collection_head *head)
function port_filter_add (line 522) | bool port_filter_add(struct port_filters_head *head, const port_filter *pf)
function port_filters_destroy (line 532) | void port_filters_destroy(struct port_filters_head *head)
function port_filters_in_range (line 541) | bool port_filters_in_range(const struct port_filters_head *head, uint16_...
function port_filters_deny_if_empty (line 553) | bool port_filters_deny_if_empty(struct port_filters_head *head)
type blob_item (line 562) | struct blob_item
type blob_collection_head (line 562) | struct blob_collection_head
type blob_item (line 564) | struct blob_item
type blob_item (line 564) | struct blob_item
type blob_item (line 568) | struct blob_item
type blob_item (line 579) | struct blob_item
type blob_collection_head (line 579) | struct blob_collection_head
type blob_item (line 582) | struct blob_item
type blob_item (line 582) | struct blob_item
type blob_item (line 595) | struct blob_item
function blob_collection_destroy (line 607) | void blob_collection_destroy(struct blob_collection_head *head)
function blob_collection_empty (line 619) | bool blob_collection_empty(const struct blob_collection_head *head)
function ipcache_item_touch (line 626) | static void ipcache_item_touch(ip_cache_item *item)
function ipcache_item_init (line 630) | static void ipcache_item_init(ip_cache_item *item)
function ipcache_item_destroy (line 637) | static void ipcache_item_destroy(ip_cache_item *item)
function ipcache4Destroy (line 642) | static void ipcache4Destroy(ip_cache4 **ipcache)
function ipcache4Key (line 652) | static void ipcache4Key(ip4if *key, const struct in_addr *a, const char ...
function ip_cache4 (line 658) | static ip_cache4 *ipcache4Find(ip_cache4 *ipcache, const struct in_addr ...
function ip_cache4 (line 667) | static ip_cache4 *ipcache4Add(ip_cache4 **ipcache, const struct in_addr ...
function ipcache4Print (line 685) | static void ipcache4Print(ip_cache4 *ipcache)
function ipcache6Destroy (line 700) | static void ipcache6Destroy(ip_cache6 **ipcache)
function ipcache6Key (line 710) | static void ipcache6Key(ip6if *key, const struct in6_addr *a, const char...
function ip_cache6 (line 716) | static ip_cache6 *ipcache6Find(ip_cache6 *ipcache, const struct in6_addr...
function ip_cache6 (line 725) | static ip_cache6 *ipcache6Add(ip_cache6 **ipcache, const struct in6_addr...
function ipcache6Print (line 743) | static void ipcache6Print(ip_cache6 *ipcache)
function ipcacheDestroy (line 758) | void ipcacheDestroy(ip_cache *ipcache)
function ipcachePrint (line 763) | void ipcachePrint(ip_cache *ipcache)
function ip_cache_item (line 769) | ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4,...
function ipcache4_purge (line 792) | static void ipcache4_purge(ip_cache4 **ipcache, time_t lifetime)
function ipcache6_purge (line 806) | static void ipcache6_purge(ip_cache6 **ipcache, time_t lifetime)
function ipcache_purge (line 820) | static void ipcache_purge(ip_cache *ipcache, time_t lifetime)
function ipcachePurgeRateLimited (line 829) | void ipcachePurgeRateLimited(ip_cache *ipcache, time_t lifetime)
FILE: nfq/pools.h
type hostlist_pool (line 20) | typedef struct hostlist_pool {
type str_list (line 31) | struct str_list {
type str_list_head (line 37) | struct str_list_head
type str_list_head (line 38) | struct str_list_head
type str_list_head (line 39) | struct str_list_head
type hostfail_pool (line 42) | typedef struct hostfail_pool {
type hostlist_file (line 58) | struct hostlist_file {
type hostlist_file (line 66) | struct hostlist_file
type hostlist_files_head (line 66) | struct hostlist_files_head
type hostlist_files_head (line 67) | struct hostlist_files_head
type hostlist_file (line 68) | struct hostlist_file
type hostlist_files_head (line 68) | struct hostlist_files_head
type hostlist_files_head (line 69) | struct hostlist_files_head
type hostlist_item (line 71) | struct hostlist_item {
type hostlist_item (line 76) | struct hostlist_item
type hostlist_collection_head (line 76) | struct hostlist_collection_head
type hostlist_file (line 76) | struct hostlist_file
type hostlist_collection_head (line 77) | struct hostlist_collection_head
type hostlist_item (line 78) | struct hostlist_item
type hostlist_collection_head (line 78) | struct hostlist_collection_head
type hostlist_collection_head (line 79) | struct hostlist_collection_head
type kavl_bit_elem (line 82) | struct kavl_bit_elem
type kavl_bit_elem (line 89) | struct kavl_bit_elem
type kavl_bit_elem (line 89) | struct kavl_bit_elem
type kavl_bit_elem (line 90) | struct kavl_bit_elem
type kavl_bit_elem (line 90) | struct kavl_bit_elem
type kavl_bit_elem (line 91) | struct kavl_bit_elem
type kavl_bit_elem (line 92) | struct kavl_bit_elem
type ipset (line 95) | typedef struct ipset {
type kavl_bit_elem (line 101) | struct kavl_bit_elem
type in_addr (line 101) | struct in_addr
function ipset4AddCidr (line 102) | static inline bool ipset4AddCidr(struct kavl_bit_elem **ipset, const str...
type kavl_bit_elem (line 106) | struct kavl_bit_elem
type in_addr (line 106) | struct in_addr
type kavl_bit_elem (line 107) | struct kavl_bit_elem
type kavl_bit_elem (line 109) | struct kavl_bit_elem
type in6_addr (line 109) | struct in6_addr
function ipset6AddCidr (line 110) | static inline bool ipset6AddCidr(struct kavl_bit_elem **ipset, const str...
type kavl_bit_elem (line 114) | struct kavl_bit_elem
type in6_addr (line 114) | struct in6_addr
type kavl_bit_elem (line 115) | struct kavl_bit_elem
type ipset_file (line 121) | struct ipset_file {
type ipset_file (line 129) | struct ipset_file
type ipset_files_head (line 129) | struct ipset_files_head
type ipset_files_head (line 130) | struct ipset_files_head
type ipset_file (line 131) | struct ipset_file
type ipset_files_head (line 131) | struct ipset_files_head
type ipset_files_head (line 132) | struct ipset_files_head
type ipset_item (line 134) | struct ipset_item {
type ipset_item (line 139) | struct ipset_item
type ipset_collection_head (line 139) | struct ipset_collection_head
type ipset_file (line 139) | struct ipset_file
type ipset_collection_head (line 140) | struct ipset_collection_head
type ipset_item (line 141) | struct ipset_item
type ipset_collection_head (line 141) | struct ipset_collection_head
type ipset_collection_head (line 142) | struct ipset_collection_head
type port_filter_item (line 145) | struct port_filter_item {
type port_filters_head (line 150) | struct port_filters_head
type port_filters_head (line 151) | struct port_filters_head
type port_filters_head (line 152) | struct port_filters_head
type port_filters_head (line 153) | struct port_filters_head
type blob_item (line 156) | struct blob_item {
type blob_item (line 166) | struct blob_item
type blob_collection_head (line 166) | struct blob_collection_head
type blob_item (line 167) | struct blob_item
type blob_collection_head (line 167) | struct blob_collection_head
type blob_collection_head (line 168) | struct blob_collection_head
type blob_collection_head (line 169) | struct blob_collection_head
type ip4if (line 172) | typedef struct ip4if
type ip6if (line 177) | typedef struct ip6if
type ip_cache_item (line 182) | typedef struct ip_cache_item
type ip_cache4 (line 189) | typedef struct ip_cache4
type ip_cache6 (line 195) | typedef struct ip_cache6
type ip_cache (line 201) | typedef struct ip_cache
type in_addr (line 207) | struct in_addr
type in6_addr (line 207) | struct in6_addr
FILE: nfq/protocol.c
function FindNLD (line 13) | static bool FindNLD(const uint8_t *dom, size_t dlen, int level, const ui...
function l7_proto_match (line 43) | bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7)
function IsHostMarker (line 55) | bool IsHostMarker(uint8_t posmarker)
function CheckPos (line 85) | static size_t CheckPos(size_t sz, ssize_t offset)
function AnyProtoPos (line 89) | size_t AnyProtoPos(uint8_t posmarker, int16_t pos, const uint8_t *data, ...
function HostPos (line 101) | static size_t HostPos(uint8_t posmarker, int16_t pos, const uint8_t *dat...
function ResolvePos (line 126) | size_t ResolvePos(const uint8_t *data, size_t sz, t_l7proto l7proto, con...
function ResolveMultiPos (line 138) | void ResolveMultiPos(const uint8_t *data, size_t sz, t_l7proto l7proto, ...
function IsHttp (line 165) | bool IsHttp(const uint8_t *data, size_t len)
function IsHostAt (line 170) | static bool IsHostAt(const uint8_t *p)
function HttpFindHost (line 203) | bool HttpFindHost(uint8_t **pHost,uint8_t *buf,size_t bs)
function HttpFindHostConst (line 212) | bool HttpFindHostConst(const uint8_t **pHost,const uint8_t *buf,size_t bs)
function IsHttpReply (line 222) | bool IsHttpReply(const uint8_t *data, size_t len)
function HttpReplyCode (line 230) | int HttpReplyCode(const uint8_t *data, size_t len)
function HttpExtractHeader (line 234) | bool HttpExtractHeader(const uint8_t *data, size_t len, const char *head...
function HttpExtractHost (line 257) | bool HttpExtractHost(const uint8_t *data, size_t len, char *host, size_t...
function HttpReplyLooksLikeDPIRedirect (line 262) | bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, cons...
function HttpPos (line 298) | size_t HttpPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size...
function TLSRecordDataLen (line 354) | uint16_t TLSRecordDataLen(const uint8_t *data)
function TLSRecordLen (line 358) | size_t TLSRecordLen(const uint8_t *data)
function IsTLSRecordFull (line 362) | bool IsTLSRecordFull(const uint8_t *data, size_t len)
function IsTLSClientHello (line 366) | bool IsTLSClientHello(const uint8_t *data, size_t len, bool bPartialIsOK)
function TLSHandshakeLen (line 371) | size_t TLSHandshakeLen(const uint8_t *data)
function IsTLSHandshakeClientHello (line 375) | bool IsTLSHandshakeClientHello(const uint8_t *data, size_t len)
function IsTLSHandshakeFull (line 379) | bool IsTLSHandshakeFull(const uint8_t *data, size_t len)
function TLSFindExtLenOffsetInHandshake (line 385) | bool TLSFindExtLenOffsetInHandshake(const uint8_t *data, size_t len, siz...
function TLSFindExtLen (line 417) | bool TLSFindExtLen(const uint8_t *data, size_t len, size_t *off)
function TLSFindExtInHandshake (line 426) | bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t typ...
function TLSFindExt (line 480) | bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const ui...
function TLSAdvanceToHostInSNI (line 492) | bool TLSAdvanceToHostInSNI(const uint8_t **ext, size_t *elen, size_t *slen)
function TLSExtractHostFromExt (line 502) | static bool TLSExtractHostFromExt(const uint8_t *ext, size_t elen, char ...
function TLSHelloExtractHost (line 518) | bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, si...
function TLSHelloExtractHostFromHandshake (line 526) | bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, c...
function TLSPos (line 535) | size_t TLSPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_...
function tvb_get_varint (line 572) | static uint8_t tvb_get_varint(const uint8_t *tvb, uint64_t *value)
function tvb_get_size (line 593) | static uint8_t tvb_get_size(uint8_t tvb)
function IsQUICCryptoHello (line 598) | bool IsQUICCryptoHello(const uint8_t *data, size_t len, size_t *hello_of...
function QUICDraftVersion (line 615) | uint8_t QUICDraftVersion(uint32_t version)
function is_quic_draft_max (line 651) | static bool is_quic_draft_max(uint32_t draft_version, uint8_t max_version)
function is_quic_v2 (line 655) | static bool is_quic_v2(uint32_t version)
function quic_hkdf_expand_label (line 660) | static bool quic_hkdf_expand_label(const uint8_t *secret, uint8_t secret...
function quic_derive_initial_secret (line 676) | static bool quic_derive_initial_secret(const quic_cid_t *cid, uint8_t *c...
function QUICIsLongHeader (line 762) | bool QUICIsLongHeader(const uint8_t *data, size_t len)
function QUICExtractVersion (line 766) | uint32_t QUICExtractVersion(const uint8_t *data, size_t len)
function QUICExtractDCID (line 771) | bool QUICExtractDCID(const uint8_t *data, size_t len, quic_cid_t *cid)
function QUICDecryptInitial (line 778) | bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *c...
type range64 (line 847) | struct range64
function cmp_range64 (line 852) | static int cmp_range64(const void * a, const void * b)
function QUICDefragCrypto (line 856) | bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *de...
function IsQUICInitial (line 977) | bool IsQUICInitial(const uint8_t *data, size_t len)
function IsWireguardHandshakeInitiation (line 1018) | bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len)
function IsDhtD1 (line 1022) | bool IsDhtD1(const uint8_t *data, size_t len)
function IsDiscordIpDiscoveryRequest (line 1026) | bool IsDiscordIpDiscoveryRequest(const uint8_t *data, size_t len)
function IsStunMessage (line 1034) | bool IsStunMessage(const uint8_t *data, size_t len)
FILE: nfq/protocol.h
type t_l7proto (line 10) | typedef enum {UNKNOWN=0, HTTP, TLS, QUIC, WIREGUARD, DHT, DISCORD, STUN}...
type proto_pos (line 31) | struct proto_pos
type proto_pos (line 42) | struct proto_pos
type proto_pos (line 43) | struct proto_pos
type quic_cid_t (line 82) | typedef struct quic_cid {
FILE: nfq/sec.c
function set_filter (line 147) | static void set_filter(struct sock_filter *filter, __u16 code, __u8 jt, ...
function set_seccomp (line 155) | static bool set_seccomp(void)
function sec_harden (line 193) | bool sec_harden(void)
function checkpcap (line 215) | bool checkpcap(uint64_t caps)
function setpcap (line 226) | bool setpcap(uint64_t caps)
function getmaxcap (line 238) | int getmaxcap(void)
function dropcaps (line 250) | bool dropcaps(void)
function sec_harden (line 280) | bool sec_harden(void)
function can_drop_root (line 287) | bool can_drop_root(void)
function droproot (line 298) | bool droproot(uid_t uid, const char *user, const gid_t *gid, int gid_count)
function print_id (line 343) | void print_id(void)
function daemonize (line 364) | void daemonize(void)
function writepid (line 401) | bool writepid(const char *filename)
FILE: nfq/uthash.h
type UT_hash_bucket (line 1068) | typedef struct UT_hash_bucket {
type UT_hash_table (line 1092) | typedef struct UT_hash_table {
type UT_hash_handle (line 1125) | typedef struct UT_hash_handle {
FILE: nfq/win.c
function service_run (line 17) | bool service_run(int argc, char *argv[])
function service_set_status (line 30) | static void service_set_status(DWORD state)
function service_controlhandler (line 37) | void service_controlhandler(DWORD request)
function service_main (line 50) | void service_main(int argc __attribute__((unused)), char *argv[] __attri...
FILE: nfq/windows/windivert/windivert.h
type WINDIVERT_LAYER (line 75) | typedef enum
type WINDIVERT_DATA_NETWORK (line 87) | typedef struct
type WINDIVERT_DATA_FLOW (line 96) | typedef struct
type WINDIVERT_DATA_SOCKET (line 111) | typedef struct
type WINDIVERT_DATA_REFLECT (line 126) | typedef struct
type WINDIVERT_ADDRESS (line 142) | typedef struct
type WINDIVERT_EVENT (line 173) | typedef enum
type WINDIVERT_PARAM (line 203) | typedef enum
type WINDIVERT_SHUTDOWN (line 216) | typedef enum
type WINDIVERT_IPHDR (line 341) | typedef struct
type WINDIVERT_IPV6HDR (line 394) | typedef struct
type WINDIVERT_ICMPHDR (line 428) | typedef struct
type WINDIVERT_ICMPV6HDR (line 436) | typedef struct
type WINDIVERT_TCPHDR (line 444) | typedef struct
type WINDIVERT_UDPHDR (line 464) | typedef struct
FILE: tpws/andr/getifaddrs.c
type sockaddr_ll_hack (line 18) | struct sockaddr_ll_hack {
type sockaddr (line 27) | struct sockaddr
type sockaddr_ll_hack (line 28) | struct sockaddr_ll_hack
type sockaddr_in (line 29) | struct sockaddr_in
type sockaddr_in6 (line 30) | struct sockaddr_in6
type ifaddrs_storage (line 33) | struct ifaddrs_storage {
type ifaddrs_ctx (line 41) | struct ifaddrs_ctx {
function freeifaddrs (line 47) | void freeifaddrs(struct ifaddrs *ifp)
function copy_addr (line 57) | static void copy_addr(struct sockaddr **r, int af, union sockany *sa, vo...
function gen_netmask (line 82) | static void gen_netmask(struct sockaddr **r, int af, union sockany *sa, ...
function copy_lladdr (line 94) | static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *ad...
function netlink_msg_to_ifaddr (line 105) | static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h)
function getifaddrs (line 207) | int getifaddrs(struct ifaddrs **ifap)
FILE: tpws/andr/ifaddrs.h
type ifaddrs (line 6) | struct ifaddrs
type ifaddrs (line 7) | struct ifaddrs
FILE: tpws/andr/netlink.c
function __netlink_enumerate (line 9) | static int __netlink_enumerate(int fd, unsigned int seq, int type, int af,
function __rtnetlink_enumerate (line 44) | int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx,...
FILE: tpws/andr/netlink.h
type nlmsghdr (line 7) | struct nlmsghdr {
type rtattr (line 36) | struct rtattr {
type rtgenmsg (line 41) | struct rtgenmsg {
type ifinfomsg (line 45) | struct ifinfomsg {
type ifaddrmsg (line 63) | struct ifaddrmsg {
type nlmsghdr (line 94) | struct nlmsghdr
FILE: tpws/epoll-shim/include/sys/epoll.h
type EPOLL_EVENTS (line 21) | enum EPOLL_EVENTS { __EPOLL_DUMMY }
type epoll_data_t (line 43) | typedef union epoll_data {
type epoll_event (line 50) | struct epoll_event {
type epoll_event (line 62) | struct epoll_event
type epoll_event (line 63) | struct epoll_event
type epoll_event (line 64) | struct epoll_event
FILE: tpws/epoll-shim/src/epoll.c
function errno_t (line 35) | static errno_t
function FDContextMapNode (line 47) | static FDContextMapNode *
function epoll_create_common (line 73) | static int
function epoll_create (line 88) | int
function epoll_create1 (line 99) | int
function errno_t (line 110) | static errno_t
function epoll_ctl (line 126) | int
function is_no_wait_deadline (line 138) | static bool
function errno_t (line 144) | static errno_t
function errno_t (line 234) | static errno_t
function errno_t (line 262) | static errno_t
function epoll_pwait (line 286) | int
function epoll_wait (line 301) | int
FILE: tpws/epoll-shim/src/epoll_shim_ctx.c
function fd_context_map_node_init (line 10) | static void
function FDContextMapNode (line 17) | static FDContextMapNode *
function errno_t (line 32) | static errno_t
function errno_t (line 44) | errno_t
function errno_t (line 54) | errno_t
function errno_t (line 66) | errno_t
function fd_context_map_node_cmp (line 80) | static int
function FDContextMapNode (line 96) | static FDContextMapNode *
function FDContextMapNode (line 136) | FDContextMapNode *
function FDContextMapNode (line 158) | static FDContextMapNode *
function FDContextMapNode (line 172) | FDContextMapNode *
function FDContextMapNode (line 184) | FDContextMapNode *
function epoll_shim_ctx_remove_node_explicit (line 200) | void
function epoll_shim_close (line 212) | int
function epoll_shim_read (line 231) | ssize_t
function epoll_shim_write (line 257) | ssize_t
FILE: tpws/epoll-shim/src/epoll_shim_ctx.h
type fd_context_map_node_ (line 15) | struct fd_context_map_node_
type FDContextMapNode (line 16) | typedef struct fd_context_map_node_ FDContextMapNode;
type errno_t (line 18) | typedef errno_t (*fd_context_read_fun)(FDContextMapNode *node, /**/
type errno_t (line 20) | typedef errno_t (*fd_context_write_fun)(FDContextMapNode *node, /**/
type errno_t (line 22) | typedef errno_t (*fd_context_close_fun)(FDContextMapNode *node);
type FDContextVTable (line 24) | typedef struct {
type fd_context_map_node_ (line 35) | struct fd_context_map_node_ {
type FDContextMap (line 52) | typedef RB_HEAD(fd_context_map_, fd_context_map_node_) FDContextMap;
type EpollShimCtx (line 54) | typedef struct {
FILE: tpws/epoll-shim/src/epollfd_ctx.c
function RegisteredFDsNode (line 28) | static RegisteredFDsNode *
function registered_fds_node_destroy (line 43) | static void
type NeededFilters (line 54) | typedef struct {
function NeededFilters (line 60) | static NeededFilters
function registered_fds_node_update_flags_from_epoll_event (line 214) | static void
function errno_t (line 229) | static errno_t
function registered_fds_node_trigger_self (line 261) | static void
type kevent (line 281) | struct kevent
type pollfd (line 296) | struct pollfd
type kevent (line 326) | struct kevent
type pollfd (line 360) | struct pollfd
function else (line 378) | else if (kev->filter == EVFILT_EXCEPT) {
function else (line 506) | else if (kev->filter == EVFILT_EXCEPT) {
function registered_fds_node_register_for_completion (line 513) | static void
function registered_fds_node_complete (line 550) | static void
function fd_cmp (line 574) | static int
function errno_t (line 583) | errno_t
function errno_t (line 616) | errno_t
function errno_t (line 648) | static errno_t
function errno_t (line 673) | static errno_t
function errno_t (line 698) | static errno_t
function epollfd_ctx__trigger_self (line 728) | static void
function epollfd_ctx__trigger_repoll (line 744) | static void
function epollfd_ctx__remove_node_from_kq (line 771) | static void
function errno_t (line 822) | static errno_t
function epollfd_ctx_remove_node (line 980) | static void
function modify_fifo_rights_from_capabilities (line 993) | static void
function errno_t (line 1021) | static errno_t
function errno_t (line 1103) | static errno_t
function errno_t (line 1120) | static errno_t
function epollfd_ctx_fill_pollfds (line 1183) | void
function errno_t (line 1201) | errno_t
function errno_t (line 1213) | static errno_t
function errno_t (line 1375) | errno_t
FILE: tpws/epoll-shim/src/epollfd_ctx.h
type registered_fds_node_ (line 19) | struct registered_fds_node_
type RegisteredFDsNode (line 20) | typedef struct registered_fds_node_ RegisteredFDsNode;
type EOFState (line 22) | typedef enum {
type NodeType (line 27) | typedef enum {
type registered_fds_node_ (line 35) | struct registered_fds_node_ {
type PollFDList (line 72) | typedef TAILQ_HEAD(pollfds_list_, registered_fds_node_) PollFDList;
type RegisteredFDsSet (line 73) | typedef RB_HEAD(registered_fds_set_, registered_fds_node_) RegisteredFDs...
type EpollFDCtx (line 75) | typedef struct {
type pollfd (line 101) | struct pollfd
type epoll_event (line 104) | struct epoll_event
type epoll_event (line 105) | struct epoll_event
FILE: tpws/epoll-shim/src/eventfd_ctx.h
type EventFDCtx (line 14) | typedef struct {
FILE: tpws/epoll-shim/src/fix.c
function ppoll (line 7) | int ppoll(struct pollfd *fds, nfds_t nfds,const struct timespec *tmo_p, ...
FILE: tpws/epoll-shim/src/fix.h
type errno_t (line 5) | typedef int errno_t;
type itimerspec (line 14) | struct itimerspec {
type pollfd (line 18) | struct pollfd
type timespec (line 18) | struct timespec
FILE: tpws/epoll-shim/src/signalfd_ctx.h
type SignalFDCtx (line 10) | typedef struct {
FILE: tpws/epoll-shim/src/timerfd_ctx.h
type TimerFDCtx (line 14) | typedef struct {
type itimerspec (line 33) | struct itimerspec
type itimerspec (line 33) | struct itimerspec
type itimerspec (line 34) | struct itimerspec
FILE: tpws/gzip.c
function z_readfile (line 10) | int z_readfile(FILE *F, char **buf, size_t *size)
function is_gzip (line 73) | bool is_gzip(FILE* F)
FILE: tpws/helpers.c
function unique_size_t (line 28) | int unique_size_t(size_t *pu, int ct)
function cmp_size_t (line 39) | static int cmp_size_t(const void * a, const void * b)
function qsort_size_t (line 43) | void qsort_size_t(size_t *array, size_t ct)
function rtrim (line 49) | void rtrim(char *s)
function replace_char (line 55) | void replace_char(char *s, char from, char to)
function str_ends_with (line 81) | bool str_ends_with(const char *s, const char *suffix)
function load_file (line 88) | bool load_file(const char *filename, void *buffer, size_t *buffer_size)
function append_to_list_file (line 106) | bool append_to_list_file(const char *filename, const char *s)
function expand_bits (line 115) | void expand_bits(void *target, const void *source, unsigned int source_b...
function strip_host_to_ip (line 132) | bool strip_host_to_ip(char *host)
function ntop46 (line 181) | void ntop46(const struct sockaddr *sa, char *str, size_t len)
function ntop46_port (line 197) | void ntop46_port(const struct sockaddr *sa, char *str, size_t len)
function print_sockaddr (line 213) | void print_sockaddr(const struct sockaddr *sa)
function check_local_ip (line 222) | bool check_local_ip(const struct sockaddr *saddr)
function print_addrinfo (line 246) | void print_addrinfo(const struct addrinfo *ai)
function saismapped (line 268) | bool saismapped(const struct sockaddr_in6 *sa)
function samappedcmp (line 273) | bool samappedcmp(const struct sockaddr_in *sa1, const struct sockaddr_in...
function sacmp (line 277) | bool sacmp(const struct sockaddr *sa1, const struct sockaddr *sa2)
function saport (line 284) | uint16_t saport(const struct sockaddr *sa)
function saconvmapped (line 289) | bool saconvmapped(struct sockaddr_storage *a)
function sacopy (line 303) | void sacopy(struct sockaddr_storage *sa_dest, const struct sockaddr *sa)
function sa46copy (line 317) | void sa46copy(sockaddr_in46 *sa_dest, const struct sockaddr *sa)
function is_localnet (line 322) | bool is_localnet(const struct sockaddr *a)
function is_linklocal (line 332) | bool is_linklocal(const struct sockaddr_in6 *a)
function is_private6 (line 337) | bool is_private6(const struct sockaddr_in6* a)
function set_keepalive (line 345) | bool set_keepalive(int fd)
function set_ttl (line 350) | bool set_ttl(int fd, int ttl)
function set_hl (line 354) | bool set_hl(int fd, int hl)
function set_ttl_hl (line 358) | bool set_ttl_hl(int fd, int ttl)
function get_so_error (line 366) | int get_so_error(int fd)
function fprint_localtime (line 376) | int fprint_localtime(FILE *F)
function time_t (line 386) | time_t file_mod_time(const char *filename)
function file_mod_signature (line 391) | bool file_mod_signature(const char *filename, file_mod_sig *ms)
function file_open_test (line 404) | bool file_open_test(const char *filename, int flags)
function pf_in_range (line 415) | bool pf_in_range(uint16_t port, const port_filter *pf)
function pf_parse (line 419) | bool pf_parse(const char *s, port_filter *pf)
function pf_is_empty (line 454) | bool pf_is_empty(const port_filter *pf)
function set_console_io_buffering (line 459) | void set_console_io_buffering(void)
function set_env_exedir (line 465) | bool set_env_exedir(const char *argv0)
function str_cidr4 (line 479) | void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr)
function print_cidr4 (line 486) | void print_cidr4(const struct cidr4 *cidr)
function str_cidr6 (line 492) | void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr)
function print_cidr6 (line 499) | void print_cidr6(const struct cidr6 *cidr)
function parse_cidr4 (line 505) | bool parse_cidr4(char *s, struct cidr4 *cidr)
function parse_cidr6 (line 524) | bool parse_cidr6(char *s, struct cidr6 *cidr)
function msleep (line 545) | void msleep(unsigned int ms)
function socket_supports_notsent (line 555) | bool socket_supports_notsent()
function socket_has_notsent (line 573) | bool socket_has_notsent(int sfd)
function socket_wait_notsent (line 588) | bool socket_wait_notsent(int sfd, unsigned int delay_ms, unsigned int *w...
function is_wsl (line 614) | int is_wsl(void)
FILE: tpws/helpers.h
type sockaddr_in46 (line 13) | typedef union
type sockaddr (line 36) | struct sockaddr
type sockaddr (line 37) | struct sockaddr
type sockaddr (line 38) | struct sockaddr
type addrinfo (line 39) | struct addrinfo
type sockaddr (line 40) | struct sockaddr
type sockaddr_in6 (line 42) | struct sockaddr_in6
type sockaddr_in (line 43) | struct sockaddr_in
type sockaddr_in6 (line 43) | struct sockaddr_in6
type sockaddr (line 44) | struct sockaddr
type sockaddr (line 44) | struct sockaddr
type sockaddr (line 45) | struct sockaddr
type sockaddr_storage (line 47) | struct sockaddr_storage
type sockaddr_storage (line 49) | struct sockaddr_storage
type sockaddr (line 49) | struct sockaddr
type sockaddr (line 50) | struct sockaddr
type sockaddr (line 52) | struct sockaddr
type sockaddr_in6 (line 53) | struct sockaddr_in6
type sockaddr_in6 (line 54) | struct sockaddr_in6
function pntoh16 (line 63) | static inline uint16_t pntoh16(const uint8_t *p) {
function phton16 (line 66) | static inline void phton16(uint8_t *p, uint16_t v) {
type file_mod_sig (line 73) | typedef struct
type port_filter (line 84) | typedef struct
type cidr4 (line 110) | struct cidr4
type cidr6 (line 115) | struct cidr6
type cidr4 (line 120) | struct cidr4
type cidr4 (line 121) | struct cidr4
type cidr6 (line 122) | struct cidr6
type cidr6 (line 123) | struct cidr6
type cidr4 (line 124) | struct cidr4
type cidr6 (line 125) | struct cidr6
FILE: tpws/hostlist.c
function addpool (line 7) | static bool addpool(hostlist_pool **hostlist, char **s, const char *end,...
function AppendHostlistItem (line 41) | bool AppendHostlistItem(hostlist_pool **hostlist, char *s)
function AppendHostList (line 46) | bool AppendHostList(hostlist_pool **hostlist, const char *filename)
function LoadHostList (line 110) | static bool LoadHostList(struct hostlist_file *hfile)
function LoadHostLists (line 133) | static bool LoadHostLists(struct hostlist_files_head *list)
function NonEmptyHostlist (line 147) | bool NonEmptyHostlist(hostlist_pool **hostlist)
function MakeAutolistsNonEmpty (line 153) | static void MakeAutolistsNonEmpty()
function LoadAllHostLists (line 163) | bool LoadAllHostLists()
function SearchHostList (line 173) | static bool SearchHostList(hostlist_pool *hostlist, const char *host, bo...
function HostlistsReloadCheck (line 208) | static bool HostlistsReloadCheck(const struct hostlist_collection_head *...
function HostlistsReloadCheckForProfile (line 219) | bool HostlistsReloadCheckForProfile(const struct desync_profile *dp)
function HostlistCheck_ (line 224) | static bool HostlistCheck_(const struct hostlist_collection_head *hostli...
function HostlistCheck (line 259) | bool HostlistCheck(const struct desync_profile *dp, const char *host, bo...
type hostlist_file (line 266) | struct hostlist_file
type hostlist_files_head (line 266) | struct hostlist_files_head
type hostlist_collection_head (line 266) | struct hostlist_collection_head
type hostlist_file (line 268) | struct hostlist_file
type hostlist_file (line 289) | struct hostlist_file
type desync_profile (line 289) | struct desync_profile
function HostlistsDebug (line 304) | void HostlistsDebug()
FILE: tpws/hostlist.h
type desync_profile (line 12) | struct desync_profile
type hostlist_file (line 13) | struct hostlist_file
type desync_profile (line 13) | struct desync_profile
type desync_profile (line 14) | struct desync_profile
FILE: tpws/ipset.c
function addpool (line 8) | static bool addpool(ipset *ips, char **s, const char *end, int *ct)
function AppendIpsetItem (line 56) | bool AppendIpsetItem(ipset *ips, char *ip)
function AppendIpset (line 61) | static bool AppendIpset(ipset *ips, const char *filename)
function LoadIpset (line 125) | static bool LoadIpset(struct ipset_file *hfile)
function LoadIpsets (line 148) | static bool LoadIpsets(struct ipset_files_head *list)
function LoadAllIpsets (line 162) | bool LoadAllIpsets()
function SearchIpset (line 167) | static bool SearchIpset(const ipset *ips, const struct in_addr *ipv4, co...
function IpsetsReloadCheck (line 193) | static bool IpsetsReloadCheck(const struct ipset_collection_head *ipsets)
function IpsetsReloadCheckForProfile (line 203) | bool IpsetsReloadCheckForProfile(const struct desync_profile *dp)
function IpsetCheck_ (line 208) | static bool IpsetCheck_(const struct ipset_collection_head *ips, const s...
function IpsetCheck (line 235) | bool IpsetCheck(const struct desync_profile *dp, const struct in_addr *i...
type ipset_file (line 243) | struct ipset_file
type ipset_files_head (line 243) | struct ipset_files_head
type ipset_collection_head (line 243) | struct ipset_collection_head
type ipset_file (line 245) | struct ipset_file
type ipset_file (line 264) | struct ipset_file
type desync_profile (line 264) | struct desync_profile
function IpsetsDebug (line 290) | void IpsetsDebug()
FILE: tpws/ipset.h
type desync_profile (line 9) | struct desync_profile
type in_addr (line 9) | struct in_addr
type in6_addr (line 9) | struct in6_addr
type ipset_file (line 10) | struct ipset_file
type desync_profile (line 10) | struct desync_profile
FILE: tpws/linux_compat.h
type tcp_info_new (line 19) | struct tcp_info_new {
FILE: tpws/macos/net/pfvar.h
type pf_addr (line 13) | struct pf_addr {
type pfioc_natlook (line 34) | struct pfioc_natlook {
FILE: tpws/macos/sys/tree.h
type type (line 79) | struct type
type type (line 128) | struct type
type name (line 129) | struct name
type type (line 129) | struct type
type type (line 139) | struct type
type name (line 140) | struct name
type type (line 140) | struct type
type type (line 153) | struct type
type name (line 154) | struct name
function _SPLAY_MINMAX (line 247) | void name##_SPLAY_MINMAX(struct name *head, int __comp) \
type type (line 315) | struct type
type type (line 316) | struct type
FILE: tpws/params.c
function DLOG_FILE (line 11) | int DLOG_FILE(FILE *F, const char *format, va_list args)
function DLOG_CON (line 15) | int DLOG_CON(const char *format, int syslog_priority, va_list args)
function DLOG_FILENAME (line 19) | int DLOG_FILENAME(const char *filename, const char *format, va_list args)
function syslog_log_function (line 37) | static void syslog_log_function(int priority, const char *line)
function syslog_priority_to_android (line 42) | static enum android_LogPriority syslog_priority_to_android(int priority)
function android_log_function (line 59) | static void android_log_function(int priority, const char *line)
function log_buffered (line 64) | static void log_buffered(f_log_function log_function, int syslog_priorit...
function DLOG_VA (line 78) | static int DLOG_VA(const char *format, int syslog_priority, bool condup,...
function DLOG (line 118) | int DLOG(const char *format, int level, ...)
function DLOG_CONDUP (line 127) | int DLOG_CONDUP(const char *format, ...)
function DLOG_ERR (line 136) | int DLOG_ERR(const char *format, ...)
function DLOG_PERROR (line 145) | int DLOG_PERROR(const char *s)
function LOG_APPEND (line 151) | int LOG_APPEND(const char *filename, const char *format, va_list args)
function HOSTLIST_DEBUGLOG_APPEND (line 168) | int HOSTLIST_DEBUGLOG_APPEND(const char *format, ...)
function hexdump_limited_dlog (line 184) | void hexdump_limited_dlog(const uint8_t *data, size_t size, size_t limit)
function dp_init (line 200) | void dp_init(struct desync_profile *dp)
type desync_profile_list (line 214) | struct desync_profile_list
type desync_profile_list_head (line 214) | struct desync_profile_list_head
type desync_profile_list (line 216) | struct desync_profile_list
type desync_profile_list (line 216) | struct desync_profile_list
type desync_profile_list (line 222) | struct desync_profile_list
function dp_clear_dynamic (line 233) | static void dp_clear_dynamic(struct desync_profile *dp)
function dp_clear (line 242) | void dp_clear(struct desync_profile *dp)
function dp_entry_destroy (line 247) | void dp_entry_destroy(struct desync_profile_list *entry)
function dp_list_destroy (line 252) | void dp_list_destroy(struct desync_profile_list_head *head)
function cleanup_args (line 264) | void cleanup_args(struct params_s *params)
function cleanup_params (line 269) | void cleanup_params(struct params_s *params)
FILE: tpws/params.h
type bindll (line 29) | enum bindll { unwanted=0, no, prefer, force }
type bind_s (line 32) | struct bind_s
type log_target (line 42) | enum log_target { LOG_TARGET_CONSOLE=0, LOG_TARGET_FILE, LOG_TARGET_SYSL...
type desync_profile (line 44) | struct desync_profile
type desync_profile_list (line 86) | struct desync_profile_list {
type desync_profile_list (line 91) | struct desync_profile_list
type desync_profile_list_head (line 91) | struct desync_profile_list_head
type desync_profile_list (line 92) | struct desync_profile_list
type desync_profile_list_head (line 93) | struct desync_profile_list_head
type desync_profile (line 94) | struct desync_profile
type desync_profile (line 95) | struct desync_profile
type params_s (line 97) | struct params_s
type params_s (line 157) | struct params_s
type params_s (line 160) | struct params_s
type params_s (line 162) | struct params_s
FILE: tpws/pools.c
function ut_oom_recover (line 46) | static void ut_oom_recover(void *elem)
function HostlistPoolAddStrLen (line 52) | bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t sle...
function HostlistPoolAddStr (line 58) | bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags)
function hostlist_pool (line 63) | hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s)
function HostlistPoolCheckStr (line 69) | bool HostlistPoolCheckStr(hostlist_pool *p, const char *s)
function HostlistPoolDestroy (line 74) | void HostlistPoolDestroy(hostlist_pool **pp)
function HostFailPoolDestroy (line 81) | void HostFailPoolDestroy(hostfail_pool **pp)
function hostfail_pool (line 85) | hostfail_pool * HostFailPoolAdd(hostfail_pool **pp,const char *s,int fai...
function hostfail_pool (line 93) | hostfail_pool *HostFailPoolFind(hostfail_pool *p,const char *s)
function HostFailPoolDel (line 99) | void HostFailPoolDel(hostfail_pool **p, hostfail_pool *elem)
function HostFailPoolPurge (line 105) | void HostFailPoolPurge(hostfail_pool **pp)
function HostFailPoolPurgeRateLimited (line 116) | void HostFailPoolPurgeRateLimited(hostfail_pool **pp)
function HostFailPoolDump (line 126) | void HostFailPoolDump(hostfail_pool *p)
function strlist_add (line 135) | bool strlist_add(struct str_list_head *head, const char *filename)
function strlist_entry_destroy (line 148) | static void strlist_entry_destroy(struct str_list *entry)
function strlist_destroy (line 153) | void strlist_destroy(struct str_list_head *head)
type hostlist_file (line 165) | struct hostlist_file
type hostlist_files_head (line 165) | struct hostlist_files_head
type hostlist_file (line 167) | struct hostlist_file
type hostlist_file (line 167) | struct hostlist_file
function hostlist_files_entry_destroy (line 186) | static void hostlist_files_entry_destroy(struct hostlist_file *entry)
function hostlist_files_destroy (line 192) | void hostlist_files_destroy(struct hostlist_files_head *head)
type hostlist_file (line 201) | struct hostlist_file
type hostlist_files_head (line 201) | struct hostlist_files_head
type hostlist_file (line 203) | struct hostlist_file
function hostlist_files_reset_modtime (line 212) | void hostlist_files_reset_modtime(struct hostlist_files_head *list)
type hostlist_item (line 220) | struct hostlist_item
type hostlist_collection_head (line 220) | struct hostlist_collection_head
type hostlist_file (line 220) | struct hostlist_file
type hostlist_item (line 222) | struct hostlist_item
type hostlist_item (line 222) | struct hostlist_item
function hostlist_collection_destroy (line 230) | void hostlist_collection_destroy(struct hostlist_collection_head *head)
type hostlist_item (line 239) | struct hostlist_item
type hostlist_collection_head (line 239) | struct hostlist_collection_head
type hostlist_item (line 241) | struct hostlist_item
function hostlist_collection_is_empty (line 250) | bool hostlist_collection_is_empty(const struct hostlist_collection_head ...
function kavl_bit_cmp (line 263) | static int kavl_bit_cmp(const struct kavl_bit_elem *p, const struct kavl...
function kavl_bit_destroy_elem (line 276) | static void kavl_bit_destroy_elem(struct kavl_bit_elem *e)
function kavl_bit_delete (line 284) | void kavl_bit_delete(struct kavl_bit_elem **hdr, const void *data, unsig...
function kavl_bit_destroy (line 291) | void kavl_bit_destroy(struct kavl_bit_elem **hdr)
type kavl_bit_elem (line 301) | struct kavl_bit_elem
type kavl_bit_elem (line 301) | struct kavl_bit_elem
type kavl_bit_elem (line 303) | struct kavl_bit_elem
type kavl_bit_elem (line 305) | struct kavl_bit_elem
type kavl_bit_elem (line 320) | struct kavl_bit_elem
type kavl_bit_elem (line 320) | struct kavl_bit_elem
type kavl_bit_elem (line 322) | struct kavl_bit_elem
function ipset_kavl_add (line 328) | static bool ipset_kavl_add(struct kavl_bit_elem **ipset, const void *a, ...
function ipset4Check (line 343) | bool ipset4Check(const struct kavl_bit_elem *ipset, const struct in_addr...
function ipset4Add (line 347) | bool ipset4Add(struct kavl_bit_elem **ipset, const struct in_addr *a, ui...
function ipset4Print (line 352) | void ipset4Print(struct kavl_bit_elem *ipset)
function ipset6Check (line 371) | bool ipset6Check(const struct kavl_bit_elem *ipset, const struct in6_add...
function ipset6Add (line 375) | bool ipset6Add(struct kavl_bit_elem **ipset, const struct in6_addr *a, u...
function ipset6Print (line 380) | void ipset6Print(struct kavl_bit_elem *ipset)
function ipsetDestroy (line 399) | void ipsetDestroy(ipset *ipset)
function ipsetPrint (line 404) | void ipsetPrint(ipset *ipset)
type ipset_file (line 411) | struct ipset_file
type ipset_files_head (line 411) | struct ipset_files_head
type ipset_file (line 413) | struct ipset_file
type ipset_file (line 413) | struct ipset_file
function ipset_files_entry_destroy (line 432) | static void ipset_files_entry_destroy(struct ipset_file *entry)
function ipset_files_destroy (line 438) | void ipset_files_destroy(struct ipset_files_head *head)
type ipset_file (line 447) | struct ipset_file
type ipset_files_head (line 447) | struct ipset_files_head
type ipset_file (line 449) | struct ipset_file
function ipset_files_reset_modtime (line 458) | void ipset_files_reset_modtime(struct ipset_files_head *list)
type ipset_item (line 466) | struct ipset_item
type ipset_collection_head (line 466) | struct ipset_collection_head
type ipset_file (line 466) | struct ipset_file
type ipset_item (line 468) | struct ipset_item
type ipset_item (line 468) | struct ipset_item
function ipset_collection_destroy (line 476) | void ipset_collection_destroy(struct ipset_collection_head *head)
type ipset_item (line 485) | struct ipset_item
type ipset_collection_head (line 485) | struct ipset_collection_head
type ipset_item (line 487) | struct ipset_item
function ipset_collection_is_empty (line 496) | bool ipset_collection_is_empty(const struct ipset_collection_head *head)
function port_filter_add (line 509) | bool port_filter_add(struct port_filters_head *head, const port_filter *pf)
function port_filters_destroy (line 519) | void port_filters_destroy(struct port_filters_head *head)
function port_filters_in_range (line 528) | bool port_filters_in_range(const struct port_filters_head *head, uint16_...
function port_filters_deny_if_empty (line 540) | bool port_filters_deny_if_empty(struct port_filters_head *head)
type blob_item (line 549) | struct blob_item
type blob_collection_head (line 549) | struct blob_collection_head
type blob_item (line 551) | struct blob_item
type blob_item (line 551) | struct blob_item
type blob_item (line 555) | struct blob_item
type blob_item (line 566) | struct blob_item
type blob_collection_head (line 566) | struct blob_collection_head
type blob_item (line 568) | struct blob_item
type blob_item (line 568) | struct blob_item
type blob_item (line 580) | struct blob_item
function blob_collection_destroy (line 592) | void blob_collection_destroy(struct blob_collection_head *head)
function blob_collection_empty (line 604) | bool blob_collection_empty(const struct blob_collection_head *head)
function ipcache_item_touch (line 611) | static void ipcache_item_touch(ip_cache_item *item)
function ipcache_item_init (line 615) | static void ipcache_item_init(ip_cache_item *item)
function ipcache_item_destroy (line 621) | static void ipcache_item_destroy(ip_cache_item *item)
function ipcache4Destroy (line 626) | static void ipcache4Destroy(ip_cache4 **ipcache)
function ipcache4Key (line 636) | static void ipcache4Key(ip4if *key, const struct in_addr *a)
function ip_cache4 (line 641) | static ip_cache4 *ipcache4Find(ip_cache4 *ipcache, const struct in_addr *a)
function ip_cache4 (line 650) | static ip_cache4 *ipcache4Add(ip_cache4 **ipcache, const struct in_addr *a)
function ipcache4Print (line 668) | static void ipcache4Print(ip_cache4 *ipcache)
function ipcache6Destroy (line 683) | static void ipcache6Destroy(ip_cache6 **ipcache)
function ipcache6Key (line 693) | static void ipcache6Key(ip6if *key, const struct in6_addr *a)
function ip_cache6 (line 698) | static ip_cache6 *ipcache6Find(ip_cache6 *ipcache, const struct in6_addr...
function ip_cache6 (line 707) | static ip_cache6 *ipcache6Add(ip_cache6 **ipcache, const struct in6_addr...
function ipcache6Print (line 725) | static void ipcache6Print(ip_cache6 *ipcache)
function ipcacheDestroy (line 740) | void ipcacheDestroy(ip_cache *ipcache)
function ipcachePrint (line 745) | void ipcachePrint(ip_cache *ipcache)
function ip_cache_item (line 751) | ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4,...
function ipcache4_purge (line 774) | static void ipcache4_purge(ip_cache4 **ipcache, time_t lifetime)
function ipcache6_purge (line 788) | static void ipcache6_purge(ip_cache6 **ipcache, time_t lifetime)
function ipcache_purge (line 802) | static void ipcache_purge(ip_cache *ipcache, time_t lifetime)
function ipcachePurgeRateLimited (line 811) | void ipcachePurgeRateLimited(ip_cache *ipcache, time_t lifetime)
FILE: tpws/pools.h
type hostlist_pool (line 20) | typedef struct hostlist_pool {
type str_list (line 31) | struct str_list {
type hostfail_pool (line 37) | typedef struct hostfail_pool {
type str_list_head (line 52) | struct str_list_head
type str_list_head (line 53) | struct str_list_head
type hostlist_file (line 57) | struct hostlist_file {
type hostlist_file (line 65) | struct hostlist_file
type hostlist_files_head (line 65) | struct hostlist_files_head
type hostlist_files_head (line 66) | struct hostlist_files_head
type hostlist_file (line 67) | struct hostlist_file
type hostlist_files_head (line 67) | struct hostlist_files_head
type hostlist_files_head (line 68) | struct hostlist_files_head
type hostlist_item (line 70) | struct hostlist_item {
type hostlist_item (line 75) | struct hostlist_item
type hostlist_collection_head (line 75) | struct hostlist_collection_head
type hostlist_file (line 75) | struct hostlist_file
type hostlist_collection_head (line 76) | struct hostlist_collection_head
type hostlist_item (line 77) | struct hostlist_item
type hostlist_collection_head (line 77) | struct hostlist_collection_head
type hostlist_collection_head (line 78) | struct hostlist_collection_head
type kavl_bit_elem (line 81) | struct kavl_bit_elem
type kavl_bit_elem (line 88) | struct kavl_bit_elem
type kavl_bit_elem (line 88) | struct kavl_bit_elem
type kavl_bit_elem (line 89) | struct kavl_bit_elem
type kavl_bit_elem (line 89) | struct kavl_bit_elem
type kavl_bit_elem (line 90) | struct kavl_bit_elem
type kavl_bit_elem (line 91) | struct kavl_bit_elem
type ipset (line 94) | typedef struct ipset {
type kavl_bit_elem (line 100) | struct kavl_bit_elem
type in_addr (line 100) | struct in_addr
function ipset4AddCidr (line 101) | static inline bool ipset4AddCidr(struct kavl_bit_elem **ipset, const str...
type kavl_bit_elem (line 105) | struct kavl_bit_elem
type in_addr (line 105) | struct in_addr
type kavl_bit_elem (line 106) | struct kavl_bit_elem
type kavl_bit_elem (line 108) | struct kavl_bit_elem
type in6_addr (line 108) | struct in6_addr
function ipset6AddCidr (line 109) | static inline bool ipset6AddCidr(struct kavl_bit_elem **ipset, const str...
type kavl_bit_elem (line 113) | struct kavl_bit_elem
type in6_addr (line 113) | struct in6_addr
type kavl_bit_elem (line 114) | struct kavl_bit_elem
type ipset_file (line 120) | struct ipset_file {
type ipset_file (line 128) | struct ipset_file
type ipset_files_head (line 128) | struct ipset_files_head
type ipset_files_head (line 129) | struct ipset_files_head
type ipset_file (line 130) | struct ipset_file
type ipset_files_head (line 130) | struct ipset_files_head
type ipset_files_head (line 131) | struct ipset_files_head
type ipset_item (line 133) | struct ipset_item {
type ipset_item (line 138) | struct ipset_item
type ipset_collection_head (line 138) | struct ipset_collection_head
type ipset_file (line 138) | struct ipset_file
type ipset_collection_head (line 139) | struct ipset_collection_head
type ipset_item (line 140) | struct ipset_item
type ipset_collection_head (line 140) | struct ipset_collection_head
type ipset_collection_head (line 141) | struct ipset_collection_head
type port_filter_item (line 144) | struct port_filter_item {
type port_filters_head (line 149) | struct port_filters_head
type port_filters_head (line 150) | struct port_filters_head
type port_filters_head (line 151) | struct port_filters_head
type port_filters_head (line 152) | struct port_filters_head
type blob_item (line 155) | struct blob_item {
type blob_item (line 164) | struct blob_item
type blob_collection_head (line 164) | struct blob_collection_head
type blob_item (line 165) | struct blob_item
type blob_collection_head (line 165) | struct blob_collection_head
type blob_collection_head (line 166) | struct blob_collection_head
type blob_collection_head (line 167) | struct blob_collection_head
type ip4if (line 170) | typedef struct ip4if
type ip6if (line 174) | typedef struct ip6if
type ip_cache_item (line 178) | typedef struct ip_cache_item
type ip_cache4 (line 184) | typedef struct ip_cache4
type ip_cache6 (line 190) | typedef struct ip_cache6
type ip_cache (line 196) | typedef struct ip_cache
type in_addr (line 202) | struct in_addr
type in6_addr (line 202) | struct in6_addr
FILE: tpws/protocol.c
function FindNLD (line 11) | static bool FindNLD(const uint8_t *dom, size_t dlen, int level, const ui...
function l7_proto_match (line 39) | bool l7_proto_match(t_l7proto l7proto, uint32_t filter_l7)
function IsHostMarker (line 57) | bool IsHostMarker(uint8_t posmarker)
function CheckPos (line 87) | static size_t CheckPos(size_t sz, ssize_t offset)
function AnyProtoPos (line 91) | size_t AnyProtoPos(uint8_t posmarker, int16_t pos, const uint8_t *data, ...
function HostPos (line 103) | static size_t HostPos(uint8_t posmarker, int16_t pos, const uint8_t *dat...
function ResolvePos (line 128) | size_t ResolvePos(const uint8_t *data, size_t sz, t_l7proto l7proto, con...
function ResolveMultiPos (line 140) | void ResolveMultiPos(const uint8_t *data, size_t sz, t_l7proto l7proto, ...
function IsHttp (line 167) | bool IsHttp(const uint8_t *data, size_t len)
function IsHostAt (line 172) | static bool IsHostAt(const uint8_t *p)
function HttpFindHost (line 205) | bool HttpFindHost(uint8_t **pHost,uint8_t *buf,size_t bs)
function HttpFindHostConst (line 214) | bool HttpFindHostConst(const uint8_t **pHost,const uint8_t *buf,size_t bs)
function IsHttpReply (line 223) | bool IsHttpReply(const uint8_t *data, size_t len)
function HttpReplyCode (line 231) | int HttpReplyCode(const uint8_t *data, size_t len)
function HttpExtractHeader (line 235) | bool HttpExtractHeader(const uint8_t *data, size_t len, const char *head...
function HttpExtractHost (line 258) | bool HttpExtractHost(const uint8_t *data, size_t len, char *host, size_t...
function HttpReplyLooksLikeDPIRedirect (line 263) | bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, cons...
function HttpPos (line 299) | size_t HttpPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size...
function TLSRecordDataLen (line 356) | uint16_t TLSRecordDataLen(const uint8_t *data)
function TLSRecordLen (line 360) | size_t TLSRecordLen(const uint8_t *data)
function IsTLSRecordFull (line 364) | bool IsTLSRecordFull(const uint8_t *data, size_t len)
function IsTLSClientHello (line 368) | bool IsTLSClientHello(const uint8_t *data, size_t len, bool bPartialIsOK)
function TLSFindExtInHandshake (line 374) | bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t typ...
function TLSFindExt (line 442) | bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const ui...
function TLSAdvanceToHostInSNI (line 454) | static bool TLSAdvanceToHostInSNI(const uint8_t **ext, size_t *elen, siz...
function TLSExtractHostFromExt (line 464) | static bool TLSExtractHostFromExt(const uint8_t *ext, size_t elen, char ...
function TLSHelloExtractHost (line 480) | bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, si...
function TLSHelloExtractHostFromHandshake (line 488) | bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, c...
function TLSHelloFindNLDInSNI (line 498) | static bool TLSHelloFindNLDInSNI(const uint8_t *ext, size_t elen, int le...
function TLSHelloFindMiddleOfSLDInSNI (line 505) | static bool TLSHelloFindMiddleOfSLDInSNI(const uint8_t *ext, size_t elen...
function TLSPos (line 514) | size_t TLSPos(uint8_t posmarker, int16_t pos, const uint8_t *data, size_...
FILE: tpws/protocol.h
type t_l7proto (line 7) | typedef enum {UNKNOWN=0, HTTP, TLS, QUIC, WIREGUARD, DHT} t_l7proto;
type proto_pos (line 26) | struct proto_pos
type proto_pos (line 37) | struct proto_pos
type proto_pos (line 38) | struct proto_pos
FILE: tpws/redirect.c
function redir_close (line 26) | void redir_close(void)
function redir_open_private (line 35) | static bool redir_open_private(const char *fname, int flags)
function redir_init (line 47) | bool redir_init(void)
function destination_from_pf (line 52) | static bool destination_from_pf(const struct sockaddr *accept_sa, struct...
function redir_init (line 166) | bool redir_init(void) {return true;}
function redir_close (line 167) | void redir_close(void) {}
type sockaddr (line 174) | struct sockaddr
type sockaddr_storage (line 174) | struct sockaddr_storage
type sockaddr (line 188) | struct sockaddr
type sockaddr (line 190) | struct sockaddr
type sockaddr (line 196) | struct sockaddr
type sockaddr_in6 (line 203) | struct sockaddr_in6
type sockaddr_in (line 218) | struct sockaddr_in
type sockaddr_in (line 219) | struct sockaddr_in
type sockaddr_in6 (line 223) | struct sockaddr_in6
type sockaddr_in6 (line 224) | struct sockaddr_in6
FILE: tpws/redirect.h
type sockaddr (line 7) | struct sockaddr
type sockaddr_storage (line 7) | struct sockaddr_storage
FILE: tpws/resolver.c
type t_resolver (line 25) | typedef struct
function resolver_clear_list (line 43) | static void resolver_clear_list(void)
function resolver_thread_count (line 56) | int resolver_thread_count(void)
type resolve_item (line 85) | struct resolve_item
type addrinfo (line 95) | struct addrinfo
type addrinfo (line 100) | struct addrinfo
function sigbreak (line 140) | static void sigbreak(int sig)
function resolver_deinit (line 144) | void resolver_deinit(void)
function resolver_init (line 174) | bool resolver_init(int threads, int fd_signal_pipe)
type resolve_item (line 250) | struct resolve_item
type resolve_item (line 252) | struct resolve_item
type resolve_item (line 252) | struct resolve_item
FILE: tpws/resolver.h
type resolve_item (line 11) | struct resolve_item
type resolve_item (line 21) | struct resolve_item
FILE: tpws/sec.c
function set_filter (line 124) | static void set_filter(struct sock_filter *filter, __u16 code, __u8 jt, ...
function set_seccomp (line 132) | static bool set_seccomp(void)
function sec_harden (line 170) | bool sec_harden(void)
function checkpcap (line 190) | bool checkpcap(uint64_t caps)
function setpcap (line 201) | bool setpcap(uint64_t caps)
function getmaxcap (line 213) | int getmaxcap(void)
function dropcaps (line 225) | bool dropcaps(void)
function sec_harden (line 251) | bool sec_harden(void)
function can_drop_root (line 261) | bool can_drop_root(void)
function droproot (line 272) | bool droproot(uid_t uid, const char *user, const gid_t *gid, int gid_count)
function print_id (line 317) | void print_id(void)
function daemonize (line 334) | void daemonize(void)
function writepid (line 364) | bool writepid(const char *filename)
FILE: tpws/socks.h
type s4_req (line 10) | typedef struct
type s4_rep (line 21) | typedef struct
type s5_handshake (line 34) | typedef struct
type s5_handshake_ack (line 39) | typedef struct
type s5_req (line 50) | typedef struct
type s5_rep (line 82) | typedef struct
FILE: tpws/tamper.c
function packet_debug (line 14) | void packet_debug(const uint8_t *data, size_t sz)
function TLSDebugHandshake (line 19) | static void TLSDebugHandshake(const uint8_t *tls,size_t sz)
function TLSDebug (line 80) | static void TLSDebug(const uint8_t *tls,size_t sz)
function ipcache_put_hostname (line 94) | bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_add...
function ipcache_get_hostname (line 117) | static bool ipcache_get_hostname(const struct in_addr *a4, const struct ...
function dp_match (line 141) | static bool dp_match(struct desync_profile *dp, const struct sockaddr *d...
type desync_profile (line 176) | struct desync_profile
type desync_profile_list_head (line 176) | struct desync_profile_list_head
type sockaddr (line 176) | struct sockaddr
type desync_profile_list (line 178) | struct desync_profile_list
function apply_desync_profile (line 197) | void apply_desync_profile(t_ctrack *ctrack, const struct sockaddr *dest)
function tamper_out (line 213) | void tamper_out(t_ctrack *ctrack, const struct sockaddr *dest, uint8_t *...
function auto_hostlist_reset_fail_counter (line 533) | static void auto_hostlist_reset_fail_counter(struct desync_profile *dp, ...
function auto_hostlist_failed (line 549) | static void auto_hostlist_failed(struct desync_profile *dp, const char *...
function tamper_in (line 598) | void tamper_in(t_ctrack *ctrack, const struct sockaddr *client, uint8_t ...
function rst_in (line 640) | void rst_in(t_ctrack *ctrack, const struct sockaddr *client)
function hup_out (line 662) | void hup_out(t_ctrack *ctrack, const struct sockaddr *client)
FILE: tpws/tamper.h
type t_ctrack (line 12) | typedef struct
type sockaddr (line 24) | struct sockaddr
type in_addr (line 25) | struct in_addr
type in6_addr (line 25) | struct in6_addr
type sockaddr (line 27) | struct sockaddr
type sockaddr (line 28) | struct sockaddr
type sockaddr (line 30) | struct sockaddr
type sockaddr (line 32) | struct sockaddr
FILE: tpws/tpws.c
type params_s (line 53) | struct params_s
function onhup (line 56) | static void onhup(int sig)
function ReloadCheck (line 61) | void ReloadCheck()
function onusr2 (line 81) | static void onusr2(int sig)
function block_sigpipe (line 102) | static int8_t block_sigpipe(void)
function test_list_files (line 126) | static bool test_list_files()
function is_interface_online (line 148) | static bool is_interface_online(const char *ifname)
function get_default_ttl (line 162) | static int get_default_ttl(void)
function exithelp_clean (line 293) | static void exithelp_clean(void)
function exit_clean (line 298) | static void exit_clean(int code)
function nextbind_clean (line 303) | static void nextbind_clean(void)
function checkbind_clean (line 312) | static void checkbind_clean(void)
function save_default_ttl (line 322) | void save_default_ttl(void)
function parse_httpreqpos (line 335) | static bool parse_httpreqpos(const char *s, struct proto_pos *sp)
function parse_tlspos (line 351) | static bool parse_tlspos(const char *s, struct proto_pos *sp)
function parse_int16 (line 373) | static bool parse_int16(const char *p, int16_t *v)
function parse_posmarker (line 383) | static bool parse_posmarker(const char *opt, uint8_t *posmarker)
function parse_split_pos (line 403) | static bool parse_split_pos(char *opt, struct proto_pos *split)
function parse_split_pos_list (line 427) | static bool parse_split_pos_list(char *opt, struct proto_pos *splits, in...
function SplitDebug (line 445) | static void SplitDebug(void)
function wf_make_l3 (line 460) | static bool wf_make_l3(char *opt, bool *ipv4, bool *ipv6)
function parse_l7_list (line 484) | static bool parse_l7_list(char *opt, uint32_t *l7)
function parse_pf_list (line 510) | static bool parse_pf_list(char *opt, struct port_filters_head *pfl)
function parse_domain_list (line 533) | static bool parse_domain_list(char *opt, hostlist_pool **pp)
function parse_ip_list (line 553) | static bool parse_ip_list(char *opt, ipset *pp)
function parse_uid (line 573) | static bool parse_uid(const char *opt, uid_t *uid, gid_t *gid, int *gid_...
function config_from_file (line 604) | void config_from_file(const char *filename)
function check_oob_disorder (line 630) | static bool check_oob_disorder(const struct desync_profile *dp)
type opt_indices (line 639) | enum opt_indices {
type option (line 732) | struct option
function parse_params (line 825) | void parse_params(int argc, char *argv[])
function find_listen_addr (line 1727) | static bool find_listen_addr(struct sockaddr_storage *salisten, const ch...
function read_system_maxfiles (line 1780) | static bool read_system_maxfiles(rlim_t *maxfile)
function write_system_maxfiles (line 1804) | static bool write_system_maxfiles(rlim_t maxfile)
function set_ulimit (line 1824) | static bool set_ulimit(void)
type salisten_s (line 1865) | struct salisten_s
function main (line 1890) | int main(int argc, char *argv[])
FILE: tpws/tpws_conn.c
function notify_ready (line 32) | static void notify_ready(void)
function print_legs (line 54) | static void print_legs(void)
function socks5_send_rep (line 60) | static bool socks5_send_rep(int fd,uint8_t rep)
function socks5_send_rep_errno (line 69) | static bool socks5_send_rep_errno(int fd,int errn)
function socks4_send_rep (line 88) | static bool socks4_send_rep(int fd, uint8_t rep)
function socks4_send_rep_errno (line 95) | static bool socks4_send_rep_errno(int fd, int errn)
function socks_send_rep (line 99) | static bool socks_send_rep(uint8_t ver, int fd, uint8_t rep5)
function socks_send_rep_errno (line 103) | static bool socks_send_rep_errno(uint8_t ver, int fd, int errn)
function cork (line 109) | static bool cork(int fd, int enable)
function send_with_ttl (line 124) | ssize_t send_with_ttl(int fd, const void *buf, size_t len, int flags, in...
function send_buffer_create (line 144) | static bool send_buffer_create(send_buffer_t *sb, const void *data, size...
function send_buffer_realloc (line 164) | static bool send_buffer_realloc(send_buffer_t *sb, size_t extra_bytes)
function send_buffer_free (line 183) | static void send_buffer_free(send_buffer_t *sb)
function send_buffers_free (line 188) | static void send_buffers_free(send_buffer_t *sb_array, int count)
function conn_free_buffers (line 193) | static void conn_free_buffers(tproxy_conn_t *conn)
function send_buffer_present (line 197) | static bool send_buffer_present(send_buffer_t *sb)
function send_buffers_present (line 201) | static bool send_buffers_present(send_buffer_t *sb_array, int count)
function send_buffer_send (line 208) | static ssize_t send_buffer_send(send_buffer_t *sb, int fd)
function send_buffers_send (line 226) | static ssize_t send_buffers_send(send_buffer_t *sb_array, int count, int...
function conn_in_tcp_mode (line 250) | static bool conn_in_tcp_mode(tproxy_conn_t *conn)
function conn_partner_alive (line 255) | static bool conn_partner_alive(tproxy_conn_t *conn)
function conn_buffers_present (line 259) | static bool conn_buffers_present(tproxy_conn_t *conn)
function conn_buffers_send (line 263) | static ssize_t conn_buffers_send(tproxy_conn_t *conn)
function conn_has_unsent (line 270) | static bool conn_has_unsent(tproxy_conn_t *conn)
function conn_bytes_unread (line 274) | static int conn_bytes_unread(tproxy_conn_t *conn)
function conn_has_unsent_pair (line 280) | static bool conn_has_unsent_pair(tproxy_conn_t *conn)
function conn_shutdown (line 285) | static bool conn_shutdown(tproxy_conn_t *conn)
function send_or_buffer (line 296) | static ssize_t send_or_buffer(send_buffer_t *sb, int fd, const void *buf...
function dbgprint_socket_buffers (line 312) | static void dbgprint_socket_buffers(int fd)
function set_socket_buffers (line 327) | bool set_socket_buffers(int fd, int rcvbuf, int sndbuf)
function proxy_remote_conn_ack (line 345) | static bool proxy_remote_conn_ack(tproxy_conn_t *conn, int sock_err)
function set_user_timeout (line 367) | static void set_user_timeout(int fd, int timeout)
function connect_remote (line 392) | static int connect_remote(const struct sockaddr *remote_addr, int mss)
function connect_remote_conn (line 493) | static bool connect_remote_conn(tproxy_conn_t *conn)
function free_conn (line 525) | static void free_conn(tproxy_conn_t *conn)
function tproxy_conn_t (line 540) | static tproxy_conn_t *new_conn(int fd, bool remote)
function epoll_set (line 569) | static bool epoll_set(tproxy_conn_t *conn, uint32_t events)
function epoll_del (line 585) | static bool epoll_del(tproxy_conn_t *conn)
function epoll_update_flow (line 600) | static bool epoll_update_flow(tproxy_conn_t *conn)
function epoll_set_flow (line 613) | static bool epoll_set_flow(tproxy_conn_t *conn, bool bFlowIn, bool bFlow...
function tproxy_conn_t (line 622) | static tproxy_conn_t* add_tcp_connection(int efd, struct tailhead *conn_...
function check_connection_attempt (line 726) | static bool check_connection_attempt(tproxy_conn_t *conn, int efd)
function epoll_set_flow_pair (line 771) | static bool epoll_set_flow_pair(tproxy_conn_t *conn)
function handle_unsent (line 788) | static bool handle_unsent(tproxy_conn_t *conn)
function proxy_mode_connect_remote (line 836) | static bool proxy_mode_connect_remote(tproxy_conn_t *conn, struct tailhe...
function handle_proxy_mode (line 889) | static bool handle_proxy_mode(tproxy_conn_t *conn, struct tailhead *conn...
function resolve_complete (line 1074) | static bool resolve_complete(struct resolve_item *ri, struct tailhead *c...
function in_tamper_out_range (line 1110) | static bool in_tamper_out_range(tproxy_conn_t *conn)
function tamper (line 1125) | static void tamper(tproxy_conn_t *conn, uint8_t *segment, size_t segment...
function send_oob (line 1144) | static ssize_t send_oob(int fd, uint8_t *buf, size_t len, int ttl, bool ...
function report_segfail (line 1164) | static void report_segfail(void)
function handle_epoll (line 1180) | static bool handle_epoll(tproxy_conn_t *conn, struct tailhead *conn_list...
function remove_closed_connections (line 1348) | static bool remove_closed_connections(int efd, struct tailhead *close_list)
function close_tcp_conn (line 1368) | static void close_tcp_conn(struct tailhead *conn_list, struct tailhead *...
function read_all_and_buffer (line 1379) | static bool read_all_and_buffer(tproxy_conn_t *conn, int buffer_number)
function conn_timed_out (line 1411) | static bool conn_timed_out(tproxy_conn_t *conn)
function conn_close_timed_out (line 1421) | static void conn_close_timed_out(struct tailhead *conn_list, struct tail...
function conn_close_both (line 1440) | static void conn_close_both(struct tailhead *conn_list, struct tailhead ...
function conn_close_with_partner_check (line 1445) | static void conn_close_with_partner_check(struct tailhead *conn_list, st...
function handle_resolve_pipe (line 1459) | static bool handle_resolve_pipe(tproxy_conn_t **conn, struct tailhead *c...
function event_loop (line 1484) | int event_loop(const int *listen_fd, size_t listen_fd_ct)
FILE: tpws/tpws_conn.h
type conn_state_t (line 29) | typedef uint8_t conn_state_t;
type send_buffer (line 34) | struct send_buffer
type send_buffer_t (line 40) | typedef struct send_buffer send_buffer_t;
type conn_type_t (line 46) | typedef uint8_t conn_type_t;
type tproxy_conn (line 48) | struct tproxy_conn
type tproxy_conn_t (line 101) | typedef struct tproxy_conn tproxy_conn_t;
FILE: tpws/uthash.h
type UT_hash_bucket (line 1068) | typedef struct UT_hash_bucket {
type UT_hash_table (line 1092) | typedef struct UT_hash_table {
type UT_hash_handle (line 1125) | typedef struct UT_hash_handle {
Condensed preview — 235 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,058K chars).
[
{
"path": ".gitattributes",
"chars": 110,
"preview": "* text=auto eol=lf\n*.cmd eol=crlf\n*.bat eol=crlf\ninit.d/windivert.filter.examples/** eol=crlf\nfiles/** binary\n"
},
{
"path": ".github/ISSUE_TEMPLATE/config.yml",
"chars": 27,
"preview": "blank_issues_enabled: false"
},
{
"path": ".github/ISSUE_TEMPLATE/issue-warning.md",
"chars": 1837,
"preview": "---\nname: bugs\nabout: do not write lame questions\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\nIssues - это место для обраще"
},
{
"path": ".github/workflows/build.yml",
"chars": 17811,
"preview": "name: build\nrun-name: ${{ startsWith(github.ref, 'refs/tags/v') && format('Release {0}', github.ref_name) || null }}\n\non"
},
{
"path": ".github/workflows/libnetfilter_queue-android.patch",
"chars": 996,
"preview": "--- a/src/extra/pktbuff.c\n+++ b/src/extra/pktbuff.c\n@@ -14,7 +14,7 @@\n #include <string.h> /* for memcpy */\n #include <s"
},
{
"path": ".gitignore",
"chars": 192,
"preview": "/config\nip2net/ip2net\nmdig/mdig\nnfq/dvtws\nnfq/nfqws\nnfq/winws.exe\nnfq/WinDivert*\ntpws/tpws\nbinaries/my/\nipset/zapret-ip*"
},
{
"path": "Makefile",
"chars": 2129,
"preview": "DIRS := nfq tpws ip2net mdig\nDIRS_MAC := tpws ip2net mdig\nTGT := binaries/my\n\nall:\tclean\n\t@mkdir -p \"$(TGT)\"; \\\n\tfor dir"
},
{
"path": "blockcheck.sh",
"chars": 64327,
"preview": "#!/bin/sh\n\nEXEDIR=\"$(dirname \"$0\")\"\nEXEDIR=\"$(cd \"$EXEDIR\"; pwd)\"\nZAPRET_BASE=${ZAPRET_BASE:-\"$EXEDIR\"}\nZAPRET_RW=${ZAPR"
},
{
"path": "common/base.sh",
"chars": 8135,
"preview": "which()\n{\n\t# on some systems 'which' command is considered deprecated and not installed by default\n\t# 'command -v' repla"
},
{
"path": "common/custom.sh",
"chars": 643,
"preview": "custom_runner()\n{\n\t# $1 - function name\n\t# $2+ - params\n\n\t[ \"$DISABLE_CUSTOM\" = 1 ] && return 0\n\n\tlocal n script FUNC=$1"
},
{
"path": "common/dialog.sh",
"chars": 1156,
"preview": "read_yes_no()\n{\n\t# $1 - default (Y/N)\n\tlocal A\n\tread A\n\t[ -z \"$A\" ] || ([ \"$A\" != \"Y\" ] && [ \"$A\" != \"y\" ] && [ \"$A\" != "
},
{
"path": "common/elevate.sh",
"chars": 530,
"preview": "require_root()\n{\n\tlocal exe preserve_env\n\techo \\* checking privileges\n\t[ $(id -u) -ne \"0\" ] && {\n\t\techo root is required"
},
{
"path": "common/fwtype.sh",
"chars": 929,
"preview": "linux_ipt_avail()\n{\n\texists iptables && exists ip6tables\n}\nlinux_maybe_iptables_fwtype()\n{\n\tlinux_ipt_avail && FWTYPE=ip"
},
{
"path": "common/installer.sh",
"chars": 18988,
"preview": "GET_LIST_PREFIX=/ipset/get_\n\nSYSTEMD_DIR=/lib/systemd\n[ -d \"$SYSTEMD_DIR\" ] || SYSTEMD_DIR=/usr/lib/systemd\n[ -d \"$SYSTE"
},
{
"path": "common/ipt.sh",
"chars": 11108,
"preview": "std_ports\nipt_connbytes=\"-m connbytes --connbytes-dir=original --connbytes-mode=packets --connbytes\"\nIPSET_EXCLUDE=\"-m s"
},
{
"path": "common/linux_daemons.sh",
"chars": 1025,
"preview": "standard_mode_tpws_socks()\n{\n\t# $1 - 1 - run, 0 - stop\n\tlocal opt\n\t[ \"$TPWS_SOCKS_ENABLE\" = 1 ] && {\n\t\topt=\"--port=$TPPO"
},
{
"path": "common/linux_fw.sh",
"chars": 1241,
"preview": "set_conntrack_liberal_mode()\n{\n\t[ -n \"$SKIP_CONNTRACK_LIBERAL_MODE\" ] || sysctl -w net.netfilter.nf_conntrack_tcp_be_lib"
},
{
"path": "common/linux_iphelper.sh",
"chars": 3918,
"preview": "# there's no route_localnet for ipv6\n# the best we can is to route to link local of the incoming interface\n# OUTPUT - ca"
},
{
"path": "common/list.sh",
"chars": 2227,
"preview": "HOSTLIST_MARKER=\"<HOSTLIST>\"\nHOSTLIST_NOAUTO_MARKER=\"<HOSTLIST_NOAUTO>\"\n\nfind_hostlists()\n{\n\t[ -n \"$HOSTLIST_BASE\" ] || "
},
{
"path": "common/nft.sh",
"chars": 21091,
"preview": "[ -n \"$ZAPRET_NFT_TABLE\" ] || ZAPRET_NFT_TABLE=zapret\nnft_connbytes=\"ct original packets\"\n\n# required for : nft -f -\ncre"
},
{
"path": "common/pf.sh",
"chars": 6401,
"preview": "PF_MAIN=\"/etc/pf.conf\"\nPF_ANCHOR_DIR=\"/etc/pf.anchors\"\nPF_ANCHOR_ZAPRET=\"$PF_ANCHOR_DIR/zapret\"\nPF_ANCHOR_ZAPRET_V4=\"$PF"
},
{
"path": "common/virt.sh",
"chars": 966,
"preview": "get_virt()\n{\n\tlocal vm s v UNAME\n\tUNAME=$(uname)\n\tcase \"$UNAME\" in\n\t\tLinux)\n\t\t\tif exists systemd-detect-virt; then\n\t\t\t\tv"
},
{
"path": "config.default",
"chars": 6083,
"preview": "# this file is included from init scripts\n# change values here\n\n# can help in case /tmp has not enough space\n#TMPDIR=/op"
},
{
"path": "docs/LICENSE.txt",
"chars": 1069,
"preview": "MIT License\n\nCopyright (c) 2016-2024 bol-van\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
},
{
"path": "docs/bsd.en.md",
"chars": 22977,
"preview": "## Table of contents\n\n- [Table of contents](#table-of-contents)\n- [Supported versions](#supported-versions)\n- [BSD featu"
},
{
"path": "docs/bsd.md",
"chars": 29084,
"preview": "# Настройка BSD-подобных систем\n\n* [Поддерживаемые версии](#поддерживаемые-версии)\n* [Особенности BSD систем](#особеннос"
},
{
"path": "docs/bsdfw.txt",
"chars": 5112,
"preview": "WAN=em0 LAN=em1\n\nFreeBSD IPFW :\n\nipfw delete 100\nipfw add 100 fwd 127.0.0.1,988 tcp from me to any 80,443 proto ip4 xm"
},
{
"path": "docs/changes.txt",
"chars": 16768,
"preview": "v1\n\nInitial release\n\nv2\n\nnfqws : command line options change. now using standard getopt.\nnfqws : added options for windo"
},
{
"path": "docs/compile/build_howto_openwrt.txt",
"chars": 2140,
"preview": "How to compile native programs for use in openwrt\n-------------------------------------------------\n\n1) Install required"
},
{
"path": "docs/compile/build_howto_unix.txt",
"chars": 239,
"preview": "debian,ubuntu :\n\napt install make gcc zlib1g-dev libcap-dev libnetfilter-queue-dev libmnl-dev libsystemd-dev\nmake -C /op"
},
{
"path": "docs/compile/build_howto_windows.txt",
"chars": 858,
"preview": "Windows x64\n\n1) Download latest cygwin for windows 7\n\ncurl -O https://www.cygwin.com/setup-x86_64.exe\nsetup-x86_64.exe -"
},
{
"path": "docs/compile/openwrt/package/zapret/ip2net/Makefile",
"chars": 552,
"preview": "#\n\ninclude $(TOPDIR)/rules.mk\n\nPKG_NAME:=ip2net\nPKG_RELEASE:=1\n\ninclude $(INCLUDE_DIR)/package.mk\n\ndefine Package/ip2net"
},
{
"path": "docs/compile/openwrt/package/zapret/ip2net/readme.txt",
"chars": 28,
"preview": "Copy \"ip2net\" folder here !\n"
},
{
"path": "docs/compile/openwrt/package/zapret/mdig/Makefile",
"chars": 538,
"preview": "#\n\ninclude $(TOPDIR)/rules.mk\n\nPKG_NAME:=mdig\nPKG_RELEASE:=1\n\ninclude $(INCLUDE_DIR)/package.mk\n\ndefine Package/mdig\n\tSE"
},
{
"path": "docs/compile/openwrt/package/zapret/mdig/readme.txt",
"chars": 26,
"preview": "Copy \"mdig\" folder here !\n"
},
{
"path": "docs/compile/openwrt/package/zapret/nfqws/Makefile",
"chars": 594,
"preview": "#\n\ninclude $(TOPDIR)/rules.mk\n\nPKG_NAME:=nfqws\nPKG_RELEASE:=1\n\ninclude $(INCLUDE_DIR)/package.mk\n\ndefine Package/nfqws\n\t"
},
{
"path": "docs/compile/openwrt/package/zapret/nfqws/readme.txt",
"chars": 25,
"preview": "Copy \"nfq\" folder here !\n"
},
{
"path": "docs/compile/openwrt/package/zapret/tpws/Makefile",
"chars": 563,
"preview": "#\n\ninclude $(TOPDIR)/rules.mk\n\nPKG_NAME:=tpws\nPKG_RELEASE:=1\n\ninclude $(INCLUDE_DIR)/package.mk\n\ndefine Package/tpws\n\tSE"
},
{
"path": "docs/compile/openwrt/package/zapret/tpws/readme.txt",
"chars": 26,
"preview": "Copy \"tpws\" folder here !\n"
},
{
"path": "docs/iptables.txt",
"chars": 2947,
"preview": "For window size changing :\n\niptables -t mangle -I PREROUTING -p tcp --sport 80 --tcp-flags SYN,ACK SYN,ACK -j NFQUEUE --"
},
{
"path": "docs/nftables.txt",
"chars": 1284,
"preview": "nftables test cheat sheet\nsimplified rules to test nfqws and tpws\n\n\nFor DNAT :\n\n# run tpws as user \"tpws\". its required "
},
{
"path": "docs/nftables_notes.txt",
"chars": 7973,
"preview": "nftables - это технология, пришедшая на замену iptables.\nВ ней собрали все, что относилось к различным iptables. А их не"
},
{
"path": "docs/quick_start.md",
"chars": 14059,
"preview": "# Быстрая настройка Linux/OpenWrt\n\n> [!CAUTION] \n> Не пишите в issue вопросы типа \"как скопировать файл\", \"как скачать\""
},
{
"path": "docs/quick_start_windows.md",
"chars": 13018,
"preview": "# Быстрая настройка Windows\n\nСпециально для тех, кто хочет побыстрее начать, но не хочет слишком углубляться в простыню "
},
{
"path": "docs/readme.en.md",
"chars": 103420,
"preview": "# SCAMMER WARNING\n\nThis software is free and open source under [MIT license](./LICENSE.txt).\nIf anyone demands you to do"
},
{
"path": "docs/readme.md",
"chars": 183604,
"preview": "# ВНИМАНИЕ, остерегайтесь мошенников\n\nzapret является свободным и open source.\nВсякий, кто понуждает вас скачивать zapre"
},
{
"path": "docs/redsocks.txt",
"chars": 8375,
"preview": "Данный мануал пишется не как копипастная инструкция, а как помощь уже соображающему.\nЕсли вы не знаете основ сетей, linu"
},
{
"path": "docs/windows.en.md",
"chars": 10151,
"preview": "### tpws\n\nUsing `WSL` (Windows subsystem for Linux) it's possible to run `tpws` in socks mode under rather new builds of"
},
{
"path": "docs/windows.md",
"chars": 17784,
"preview": "# Windows\n\n## tpws\n\nЗапуск tpws возможен только в Linux варианте под **WSL** _(Windows Subsystem for Linux)_.\nНативного"
},
{
"path": "docs/wireguard_iproute_openwrt.txt",
"chars": 32230,
"preview": "Данный мануал пишется не как копипастная инструкция, а как помощь уже соображающему.\r\nЕсли вы не знаете основ сетей, li"
},
{
"path": "files/huawei/E8372/run-zapret-hostlist",
"chars": 797,
"preview": "#!/system/bin/busybox sh\n\n# download hostlist from http(s) (need curl, its absent by default),\n# feed it to zapret. save"
},
{
"path": "files/huawei/E8372/run-zapret-ip",
"chars": 888,
"preview": "#!/system/bin/busybox sh\n\n# download hostlist from http(s) (need curl, its absent by default),\n# resolve to ip list, fee"
},
{
"path": "files/huawei/E8372/unzapret",
"chars": 418,
"preview": "#!/system/bin/busybox sh\n\nrule=\"PREROUTING -t nat -i br0 ! -d 192.168.0.0/16 -p tcp -m multiport --dports 80,443 -j REDI"
},
{
"path": "files/huawei/E8372/unzapret-ip",
"chars": 430,
"preview": "#!/system/bin/busybox sh\n\nrule=\"PREROUTING -t nat -i br0 -p tcp -m multiport --dports 80,443 -j tpws\"\niptables -C $rule "
},
{
"path": "files/huawei/E8372/zapret",
"chars": 630,
"preview": "#!/system/bin/busybox sh\n\n# $1 - additional parameters for nfqws\n\ninsmod /online/modules/unfuck_nfqueue.ko 2>/dev/null\n"
},
{
"path": "files/huawei/E8372/zapret-ip",
"chars": 979,
"preview": "#!/system/bin/busybox sh\n\n# $1 - ip list file. create individual rules for tpws redirection. ipset is not available\n\n[ -"
},
{
"path": "init.d/custom.d.examples.linux/10-keenetic-udp-fix",
"chars": 819,
"preview": "# This script fixes keenetic issue with nfqws generated udp packets\n# Keenetic uses proprietary ndmmark and does not mas"
},
{
"path": "init.d/custom.d.examples.linux/20-fw-extra",
"chars": 2254,
"preview": "# this custom script runs standard mode with extra firewall rules\n\n# config: use TPWS_ENABLE_OVERRIDE, NFQWS_ENABLE_OVER"
},
{
"path": "init.d/custom.d.examples.linux/50-dht4all",
"chars": 1177,
"preview": "# this custom script runs desync to DHT packets with udp payload length >=5 , without ipset/hostlist filtering\n# NOTE: @"
},
{
"path": "init.d/custom.d.examples.linux/50-discord-media",
"chars": 1500,
"preview": "# this custom script runs desync to all discord media packets\n# NOTE: @ih requires nft 1.0.1+ and updated kernel version"
},
{
"path": "init.d/custom.d.examples.linux/50-nfqws-ipset",
"chars": 5546,
"preview": "# this custom script demonstrates how to launch extra nfqws instance limited by ipset\n\n# can override in config :\nNFQWS_"
},
{
"path": "init.d/custom.d.examples.linux/50-quic4all",
"chars": 947,
"preview": "# this custom script runs desync to all IETF QUIC initials\n# NOTE: @ih requires nft 1.0.1+ and updated kernel version. i"
},
{
"path": "init.d/custom.d.examples.linux/50-stun4all",
"chars": 959,
"preview": "# this custom script runs desync to all stun packets\n# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's co"
},
{
"path": "init.d/custom.d.examples.linux/50-tpws-ipset",
"chars": 2759,
"preview": "# this custom script demonstrates how to launch extra tpws instance limited by ipset\n\n# can override in config :\nTPWS_MY"
},
{
"path": "init.d/custom.d.examples.linux/50-wg4all",
"chars": 1068,
"preview": "# this custom script runs desync to all wireguard handshake initiation packets\n# NOTE: this works for original wireguard"
},
{
"path": "init.d/macos/custom.d/.keep",
"chars": 0,
"preview": ""
},
{
"path": "init.d/macos/custom.d.examples/50-extra-tpws",
"chars": 871,
"preview": "# this script is an example describing how to run tpws on a custom port\n\nTPWS_OPT_EXTRA=${TPWS_OPT_EXTRA:---split-pos=2}"
},
{
"path": "init.d/macos/functions",
"chars": 4328,
"preview": "# init script functions library for macos\n\nZAPRET_BASE=${ZAPRET_BASE:-/opt/zapret}\nZAPRET_RW=${ZAPRET_RW:-\"$ZAPRET_BASE\""
},
{
"path": "init.d/macos/zapret",
"chars": 915,
"preview": "#!/bin/sh\n\nEXEDIR=\"$(dirname \"$0\")\"\nZAPRET_BASE=\"$EXEDIR/../..\"\nZAPRET_BASE=\"$(cd \"$ZAPRET_BASE\"; pwd)\"\n\n. \"$EXEDIR/func"
},
{
"path": "init.d/macos/zapret.plist",
"chars": 462,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "init.d/openrc/zapret",
"chars": 1486,
"preview": "#!/sbin/openrc-run\n\n# zapret openrc to sysv adapter\n# on some systems (alpine) for unknown reason non-openrc-run scripts"
},
{
"path": "init.d/openwrt/90-zapret",
"chars": 1736,
"preview": "#!/bin/sh\n\nZAPRET=/etc/init.d/zapret\n\ncheck_lan()\n{\n\tIS_LAN=\n\t[ -n \"$OPENWRT_LAN\" ] || OPENWRT_LAN=lan\n\tfor lan in $OPEN"
},
{
"path": "init.d/openwrt/custom.d/.keep",
"chars": 0,
"preview": ""
},
{
"path": "init.d/openwrt/firewall.zapret",
"chars": 236,
"preview": "SCRIPT=$(readlink /etc/init.d/zapret)\nif [ -n \"$SCRIPT\" ]; then\n EXEDIR=$(dirname \"$SCRIPT\")\n ZAPRET_BASE=$(readlink -f "
},
{
"path": "init.d/openwrt/functions",
"chars": 6907,
"preview": ". /lib/functions/network.sh\n\nZAPRET_BASE=${ZAPRET_BASE:-/opt/zapret}\nZAPRET_RW=${ZAPRET_RW:-\"$ZAPRET_BASE\"}\nZAPRET_CONFI"
},
{
"path": "init.d/openwrt/zapret",
"chars": 4369,
"preview": "#!/bin/sh /etc/rc.common\n\nUSE_PROCD=1\n# after network\nSTART=21\n\nmy_extra_command() {\n\tlocal cmd=\"$1\"\n\tlocal help=\"$2\"\n\n\t"
},
{
"path": "init.d/openwrt-minimal/readme.txt",
"chars": 1632,
"preview": "Minimal tpws startup script for low storage openwrt.\n\n--- openwrt with NFTABLES (22+)\n\nMake sure you are running openwrt"
},
{
"path": "init.d/openwrt-minimal/tpws/etc/config/tpws",
"chars": 240,
"preview": "config global defaults\n\toption user daemon\n\toption tpws /usr/bin/tpws\n\nconfig tpws\n\toption port 900\n\toption opt '--split"
},
{
"path": "init.d/openwrt-minimal/tpws/etc/firewall.user",
"chars": 907,
"preview": "DISABLE_IPV6=0\nTP_PORT=900\nTP_USER=daemon\n\nEXCLUDE4=\"10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16 127.0.0.0/8\""
},
{
"path": "init.d/openwrt-minimal/tpws/etc/init.d/tpws",
"chars": 610,
"preview": "#!/bin/sh /etc/rc.common\n\nTPWS_DEFAULT=/usr/bin/tpws\nTPWS_USER_DEFAULT=daemon\n\nSTART=99\nSTOP=01\nUSE_PROCD=1\n\ntpws_instan"
},
{
"path": "init.d/openwrt-minimal/tpws/etc/nftables.d/90-tpws.nft",
"chars": 710,
"preview": "set tpws_exclude4 {\n\ttype ipv4_addr; flags interval; auto-merge;\n elements = { 10.0.0.0/8,172.16.0.0/12,192.168.0"
},
{
"path": "init.d/pfsense/zapret.sh",
"chars": 660,
"preview": "#!/bin/sh\n\n# this file should be placed to /usr/local/etc/rc.d and chmod 755\n\n# prepare system\n\nkldload ipfw\nkldload ipd"
},
{
"path": "init.d/runit/zapret/finish",
"chars": 46,
"preview": "#!/bin/sh\n/opt/zapret/init.d/sysv/zapret stop\n"
},
{
"path": "init.d/runit/zapret/run",
"chars": 83,
"preview": "#!/bin/sh\n/opt/zapret/init.d/sysv/zapret start\nexec chpst -b zapret sleep infinity\n"
},
{
"path": "init.d/s6/zapret/down",
"chars": 61,
"preview": "#!/bin/execlineb -P\nexec /opt/zapret/init.d/sysv/zapret stop\n"
},
{
"path": "init.d/s6/zapret/type",
"chars": 8,
"preview": "oneshot\n"
},
{
"path": "init.d/s6/zapret/up",
"chars": 62,
"preview": "#!/bin/execlineb -P\nexec /opt/zapret/init.d/sysv/zapret start\n"
},
{
"path": "init.d/systemd/nfqws@.service",
"chars": 1418,
"preview": "# Example systemd service unit for nfqws. Adjust for your installation.\n\n# WARNING ! This unit requires to compile nfqws"
},
{
"path": "init.d/systemd/tpws@.service",
"chars": 1372,
"preview": "# Example systemd service unit for tpws. Adjust for your installation.\n\n# WARNING ! This unit requires to compile tpws u"
},
{
"path": "init.d/systemd/zapret-list-update.service",
"chars": 223,
"preview": "[Unit]\nDescription=zapret ip/host list update\n\n[Service]\nRestart=no\nIgnoreSIGPIPE=no\nKillMode=control-group\nGuessMainPID"
},
{
"path": "init.d/systemd/zapret-list-update.timer",
"chars": 233,
"preview": "[Unit]\nDescription=zapret ip/host list update timer\n\n[Timer]\nOnCalendar=*-*-2,4,6,8,10,12,14,16,18,20,22,24,26,28,30 00:"
},
{
"path": "init.d/systemd/zapret.service",
"chars": 311,
"preview": "[Unit]\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=forking\nRestart=no\nTimeoutSec=30sec\nIgnor"
},
{
"path": "init.d/sysv/custom.d/.keep",
"chars": 0,
"preview": ""
},
{
"path": "init.d/sysv/functions",
"chars": 6023,
"preview": "# init script functions library for desktop linux systems\n\nZAPRET_BASE=${ZAPRET_BASE:-/opt/zapret}\nZAPRET_RW=${ZAPRET_RW"
},
{
"path": "init.d/sysv/zapret",
"chars": 1358,
"preview": "#!/bin/sh\n### BEGIN INIT INFO\n# Provides:\t\tzapret\n# Required-Start:\t$local_fs $network\n# Required-Stop:\t$local_fs $netwo"
},
{
"path": "init.d/windivert.filter.examples/README.txt",
"chars": 1158,
"preview": "Цель этих фильтров - отсекать полезную нагрузку в режиме ядра, не насилуя процессор перенаправлением целого потока на w"
},
{
"path": "init.d/windivert.filter.examples/windivert_part.discord_media.txt",
"chars": 553,
"preview": " outbound and ip and\r\n udp.DstPort>=50000 and udp.DstPort<=50099 and\r\n udp.PayloadLength=74 and\r\n udp.Payload32[0]=0"
},
{
"path": "init.d/windivert.filter.examples/windivert_part.quic_initial_ietf.txt",
"chars": 162,
"preview": " outbound and\r\n udp.PayloadLength>=256 and\r\n udp.Payload[0]>=0xC0 and udp.Payload[0]<0xD0 and\r\n udp.Payload[1]=0 and"
},
{
"path": "init.d/windivert.filter.examples/windivert_part.stun.txt",
"chars": 98,
"preview": " outbound and\r\n udp.PayloadLength>=20 and\r\n udp.Payload32[1]=0x2112A442 and udp.Payload[0]<0x40"
},
{
"path": "init.d/windivert.filter.examples/windivert_part.wireguard.txt",
"chars": 66,
"preview": " outbound and\r\n udp.PayloadLength=148 and\r\n udp.Payload[0]=0x01"
},
{
"path": "install_bin.sh",
"chars": 5166,
"preview": "#!/bin/sh\n\nEXEDIR=\"$(dirname \"$0\")\"\nEXEDIR=\"$(cd \"$EXEDIR\"; pwd)\"\nBINS=binaries\nBINDIR=\"$EXEDIR/$BINS\"\n\nZAPRET_BASE=${ZA"
},
{
"path": "install_easy.sh",
"chars": 23942,
"preview": "#!/bin/sh\n\n# automated script for easy installing zapret\n\nEXEDIR=\"$(dirname \"$0\")\"\nEXEDIR=\"$(cd \"$EXEDIR\"; pwd)\"\nZAPRET_"
},
{
"path": "install_prereq.sh",
"chars": 1041,
"preview": "#!/bin/sh\n\n# install prerequisites\n\nEXEDIR=\"$(dirname \"$0\")\"\nEXEDIR=\"$(cd \"$EXEDIR\"; pwd)\"\nZAPRET_BASE=${ZAPRET_BASE:-\"$"
},
{
"path": "ip2net/Makefile",
"chars": 860,
"preview": "CC ?= cc\nOPTIMIZE ?= -Os\nCFLAGS += -std=gnu99 $(OPTIMIZE) -flto=auto\nCFLAGS_BSD = -Wno-address-of-packed-member\nCFLAGS_W"
},
{
"path": "ip2net/ip2net.c",
"chars": 14937,
"preview": "// group ipv4/ipv6 list from stdout into subnets\n// each line must contain either ip or ip/bitcount\n// valid ip/bitcount"
},
{
"path": "ip2net/qsort.c",
"chars": 8393,
"preview": "/* Copyright (C) 1991-2018 Free Software Foundation, Inc.\n This file is part of the GNU C Library.\n Written by Dougl"
},
{
"path": "ip2net/qsort.h",
"chars": 233,
"preview": "#pragma once\n\n// GNU qsort is 2x faster than musl\n\ntypedef int (*__gnu_compar_d_fn_t) (const void *, const void *, void "
},
{
"path": "ipset/antifilter.helper",
"chars": 491,
"preview": "get_antifilter()\n{\n # $1 - list url\n # $2 - target file\n local ZIPLISTTMP=\"$TMPDIR/zapret-ip.txt\"\n\n [ \"$DISABLE_IPV4\" !="
},
{
"path": "ipset/clear_lists.sh",
"chars": 298,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\nrm -f \"$ZIPLIST\"* \"$Z"
},
{
"path": "ipset/create_ipset.sh",
"chars": 8187,
"preview": "#!/bin/sh\n\n# create ipset or ipfw table from resolved ip's\n# $1=no-update - do not update ipset, only create if its a"
},
{
"path": "ipset/def.sh",
"chars": 6619,
"preview": "EXEDIR=\"$(dirname \"$0\")\"\nEXEDIR=\"$(cd \"$EXEDIR\"; pwd)\"\nZAPRET_BASE=${ZAPRET_BASE:-\"$(cd \"$EXEDIR/..\"; pwd)\"}\nZAPRET_RW=$"
},
{
"path": "ipset/get_antifilter_allyouneed.sh",
"chars": 253,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\ngetuser && {\n . \"$IPS"
},
{
"path": "ipset/get_antifilter_ip.sh",
"chars": 245,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\ngetuser && {\n . \"$IPS"
},
{
"path": "ipset/get_antifilter_ipresolve.sh",
"chars": 252,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\ngetuser && {\n . \"$IPS"
},
{
"path": "ipset/get_antifilter_ipsmart.sh",
"chars": 253,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\ngetuser && {\n . \"$IPS"
},
{
"path": "ipset/get_antifilter_ipsum.sh",
"chars": 248,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\ngetuser && {\n . \"$IPS"
},
{
"path": "ipset/get_antizapret_domains.sh",
"chars": 743,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\n# useful in case ipba"
},
{
"path": "ipset/get_config.sh",
"chars": 269,
"preview": "#!/bin/sh\n# run script specified in config\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n[ -f \"$IPSE"
},
{
"path": "ipset/get_exclude.sh",
"chars": 165,
"preview": "#!/bin/sh\n# resolve user host list\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.s"
},
{
"path": "ipset/get_ipban.sh",
"chars": 174,
"preview": "#!/bin/sh\n# resolve only ipban user host list\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSE"
},
{
"path": "ipset/get_reestr_preresolved.sh",
"chars": 1081,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\nTMPLIST=\"$TMPDIR/list"
},
{
"path": "ipset/get_reestr_preresolved_smart.sh",
"chars": 1075,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\nTMPLIST=\"$TMPDIR/list"
},
{
"path": "ipset/get_reestr_resolvable_domains.sh",
"chars": 1034,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\nTMPLIST=\"$TMPDIR/list"
},
{
"path": "ipset/get_refilter_domains.sh",
"chars": 888,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\nTMPLIST=\"$TMPDIR/list"
},
{
"path": "ipset/get_refilter_ipsum.sh",
"chars": 804,
"preview": "#!/bin/sh\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.sh\"\n\nTMPLIST=\"$TMPDIR/list"
},
{
"path": "ipset/get_user.sh",
"chars": 162,
"preview": "#!/bin/sh\n# resolve user host list\n\nIPSET_DIR=\"$(dirname \"$0\")\"\nIPSET_DIR=\"$(cd \"$IPSET_DIR\"; pwd)\"\n\n. \"$IPSET_DIR/def.s"
},
{
"path": "ipset/zapret-hosts-user-exclude.txt.default",
"chars": 104,
"preview": "127.0.0.0/8\n10.0.0.0/8\n172.16.0.0/12\n192.168.0.0/16\n169.254.0.0/16\n100.64.0.0/10\n::1\nfc00::/7\nfe80::/10\n"
},
{
"path": "mdig/Makefile",
"chars": 910,
"preview": "CC ?= cc\nOPTIMIZE ?= -Os\nCFLAGS += -std=gnu99 $(OPTIMIZE)\nCFLAGS_BSD = -Wno-address-of-packed-member\nCFLAGS_WIN = -stati"
},
{
"path": "mdig/mdig.c",
"chars": 14854,
"preview": "// multi thread dns resolver\n// domain list <stdin\n// ip list >stdout\n// errors, verbose >stderr\n// transparent for vali"
},
{
"path": "nfq/BSDmakefile",
"chars": 252,
"preview": "CC ?= cc\nOPTIMIZE ?= -Os\nCFLAGS += -std=gnu99 -s $(OPTIMIZE) -flto=auto -Wno-address-of-packed-member\nLIBS = -lz\nSRC_FIL"
},
{
"path": "nfq/Makefile",
"chars": 1989,
"preview": "CC ?= cc\nOPTIMIZE ?= -Os\nCFLAGS += -std=gnu99 $(OPTIMIZE) -flto=auto -ffunction-sections -fdata-sections\nCFLAGS_SYSTEMD "
},
{
"path": "nfq/checksum.c",
"chars": 4288,
"preview": "#define _GNU_SOURCE\n#include \"checksum.h\"\n#include <netinet/in.h>\n\n//#define htonll(x) ((1==htonl(1)) ? (x) : ((uint64_t"
},
{
"path": "nfq/checksum.h",
"chars": 1269,
"preview": "#pragma once\n\n#include <stddef.h>\n#include <stdint.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n\n#define __FAVOR_BS"
},
{
"path": "nfq/conntrack.c",
"chars": 11447,
"preview": "#include \"conntrack.h\"\n#include \"darkmagic.h\"\n#include <arpa/inet.h>\n#include <stdio.h>\n\n#undef uthash_nonfatal_oom\n#def"
},
{
"path": "nfq/conntrack.h",
"chars": 5163,
"preview": "#pragma once\n\n\n// this conntrack is not bullet-proof\n// its designed to satisfy dpi desync needs only\n\n#include <stdbool"
},
{
"path": "nfq/crypto/aes-gcm.c",
"chars": 535,
"preview": "#include \"aes-gcm.h\"\n\nint aes_gcm_crypt(int mode, uint8_t *output, const uint8_t *input, size_t input_length, const uint"
},
{
"path": "nfq/crypto/aes-gcm.h",
"chars": 312,
"preview": "#pragma once\n\n#include \"gcm.h\" \n\n// mode : AES_ENCRYPT, AES_DECRYPT\nint aes_gcm_crypt(int mode, uint8_t *output, const "
},
{
"path": "nfq/crypto/aes.c",
"chars": 16399,
"preview": "/******************************************************************************\n*\n* THIS SOURCE CODE IS HEREBY PLACED IN"
},
{
"path": "nfq/crypto/aes.h",
"chars": 3385,
"preview": "/******************************************************************************\n*\n* THIS SOURCE CODE IS HEREBY PLACED IN"
},
{
"path": "nfq/crypto/gcm.c",
"chars": 19962,
"preview": "/******************************************************************************\n*\n* THIS SOURCE CODE IS HEREBY PLACED IN"
},
{
"path": "nfq/crypto/gcm.h",
"chars": 8345,
"preview": "/******************************************************************************\n*\n* THIS SOURCE CODE IS HEREBY PLACED IN"
},
{
"path": "nfq/crypto/hkdf.c",
"chars": 9936,
"preview": "/**************************** hkdf.c ***************************/\n/***************** See RFC 6234 for details. *********"
},
{
"path": "nfq/crypto/hmac.c",
"chars": 6935,
"preview": "/**************************** hmac.c ***************************/\n/***************** See RFC 6234 for details. *********"
},
{
"path": "nfq/crypto/sha-private.h",
"chars": 824,
"preview": "/************************ sha-private.h ************************/\n/***************** See RFC 6234 for details. *********"
},
{
"path": "nfq/crypto/sha.h",
"chars": 10614,
"preview": "/**************************** sha.h ****************************/\n/***************** See RFC 6234 for details. *********"
},
{
"path": "nfq/crypto/sha224-256.c",
"chars": 18067,
"preview": "/************************* sha224-256.c ************************/\n/***************** See RFC 6234 for details. *********"
},
{
"path": "nfq/crypto/usha.c",
"chars": 4593,
"preview": "/**************************** usha.c ***************************/\n/***************** See RFC 6234 for details. *********"
},
{
"path": "nfq/darkmagic.c",
"chars": 63761,
"preview": "#define _GNU_SOURCE\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n#include <arpa/inet."
},
{
"path": "nfq/darkmagic.h",
"chars": 9298,
"preview": "#pragma once\n\n#include \"nfqws.h\"\n#include \"checksum.h\"\n#include \"packet_queue.h\"\n#include \"pools.h\"\n\n#include <stdint.h>"
},
{
"path": "nfq/desync.c",
"chars": 120976,
"preview": "#define _GNU_SOURCE\n\n#include <string.h>\n#include <errno.h>\n\n#include \"desync.h\"\n#include \"protocol.h\"\n#include \"params."
},
{
"path": "nfq/desync.h",
"chars": 1403,
"preview": "#pragma once\n\n#include \"darkmagic.h\"\n\n#include <stdint.h>\n#include <stdbool.h>\n\n#define __FAVOR_BSD\n#include <netinet/ip"
},
{
"path": "nfq/gzip.c",
"chars": 1440,
"preview": "#include \"gzip.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#define ZCHUNK 16384\n#define BUFMIN 128\n#d"
},
{
"path": "nfq/gzip.h",
"chars": 145,
"preview": "#pragma once\n\n#include <stdio.h>\n#include <zlib.h>\n#include <stdbool.h>\n\nint z_readfile(FILE *F,char **buf,size_t *size)"
},
{
"path": "nfq/helpers.c",
"chars": 11290,
"preview": "#define _GNU_SOURCE\n\n#include \"helpers.h\"\n\n#include <stdio.h>\n#include <string.h>\n#include <unistd.h>\n#include <stdlib.h"
},
{
"path": "nfq/helpers.h",
"chars": 3725,
"preview": "#pragma once\n\n#include <arpa/inet.h>\n#include <netinet/in.h>\n#include <sys/socket.h>\n#include <stddef.h>\n#include <stdbo"
},
{
"path": "nfq/hostlist.c",
"chars": 8431,
"preview": "#include <stdio.h>\n#include \"hostlist.h\"\n#include \"gzip.h\"\n#include \"helpers.h\"\n\n// inplace tolower() and add to pool\nst"
},
{
"path": "nfq/hostlist.h",
"chars": 749,
"preview": "#pragma once\n\n#include <stdbool.h>\n#include \"pools.h\"\n#include \"params.h\"\n\nbool AppendHostlistItem(hostlist_pool **hostl"
},
{
"path": "nfq/ipset.c",
"chars": 7479,
"preview": "#include <stdio.h>\n#include \"ipset.h\"\n#include \"gzip.h\"\n#include \"helpers.h\"\n\n\n// inplace tolower() and add to pool\nstat"
},
{
"path": "nfq/ipset.h",
"chars": 463,
"preview": "#pragma once\n\n#include <stdbool.h>\n#include <arpa/inet.h>\n#include \"params.h\"\n#include \"pools.h\"\n\nbool LoadAllIpsets();\n"
},
{
"path": "nfq/kavl.h",
"chars": 13229,
"preview": "/* The MIT License\n\n Copyright (c) 2018 by Attractive Chaos <attractor@live.co.uk>\n\n Permission is hereby granted, f"
},
{
"path": "nfq/nfqws.c",
"chars": 109913,
"preview": "#define _GNU_SOURCE\n\n#include \"nfqws.h\"\n#include \"sec.h\"\n#include \"desync.h\"\n#include \"helpers.h\"\n#include \"checksum.h\"\n"
},
{
"path": "nfq/nfqws.h",
"chars": 165,
"preview": "#pragma once\n\n#include <stdbool.h>\n\n#ifdef __linux__\n#define HAS_FILTER_SSID 1\n#endif\n\n#ifdef __CYGWIN__\nextern bool bQu"
},
{
"path": "nfq/packet_queue.c",
"chars": 1512,
"preview": "#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n\n#include \"packet_queue.h\"\n\nvoid rawpacket_queue_init(struct "
},
{
"path": "nfq/packet_queue.h",
"chars": 913,
"preview": "#pragma once\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <sys/queue.h>\n#include <net/if.h>\n#include <sys/socket"
},
{
"path": "nfq/params.c",
"chars": 10093,
"preview": "#include \"params.h\"\n\n#include <stdarg.h>\n#include <syslog.h>\n#include <errno.h>\n#ifdef __ANDROID__\n#include <android/log"
},
{
"path": "nfq/params.h",
"chars": 8141,
"preview": "#pragma once\n\n#include \"nfqws.h\"\n#include \"pools.h\"\n#include \"conntrack.h\"\n#include \"desync.h\"\n#include \"protocol.h\"\n#in"
},
{
"path": "nfq/pools.c",
"chars": 19537,
"preview": "#define _GNU_SOURCE\n#include \"pools.h\"\n#include <string.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <arpa/inet.h>"
},
{
"path": "nfq/pools.h",
"chars": 7039,
"preview": "#pragma once\n\n#include <stdbool.h>\n#include <ctype.h>\n#include <sys/queue.h>\n#include <net/if.h>\n#include <time.h>\n\n#inc"
},
{
"path": "nfq/protocol.c",
"chars": 29992,
"preview": "#define _GNU_SOURCE\n\n#include \"protocol.h\"\n#include \"helpers.h\"\n#include \"params.h\"\n\n#include <string.h>\n#include <ctype"
},
{
"path": "nfq/protocol.h",
"chars": 4683,
"preview": "#pragma once\n\n#include <stddef.h>\n#include <stdint.h>\n#include <stdbool.h>\n#include \"crypto/sha.h\"\n#include \"crypto/aes-"
},
{
"path": "nfq/sec.c",
"chars": 8022,
"preview": "#define _GNU_SOURCE\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"sec.h\"\n#include <unistd.h>\n#include <fcntl.h>\n#inc"
},
{
"path": "nfq/sec.h",
"chars": 2416,
"preview": "#pragma once\n\n#include <sys/types.h>\n#include <stdbool.h>\n\n#ifdef __linux__\n\n#include <stddef.h>\n#include <sys/capabilit"
},
{
"path": "nfq/uthash.h",
"chars": 73785,
"preview": "/*\nCopyright (c) 2003-2021, Troy D. Hanson http://troydhanson.github.io/uthash/\nAll rights reserved.\n\nRedistribution"
},
{
"path": "nfq/win.c",
"chars": 1926,
"preview": "#ifdef __CYGWIN__\n\n#include <windows.h>\n\n#include \"win.h\"\n#include \"nfqws.h\"\n\n#define SERVICE_NAME \"winws\"\n\nstatic SERVI"
},
{
"path": "nfq/win.h",
"chars": 106,
"preview": "#pragma once\n\n#ifdef __CYGWIN__\n\n#include <stdbool.h>\n\nbool service_run(int argc, char *argv[]);\n\n#endif\n\n"
},
{
"path": "nfq/windows/windivert/windivert.h",
"chars": 20041,
"preview": "/*\n * windivert.h\n * (C) 2019, all rights reserved,\n *\n * This file is part of WinDivert.\n *\n * WinDivert is free softwa"
},
{
"path": "tmp/.keep",
"chars": 0,
"preview": ""
},
{
"path": "tpws/BSDmakefile",
"chars": 261,
"preview": "CC ?= cc\nOPTIMIZE ?= -Os\nCFLAGS += -std=gnu99 -s $(OPTIMIZE) -flto=auto\nLIBS = -lz -lpthread\nSRC_FILES = *.c\n\nall: tpws\n"
},
{
"path": "tpws/Makefile",
"chars": 1421,
"preview": "CC ?= cc\nOPTIMIZE ?= -Os\nCFLAGS += -std=gnu99 $(OPTIMIZE) -flto=auto -ffunction-sections -fdata-sections\nCFLAGS_SYSTEMD "
},
{
"path": "tpws/andr/_musl_license.txt",
"chars": 1357,
"preview": "Code in this dir is taken from musl libc to support old android versions <7.0\n\nmusl as a whole is licensed under the fol"
},
{
"path": "tpws/andr/getifaddrs.c",
"chars": 6153,
"preview": "#define _GNU_SOURCE\n#include <errno.h>\n#include <string.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <ifaddrs.h>\n"
},
{
"path": "tpws/andr/ifaddrs.h",
"chars": 139,
"preview": "#pragma once\n\n#include <ifaddrs.h>\n\n#if __ANDROID_API__ < 24\nvoid freeifaddrs(struct ifaddrs *);\nint getifaddrs(struct i"
},
{
"path": "tpws/andr/netlink.c",
"chars": 1377,
"preview": "#include <errno.h>\n#include <string.h>\n#include <syscall.h>\n#include <sys/socket.h>\n#include <unistd.h>\n\n#include \"netli"
},
{
"path": "tpws/andr/netlink.h",
"chars": 2288,
"preview": "#include <stdint.h>\n\n/* linux/netlink.h */\n\n#define NETLINK_ROUTE 0\n\nstruct nlmsghdr {\n\tuint32_t\tnlmsg_len;\n\tuint16_t\tnl"
},
{
"path": "tpws/epoll-shim/include/sys/epoll.h",
"chars": 1593,
"preview": "#ifndef\tSHIM_SYS_EPOLL_H\n#define\tSHIM_SYS_EPOLL_H\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#include <stdint.h>\n#include "
},
{
"path": "tpws/epoll-shim/src/epoll.c",
"chars": 6407,
"preview": "#include <sys/epoll.h>\n\n#include <sys/event.h>\n#include <sys/param.h>\n#include <sys/stat.h>\n#include <sys/time.h>\n\n#incl"
},
{
"path": "tpws/epoll-shim/src/epoll_shim_ctx.c",
"chars": 5546,
"preview": "#include \"epoll_shim_ctx.h\"\n\n#include <sys/event.h>\n\n#include <assert.h>\n#include <errno.h>\n#include <limits.h>\n#include"
},
{
"path": "tpws/epoll-shim/src/epoll_shim_ctx.h",
"chars": 2039,
"preview": "#ifndef EPOLL_SHIM_CTX_H_\n#define EPOLL_SHIM_CTX_H_\n\n#include \"fix.h\"\n\n#include <sys/tree.h>\n\n#include <unistd.h>\n\n#incl"
},
{
"path": "tpws/epoll-shim/src/epollfd_ctx.c",
"chars": 32065,
"preview": "#include \"epollfd_ctx.h\"\n\n#include <sys/types.h>\n\n#if defined(__FreeBSD__)\n#include <sys/capsicum.h>\n#endif\n#include <sy"
},
{
"path": "tpws/epoll-shim/src/epollfd_ctx.h",
"chars": 2112,
"preview": "#ifndef EPOLLFD_CTX_H_\n#define EPOLLFD_CTX_H_\n\n#include \"fix.h\"\n\n#define SHIM_SYS_SHIM_HELPERS\n#include <sys/epoll.h>\n\n#"
},
{
"path": "tpws/epoll-shim/src/eventfd_ctx.h",
"chars": 682,
"preview": "#ifndef EVENTFD_CTX_H_\n#define EVENTFD_CTX_H_\n\n#include \"fix.h\"\n\n#include <stdbool.h>\n#include <stdint.h>\n#include <stdl"
},
{
"path": "tpws/epoll-shim/src/fix.c",
"chars": 428,
"preview": "#include \"fix.h\"\r\n\r\n#ifdef __APPLE__\r\n\r\n#include <errno.h>\r\n\r\nint ppoll(struct pollfd *fds, nfds_t nfds,const struct tim"
},
{
"path": "tpws/epoll-shim/src/fix.h",
"chars": 370,
"preview": "#pragma once\n\n#ifndef _ERRNO_T_DEFINED\n#define _ERRNO_T_DEFINED\ntypedef int errno_t;\n#endif\n\n#ifdef __APPLE__\n\n#include "
},
{
"path": "tpws/epoll-shim/src/signalfd_ctx.h",
"chars": 395,
"preview": "#ifndef SIGNALFD_CTX_H_\n#define SIGNALFD_CTX_H_\n\n#include \"fix.h\"\n\n#include <signal.h>\n#include <stdint.h>\n#include <std"
},
{
"path": "tpws/epoll-shim/src/timerfd_ctx.h",
"chars": 918,
"preview": "#ifndef TIMERFD_CTX_H_\n#define TIMERFD_CTX_H_\n\n#include \"fix.h\"\n\n#include <stdatomic.h>\n#include <stdbool.h>\n#include <s"
},
{
"path": "tpws/gzip.c",
"chars": 1440,
"preview": "#include \"gzip.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#define ZCHUNK 16384\n#define BUFMIN 128\n#d"
},
{
"path": "tpws/gzip.h",
"chars": 145,
"preview": "#pragma once\n\n#include <stdio.h>\n#include <zlib.h>\n#include <stdbool.h>\n\nint z_readfile(FILE *F,char **buf,size_t *size)"
},
{
"path": "tpws/helpers.c",
"chars": 14247,
"preview": "#define _GNU_SOURCE\n\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#include <ctype.h>\n#include <errno.h>\n#i"
},
{
"path": "tpws/helpers.h",
"chars": 4020,
"preview": "#pragma once\n\n#include <stddef.h>\n#include <stdbool.h>\n#include <netinet/in.h>\n#include <sys/socket.h>\n#include <netdb.h"
},
{
"path": "tpws/hostlist.c",
"chars": 8459,
"preview": "#include <stdio.h>\n#include \"hostlist.h\"\n#include \"gzip.h\"\n#include \"helpers.h\"\n\n// inplace tolower() and add to pool\nst"
}
]
// ... and 35 more files (download for full content)
About this extraction
This page contains the full source code of the bol-van/zapret GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 235 files (1.8 MB), approximately 584.4k tokens, and a symbol index with 1685 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.