mirror of
https://github.com/okhsunrog/vpnhide.git
synced 2026-04-30 23:52:00 +00:00
The kernel module, zygisk, lsposed-native, and the LSPosed Kotlin module each had their own hand-written list of VPN interface name prefixes, and the four had drifted: kmod/zygisk/HookEntry knew utun/l2tp/gre while lsposed-native and DiagnosticsScreen only knew tun/wg/ppp/tap/ ipsec/xfrm. So the self-test could PASS while the hooks were actually hiding more interfaces. Move the rules to data/interfaces.toml and render four matchers from it via scripts/codegen-interfaces.py — one per language target. A new lint job re-runs the codegen and fails if anything drifts. The match grammar is intentionally tiny so each codegen target implements it without depending on regex (kernel C can't): exact / prefix / prefix+digits / contains. Side effect: native diagnostics now agree with the hooks, so the self-test in DiagnosticsScreen will recognize utun*, l2tp*, gre* and *vpn* substrings as VPN tunnels (previously it would silently PASS on those). The /proc/net/route check also moved from raw substring to whitespace-tokenized matching, which avoids matching VPN-prefix substrings that show up by chance inside hex-encoded IP addresses. Existing zygisk filter unit tests still pass unchanged — public API of is_vpn_iface_bytes / is_vpn_iface_cstr is preserved, only the body now delegates to the generated matches_vpn(). Cargo.lock files updated incidentally (synced with Cargo.toml versions that were already 0.7.1 in the manifests).
110 lines
2.7 KiB
C
110 lines
2.7 KiB
C
/* AUTO-GENERATED from data/interfaces.toml — do not edit by hand. Regenerate with: python3 scripts/codegen-interfaces.py */
|
|
#ifndef VPNHIDE_GENERATED_IFACE_LISTS_H
|
|
#define VPNHIDE_GENERATED_IFACE_LISTS_H
|
|
|
|
#include <linux/string.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/types.h>
|
|
|
|
static inline bool vpnhide_iface_starts_with_ci(
|
|
const char *name, const char *prefix)
|
|
{
|
|
size_t i;
|
|
for (i = 0; prefix[i]; i++) {
|
|
if (!name[i])
|
|
return false;
|
|
if (tolower((unsigned char)name[i]) !=
|
|
(unsigned char)prefix[i])
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static inline bool vpnhide_iface_starts_with_then_digits_ci(
|
|
const char *name, const char *prefix)
|
|
{
|
|
size_t i;
|
|
if (!vpnhide_iface_starts_with_ci(name, prefix))
|
|
return false;
|
|
i = strlen(prefix);
|
|
if (!name[i])
|
|
return false;
|
|
for (; name[i]; i++)
|
|
if (name[i] < '0' || name[i] > '9')
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
static inline bool vpnhide_iface_equals_ci(
|
|
const char *name, const char *other)
|
|
{
|
|
size_t i;
|
|
for (i = 0; other[i]; i++) {
|
|
if (!name[i])
|
|
return false;
|
|
if (tolower((unsigned char)name[i]) !=
|
|
(unsigned char)other[i])
|
|
return false;
|
|
}
|
|
return name[i] == '\0';
|
|
}
|
|
|
|
static inline bool vpnhide_iface_contains_ci(
|
|
const char *name, const char *needle)
|
|
{
|
|
size_t nlen = strlen(needle);
|
|
size_t i, j;
|
|
if (nlen == 0)
|
|
return true;
|
|
for (i = 0; name[i]; i++) {
|
|
for (j = 0; j < nlen; j++) {
|
|
if (!name[i + j])
|
|
return false;
|
|
if (tolower((unsigned char)name[i + j]) !=
|
|
(unsigned char)needle[j])
|
|
break;
|
|
}
|
|
if (j == nlen)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static inline bool vpnhide_iface_is_vpn(const char *name)
|
|
{
|
|
if (!name || !name[0])
|
|
return false;
|
|
/* OpenVPN, WireGuard userspace, Tailscale, generic tunneling */
|
|
if (vpnhide_iface_starts_with_ci(name, "tun"))
|
|
return true;
|
|
/* OpenVPN bridged */
|
|
if (vpnhide_iface_starts_with_ci(name, "tap"))
|
|
return true;
|
|
/* WireGuard kernel */
|
|
if (vpnhide_iface_starts_with_ci(name, "wg"))
|
|
return true;
|
|
/* PPTP / L2TP PPP tunnels */
|
|
if (vpnhide_iface_starts_with_ci(name, "ppp"))
|
|
return true;
|
|
/* Android built-in IPsec VPN */
|
|
if (vpnhide_iface_starts_with_ci(name, "ipsec"))
|
|
return true;
|
|
/* kernel IPsec XFRM framework */
|
|
if (vpnhide_iface_starts_with_ci(name, "xfrm"))
|
|
return true;
|
|
/* Apple-style, rare on Android */
|
|
if (vpnhide_iface_starts_with_ci(name, "utun"))
|
|
return true;
|
|
/* L2TP */
|
|
if (vpnhide_iface_starts_with_ci(name, "l2tp"))
|
|
return true;
|
|
/* GRE tunnels */
|
|
if (vpnhide_iface_starts_with_ci(name, "gre"))
|
|
return true;
|
|
/* catch-all for renamed clients (myvpn0, vpn-client, xvpn1, ...) */
|
|
if (vpnhide_iface_contains_ci(name, "vpn"))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
#endif /* VPNHIDE_GENERATED_IFACE_LISTS_H */
|