Files
MeowOS 8a43f17653 meow_netmgrd 期4:SDK 自愿通道 + wifi forget + RSSI signal_poll + AAAA 过滤 + iptables 评估
NETMGR_DESIGN.md §7/§13 期4 落地(只动 patch_v2/meow_netmgrd/ + patch_v2/sdk/ 追加式):
1. SDK 自愿通道(§6.3/§4):meow_ui.h 新增 meow_net_policy_check(host)(0=放行 1=block;
   netmgrd 不在/超时→0 乐观放行)+ meow_net_report(rx,tx)(自愿上报,§4 字节级记账自报通道)。
   meow_ipc.h 追加 0xEE MSG_NET_SDK(op=CHECK/REPORT)/ 0xEF RESULT。netmgrd 侧:CHECK 以
   app_id→实体 app:<pkg> 评估 policy_net_blocked||dns_query_domain_denied;REPORT 记入 per-实体
   g_ent_bytes(status JSON 新增 entity_bytes)。SDK 实现 meow_net_ipc.c(一次 connect+send+read,
   降级不崩);meow_ui.a 重编。
2. wifi forget <id>:wpa_cli remove_network+save_config(MeowOS;HibyOS 只读门控),CLI+IPC 接通
   (286 launcher 录入 UI 缺口)。
3. RSSI:wifi_status 在 status 无 signal= 时回退 wpa_cli signal_poll(真机 rssi=-38,修面板 rssi=null 缺口)。
4. DNS AAAA 过滤:global dns.filter_aaaa=0|1(默认 0 透传;纯 IPv4 设备可置 1 让 AAAA 查询回空答案回落 A)。
5. 静态 iptables 评估(devdocs/plan/NETMGR_IPTABLES_EVAL.md,本机不入库):iptables-legacy 1.8.9 交叉
   编译成功(~578KB,含 owner/cgroup/REDIRECT 等全部 extension),但内核实测 matches 仅
   quota/icmp/udp/tcp、targets 仅 NFQUEUE/NFLOG/ERROR、无 nat 表、全部进程 UID 0 → **per-app 管控
   与 REDIRECT 透明代理判不可行**(与 NETWORK_HW_FACTS 一致);正路为 per-app UID 框架改造(单独立项)。

验证:宿主 test_netmgrd.sh 70/70 + qemu 70/70;test_netmgrd_p2/p3/p5 宿主全过 + 交叉 0 warning;
netmgrd_authtest 全过;sdk meow_net_ipc 交叉 0 warning。真机(固件 netmgrd 共存,独立 socket+DNS off):
wifi status rssi=-38(signal_poll)、wifi forget 0(DISABLED 安全移除,id1 CURRENT 保留、wifi 未断)、
SDK policy check(CHECK_GOOD=0/CHECK_BLOCK=1/REPORT ok)、policy show 正常;resolv.conf 未触碰、
固件 meow_netmgrd(pid) running 未动;测试产物全清。

新 md5:meow_netmgrd 20243ea1a800b29badefebb395603aaf;meow_ui.a be24214e24faadba63577f3a98c2c9d1
(主会话更 fw_content.conf / 热更设备 / 记录新 meow_ui.a)。
2026-09-02 16:19:40 +08:00

