meow_netmgrd 期2:观测层(PID→实体归因+连接普查)+DNS 代理+事件日志+连接/DNS IPC 与 CLI
NETMGR_DESIGN.md 期2范围落地(全在 patch_v2/meow_netmgrd/ + meow_ipc.h 追加):
- 连接普查(§4):每 2s 解析 /proc/net/{tcp,udp}(IPv4) → socket inode→pid(由 inode 集驱动扫
/proc/<pid>/fd,不逐 pid 盲扫)→ 三实体归因 app:<pkg>(amsd status)/svc:<svc>(svcd 落盘状态
/tmp/meow_svcd.status,socket 查询兜底)/proc:<comm>(无则 proc:unknown)。连接表静态 ≤512:
entity/五元组/状态/寿命;远端 IP 由 DNS 缓存反查域名。
- DNS 代理(§5):监听 127.0.0.1:53 UDP;启动备份 resolv.conf 写双行(127.0.0.1+原上游,崩溃零断流);
透传转发+缓存(TTL 尊重;≤256 条);按源端口(port→entity)归因;域名规则 per-entity+global allow/deny
(deny→NXDOMAIN+日志);atexit/SIGTERM/SIGHUP 恢复;5s 自检被第三方改回即重写;HibyOS 绝不启用/绝不改 resolv。
DNS wire(deny NXDOMAIN / forward→A+cache / NXDOMAIN id 回显) 宿主+qemu 实测 PASS。
- 事件日志(§8):新连接/关闭/dns deny/接口状态变化;同 entity 同 dst 1 分钟去重(首条+计数)。
- IPC meow_ipc.h 追加 0x00E8 CONNS_REQ/RESULT、0x00EC DNS_CTL/RESULT(纯追加不改既有行;
0x00EA 策略(期3)/0x00EE 事件推送(预留) 保留)。
- CLI meow_net 补 apps / conns [entity] / top(2s 刷新) / dns status|stats|flush。
- 内存:静态表禁 malloc,mipsel bss 228KB → RSS≈374KB,≤600KB 目标 / ≤1MB 预算。
宿主编译 -Wall -Wextra 0 warning;test_netmgrd.sh 48/48(宿主+qemu)、test_netmgrd_p2 全过(宿主+qemu)、
netmgrd_authtest 全过;真机(M6.0/0.8.0)只读实测 apps/conns/dns status 正确
(svc:meowpanel/svc:mdnsd/proc:dropbear 真实三实体归因),resolv.conf 测后核验原值未触碰。
This commit is contained in:
1 parent
239345bfd2
commit
52edf0c9e4
8 files changed
+1400
-8
No files matched your search
@@ -564,4 +564,41 @@ typedef struct m_net_cmd_result {
|
||||
char text[MEOW_IPC_MAX - 8];
|
||||
} m_net_cmd_result_t;
|
||||
|
||||
/* ---- 期 2:观测层(连接普查)+ DNS 代理(NETMGR_DESIGN §4/§5)----
|
||||
* 0x00E8/0x00EC 实现取代上方「0x00E8-0x00EF 保留」注释中的连接表/DNS 控制两项;
|
||||
* 0x00EA(策略读写,期3)/0x00EE(事件推送,期2 订阅制预留)仍保留未实装。 */
|
||||
enum { /* 与主 enum 分列,追加式不改既有行 */
|
||||
MSG_NET_CONNS_REQ = 0x00E8, /* ↑ 连接表查询(entity 空=全部) */
|
||||
MSG_NET_CONNS_RESULT = 0x00E9, /* ↓ 连接表文本(定长行;超帧截断标记) */
|
||||
MSG_NET_DNS_CTL = 0x00EC, /* ↑ dns status|stats|flush */
|
||||
MSG_NET_DNS_RESULT = 0x00ED /* ↓ 结果/统计文本 */
|
||||
/* 0x00EA 策略读写(期3)/ 0x00EE 事件推送(预留,期2 订阅制)/ 0xEB、0xEF 余量 */
|
||||
};
|
||||
|
||||
/* MSG_NET_CONNS_REQ ↑:entity 前缀过滤(空=全部)。entity 形如 `app:<pkg>`/`svc:<svc>`/`proc:<comm>`。 */
|
||||
typedef struct m_net_conns_req {
|
||||
char entity[48];
|
||||
} m_net_conns_req_t; /* 48 B */
|
||||
|
||||
/* MSG_NET_CONNS_RESULT ↓:连接表文本(每行 `entity|lip:lport|rip:rport|state|age_s|domain`)。
|
||||
* 超单帧上限时截断并置 truncated=1(app/top 由客户端按行聚合,容纳全部)。 */
|
||||
typedef struct m_net_conns_result {
|
||||
uint32_t code; /* MEOW_OK / MEOW_ERR_* */
|
||||
uint16_t text_len;
|
||||
uint16_t truncated; /* 1=被截断 */
|
||||
char text[MEOW_IPC_MAX - 8];
|
||||
} m_net_conns_result_t;
|
||||
|
||||
/* MSG_NET_DNS_CTL ↑:cmd=status|stats|flush。status/stats 读级任意;flush(清缓存)为动作级系统身份。 */
|
||||
typedef struct m_net_dns_ctl {
|
||||
char cmd[16];
|
||||
} m_net_dns_ctl_t; /* 16 B */
|
||||
|
||||
typedef struct m_net_dns_result {
|
||||
uint32_t code;
|
||||
uint16_t text_len;
|
||||
uint16_t pad;
|
||||
char text[MEOW_IPC_MAX - 8];
|
||||
} m_net_dns_result_t;
|
||||
|
||||
#endif /* MEOW_IPC_H */
|
||||
Binary file not shown.
File diff suppressed because it is too large.
Load diff
Binary file not shown.
Binary file not shown.
@@ -37,6 +37,19 @@ EOF
|
||||
printf 'nameserver 223.5.5.5\nnameserver 10.78.193.1\n' > "$T/resolv"
|
||||
echo meow > "$T/boot_mode"
|
||||
|
||||
# ---- 期2 观测层打桩:/proc/net/{tcp,udp}(IPv4 LE hex)+ 域名规则 conf + amsd/svcd 缺省 ----
|
||||
cat > "$T/tcp" <<'EOF'
|
||||
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
|
||||
0: 32C14E0A:5137 0905CD8C:01BB 01 00000000:00000000 00:00000000 00000000 1000 0 12345 1 0 0 10 0
|
||||
1: 32C14E0A:4F32 32C34E0A:01BB 01 00000000:00000000 00:00000000 00000000 1000 0 12346 1 0 0 10 0
|
||||
2: 32C14E0A:0A00 00000000:0000 07 00000000:00000000 00:00000000 00000000 1000 0 67890 1 0 0 10 0
|
||||
EOF
|
||||
cat > "$T/udp" <<'EOF'
|
||||
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
|
||||
0: 0100007F:D301 0100007F:0035 07 00000000:00000000 00:00000000 00000000 0 0 99999 1 0 0 10 0
|
||||
EOF
|
||||
printf 'app:dev.player.ncm domain=-ads.example.com\nproc:dropbear domain=+x\n' > "$T/policy"
|
||||
|
||||
# 桩后端命令(popen stubbing)
|
||||
cat > "$T/wpa_cli" <<'EOF'
|
||||
#!/bin/sh
|
||||
@@ -75,10 +88,13 @@ EOF
|
||||
for f in wpa_cli hciconfig bluetoothctl ip; do chmod +x "$T/$f"; done
|
||||
|
||||
mkdir -p "$T/logs" "$T/pid"
|
||||
# 期2:DNS 禁用(宿主无 root 不绑 53),观测层经 MEOW_TCP/UDP 打桩;amsd/svcd 缺省(实体归因走 proc:comm→unknown)。
|
||||
ENVS="MEOW_NET_DIR=$NET MEOW_NETDEV=$T/netdev MEOW_NET_ROUTE=$T/route MEOW_RESOLV=$T/resolv
|
||||
MEOW_RFKILL_DIR=$RF MEOW_BT_DIR=$BT MEOW_BOOT_MODE=$T/boot_mode MEOW_BOOTTS_CACHE=$T/bootts
|
||||
MEOW_IP=$T/ip MEOW_WPA_CLI=$T/wpa_cli MEOW_HCICONFIG=$T/hciconfig MEOW_BLUETOOTHCTL=$T/bluetoothctl
|
||||
MEOW_NET_SOCK=$T/net.sock MEOW_NET_POLL_SEC=1 MEOW_LOG_DIR=$T/logs"
|
||||
MEOW_NET_SOCK=$T/net.sock MEOW_NET_POLL_SEC=1 MEOW_LOG_DIR=$T/logs
|
||||
MEOW_TCP=$T/tcp MEOW_UDP=$T/udp MEOW_NET_POLICY=$T/policy
|
||||
MEOW_AMS_SOCK=$T/no_ams MEOW_SVCD_SOCK=$T/no_svcd MEOW_DNS_DISABLE=1"
|
||||
ln -sf "$(readlink -f "$BIN")" "$T/meow_net" # argv[0] 双形态 → CLI
|
||||
|
||||
# ---- T0: 守护起 ----
|
||||
@@ -159,6 +175,95 @@ ck T9a "usage: meow_net" "$OUT"
|
||||
OUT=$(env $ENVS $Q "$T/meow_net" bogus 2>&1); RC=$?
|
||||
ck T9b "usage: meow_net" "$OUT"
|
||||
|
||||
# ---- 重启 daemon A(T8 已停)供期2 观测/连接表/日志测试 ----
|
||||
env $ENVS $Q "$BIN" --sock "$T/net.sock" >"$T/daemon2.log" 2>&1 &
|
||||
DPID=$!
|
||||
for i in $(seq 1 30); do [ -S "$T/net.sock" ] && break; sleep 0.2; done
|
||||
[ -S "$T/net.sock" ] || { echo "FAIL T10-pre: daemon 未重启"; cat "$T/daemon2.log"; exit 1; }
|
||||
|
||||
# ---- T10: 期2 conns(读级;观测层经 MEOW_TCP/UDP 桩 + amsd/svcd 缺省 → proc:unknown 归因)----
|
||||
sleep 1 # 等守护普查一拍
|
||||
OUT=$(env $ENVS $Q "$T/meow_net" conns 2>&1)
|
||||
ck T10a "proc:unknown" "$OUT"
|
||||
ck T10b "10.78.193.50:20791" "$OUT"
|
||||
ck T10b2 "140.205.5.9:443" "$OUT"
|
||||
ck T10c "ESTAB" "$OUT"
|
||||
ck T10d "UDP" "$OUT"
|
||||
ck T10e "connection" "$OUT"
|
||||
# ---- T11: apps(实体聚合)----
|
||||
OUT=$(env $ENVS $Q "$T/meow_net" apps 2>&1)
|
||||
ck T11a "entity" "$OUT"
|
||||
ck T11b "proc:unknown" "$OUT"
|
||||
# ---- T12: dns status/stats(DNS 禁用 → 显示 disabled)----
|
||||
OUT=$(env $ENVS $Q "$T/meow_net" dns status 2>&1)
|
||||
ck T12a "proxy disabled" "$OUT"
|
||||
OUT=$(env $ENVS $Q "$T/meow_net" dns stats 2>&1)
|
||||
ck T12b "proxy disabled" "$OUT"
|
||||
# ---- T13: dns flush(写级;宿主 CLI=CALL_OTHER → 拒)----
|
||||
OUT=$(env $ENVS $Q "$T/meow_net" dns flush 2>&1)
|
||||
ck T13a "permission denied" "$OUT"
|
||||
|
||||
# ---- T14: DNS 代理 wire 实测(守护 B:高端口 + 桩上游 + 全局 deny;测 deny/forward/cache)----
|
||||
HOSTIP=$(hostname -I 2>/dev/null | awk '{print $1}')
|
||||
[ -n "$HOSTIP" ] || HOSTIP="127.0.0.1"
|
||||
cat > "$T/policy_dns" <<'EOF'
|
||||
global domain=-ads.example.com
|
||||
EOF
|
||||
printf 'nameserver %s\n' "$HOSTIP" > "$T/resolv_dns"
|
||||
cat > "$T/dns_test.py" <<'PYEOF'
|
||||
import socket, struct, threading, sys, os
|
||||
UP_IP = os.environ.get("T_UP_IP", "0.0.0.0")
|
||||
up = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
up.bind((UP_IP, 5311)) # 0.0.0.0 通配,绑到宿主自身 IP
|
||||
up.settimeout(6)
|
||||
def serve():
|
||||
try:
|
||||
while True:
|
||||
d,a = up.recvfrom(1536)
|
||||
off=12
|
||||
while d[off]!=0: off += 1+d[off]
|
||||
off += 1+4
|
||||
qsec = d[12:off]
|
||||
resp = d[:2] + b'\x81\x80' + b'\x00\x01\x00\x01\x00\x00\x00\x00' + qsec
|
||||
resp += b'\xc0\x0c' + b'\x00\x01\x00\x01' + struct.pack('>I',60) + b'\x00\x04' + socket.inet_aton('11.22.33.44')
|
||||
up.sendto(resp, a)
|
||||
except Exception:
|
||||
pass
|
||||
threading.Thread(target=serve, daemon=True).start()
|
||||
def query(name):
|
||||
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM); s.settimeout(3)
|
||||
hdr=b'\x12\x34'+b'\x01\x00'+b'\x00\x01\x00\x00\x00\x00\x00\x00'
|
||||
q=b''.join(bytes([len(l)])+l.encode() for l in name.split('.'))+b'\x00'+b'\x00\x01\x00\x01'
|
||||
s.sendto(hdr+q, ("127.0.0.1", 5300))
|
||||
r,_=s.recvfrom(1536); rco=r[3]&0xf; an=struct.unpack('>H',r[6:8])[0]
|
||||
return rco,an
|
||||
try:
|
||||
d1,a1 = query("ads.example.com") # deny → NXDOMAIN (rcode 3)
|
||||
d2,a2 = query("music.163.com") # allow → forward → A 11.22.33.44
|
||||
sys.stdout.write("DENY_RCODE=%d\nALLOW_AN=%d\n" % (d1, a2))
|
||||
except Exception as e:
|
||||
sys.stdout.write("ERR=%s\n" % e)
|
||||
PYEOF
|
||||
# 追加式覆写(env 左→右,后者胜出):DNS 启用、换独立 socket/resolv/policy、上游端口。
|
||||
DNSENV="$ENVS MEOW_DNS_DISABLE=0 MEOW_NET_SOCK=$T/dns.sock MEOW_RESOLV=$T/resolv_dns
|
||||
MEOW_NET_POLICY=$T/policy_dns MEOW_DNS_PORT=5300 MEOW_DNS_UPSTREAM_PORT=5311"
|
||||
ln -sf "$(readlink -f "$BIN")" "$T/dns_netmgrd"
|
||||
env $DNSENV $Q "$BIN" --sock "$T/dns.sock" >"$T/dnsd.log" 2>&1 &
|
||||
D2PID=$!
|
||||
for i in $(seq 1 30); do [ -S "$T/dns.sock" ] && break; sleep 0.2; done
|
||||
sleep 1
|
||||
OUT=$(env $DNSENV $Q "$T/meow_net" dns status 2>&1)
|
||||
ck T14a "enabled=1 upstream=$HOSTIP" "$OUT"
|
||||
WIRE=$(python3 "$T/dns_test.py" 2>&1)
|
||||
ck T14b "DENY_RCODE=3" "$WIRE"
|
||||
ck T14c "ALLOW_AN=1" "$WIRE"
|
||||
OUT=$(env $DNSENV $Q "$T/meow_net" dns stats 2>&1)
|
||||
ck T14d "q=2" "$OUT"
|
||||
ck T14e "deny=1" "$OUT"
|
||||
kill $D2PID 2>/dev/null; wait $D2PID 2>/dev/null
|
||||
# 恢复守护 A 的 MEOW_RESOLV(其未被 DNS 触碰,此处确认)
|
||||
grep -q "nameserver 223.5.5.5" "$T/resolv" && { PASS=$((PASS+1)); echo "PASS T14f daemonA resolv untouched"; } || { FAIL=$((FAIL+1)); echo "FAIL T14f daemonA resolv touched"; }
|
||||
|
||||
echo "=============================="
|
||||
echo "PASS=$PASS FAIL=$FAIL"
|
||||
[ $FAIL -eq 0 ]
|
||||
Executable
BIN
Binary file not shown.
@@ -0,0 +1,213 @@
|
||||
/* test_netmgrd_p2.c — meow_netmgrd 期2 观测层/DNS 代理 纯逻辑宿主自测(本程序非生产代码)。
|
||||
*
|
||||
* 通过 #include 生产源文件(meow_netmgrd.c,用 #define main 改名避免入口冲突),同一 TU 直接访问
|
||||
* FILE-STATIC 函数/全局:dns_parse_query / dns_build_nxdomain / dns_cache_* / suffix_match /
|
||||
* rules_load / dns_query_domain_denied / pid_ent_put / entity_for_pid / parse_proc_net /
|
||||
* build_conns_text / build_dns_ctl_text / dns_cache_from_response / hex_ip / ip_fmt。
|
||||
* 覆盖 DNS wire 编解码、缓存 TTL、域名规则判定、实体归因(app/svc/proc:comm)、/proc/net 解析、
|
||||
* 连接表文本构建。真实 amsd/svcd socket + /proc/<pid>/fd 归因留真机验证。
|
||||
*
|
||||
* 用法:cc -Wall -Wextra -I../meow_launcherd test_netmgrd_p2.c -o test_netmgrd_p2 && ./test_netmgrd_p2
|
||||
*/
|
||||
#define main meow_netmgrd_prod_main_unused
|
||||
#include "meow_netmgrd.c"
|
||||
#undef main
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int g_fail = 0;
|
||||
#define CHECK(cond) do { if (!(cond)) { printf(" FAIL: %s (line %d)\n", #cond, __LINE__); g_fail++; } \
|
||||
else { printf(" ok : %s\n", #cond); } } while (0)
|
||||
|
||||
static void wf(const char *p, const char *s)
|
||||
{
|
||||
FILE *f = fopen(p, "w");
|
||||
if (f) { fputs(s, f); fclose(f); }
|
||||
}
|
||||
|
||||
static int make_query(const char *name, uint8_t *out)
|
||||
{
|
||||
memset(out, 0, 16);
|
||||
out[0] = 0x12; out[1] = 0x34; /* id */
|
||||
out[2] = 0x01; out[3] = 0x00; /* RD */
|
||||
out[4] = 0; out[5] = 1; /* qdcount=1 */
|
||||
int off = 12;
|
||||
const char *p = name;
|
||||
while (*p) {
|
||||
const char *dot = strchr(p, '.');
|
||||
size_t l = dot ? (size_t)(dot - p) : strlen(p);
|
||||
out[off++] = (uint8_t)l;
|
||||
memcpy(out + off, p, l); off += (int)l;
|
||||
p = dot ? dot + 1 : p + l;
|
||||
}
|
||||
out[off++] = 0;
|
||||
out[off++] = 0; out[off++] = 1; /* qtype=A */
|
||||
out[off++] = 0; out[off++] = 1; /* qclass=IN */
|
||||
return off;
|
||||
}
|
||||
|
||||
static int make_a_response(const char *name, const char *ip, uint8_t *out)
|
||||
{
|
||||
int ql = make_query(name, out);
|
||||
out[0] = 0x12; out[1] = 0x34;
|
||||
out[2] = 0x81; out[3] = 0x80; /* QR|RD|RA */
|
||||
out[6] = 0; out[7] = 1; /* ancount=1 */
|
||||
int off = ql;
|
||||
out[off++] = 0xC0; out[off++] = 0x0C; /* answer name pointer → offset 12 (question) */
|
||||
out[off++] = 0; out[off++] = 1; /* type A */
|
||||
out[off++] = 0; out[off++] = 1; /* class IN */
|
||||
out[off++] = 0; out[off++] = 0; out[off++] = 0; out[off++] = 0x3C; /* ttl=60 */
|
||||
out[off++] = 0; out[off++] = 4; /* rdlen=4 */
|
||||
int b0 = 0, b1 = 0, b2 = 0, b3 = 0;
|
||||
sscanf(ip, "%d.%d.%d.%d", &b0, &b1, &b2, &b3);
|
||||
out[off++] = (uint8_t)b0; out[off++] = (uint8_t)b1;
|
||||
out[off++] = (uint8_t)b2; out[off++] = (uint8_t)b3;
|
||||
return off;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
static const char *T = "/tmp/nmg_p2";
|
||||
char path[192];
|
||||
mkdir(T, 0755);
|
||||
uint8_t q[256], r[512];
|
||||
|
||||
printf("== dns_parse_query ==\n");
|
||||
{
|
||||
int ql = make_query("music.163.com", q);
|
||||
char dom[DNS_QNAME_MAX]; int qend = 0;
|
||||
CHECK(dns_parse_query(q, ql, dom, sizeof dom, &qend) == 0);
|
||||
CHECK(strcmp(dom, "music.163.com") == 0);
|
||||
CHECK(qend == ql);
|
||||
}
|
||||
printf("== dns_build_nxdomain ==\n");
|
||||
{
|
||||
int ql = make_query("ads.example.com", q);
|
||||
uint8_t resp[300];
|
||||
int rl = dns_build_nxdomain(q, ql, resp, sizeof resp);
|
||||
CHECK(rl > 12);
|
||||
CHECK((resp[2] & 0x80) != 0); /* QR */
|
||||
CHECK((resp[3] & 0x0f) == 3); /* NXDOMAIN */
|
||||
CHECK(resp[0] == 0x12 && resp[1] == 0x34); /* id echoed */
|
||||
}
|
||||
printf("== dns_cache insert/lookup/flush (TTL 尊重) ==\n");
|
||||
{
|
||||
dns_cache_flush();
|
||||
CHECK(dns_cache_insert("music.163.com", 0x0A4EC132, 60) == 0);
|
||||
char out[64];
|
||||
CHECK(dns_cache_lookup_ip(0x0A4EC132, out, sizeof out) == 0);
|
||||
CHECK(strcmp(out, "music.163.com") == 0);
|
||||
CHECK(dns_cache_lookup_name("music.163.com") == 0);
|
||||
CHECK(dns_cache_lookup_name("absent.com") != 0);
|
||||
dns_cache_flush();
|
||||
CHECK(dns_cache_lookup_name("music.163.com") != 0);
|
||||
}
|
||||
printf("== dns_cache_from_response(A 记录抓取)==\n");
|
||||
{
|
||||
dns_cache_flush();
|
||||
int rl = make_a_response("music.163.com", "39.164.0.12", r);
|
||||
dns_cache_from_response(r, rl);
|
||||
char out[64];
|
||||
CHECK(dns_cache_lookup_ip(0x27A4000C, out, sizeof out) == 0);
|
||||
CHECK(strcmp(out, "music.163.com") == 0);
|
||||
}
|
||||
printf("== suffix_match / rules_load / dns_query_domain_denied ==\n");
|
||||
{
|
||||
CHECK(suffix_match("ads.example.com", "example.com") == 1);
|
||||
CHECK(suffix_match("sub.ads.example.com", "ads.example.com") == 1);
|
||||
CHECK(suffix_match("example.com", "ads.example.com") == 0);
|
||||
snprintf(path, sizeof path, "%s/policy", T);
|
||||
wf(path, "# test\napp:dev.player.ncm domain=-ads.example.com,-tracker.net\nproc:dropbear domain=+k,l\n\n");
|
||||
g_net_policy[0] = 0; snprintf(g_net_policy, sizeof g_net_policy, "%s", path);
|
||||
rules_load();
|
||||
CHECK(g_rule_n >= 2);
|
||||
CHECK(dns_query_domain_denied("app:dev.player.ncm", "ads.example.com") == 1);
|
||||
CHECK(dns_query_domain_denied("app:dev.player.ncm", "sub.ads.example.com") == 1);
|
||||
CHECK(dns_query_domain_denied("app:dev.player.ncm", "music.163.com") == 0);
|
||||
CHECK(dns_query_domain_denied("proc:dropbear", "k") == 0); /* allow 覆盖 */
|
||||
CHECK(dns_query_domain_denied("proc:dropbear", "l") == 1); /* deny */
|
||||
CHECK(dns_query_domain_denied("proc:other", "ads.example.com") == 0); /* 无实体规则 → 默认 allow */
|
||||
}
|
||||
printf("== refresh_entity_maps(svcd 落盘状态文件 → svc: 实体)==\n");
|
||||
{
|
||||
snprintf(path, sizeof path, "%s/svcd.status", T);
|
||||
wf(path, "# meow_svcd status\ncard_present=1 wifi_up=1 services=2\n"
|
||||
"svc=meowpanel state=running pid=1038 restart=0 exit=0 trigger=boot backoff_ms=2000\n"
|
||||
"svc=meow_mdns state=running pid=1006 restart=0 exit=0 trigger=boot backoff_ms=2000\n");
|
||||
g_svcd_status[0] = 0; snprintf(g_svcd_status, sizeof g_svcd_status, "%s", path);
|
||||
g_svcd_sock[0] = 0; snprintf(g_svcd_sock, sizeof g_svcd_sock, "%s/none.sock", T);
|
||||
g_ams_sock[0] = 0; snprintf(g_ams_sock, sizeof g_ams_sock, "%s/none.sock", T);
|
||||
g_pid_ent_n = 0;
|
||||
refresh_entity_maps();
|
||||
char ent[48];
|
||||
entity_for_pid(1038, ent, sizeof ent);
|
||||
CHECK(strcmp(ent, "svc:meowpanel") == 0);
|
||||
entity_for_pid(1006, ent, sizeof ent);
|
||||
CHECK(strcmp(ent, "svc:meow_mdns") == 0);
|
||||
}
|
||||
printf("== pid_ent_put / entity_for_pid(app/svc/proc:comm)==\n");
|
||||
{
|
||||
g_pid_ent_n = 0;
|
||||
pid_ent_put(123, "app:dev.player.ncm");
|
||||
pid_ent_put(456, "svc:meowpanel");
|
||||
char ent[48];
|
||||
entity_for_pid(123, ent, sizeof ent);
|
||||
CHECK(strcmp(ent, "app:dev.player.ncm") == 0);
|
||||
entity_for_pid(456, ent, sizeof ent);
|
||||
CHECK(strcmp(ent, "svc:meowpanel") == 0);
|
||||
/* proc:<comm>:造一个 /proc-format comm 不可能,直接读当前 pid comm(非空即入 proc:) */
|
||||
int self = (int)getpid();
|
||||
snprintf(path, sizeof path, "/proc/%d/comm", self);
|
||||
if (access(path, F_OK) == 0) {
|
||||
entity_for_pid(self, ent, sizeof ent);
|
||||
CHECK(strncmp(ent, "proc:", 5) == 0);
|
||||
}
|
||||
}
|
||||
printf("== parse_proc_net(IPv4 地址/端口/inode)==\n");
|
||||
{
|
||||
snprintf(path, sizeof path, "%s/tcp", T);
|
||||
wf(path, " sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode\n"
|
||||
" 0: 32C14E0A:5137 0905CD8C:01BB 01 00000000:00000000 00:00000000 00000000 1000 0 12345 1\n"
|
||||
" 1: 32C14E0A:0A00 00000000:0000 07 00000000:00000000 00:00000000 00000000 1000 0 67890 1\n");
|
||||
g_proc_tcp[0] = 0; snprintf(g_proc_tcp, sizeof g_proc_tcp, "%s", path);
|
||||
static conn_t cur[CONN_MAX];
|
||||
int n = 0;
|
||||
CHECK(parse_proc_net(g_proc_tcp, 0, cur, &n) == 2);
|
||||
CHECK(cur[0].local_port == 0x5137 && cur[0].remote_port == 0x01BB);
|
||||
CHECK(cur[0].inode == 12345 && cur[0].state_code == 1);
|
||||
char ip[32];
|
||||
ip_fmt(cur[0].local_ip, ip, sizeof ip);
|
||||
CHECK(strcmp(ip, "10.78.193.50") == 0);
|
||||
ip_fmt(cur[0].remote_ip, ip, sizeof ip);
|
||||
CHECK(strcmp(ip, "140.205.5.9") == 0);
|
||||
}
|
||||
printf("== build_conns_text / build_dns_ctl_text ==\n");
|
||||
{
|
||||
g_conn_n = 0;
|
||||
conn_t c;
|
||||
memset(&c, 0, sizeof c);
|
||||
c.local_ip = hex_ip("32C14E0A"); c.local_port = 443; /* 10.78.193.50 */
|
||||
c.remote_ip = hex_ip("32C34E0A"); c.remote_port = 25565; /* 10.78.195.50 */
|
||||
c.state_code = 1; c.type = 0; c.inode = 555; c.pid = 12345;
|
||||
snprintf(c.entity, sizeof c.entity, "app:dev.player.ncm");
|
||||
snprintf(c.domain, sizeof c.domain, "music.163.com");
|
||||
c.mono_open = mono_now(); c.last_seen = mono_now();
|
||||
g_conn[g_conn_n++] = c;
|
||||
char out[512]; int tr = 0;
|
||||
int len = build_conns_text(NULL, out, sizeof out, &tr);
|
||||
CHECK(len > 0 && tr == 0);
|
||||
CHECK(strstr(out, "app:dev.player.ncm|10.78.193.50:443|10.78.195.50:25565|ESTAB|0|music.163.com") != NULL);
|
||||
char dout[256];
|
||||
CHECK(build_dns_ctl_text("status", dout, sizeof dout) == MEOW_OK);
|
||||
CHECK(strstr(dout, "dns mode=") != NULL);
|
||||
CHECK(build_dns_ctl_text("flush", dout, sizeof dout) == MEOW_OK);
|
||||
}
|
||||
|
||||
if (g_fail) { printf("\nNETMGR P2 TEST: %d FAIL\n", g_fail); return 1; }
|
||||
printf("\nNETMGR P2 TEST: ALL PASS\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user