/* 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 #include #include #include #include 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; }