89 if (!isUnpinned(cfg.network.bind_ip)) {
90 r.address = cfg.network.bind_ip;
91 if (!canBind(
r.address)) {
93 r.detail =
"[network].bind_ip = " +
r.address +
" is not an address on this host";
94 std::cerr <<
"[" << who <<
"] " <<
r.detail
95 <<
" — refusing to start. Board traffic would leave on an interface nobody "
96 "chose. Fix the NIC or clear the key to auto-detect."
101 r.detail =
"board traffic pinned to " +
r.address +
" (explicit [network].bind_ip)";
102 std::cout <<
"[" << who <<
"] " <<
r.detail << std::endl;
107 const std::vector<uint32_t> boards = boardAddresses(cfg);
108 std::vector<Candidate> matches;
110 struct ifaddrs* ifa_head =
nullptr;
111 if (getifaddrs(&ifa_head) == 0) {
112 for (
struct ifaddrs* ifa = ifa_head; ifa; ifa = ifa->ifa_next) {
113 if (!ifa->ifa_addr || !ifa->ifa_netmask || ifa->ifa_addr->sa_family != AF_INET)
115 if (!(ifa->ifa_flags & IFF_UP))
118 const uint32_t addr =
119 ntohl(
reinterpret_cast<struct sockaddr_in*
>(ifa->ifa_addr)->sin_addr.s_addr);
120 const uint32_t mask =
121 ntohl(
reinterpret_cast<struct sockaddr_in*
>(ifa->ifa_netmask)->sin_addr.s_addr);
123 bool holds_a_board =
false;
124 for (uint32_t
b : boards) {
125 if ((
b & mask) == (addr & mask)) {
126 holds_a_board =
true;
135 const std::string name = ifa->ifa_name ? ifa->ifa_name :
"?";
136 bool already =
false;
137 for (
const auto& c : matches)
143 char buf[INET_ADDRSTRLEN] = {0};
144 struct in_addr net_order{};
145 net_order.s_addr = htonl(addr);
146 inet_ntop(AF_INET, &net_order, buf,
sizeof(buf));
147 matches.push_back({name, buf});
149 freeifaddrs(ifa_head);
153 if (matches.size() > 1) {
154 std::ostringstream os;
155 os <<
"board subnet is reachable on " << matches.size() <<
" interfaces (";
156 for (
size_t i = 0; i < matches.size(); ++i)
157 os << (i ?
", " :
"") << matches[i].iface <<
" " << matches[i].address;
161 std::cerr <<
"[" << who <<
"] " <<
r.detail
162 <<
" — refusing to start. Set [network].bind_ip to the one board traffic should "
168 if (matches.size() == 1) {
169 r.address = matches[0].address;
171 r.detail =
"board traffic pinned to " + matches[0].iface +
" " +
r.address +
" (auto)";
172 std::cout <<
"[" << who <<
"] " <<
r.detail << std::endl;
178 r.address =
"0.0.0.0";
180 r.detail =
"no local interface on the board subnet — board traffic is NOT pinned to a NIC";
181 std::cout <<
"[" << who <<
"] " <<
r.detail
182 <<
" (expected on a dev box; on the rig this means the 192.168.2.x NIC is missing)"