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; }
void nm_ap_update_from_properties (NMAccessPoint *ap, const char *supplicant_path, GVariant *properties) { NMAccessPointPrivate *priv; char *addr; const guint8 *bytes; GVariant *v; gsize len; gboolean b = FALSE; const char *s; gint16 i16; guint16 u16; g_return_if_fail (ap != NULL); g_return_if_fail (properties != NULL); priv = NM_AP_GET_PRIVATE (ap); g_object_freeze_notify (G_OBJECT (ap)); if (g_variant_lookup (properties, "Privacy", "b", &b) && b) nm_ap_set_flags (ap, priv->flags | NM_802_11_AP_FLAGS_PRIVACY); if (g_variant_lookup (properties, "Mode", "&s", &s)) { if (!g_strcmp0 (s, "infrastructure")) nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); else if (!g_strcmp0 (s, "ad-hoc")) nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC); } if (g_variant_lookup (properties, "Signal", "n", &i16)) nm_ap_set_strength (ap, nm_ap_utils_level_to_quality (i16)); if (g_variant_lookup (properties, "Frequency", "q", &u16)) nm_ap_set_freq (ap, u16); v = g_variant_lookup_value (properties, "SSID", G_VARIANT_TYPE_BYTESTRING); if (v) { bytes = g_variant_get_fixed_array (v, &len, 1); len = MIN (32, len); /* Stupid ieee80211 layer uses <hidden> */ if ( bytes && len && !(((len == 8) || (len == 9)) && !memcmp (bytes, "<hidden>", 8)) && !nm_utils_is_empty_ssid (bytes, len)) nm_ap_set_ssid (ap, bytes, len); g_variant_unref (v); } v = g_variant_lookup_value (properties, "BSSID", G_VARIANT_TYPE_BYTESTRING); if (v) { bytes = g_variant_get_fixed_array (v, &len, 1); if (len == ETH_ALEN) { addr = nm_utils_hwaddr_ntoa (bytes, len); nm_ap_set_address (ap, addr); g_free (addr); } g_variant_unref (v); } v = g_variant_lookup_value (properties, "Rates", G_VARIANT_TYPE ("au")); if (v) { const guint32 *rates = g_variant_get_fixed_array (v, &len, sizeof (guint32)); guint32 maxrate = 0; int i; /* Find the max AP rate */ for (i = 0; i < len; i++) { if (rates[i] > maxrate) { maxrate = rates[i]; nm_ap_set_max_bitrate (ap, rates[i] / 1000); } } g_variant_unref (v); } v = g_variant_lookup_value (properties, "WPA", G_VARIANT_TYPE_VARDICT); if (v) { nm_ap_set_wpa_flags (ap, priv->wpa_flags | security_from_vardict (v)); g_variant_unref (v); } v = g_variant_lookup_value (properties, "RSN", G_VARIANT_TYPE_VARDICT); if (v) { nm_ap_set_rsn_flags (ap, priv->rsn_flags | security_from_vardict (v)); g_variant_unref (v); } if (!priv->supplicant_path) priv->supplicant_path = g_strdup (supplicant_path); nm_ap_set_last_seen (ap, nm_utils_get_monotonic_timestamp_s ()); priv->fake = FALSE; g_object_thaw_notify (G_OBJECT (ap)); }
static NMIP4Config * lease_to_ip4_config (const char *iface, int ifindex, sd_dhcp_lease *lease, GHashTable *options, guint32 default_priority, gboolean log_lease, GError **error) { NMIP4Config *ip4_config = NULL; struct in_addr tmp_addr; const struct in_addr *addr_list; char buf[INET_ADDRSTRLEN]; const char *str; guint32 lifetime = 0, i; NMPlatformIP4Address address; GString *l; struct sd_dhcp_route *routes; guint16 mtu; int r, num; guint64 end_time; const void *data; gsize data_len; gboolean metered = FALSE; g_return_val_if_fail (lease != NULL, NULL); ip4_config = nm_ip4_config_new (ifindex); /* Address */ sd_dhcp_lease_get_address (lease, &tmp_addr); memset (&address, 0, sizeof (address)); address.address = tmp_addr.s_addr; address.peer_address = tmp_addr.s_addr; str = nm_utils_inet4_ntop (tmp_addr.s_addr, NULL); LOG_LEASE (LOGD_DHCP4, " address %s", str); add_option (options, dhcp4_requests, DHCP_OPTION_IP_ADDRESS, str); /* Prefix/netmask */ sd_dhcp_lease_get_netmask (lease, &tmp_addr); address.plen = nm_utils_ip4_netmask_to_prefix (tmp_addr.s_addr); LOG_LEASE (LOGD_DHCP4, " plen %d", address.plen); add_option (options, dhcp4_requests, DHCP_OPTION_SUBNET_MASK, nm_utils_inet4_ntop (tmp_addr.s_addr, NULL)); /* Lease time */ sd_dhcp_lease_get_lifetime (lease, &lifetime); address.timestamp = nm_utils_get_monotonic_timestamp_s (); address.lifetime = address.preferred = lifetime; end_time = (guint64) time (NULL) + lifetime; LOG_LEASE (LOGD_DHCP4, " expires in %" G_GUINT32_FORMAT " seconds", lifetime); add_option_u64 (options, dhcp4_requests, DHCP_OPTION_IP_ADDRESS_LEASE_TIME, end_time); address.source = NM_IP_CONFIG_SOURCE_DHCP; nm_ip4_config_add_address (ip4_config, &address); /* Gateway */ r = sd_dhcp_lease_get_router (lease, &tmp_addr); if (r == 0) { nm_ip4_config_set_gateway (ip4_config, tmp_addr.s_addr); str = nm_utils_inet4_ntop (tmp_addr.s_addr, NULL); LOG_LEASE (LOGD_DHCP4, " gateway %s", str); add_option (options, dhcp4_requests, DHCP_OPTION_ROUTER, str); } /* DNS Servers */ num = sd_dhcp_lease_get_dns (lease, &addr_list); if (num > 0) { l = g_string_sized_new (30); for (i = 0; i < num; i++) { if (addr_list[i].s_addr) { nm_ip4_config_add_nameserver (ip4_config, addr_list[i].s_addr); str = nm_utils_inet4_ntop (addr_list[i].s_addr, NULL); LOG_LEASE (LOGD_DHCP4, " nameserver '%s'", str); g_string_append_printf (l, "%s%s", l->len ? " " : "", str); } } if (l->len) add_option (options, dhcp4_requests, DHCP_OPTION_DOMAIN_NAME_SERVER, l->str); g_string_free (l, TRUE); } /* Domain Name */ r = sd_dhcp_lease_get_domainname (lease, &str); if (r == 0) { /* Multiple domains sometimes stuffed into the option */ char **domains = g_strsplit (str, " ", 0); char **s; for (s = domains; *s; s++) { LOG_LEASE (LOGD_DHCP4, " domain name '%s'", *s); nm_ip4_config_add_domain (ip4_config, *s); } g_strfreev (domains); add_option (options, dhcp4_requests, DHCP_OPTION_DOMAIN_NAME, str); } /* Hostname */ r = sd_dhcp_lease_get_hostname (lease, &str); if (r == 0) { LOG_LEASE (LOGD_DHCP4, " hostname '%s'", str); add_option (options, dhcp4_requests, DHCP_OPTION_HOST_NAME, str); } /* Routes */ num = sd_dhcp_lease_get_routes (lease, &routes); if (num > 0) { l = g_string_sized_new (30); for (i = 0; i < num; i++) { NMPlatformIP4Route route; const char *gw_str; memset (&route, 0, sizeof (route)); route.network = routes[i].dst_addr.s_addr; route.plen = routes[i].dst_prefixlen; route.gateway = routes[i].gw_addr.s_addr; route.source = NM_IP_CONFIG_SOURCE_DHCP; route.metric = default_priority; nm_ip4_config_add_route (ip4_config, &route); str = nm_utils_inet4_ntop (route.network, buf); gw_str = nm_utils_inet4_ntop (route.gateway, NULL); LOG_LEASE (LOGD_DHCP4, " static route %s/%d gw %s", str, route.plen, gw_str); g_string_append_printf (l, "%s%s/%d %s", l->len ? " " : "", str, route.plen, gw_str); } add_option (options, dhcp4_requests, DHCP_OPTION_RFC3442_ROUTES, l->str); g_string_free (l, TRUE); } /* MTU */ r = sd_dhcp_lease_get_mtu (lease, &mtu); if (r == 0 && mtu) { nm_ip4_config_set_mtu (ip4_config, mtu, NM_IP_CONFIG_SOURCE_DHCP); add_option_u32 (options, dhcp4_requests, DHCP_OPTION_INTERFACE_MTU, mtu); LOG_LEASE (LOGD_DHCP4, " mtu %u", mtu); } /* NTP servers */ num = sd_dhcp_lease_get_ntp (lease, &addr_list); if (num > 0) { l = g_string_sized_new (30); for (i = 0; i < num; i++) { str = nm_utils_inet4_ntop (addr_list[i].s_addr, buf); LOG_LEASE (LOGD_DHCP4, " ntp server '%s'", str); g_string_append_printf (l, "%s%s", l->len ? " " : "", str); } add_option (options, dhcp4_requests, DHCP_OPTION_NTP_SERVER, l->str); g_string_free (l, TRUE); } r = sd_dhcp_lease_get_vendor_specific (lease, &data, &data_len); if (r >= 0) metered = !!memmem (data, data_len, "ANDROID_METERED", STRLEN ("ANDROID_METERED")); nm_ip4_config_set_metered (ip4_config, metered); return ip4_config; }