111 lines
4.9 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* test_netmgrd_p5.c — meow_netmgrd 期4 纯逻辑宿主自测(非生产代码)。
*
* 通过 #include 生产源,同一 TU 直接访问 FILE-STATIC:wifi_status / dns_parse_query /
* rules_load / wifi_ctl_execute / g_dns_filter_aaaa / g_policy_log_level / policy_cmd。
* 覆盖:①wifi status 缺 signal= 时回退 signal_poll 取 RSSI(面板 rssi=null 缺口修复)
* ②dns_parse_query 解析 QTYPE(A=1/AAAA=28,供 AAAA 过滤)③global dns.filter_aaaa 配置加载
* ④wifi forget(remove_network + save_config,MeowOS)⑤策略引擎回归(net/domain/防自锁)。
*
* 用法:cc -Wall -Wextra -I../meow_launcherd test_netmgrd_p5.c -o test_netmgrd_p5 && ./test_netmgrd_p5
*/
#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);} }
int main(void)
{
static const char *T = "/tmp/nmg_p5";
char path[256];
mkdir(T, 0755);
printf("== wifi_status:status 无 signal= 回退 signal_poll ==\n");
snprintf(path, sizeof path, "%s/wpa_st", T);
wf(path, "#!/bin/sh\n"
"if [ \"$1\" = \"status\" ]; then echo 'wpa_state=COMPLETED'; echo 'ssid=MyWiFi'; echo 'ip_address=10.78.193.50'; fi\n"
"if [ \"$1\" = \"signal_poll\" ]; then echo 'RSSI=-56'; echo 'LINKSPEED=54'; fi\n"
"exit 0\n");
chmod(path, 0755);
g_wpa_cli = ""; { static char w[192]; snprintf(w,sizeof w,"%s",path); g_wpa_cli=w; }
wifi_t w;
wifi_status(&w);
CHECK(w.has_rssi == 1);
CHECK(w.rssi == -56);
CHECK(w.connected == 1 && strcmp(w.ssid, "MyWiFi") == 0);
printf("== dns_parse_query:QTYPE 解析 ==\n");
{
uint8_t q[256];
int off = 12;
const char *name = "music.163.com";
memset(q,0,sizeof q); q[2]=0x01; q[4]=0; q[5]=1; /* RD=1 qdcount=1 */
for (const char *p=name; *p;) {
const char *d = strchr(p, '.');
size_t l = d ? (size_t)(d - p) : strlen(p);
q[off++] = (uint8_t)l; memcpy(q+off, p, l); off += (int)l;
p = d ? d + 1 : p + l;
}
q[off++] = 0; /* qname 终止 */
q[off++] = 0; q[off++] = 1; /* qtype A */
q[off++] = 0; q[off++] = 1; /* qclass IN */
char dom[DNS_QNAME_MAX]; int qend=0,qt=0;
CHECK(dns_parse_query(q,off,dom,sizeof dom,&qend,&qt)==0);
CHECK(strcmp(dom,"music.163.com")==0 && qt==1); /* A=1 */
q[off-4] = 0; q[off-3] = 28; /* 改 QTYPE=AAAA */
CHECK(dns_parse_query(q,off,dom,sizeof dom,&qend,&qt)==0 && qt==28);
}
printf("== global dns.filter_aaaa 配置加载 + policy 回归 ==\n");
snprintf(path, sizeof path, "%s/policy", T);
wf(path, "global log_level=debug dns.filter_aaaa=1\nproc:thttpd net=block\n");
g_net_policy[0]=0; snprintf(g_net_policy,sizeof g_net_policy,"%s",path);
rules_load();
CHECK(g_dns_filter_aaaa == 1);
CHECK(strcmp(g_policy_log_level, "debug") == 0);
CHECK(policy_net_blocked("proc:thttpd") == 1);
CHECK(dns_query_domain_denied("proc:thttpd", "anything.com") == 1); /* net=block → DNS 全 deny */
CHECK(is_self_lock("proc:dropbear") == 1);
CHECK(policy_net_blocked("proc:dropbear") == 0);
printf("== wifi forget(remove_network + save_config)==\n");
{
char rm_path[192], sv_path[192];
snprintf(rm_path, sizeof rm_path, "%s/rm.log", T);
snprintf(sv_path, sizeof sv_path, "%s/sv.log", T);
snprintf(path, sizeof path, "%s/wpa_fg", T);
char script[512];
snprintf(script, sizeof script,
"#!/bin/sh\n"
"if [ \"$1\" = \"remove_network\" ]; then echo \"$@\" > \"%s\"; fi\n"
"if [ \"$1\" = \"save_config\" ]; then echo \"$@\" > \"%s\"; fi\n"
"exit 0\n", rm_path, sv_path);
wf(path, script);
chmod(path, 0755);
g_wpa_cli = ""; { static char w2[192]; snprintf(w2,sizeof w2,"%s",path); g_wpa_cli=w2; }
g_mode_meow = 1;
ctl_result_t r;
wifi_ctl_execute("forget", "7", &r);
CHECK(r.code == MEOW_OK);
CHECK(strstr(r.text, "network_id=7") != NULL);
CHECK(strstr(r.text, "save_config") != NULL);
char buf[64]; read_file_txt(rm_path, buf, sizeof buf);
CHECK(strstr(buf, "remove_network 7") != NULL);
read_file_txt(sv_path, buf, sizeof buf);
CHECK(strstr(buf, "save_config") != NULL);
}
if (g_fail) { printf("\nNETMGR P5 TEST: %d FAIL\n", g_fail); return 1; }
printf("\nNETMGR P5 TEST: ALL PASS\n");
return 0;
}