static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMAccessPoint *ap = NM_AP (object); switch (prop_id) { case PROP_FLAGS: nm_ap_set_flags (ap, g_value_get_uint (value)); break; case PROP_WPA_FLAGS: nm_ap_set_wpa_flags (ap, g_value_get_uint (value)); break; case PROP_RSN_FLAGS: nm_ap_set_rsn_flags (ap, g_value_get_uint (value)); break; case PROP_SSID: nm_ap_set_ssid (ap, (GByteArray *) g_value_get_boxed (value)); break; case PROP_FREQUENCY: nm_ap_set_freq (ap, g_value_get_uint (value)); break; case PROP_MODE: nm_ap_set_mode (ap, g_value_get_uint (value)); break; case PROP_MAX_BITRATE: nm_ap_set_max_bitrate (ap, g_value_get_uint (value)); break; case PROP_STRENGTH: nm_ap_set_strength (ap, g_value_get_schar (value)); break; case PROP_HW_ADDRESS: break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
NMAccessPoint * nm_ap_new_fake_from_connection (NMConnection *connection) { NMAccessPoint *ap; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wireless_sec; const GByteArray *ssid; const char *mode, *band, *key_mgmt; guint32 channel, flags; gboolean psk = FALSE, eap = FALSE; g_return_val_if_fail (connection != NULL, NULL); s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS)); g_return_val_if_fail (s_wireless != NULL, NULL); ssid = nm_setting_wireless_get_ssid (s_wireless); g_return_val_if_fail (ssid != NULL, NULL); g_return_val_if_fail (ssid->len > 0, NULL); ap = nm_ap_new (); nm_ap_set_fake (ap, TRUE); nm_ap_set_ssid (ap, ssid); // FIXME: bssid too? mode = nm_setting_wireless_get_mode (s_wireless); if (mode) { if (!strcmp (mode, "infrastructure")) nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); else if (!strcmp (mode, "adhoc")) nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC); else goto error; } else { nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); } band = nm_setting_wireless_get_band (s_wireless); channel = nm_setting_wireless_get_channel (s_wireless); if (band && channel) { guint32 freq = channel_to_freq (channel, band); if (freq == 0) goto error; nm_ap_set_freq (ap, freq); } s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY); /* Assume presence of a security setting means the AP is encrypted */ if (!s_wireless_sec) goto done; key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec); /* Everything below here uses encryption */ nm_ap_set_flags (ap, nm_ap_get_flags (ap) | NM_802_11_AP_FLAGS_PRIVACY); /* Static & Dynamic WEP */ if (!strcmp (key_mgmt, "none") || !strcmp (key_mgmt, "ieee8021x")) goto done; psk = !strcmp (key_mgmt, "wpa-psk"); eap = !strcmp (key_mgmt, "wpa-eap"); if (psk || eap) { if (has_proto (s_wireless_sec, PROTO_WPA)) { flags = nm_ap_get_wpa_flags (ap); flags |= eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK; nm_ap_set_wpa_flags (ap, flags); } if (has_proto (s_wireless_sec, PROTO_RSN)) { flags = nm_ap_get_rsn_flags (ap); flags |= eap ? NM_802_11_AP_SEC_KEY_MGMT_802_1X : NM_802_11_AP_SEC_KEY_MGMT_PSK; nm_ap_set_rsn_flags (ap, flags); } add_pair_ciphers (ap, s_wireless_sec); add_group_ciphers (ap, s_wireless_sec); } else if (!strcmp (key_mgmt, "wpa-none")) { guint32 i; /* Ad-Hoc has special requirements: proto=WPA, pairwise=(none), and * group=TKIP/CCMP (but not both). */ flags = nm_ap_get_wpa_flags (ap); flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK; /* Clear ciphers; pairwise must be unset anyway, and group gets set below */ flags &= ~( NM_802_11_AP_SEC_PAIR_WEP40 | NM_802_11_AP_SEC_PAIR_WEP104 | NM_802_11_AP_SEC_PAIR_TKIP | NM_802_11_AP_SEC_PAIR_CCMP | NM_802_11_AP_SEC_GROUP_WEP40 | NM_802_11_AP_SEC_GROUP_WEP104 | NM_802_11_AP_SEC_GROUP_TKIP | NM_802_11_AP_SEC_GROUP_CCMP); for (i = 0; i < nm_setting_wireless_security_get_num_groups (s_wireless_sec); i++) { if (!strcmp (nm_setting_wireless_security_get_group (s_wireless_sec, i), "ccmp")) { flags |= NM_802_11_AP_SEC_GROUP_CCMP; break; } } /* Default to TKIP since not all WPA-capable cards can do CCMP */ if (!(flags & NM_802_11_AP_SEC_GROUP_CCMP)) flags |= NM_802_11_AP_SEC_GROUP_TKIP; nm_ap_set_wpa_flags (ap, flags); /* Don't use Ad-Hoc RSN yet */ nm_ap_set_rsn_flags (ap, NM_802_11_AP_SEC_NONE); } done: return ap; error: g_object_unref (ap); return NULL; }
static void foreach_property_cb (gpointer key, gpointer value, gpointer user_data) { GValue *variant = (GValue *) value; NMAccessPoint *ap = (NMAccessPoint *) user_data; if (G_VALUE_HOLDS_BOXED (variant)) { GArray *array = g_value_get_boxed (variant); if (!strcmp (key, "ssid")) { guint32 len = MIN (IW_ESSID_MAX_SIZE, array->len); GByteArray * ssid; /* Stupid ieee80211 layer uses <hidden> */ if (((len == 8) || (len == 9)) && (memcmp (array->data, "<hidden>", 8) == 0)) return; if (nm_utils_is_empty_ssid ((const guint8 *) array->data, len)) return; ssid = g_byte_array_sized_new (len); g_byte_array_append (ssid, (const guint8 *) array->data, len); nm_ap_set_ssid (ap, ssid); g_byte_array_free (ssid, TRUE); } else if (!strcmp (key, "bssid")) { struct ether_addr addr; if (array->len != ETH_ALEN) return; memset (&addr, 0, sizeof (struct ether_addr)); memcpy (&addr, array->data, ETH_ALEN); nm_ap_set_address (ap, &addr); } else if (!strcmp (key, "wpaie")) { guint8 * ie = (guint8 *) array->data; guint32 flags = nm_ap_get_wpa_flags (ap); if (array->len <= 0 || array->len > WPA_MAX_IE_LEN) return; flags = nm_ap_add_security_from_ie (flags, ie, array->len); nm_ap_set_wpa_flags (ap, flags); } else if (!strcmp (key, "rsnie")) { guint8 * ie = (guint8 *) array->data; guint32 flags = nm_ap_get_rsn_flags (ap); if (array->len <= 0 || array->len > WPA_MAX_IE_LEN) return; flags = nm_ap_add_security_from_ie (flags, ie, array->len); nm_ap_set_rsn_flags (ap, flags); } } else if (G_VALUE_HOLDS_INT (variant)) { gint32 int_val = g_value_get_int (variant); if (!strcmp (key, "frequency")) { nm_ap_set_freq (ap, (guint32) int_val); } else if (!strcmp (key, "maxrate")) { /* Supplicant reports as b/s, we use Kb/s internally */ nm_ap_set_max_bitrate (ap, int_val / 1000); } } else if (G_VALUE_HOLDS_UINT (variant)) { guint32 val = g_value_get_uint (variant); if (!strcmp (key, "capabilities")) { if (val & IEEE80211_CAP_ESS) { nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); } else if (val & IEEE80211_CAP_IBSS) { nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC); } if (val & IEEE80211_CAP_PRIVACY) { guint32 flags = nm_ap_get_flags (ap); nm_ap_set_flags (ap, flags | NM_802_11_AP_FLAGS_PRIVACY); } } } }
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 void foreach_property_cb (gpointer key, gpointer value, gpointer user_data) { GValue *variant = (GValue *) value; NMAccessPoint *ap = (NMAccessPoint *) user_data; if (G_VALUE_HOLDS_BOXED (variant)) { GArray *array = g_value_get_boxed (variant); if (!strcmp (key, "SSID")) { guint32 len = MIN (32, array->len); GByteArray *ssid; /* Stupid ieee80211 layer uses <hidden> */ if (((len == 8) || (len == 9)) && (memcmp (array->data, "<hidden>", 8) == 0)) return; if (nm_utils_is_empty_ssid ((const guint8 *) array->data, len)) return; ssid = g_byte_array_sized_new (len); g_byte_array_append (ssid, (const guint8 *) array->data, len); nm_ap_set_ssid (ap, ssid); g_byte_array_free (ssid, TRUE); } else if (!strcmp (key, "BSSID")) { struct ether_addr addr; if (array->len != ETH_ALEN) return; memset (&addr, 0, sizeof (struct ether_addr)); memcpy (&addr, array->data, ETH_ALEN); nm_ap_set_address (ap, &addr); } else if (!strcmp (key, "Rates")) { guint32 maxrate = 0; int i; /* Find the max AP rate */ for (i = 0; i < array->len; i++) { guint32 r = g_array_index (array, guint32, i); if (r > maxrate) { maxrate = r; nm_ap_set_max_bitrate (ap, r / 1000); } } } else if (!strcmp (key, "WPA")) { NM80211ApSecurityFlags flags = nm_ap_get_wpa_flags (ap); flags |= security_from_dict (g_value_get_boxed (variant)); nm_ap_set_wpa_flags (ap, flags); } else if (!strcmp (key, "RSN")) { NM80211ApSecurityFlags flags = nm_ap_get_rsn_flags (ap); flags |= security_from_dict (g_value_get_boxed (variant)); nm_ap_set_rsn_flags (ap, flags); } } else if (G_VALUE_HOLDS_UINT (variant)) { guint32 val = g_value_get_uint (variant); if (!strcmp (key, "Frequency")) nm_ap_set_freq (ap, val); } else if (G_VALUE_HOLDS_INT (variant)) { gint val = g_value_get_int (variant); if (!strcmp (key, "Signal")) nm_ap_set_strength (ap, nm_ap_utils_level_to_quality (val)); } else if (G_VALUE_HOLDS_STRING (variant)) { const char *val = g_value_get_string (variant); if (val && !strcmp (key, "Mode")) { if (strcmp (val, "infrastructure") == 0) nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); else if (strcmp (val, "ad-hoc") == 0) nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC); } } else if (G_VALUE_HOLDS_BOOLEAN (variant)) { gboolean val = g_value_get_boolean (variant); if (strcmp (key, "Privacy") == 0) { if (val) { NM80211ApFlags flags = nm_ap_get_flags (ap); nm_ap_set_flags (ap, flags | NM_802_11_AP_FLAGS_PRIVACY); } } } }