+void scan_ifaddrs(meshlink_handle_t *mesh) {
+#ifdef HAVE_GETIFADDRS
+ struct ifaddrs *ifa = NULL;
+
+ if(getifaddrs(&ifa) == -1) {
+ logger(mesh, MESHLINK_ERROR, "Could not get list of interface addresses: %s", strerror(errno));
+ return;
+ }
+
+ // Check for interfaces being removed
+ for(int i = 0; i < mesh->discovery.iface_count;) {
+ bool found = false;
+
+ for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) {
+ if(!ifap->ifa_name) {
+ continue;
+ }
+
+ int index = if_nametoindex(ifap->ifa_name);
+
+ if(mesh->discovery.ifaces[i] == index) {
+ found = true;
+ break;
+ }
+ }
+
+ if(!found) {
+ iface_down(mesh, mesh->discovery.ifaces[i]);
+ } else {
+ i++;
+ }
+ }
+
+ // Check for addresses being removed
+ for(int i = 0; i < mesh->discovery.address_count;) {
+ discovery_address_t *p = &mesh->discovery.addresses[i];
+ bool found = false;
+
+ for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) {
+ if(!ifap->ifa_name || !ifap->ifa_addr) {
+ continue;
+ }
+
+ int index = if_nametoindex(ifap->ifa_name);
+
+ if(p->index == index && sockaddrcmp_noport(&p->address, (sockaddr_t *)ifap->ifa_addr) == 0) {
+ found = true;
+ break;
+ }
+ }
+
+ if(!found) {
+ (void)addr_del;
+ memmove(p, p + 1, (mesh->discovery.addresses + --mesh->discovery.address_count - p) * sizeof(*p));
+ } else {
+ i++;
+ }
+ }
+
+ // Check for interfaces state changes and addresses going up
+ for(struct ifaddrs *ifap = ifa; ifap; ifap = ifap->ifa_next) {
+ if(!ifap->ifa_name) {
+ continue;
+ }
+
+ int index = if_nametoindex(ifap->ifa_name);
+
+ if(ifap->ifa_flags & IFF_UP && ifap->ifa_flags & IFF_MULTICAST && !(ifap->ifa_flags & IFF_LOOPBACK)) {
+ iface_up(mesh, index);
+ } else {
+ iface_down(mesh, index);
+ }
+
+ if(!ifap->ifa_addr) {
+ continue;
+ }
+
+ discovery_address_t addr = {
+ .index = index,
+ };
+
+ sockaddr_t *sa = (sockaddr_t *)ifap->ifa_addr;
+
+ if(sa->sa.sa_family == AF_INET) {
+ memcpy(&addr.address.in, &sa->in, sizeof(sa->in));
+ addr.address.in.sin_port = ntohs(5353);
+ } else if(sa->sa.sa_family == AF_INET6) {
+ memcpy(&addr.address.in6, &sa->in6, sizeof(sa->in6));
+ addr.address.in6.sin6_port = ntohs(5353);
+ } else {
+ addr.address.sa.sa_family = AF_UNKNOWN;
+ }
+
+ if(addr.address.sa.sa_family != AF_UNKNOWN) {
+ addr_add(mesh, &addr);
+ }
+ }
+
+ freeifaddrs(ifa);
+#else
+ (void)mesh;
+#endif
+}
+