static bool ipv4ll_address_is_valid(const struct in_addr *address) { uint32_t addr; assert(address); if (!in_addr_is_link_local(AF_INET, (const union in_addr_union *) address)) return false; addr = be32toh(address->s_addr); if ((addr & 0x0000FF00) == 0x0000 || (addr & 0x0000FF00) == 0xFF00) return false; return true; }
int dhcp6_request_address(Link *link, int ir) { int r, inf_req; bool running; assert(link); assert(link->dhcp6_client); assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0); r = sd_dhcp6_client_is_running(link->dhcp6_client); if (r < 0) return r; else running = !!r; if (running) { r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &inf_req); if (r < 0) return r; if (inf_req == ir) return 0; r = sd_dhcp6_client_stop(link->dhcp6_client); if (r < 0) return r; } else { r = sd_dhcp6_client_set_local_address(link->dhcp6_client, &link->ipv6ll_address); if (r < 0) return r; } r = sd_dhcp6_client_set_information_request(link->dhcp6_client, ir); if (r < 0) return r; r = sd_dhcp6_client_start(link->dhcp6_client); if (r < 0) return r; return 0; }
static int radv_get_ip6dns(Network *network, struct in6_addr **dns, size_t *n_dns) { _cleanup_free_ struct in6_addr *addresses = NULL; size_t i, n_addresses = 0, n_allocated = 0; assert(network); assert(dns); assert(n_dns); for (i = 0; i < network->n_dns; i++) { union in_addr_union *addr; if (network->dns[i].family != AF_INET6) continue; addr = &network->dns[i].address; if (in_addr_is_null(AF_INET6, addr) || in_addr_is_link_local(AF_INET6, addr) || in_addr_is_localhost(AF_INET6, addr)) continue; if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1)) return -ENOMEM; addresses[n_addresses++] = addr->in6; } if (addresses) { *dns = addresses; addresses = NULL; *n_dns = n_addresses; } return n_addresses; }