/* DNS information */ ndp_msg_opt_for_each_offset(offset, msg, NDP_MSG_OPT_RDNSS) { static struct in6_addr *addr; int addr_index; ndp_msg_opt_rdnss_for_each_addr (addr, addr_index, msg, offset) { NMRDiscDNSServer dns_server; memset (&dns_server, 0, sizeof (dns_server)); dns_server.address = *addr; dns_server.timestamp = now; dns_server.lifetime = ndp_msg_opt_rdnss_lifetime (msg, offset); /* Pad the lifetime somewhat to give a bit of slack in cases * where one RA gets lost or something (which can happen on unreliable * links like WiFi where certain types of frames are not retransmitted). * Note that 0 has special meaning and is therefore not adjusted. */ if (dns_server.lifetime && dns_server.lifetime < 7200) dns_server.lifetime = 7200; if (nm_rdisc_add_dns_server (rdisc, &dns_server)) changed |= NM_RDISC_CONFIG_DNS_SERVERS; }
static gboolean receive_ra (gpointer user_data) { NMFakeRDisc *self = user_data; NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); NMRDisc *rdisc = NM_RDISC (self); FakeRa *ra = priv->ras->data; NMRDiscConfigMap changed = 0; guint32 now = nm_utils_get_monotonic_timestamp_s (); guint i; priv->receive_ra_id = 0; if (rdisc->dhcp_level != ra->dhcp_level) { rdisc->dhcp_level = ra->dhcp_level; changed |= NM_RDISC_CONFIG_DHCP_LEVEL; } for (i = 0; i < ra->gateways->len; i++) { NMRDiscGateway *item = &g_array_index (ra->gateways, NMRDiscGateway, i); if (nm_rdisc_add_gateway (rdisc, item)) changed |= NM_RDISC_CONFIG_GATEWAYS; } for (i = 0; i < ra->addresses->len; i++) { NMRDiscAddress *item = &g_array_index (ra->addresses, NMRDiscAddress, i); if (nm_rdisc_add_address (rdisc, item)) changed |= NM_RDISC_CONFIG_ADDRESSES; } for (i = 0; i < ra->routes->len; i++) { NMRDiscRoute *item = &g_array_index (ra->routes, NMRDiscRoute, i); if (nm_rdisc_add_route (rdisc, item)) changed |= NM_RDISC_CONFIG_ROUTES; } for (i = 0; i < ra->dns_servers->len; i++) { NMRDiscDNSServer *item = &g_array_index (ra->dns_servers, NMRDiscDNSServer, i); if (nm_rdisc_add_dns_server (rdisc, item)) changed |= NM_RDISC_CONFIG_DNS_SERVERS; } for (i = 0; i < ra->dns_domains->len; i++) { NMRDiscDNSDomain *item = &g_array_index (ra->dns_domains, NMRDiscDNSDomain, i); if (nm_rdisc_add_dns_domain (rdisc, item)) changed |= NM_RDISC_CONFIG_DNS_DOMAINS; } if (rdisc->mtu != ra->mtu) { rdisc->mtu = ra->mtu; changed |= NM_RDISC_CONFIG_MTU; } if (rdisc->hop_limit != ra->hop_limit) { rdisc->hop_limit = ra->hop_limit; changed |= NM_RDISC_CONFIG_HOP_LIMIT; } priv->ras = g_slist_remove (priv->ras, priv->ras->data); fake_ra_free (ra); nm_rdisc_ra_received (NM_RDISC (self), now, changed); /* Schedule next RA */ if (priv->ras) { ra = priv->ras->data; priv->receive_ra_id = g_timeout_add_seconds (ra->when, receive_ra, self); } return G_SOURCE_REMOVE; }