Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake/Config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ set(CFBOX_APPLETS
dmesg hexdump more rev cal renice
clear which mount mountpoint mdev chmod chown chgrp
umount swapoff reboot
nc ifconfig ip route
nc ifconfig ip route netstat ping traceroute
)

foreach(applet IN LISTS CFBOX_APPLETS)
Expand Down
10 changes: 7 additions & 3 deletions document/ai/PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
> Tier 3(批级,易变)。单一事实源(批级)。全树见 [ROADMAP.md](ROADMAP.md),铁律见 [DIRECTIVES.md](DIRECTIVES.md);结构标尺见 [STRUCTURE-TASTE.md](STRUCTURE-TASTE.md),性能标尺见 [PERFORMANCE.md](PERFORMANCE.md)。
> **v0.3.0 已发布**:L2 rootfs 启动骨架(init/mount/mdev/umount/swapoff/reboot/poweroff,117→123 applet)+ tail -f —— cfbox 在 i.MX6ULL 上作为 PID 1 替代 BusyBox。
> ✅ **Phase 2 全部完成**(cp/test/ls/grep/find + sh 全收 8 项)+ ✅ **结构与性能标尺横切批**(PR#17/#18)—— STRUCTURE-TASTE + banned-pattern/layering gate、PERFORMANCE + io/tar/cmp/md5sum/sed 流式化 + google-benchmark 脚手架。当前基线 **436 GTest / 439 KB size-opt / 123 applet**。
> 🔄 **Phase 3 网络最小闭环进行中**:批1(`socket.hpp` + `nc`)✅、批2(`net_util.hpp` + `ifconfig` 显示)✅、批3(`ip`/`route`/`hostname` 深化)✅ —— 当前基线 **452 GTest / 463 KB / 127 applet**。详见 [phase-2-network.md](../todo/phases/phase-2-network.md)。
> **Phase 3 网络最小闭环完成**:批1(`socket.hpp` + `nc`)✅、批2(`net_util.hpp` + `ifconfig` 显示)✅、批3(`ip`/`route`/`hostname` 深化)✅、批4(`netstat` 只读 + `split_fields` 抽取)✅、批5(`ifconfig` 写操作 SIOCSIF*)✅、批6(`icmp.hpp` + `ping`)✅、批7(`traceroute` UDP 探测 + ICMP 收包)✅ —— 最终基线 **479 GTest / 479 KB / 130 applet**。详见 [phase-2-network.md](../todo/phases/phase-2-network.md)。
> 状态:✅ DONE / 🔄 NEXT / ⏳ PENDING / ⛔ BLOCKED。每批≈一 commit,完成门 `cmake --build build -j$(nproc) && ctest --test-dir build --output-on-failure` 全绿 + `bash tests/integration/run_all.sh`。

## ✅ Phase 1.5(代码质量审查)已完成 — 2026-05-26
Expand Down Expand Up @@ -56,7 +56,7 @@

> 批级记录见 [notes/2026-07-06-structure-performance.md](../notes/2026-07-06-structure-performance.md)。两批均未增删 applet,GTest 基线沿用 Phase 2 末 436;size-opt 体积 v0.3.0 的 418 KB → 439 KB(+21 KB,主因 io/tar 流式缓冲与 benchmark 链接产物,仍在 ≤ 550 KB 预算内)。

## 🔄 Phase 3(网络最小闭环)— 进行中
## Phase 3(网络最小闭环)— 已完成

> 目标:socket/http/net_util/icmp 基础设施 + ip/ifconfig/route/netstat/ping/traceroute/nslookup/wget/nc/tftp + hostname 深化(11 applet)。详见 [phase-2-network.md](../todo/phases/phase-2-network.md)。每批≈一 commit + 完成门。

Expand All @@ -65,8 +65,12 @@
| 批1(Wave 0) | `include/cfbox/socket.hpp` 基础设施(复用 `io::unique_fd`:make/resolve/dial/listen_on/accept_one/format_addr,双栈、header-only)+ `nc` applet(connect/listen 模式 + poll 双向 relay stdin→sock/sock→stdout + SHUT_WR 半关) | ✅ | 10f811f | 440/1 |
| 批2(Wave 1a) | `include/cfbox/net_util.hpp` 基础设施(`read_interfaces` 解析 /proc/net/dev + ioctl SIOCGIF* 取 flags/mtu/hwaddr/ipv4;`format_ifconfig` BusyBox 多行格式;`ipv4_from_ioctl` memcpy 解 cast-align)+ `ifconfig` applet(`-a`/`IFACE` 只读显示) | ✅ | f4279d6 | 446/1 |
| 批3(Wave 1b) | `net_util.hpp` 扩展(`read_routes` 解析 /proc/net/route tab-hex + `format_route_table` BusyBox route -n + `hex_to_ipv4`/`prefix_len`)+ `ip addr show`(iproute2 风格 index/flags/mtu/link/inet)+ `route -n`(显示)+ `hostname` 深化(`-i`/`-f`/`-d` getaddrinfo + memcpy 解 cast-align) | ✅ | f0ff0db | 452/2 |
| 批4(Wave 1c) | `net_util.hpp` 抽公共 `split_fields`(`read_routes` 改用,DRY)+ `read_tcp/udp_sockets`(解析 /proc/net/tcp\|udp `hexIP:hexPort` + state code + tx:rx queues)+ `read_unix_sockets`(/proc/net/unix)+ `parse_inet_sockets` 纯函数化(喂假数据可单测)+ `format_netstat_inet/unix`(BusyBox 风格,LISTEN 过滤/-a)+ `netstat` applet(`-t/-u/-x/-a/-n`) | ✅ | (本批) | 462/3 |
| 批5(Wave 1c) | `net_util.hpp` 写 ioctl:抽 `ctl_socket`/`parse_ipv4`/`detail::ifreq_with_addr`(memcpy 写 sockaddr 解 cast-align)/`detail::ioctl_error`(msg 含 strerror)+ `set_ipv4_addr`/`set_netmask`/`set_broadcast`/`set_mtu`/`set_if_up`(read-modify-write IFF_UP)+ `ifconfig` 写 codepath(`IFACE ADDR [netmask NM] [broadcast BC] [mtu N] [up\|down]`,EPERM 不静默) | ✅ | (本批) | 464/5 |
| 批6(Wave 2) | `include/cfbox/icmp.hpp` 新基础设施(`checksum` RFC1071 纯函数 + `build_echo_request` + `parse_icmp` 剥 IP 头按 IHL + `open_raw` SOCK_RAW IPPROTO_ICMP + `recv_icmp` match_id 过滤/monotonic deadline + `now_us`)+ `ping` applet(`-c/-i/-W/-s/-q/-n`,SIGINT RAII 打 summary,EPERM exit 2 区分 resolve 失败 exit 1) | ✅ | (本批) | 475/3 |
| 批7(Wave 2) | `traceroute` applet(UDP 探测 `setsockopt(IP_TTL)` 递增 + 每探 bump 目标端口避 conntrack + 复用 `icmp::open_raw`/`recv_icmp`(match_id=0) 收包 + `icmp::classify_reply` 判 time-exceeded/port-unreach)+ `net_util` 抽 `resolve_ipv4`/`name_of`(ping/traceroute 共享,ping.cpp 重构去重) | ✅ | (本批) | 479/3 |

> 下一批:Wave 1c `ifconfig` 写操作(ADDR/netmask/up/down/mtu,SIOCSIF*,需 root)+ `netstat`(依赖 net_util `read_sockets` 待建);或转 Wave 2(`ping`/`traceroute`,需 `icmp.hpp` raw socket)。批级记录见 [notes/2026-07-06-phase3-socket-nc.md](../notes/2026-07-06-phase3-socket-nc.md) / [notes/2026-07-06-phase3-ifconfig.md](../notes/2026-07-06-phase3-ifconfig.md) / [notes/2026-07-06-phase3-ip-route-hostname.md](../notes/2026-07-06-phase3-ip-route-hostname.md)。
> **Phase 3 收口**:11 applet 全到位(socket/nc/ifconfig/ip/route/hostname/netstat + ifconfig 写 + ping/traceroute),3 基础设施(socket.hpp/net_util.hpp/icmp.hpp)。下一焦点待定(候选:route add/del、hostname NAME、netstat -r/-i、IPv6、或转 Phase 4 用户/文件权限)。批级记录见 [notes/2026-07-06-phase3-socket-nc.md](../notes/2026-07-06-phase3-socket-nc.md) / [notes/2026-07-06-phase3-ifconfig.md](../notes/2026-07-06-phase3-ifconfig.md) / [notes/2026-07-06-phase3-ip-route-hostname.md](../notes/2026-07-06-phase3-ip-route-hostname.md) / [notes/2026-07-06-phase3-netstat.md](../notes/2026-07-06-phase3-netstat.md) / [notes/2026-07-06-phase3-ifconfig-write.md](../notes/2026-07-06-phase3-ifconfig-write.md) / [notes/2026-07-06-phase3-icmp-ping.md](../notes/2026-07-06-phase3-icmp-ping.md) / [notes/2026-07-06-phase3-traceroute.md](../notes/2026-07-06-phase3-traceroute.md)。

## OPEN GOTCHAS(跨批陷阱,改前必看)

Expand Down
8 changes: 4 additions & 4 deletions document/ai/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
| Phase 1 | ✅ | [核心系统](../todo/phases/phase-1-core-system.md) | P0 系统命令(chmod/chown/dd/mount/stty 等 24 个新 applet) |
| Phase 1.5 | ✅ | [代码质量审查](../todo/phases/phase-1.5-code-quality-review.md) | 错误处理一致性、风格、测试覆盖、体积检查(A-G 扫描全过) |
| **Phase 2** | ✅ | [核心深化(同 Phase 1 文档 Part 3)](../todo/phases/phase-1-core-system.md) | tail -f、cp -a、test POSIX、ls -R/--color、grep -A/-B/-C、find 布尔、sh 深化(全完成) |
| Phase 3 | | [网络最小闭环](../todo/phases/phase-2-network.md) | 基础网络配置、诊断、下载、连接调试 |
| Phase 3 | | [网络最小闭环](../todo/phases/phase-2-network.md) | socket/net_util/icmp 基础设施 + nc/ifconfig/ip/route/hostname/netstat + ifconfig 写 + ping/traceroute(11 applet) |
| Phase 4 | ⏳ | [生产质量门禁深化](../todo/phases/phase-3-quality.md) | fuzzing、benchmark、POSIX 子集、release 工程 |
| Phase 5 | ⏳ | [多用户与嵌入式运行时](../todo/phases/phase-4-multiuser.md) | login/getty/syslog/mdev/storage |
| Phase 6 | ⏳ | [长尾完备性](../todo/phases/phase-5-longtail.md) | vi、额外压缩格式、硬件工具、长尾 applet |
Expand All @@ -22,8 +22,8 @@
- 兼容性裁决见 [compatibility-policy.md](../todo/compatibility-policy.md);v1.0 验收边界见 [v1-production-criteria.md](../todo/v1-production-criteria.md)。

## 当前焦点
**Phase 2 核心命令深化 ✅ 全部完成**(2026-06-28)+ **结构与性能标尺横切批 ✅ 完成**(2026-07,PR#17 / PR#18)。批2-5c:`cp -a`、`test` POSIX、`ls -R`/`--color`、`grep -A/-B/-C`、`find` 布尔、`sh` 全收(算术/case/函数/here-doc/高级`${}`/break N/read/trap);横切批落 STRUCTURE-TASTE + banned-pattern/layering gate(CI 守护)、PERFORMANCE + io/tar/cmp/md5sum/sed 流式化(line reader ~7x、tar O(1)、sed 预编译 ~4x)+ google-benchmark 脚手架。基线 **436 GTest + 57 集成(sh)/ 439 KB** size-opt(v0.3.0 基线 399/418)。批级记录见 [PLAN.md](PLAN.md) 与 [notes/](../notes/)。
> **下一站**:Phase 3 网络最小闭环(基础网络配置/诊断/下载)。
**Phase 3 网络最小闭环 ✅ 全部完成**(2026-07,PR 待合):`socket.hpp`/`net_util.hpp`/`icmp.hpp` 三基础设施 + 批1-7 全 ✅ —— `nc`、`ifconfig`(读+写)、`ip addr show`、`route -n`、`hostname -i/-f/-d`、`netstat`、`ping`、`traceroute`(11 applet)。基线 **479 GTest / 479 KB / 130 applet** size-opt。之前:Phase 2 核心深化 + 结构/性能标尺横切(PR#17/#18)。批级记录见 [PLAN.md](PLAN.md) 与 [notes/](../notes/)。
> **下一站**:Phase 4 生产质量门禁深化(fuzzing/benchmark/POSIX 子集/release 工程),或 Phase 3 增量(route add/del、hostname NAME、netstat -r/-i、IPv6 ping/traceroute)。

## 当前焦点之后下一个可启动的
**Phase 3 网络最小闭环**(基础网络配置/诊断/下载)——Phase 2 核心命令深度到位后启动。更远:Phase 4 质量门禁(fuzzing/release 工程)→ Phase 5 多用户 → Phase 6 长尾。
**Phase 4 生产质量门禁深化**(fuzzing/benchmark/POSIX 子集/release 工程)——Phase 3 网络闭环完成后启动。或先补 Phase 3 增量(route add/del、hostname NAME、netstat -r/-i、IPv6)。更远:Phase 5 多用户 → Phase 6 长尾。
62 changes: 62 additions & 0 deletions document/notes/2026-07-06-phase3-icmp-ping.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Phase 3 批6(Wave 2)— icmp.hpp 基础设施 + ping

> 2026-07-06。新建 `icmp.hpp`(raw ICMP 共享层)+ `ping` applet。SOCK_RAW IPPROTO_ICMP
> 需 CAP_NET_RAW —— CI native/qemu-user 无权,集成 skip guard 接受 EPERM 或真 reply 两种结果;
> qemu-system(root)能真跑。纯函数(checksum/build/parse)单测全覆盖。

## 触及文件

- [include/cfbox/icmp.hpp](../../include/cfbox/icmp.hpp) — 新(header-only):
- `now_us()`(CLOCK_MONOTONIC 微秒,RTT + poll deadline 共用)
- `checksum(span<uint8_t>) -> uint16_t`(RFC 1071,纯函数)
- `build_echo_request(id, seq, payload, out) -> size_t`(type=ICMP_ECHO + 网络序 id/seq + 算后填 checksum)
- `ParsedIcmp{type,code,id,seq,recv_ttl}` + `parse_icmp(span) -> Result<ParsedIcmp>`(按 IHL 剥 IP 头,recv_ttl 取 IP 头偏移 8)
- `open_raw() -> Result<unique_fd>`(EPERM→err msg 含 strerror)
- `RecvResult{from, msg}` + `recv_icmp(fd, match_id, timeout_ms) -> Result<RecvResult>`(match_id≠0 过滤非己 echo,monotonic deadline 循环,EINTR continue)
- [src/applets/ping.cpp](../../src/applets/ping.cpp) — 新 applet(`-c/-i/-W/-s/-q/-n`,getaddrinfo AF_INET resolve,SIGINT RAII guard 打 summary,EPERM exit 2 / resolve 失败 exit 1)
- 注册三件套(`CFBOX_ENABLE_PING`)
- [tests/unit/test_icmp.cpp](../../tests/unit/test_icmp.cpp) — 11 测(checksum 4:全 0/全 1/奇数/carry-fold;build_echo 3:字节布局/checksum 自洽(整体 checksum=0)/out 太小;parse 4:剥 IP 头/IHL≠6 含选项/太短/坏 IHL)
- [tests/integration/test_ping.sh](../../tests/integration/test_ping.sh) — 3 测(EPERM 或 reply 二选一 + 无参 exit 非零 + 坏 -c exit 非零)

## 关键设计决策

1. **`recv_icmp` match_id 双模式**:ping 传 `id`(过滤非己 echo,避免被主机其他 ICMP 干扰),
traceroute 传 `0`(收任意 ICMP —— time-exceeded/port-unreachable 的 id 对应原始 UDP 包,
不匹配 ping 的 ICMP id)。一个 API 服务两个 applet。
2. **monotonic deadline 循环**:`recv_icmp` 内 `now_us() + timeout*1000` 算 deadline,每轮 poll
剩余时间。match_id 不匹配或 malformed 包 continue 不消耗整个 timeout(只减剩余)——
ping 不会因收到一个无关 echo 就丢掉整个等待窗口。
3. **parse_icmp 按 IHL 剥头**:raw recv 含 IP 头,`raw[0] & 0x0f * 4` 算 IP 头长。
测了 IHL=5(标准)和 IHL=6(含 IP 选项)两种。recv_ttl 取 IP 头偏移 8(标准 TTL 字节位置)。
4. **checksum 自洽性测试**:build_echo_request 后对整个包跑 checksum 应返回 0(ICMP 校验和的
定义性质 —— 含 checksum 字段的整体求和为 0xffff,~= 0)。这比对照具体 RFC 向量更强 ——
它验证了「我们填的 checksum 让接收端校验通过」。
5. **SIGINT RAII guard**:`sa.sa_flags=0`(不放 SA_RESTART)让 usleep/poll 被 SIGINT EINTR 唤醒,
ping 快速响应 Ctrl-C 打 summary。析构 restore old_act —— multi-call binary 不污染后续 applet。
6. **EPERM exit 2 ≠ resolve 失败 exit 1**:用户能区分「没权限」与「host 不存在」。
7. **RTT 微秒精度**:`now_us()` us,显示 `rtt/1000.0`(3 位小数 ms)。本地 loopback RTT < 1ms,
ms 整数精度会显示 0.0 ms 误导。
8. **`<span>` 引入**:ICMP 是字节流,`std::span<const std::uint8_t>` 比 pointer+len 更安全现代。
C++23 标准库支持,项目首次用,编译过 armhf。

## 完成门

- `ctest`:**475/475** 全绿(+11 icmp 测)
- `bash tests/integration/run_all.sh`:全绿(ping 3/3)
- size-opt:**479 KB**(+8 KB,预算 550 KB,余 71 KB)
- armhf 交叉编译 + qemu:ping EPERM path 在 32 位正确报 "socket(SOCK_RAW, ICMP) failed: Operation not permitted",无新 cast-align 警告(sockaddr_storage*→sockaddr* 对齐兼容,不触发)

## Gotcha

- **本机无 CAP_NET_RAW 不能真 ping**:开发机非 root,real ping smoke 报 EPERM exit 2(设计如此)。
真验证依赖 qemu-system 阶段(CFBox 当 PID 1 有 root)。本机单测 + 32 位 EPERM 报错路径已覆盖可测部分。
- **checksum 奇数长度**:最后单字节作高位(`data[i] << 8`)。RFC 1071 规定如此。
- **carry 折叠**:用 `while (sum >> 16)` 循环(非一次折叠),处理极端情况(多次进位)。
测 3×0xffff=0x2fffd → fold 0xffff → ~ = 0x0000。
- **`recvfrom` 缓冲 1500**:足够标准 MTU 的 IP+ICMP。jumbo frame 会截断,但 ping/traceroute
探测包远小于 1500,不影响。
- **`sa.sa_flags=0` 的代价**:usleep 被 SIGINT 中断后不重睡 —— ping 在 reply 间隔按 Ctrl-C 立即退出。
但 recv_icmp 内 poll EINTR 后 continue,若 SIGINT 到达在 recv 等待期,最坏延迟到 timeout。
权衡接受(Ctrl-C 在 sleep 期立即响应;在 recv 期延迟 ≤ timeout)。
- **`build_echo_request` 返回 0 表 out 太小**:调用者应检查。ping.cpp 用固定 1500 缓冲,
payload ≤ 1400,永不触发。
56 changes: 56 additions & 0 deletions document/notes/2026-07-06-phase3-ifconfig-write.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Phase 3 批5(Wave 1c)— ifconfig 写操作(SIOCSIF*)

> 2026-07-06。给 `ifconfig` 加写能力:`ifconfig IFACE ADDR [netmask NM] [broadcast BC]
> [mtu N] [up|down]`。`net_util` 加写 ioctl 基础设施(`ctl_socket` + 5 个 `set_*`)。
> 需 CAP_NET_ADMIN —— CI native/qemu-user 无权,靠 skip guard 验证「EPERM 不静默」,
> qemu-system(root)真跑 MTU round-trip。

## 触及文件

- [include/cfbox/net_util.hpp](../../include/cfbox/net_util.hpp) —
- `ctl_socket() -> Result<unique_fd>`(公共控制套接字,读/写 ioctl 共用)
- `parse_ipv4(sv) -> optional<in_addr>`(dotted → in_addr,纯函数可单测)
- `detail::ifreq_with_addr(iface, cmd, addr)`(建 ifreq + memcpy 写 sockaddr_in,解 cast-align)
- `detail::ioctl_error(what, errno)`(msg 含 strerror —— "SIOCSIFADDR failed: Operation not permitted")
- `set_ipv4_addr`/`set_netmask`/`set_broadcast`(SIOCSIFADDR/NETMASK/BRDADDR)
- `set_mtu`(SIOCSIFMTU)
- `set_if_up(ctl, iface, bool)`(SIOCGIFFLAGS 读改写 IFF_UP → SIOCSIFFLAGS,保留其他 flag)
- [src/applets/ifconfig.cpp](../../src/applets/ifconfig.cpp) — 加 `ifconfig_write` codepath(positional ≥2 触发),BusyBox 语法解析(`up`/`down`/`netmask`/`broadcast`/`mtu` keyword + 首个非 keyword 为 ADDR),一个 ctl_fd 上原子下发,EPERM 逐 ioctl 报错
- [tests/unit/test_net_util.cpp](../../tests/unit/test_net_util.cpp) — +2 测 `parse_ipv4` valid/invalid
- [tests/integration/test_ifconfig.sh](../../tests/integration/test_ifconfig.sh) — +1 写测试双分支(非 root grep EPERM / root MTU round-trip + 恢复)

## 关键设计决策

1. **写 path 触发条件 `positional().size() >= 2`**:`ifconfig lo`(1 个)仍走读 path 显示;
`ifconfig lo up`(2 个)走写 path。保持读语义不退化。
2. **`detail::ifreq_with_addr` memcpy 模式**:与 `ipv4_from_ioctl` 对称 —— `sockaddr_in` 填好后
memcpy 进 `ifr.ifr_addr`,避免 `reinterpret_cast<sockaddr_in*>(&ifr.ifr_addr)` 在 armhf 触发
`-Wcast-align`(memory 警示的 B2 真 bug 模式)。
3. **`detail::ioctl_error` 含 strerror**:既有 `socket.hpp` 错误不含 strerror(一致性弱点)。
写 ioctl 是用户高频诊断点("为什么 ifconfig 失败"),msg 拼 strerror 让 EPERM/ENODEV 可区分。
读 path 无错误可拼,不影响一致性。
4. **`set_if_up` read-modify-write**:不能直接 `ifr.ifr_flags = IFF_UP`(会清掉 BROADCAST/MULTICAST
等其他 flag)。先 SIOCGIFFLAGS 读现状,只改 IFF_UP 位,再 SIOCSIFFLAGS 写回。
5. **EPERM 不静默**:applet 逐 ioctl 检查 Result,失败即 `CFBOX_ERR` + return 1。绝不会
「ioctl 失败但 ifconfig 返回 0」误导用户。
6. **集成测试双分支**:非 root 验证 EPERM 报错(grep "Operation not permitted"),
root 验证 MTU round-trip(lo 默认 MTU 改 1280 再恢复 —— lo 选作目标因它安全可逆、
不会丢连接)。改 lo 地址太危险(覆盖 127.0.0.1),故 root 测试只动 MTU。

## 完成门

- `ctest`:**464/464** 全绿(+2 parse_ipv4 测)
- `bash tests/integration/run_all.sh`:全绿(ifconfig 5/5,含写测试)
- size-opt:**471 KB**(+4 KB,预算 550 KB,余 79 KB)
- armhf 交叉编译 + qemu:ifconfig 写 path 在 32 位正确报 "SIOCSIFADDR failed: Operation not permitted",无新 cast-align 警告

## Gotcha

- **`ifr.ifr_flags` 是 `short`**:`IFF_UP` 是 int,`ifr.ifr_flags |= IFF_UP` 隐式窄化触发
armhf `-Wconversion`。用 `static_cast<short>(IFF_UP)` 显式窄化。
- **alias 接口 `lo:0`**:`ifr.ifr_name="lo:0"` 对 SIOCSIFADDR 可工作(Linux alias 语义),
但 `read_interfaces` 读 /proc/net/dev 不显示 alias(只在 ip addr show)。本轮不暴露 alias 入口。
- **broadcast 通常自动算**:设了 ADDR+NETMASK 后 kernel 自动推 BCAST,显式 `broadcast BC`
仅覆盖。BusyBox 行为一致。
- **测试改 lo 的安全性**:lo 整段 127.0.0.0/8 都通(kernel 特殊处理),改 lo 的 MTU 不会断
loopback 连接;但改 lo 的主地址会丢 127.0.0.1,故 root 测试只动 MTU。
Loading
Loading