Skip to content

feat(phase3): netstat / ifconfig write / ping / traceroute (Wave 1c + Wave 2)#20

Merged
Charliechen114514 merged 6 commits into
mainfrom
feat/phase3-wave1c-wave2
Jul 6, 2026
Merged

feat(phase3): netstat / ifconfig write / ping / traceroute (Wave 1c + Wave 2)#20
Charliechen114514 merged 6 commits into
mainfrom
feat/phase3-wave1c-wave2

Conversation

@Charliechen114514

Copy link
Copy Markdown
Member

Phase 3 网络最小闭环 Wave 1c + Wave 2 —— 4 批收口。Phase 3 全部完成。

范围(4 批,按风险递增)

  • 批4 netstat(只读):net_utilsplit_fieldsread_routes 改用,DRY)+ read_tcp/udp/unix_sockets(解析 /proc/net/*)+ format_netstat_*(BusyBox 风格,LISTEN 过滤/-a)+ netstat applet(-t/-u/-x/-a/-n
  • 批5 ifconfig 写(CAP_NET_ADMIN):net_utilctl_socket/parse_ipv4/detail::ifreq_with_addr(memcpy 解 cast-align)/detail::ioctl_error(msg 含 strerror)+ set_ipv4_addr/netmask/broadcast/mtu/set_if_up(read-modify-write IFF_UP)+ ifconfig 写 codepath(IFACE ADDR [netmask NM] [broadcast BC] [mtu N] [up|down],EPERM 不静默)
  • 批6 icmp.hpp + ping(CAP_NET_RAW):新基础设施(checksum RFC1071 纯函数 + build_echo_request + parse_icmp 剥 IP 头按 IHL + open_raw + recv_icmp match_id 双模式 + now_us)+ ping-c/-i/-W/-s/-q/-n,SIGINT RAII 打 summary,EPERM exit 2)
  • 批7 traceroute(CAP_NET_RAW):UDP 探测(setsockopt(IP_TTL) 递增 + 每探 bump 目标端口避 conntrack)+ 复用 icmp::recv_icmp(match_id=0) 收 time-exceeded/port-unreachable + icmp::classify_reply 纯函数判定 + net_util::resolve_ipv4/name_of 抽取(ping 重构去重)

基线变化

before after
applet 127 130 (+netstat/ping/traceroute)
GTest 452 479 (+27 测)
size-opt 463 KB 479 KB (预算 550 KB,余 71 KB)

验证

  • ctest 479/479 全绿(+27:netstat 10 / parse_ipv4 2 / icmp 11 / classify_reply 4)
  • bash tests/integration/run_all.sh 全绿(+netstat / ifconfig 写 / ping / traceroute,含 skip guard)
  • size-opt 479 KB
  • 本地 armhf 交叉编译 + qemu-arm-static --list 全过,无新 cast-align 警告

CI 测不真桥接

网络特权操作(CAP_NET_ADMIN/CAP_NET_RAW)在 CI native/qemu-user 跑不了真功能。三招组合:

  1. 纯函数单测(checksum / parse_icmp / classify_reply / parse_inet_sockets / format_*)—— 解析/判定逻辑剥离喂假数据,CI 全覆盖
  2. 集成 skip guard(EPERM→exit 0,参照既有 test_nc.sh port-busy 跳过)—— 无特权测「报错路径正确」
  3. qemu-system 阶段(CFBox 当 PID 1,唯一有 root 的 CI 阶段)真跑特权路径

armhf cast-align 对称模式

ipv4_from_ioctl(读:sockaddr*→sockaddr_in memcpy)+ detail::ifreq_with_addr(写:sockaddr_in memcpy 进 ifr.ifr_addr)—— 32 位 -Wcast-align 标准解法。Wave 1c/2 四批本地 armhf 全过,零新 cast-align bug。

文档

各批 note 在 document/notes/2026-07-06-phase3-*.md(netstat / ifconfig-write / icmp-ping / traceroute);收口总结 phase3-recap.md。ROADMAP Phase 3 标 ✅。

… 1c)

net_util: extract split_fields (read_routes reuses), add SocketEntry/
UnixSocketEntry, tcp/unix state-name tables, parse_inet_sockets (pure fn,
fake-data testable) + read_tcp/udp/unix_sockets wrappers, format_netstat_*
BusyBox style (LISTEN hidden unless -a, remote port 0 -> *).
netstat applet: -t/-u/-x/-a/-n (defaults to tcp+udp).
net_util: ctl_socket helper, parse_ipv4, detail::ifreq_with_addr
(memcpy into ifr.ifr_addr avoids -Wcast-align on armhf), detail::ioctl_error
(msg carries strerror for EPERM vs ENODEV), set_ipv4_addr/set_netmask/
set_broadcast/set_mtu/set_if_up (read-modify-write IFF_UP).
ifconfig: write codepath on IFACE ADDR [netmask NM] [broadcast BC] [mtu N]
[up|down]; EPERM reported per-ioctl, never silent.
icmp.hpp: checksum (RFC 1071, pure), build_echo_request (id/seq network
order, self-consistent checksum), parse_icmp (strips IP header via IHL,
returns type/id/seq/recv_ttl), open_raw (SOCK_RAW IPPROTO_ICMP), recv_icmp
(match_id filter for ping mode, monotonic deadline loop for traceroute mode).
ping: -c/-i/-W/-s/-q/-n, SIGINT RAII guard prints summary, EPERM exits 2
(distinct from resolve failure exit 1), RTT in microseconds.
… 3 wave 2)

traceroute: UDP socket with setsockopt(IP_TTL) per-hop, bumps destination
port per probe to dodge conntrack, receives time-exceeded/port-unreachable
via icmp::recv_icmp (match_id=0). -m/-q/-w/-n, SIGINT RAII, EPERM exit 2.
net_util: lift resolve_ipv4/name_of out of ping.cpp (shared, DRY) — ping
refactored to use them. icmp: classify_reply pure fn (time_exceeded ->
intermediate, port-unreach -> reached) unit-testable without CAP_NET_RAW.
Phase 3 network loop closed: 11 applets, 3 infra headers.
scripts/user_test/qemu_cfbox_shell.sh: builds an armhf initramfs (cfbox as
PID 1 + inittab that mounts fs, brings up loopback, askfirst -> /bin/sh)
and boots qemu-system vexpress-a9 with the console wired to the caller's
terminal. One-shot interactive verification of the privileged network
applets (ifconfig write / ping / traceroute / netstat) that CI native and
qemu-user can't exercise (CAP_NET_ADMIN / CAP_NET_RAW). Not for CI —
hands-on only.

Verified end-to-end: boot -> askfirst -> /bin/sh -> ifconfig/ping/poweroff
all work, lo auto-up at boot so ping 127.0.0.1 works immediately.
@Charliechen114514 Charliechen114514 merged commit 882b3f3 into main Jul 6, 2026
8 checks passed
@Charliechen114514 Charliechen114514 deleted the feat/phase3-wave1c-wave2 branch July 6, 2026 05:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant