S1 #7 steps 1-2: IPv4 checks, the IP setting per Saved Network, DNS and NTP settings

The plan and decisions Q105 to Q116 (docs/milestones/S1.md). lib/net:
strict IPv4 parsing, prefix and mask, and the checks a Fixed setting must
pass, each refusal with its reason. A Saved Network is Automatic or Fixed
(address/prefix and an optional gateway), kept with it in flash. Settings:
two DNS servers (9.9.9.9, 1.1.1.1), "Always use my DNS", two NTP servers
(pool.ntp.org, time.cloudflare.com). Host-tested: 383 tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-05 23:39:07 +02:00
co-authored by Claude Opus 5.5
parent 7e8882d9cb
commit bdd027cb50
10 changed files with 429 additions and 1 deletions
+23 -1
View File
@@ -17,6 +17,8 @@ void SavedNetworks::load() {
int32_t hidden = 0;
store_.getInt(key(i, "hid").c_str(), hidden);
net.hidden = hidden != 0;
std::string ip; // "address/prefix [gateway]", or empty for Automatic
net.fixed = store_.getString(key(i, "ip").c_str(), ip) && !ip.empty() && net::parseFixed(ip, net.ip).empty();
networks_.push_back(net);
}
}
@@ -40,11 +42,30 @@ std::string SavedNetworks::add(const std::string& ssid, const std::string& passw
}
}
if (count() >= kMax) return "Already 8 saved networks: forget one first";
networks_.push_back({ssid, password, hidden});
SavedNetwork added;
added.ssid = ssid;
added.password = password;
added.hidden = hidden;
networks_.push_back(added);
save();
return "";
}
std::string SavedNetworks::setIp(const std::string& ssid, const net::FixedIp* fixed) {
for (auto& n : networks_) {
if (n.ssid != ssid) continue;
if (fixed) {
std::string why = net::checkFixed(*fixed);
if (!why.empty()) return why;
n.ip = *fixed;
}
n.fixed = fixed != nullptr;
save();
return "";
}
return "Not a saved network";
}
void SavedNetworks::forget(const std::string& ssid) {
for (auto it = networks_.begin(); it != networks_.end(); ++it) {
if (it->ssid == ssid) {
@@ -60,6 +81,7 @@ void SavedNetworks::save() {
store_.putString(key(i, "ssid").c_str(), networks_[i].ssid);
store_.putString(key(i, "pass").c_str(), networks_[i].password);
store_.putInt(key(i, "hid").c_str(), networks_[i].hidden ? 1 : 0);
store_.putString(key(i, "ip").c_str(), networks_[i].fixed ? net::formatFixed(networks_[i].ip) : "");
}
store_.putInt("net_count", count());
}