Example #1
0
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;
}
Example #2
0
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;
}