Parse the security and encryption mode in the netlink scan results. 68/172868/1
authorNiraj Kumar Goit <niraj.g@samsung.com>
Fri, 16 Mar 2018 09:55:41 +0000 (15:25 +0530)
committerNiraj Kumar Goit <niraj.g@samsung.com>
Fri, 16 Mar 2018 09:55:41 +0000 (15:25 +0530)
Change-Id: I3f16f5a09f6e1e05fbdf8ac024e66cd27fde5f45
Signed-off-by: Niraj Kumar Goit <niraj.g@samsung.com>
include/wifi-netlink-scan.h
src/wifi-netlink-scan.c

index b4e01fd..ad41b6b 100755 (executable)
@@ -53,6 +53,8 @@ struct bss_scan_info_t {
        int ssid_len;
        int freq;
        int signal;
+       int security_type;
+       int encryption_type;
 };
 
 struct netconfig_netlink_scan_results {
index d60f7ea..d66f22a 100755 (executable)
@@ -44,6 +44,8 @@ void __netconfig_notify_netlink_scan_done(void)
        const char *prop_freq = "freq";
        const char *prop_rssi = "rssi";
        const char *prop_vsie = "vsie";
+       const char *prop_sec = "security";
+       const char *prop_enc = "encryption";
 
        builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
        for (list = bss_info_list; list != NULL; list = list->next) {
@@ -55,12 +57,16 @@ void __netconfig_notify_netlink_scan_done(void)
                        char *vsie = (char *)bss_info->vsie;
                        int freq = (int)bss_info->freq;
                        int signal = (int)bss_info->signal;
+                       int sec_type = (int)bss_info->security_type;
+                       int enc_type = (int)bss_info->encryption_type;
 
                        g_variant_builder_add(builder, "{sv}", prop_ssid, g_variant_new_string(ssid));
                        g_variant_builder_add(builder, "{sv}", prop_bssid, g_variant_new_string(bssid));
                        g_variant_builder_add(builder, "{sv}", prop_freq, g_variant_new_int32(freq));
                        g_variant_builder_add(builder, "{sv}", prop_rssi, g_variant_new_int32(signal));
                        g_variant_builder_add(builder, "{sv}", prop_vsie, g_variant_new_string(vsie));
+                       g_variant_builder_add(builder, "{sv}", prop_sec, g_variant_new_int32(sec_type));
+                       g_variant_builder_add(builder, "{sv}", prop_enc, g_variant_new_int32(enc_type));
                }
        }
 
@@ -199,6 +205,187 @@ static void __netconfig_macaddress_str(char *bssid, unsigned char *user_data)
        }
 }
 
+typedef enum {
+       WIFI_SECURITY_TYPE_NONE = 0,
+       WIFI_SECURITY_TYPE_WEP = 1,
+       WIFI_SECURITY_TYPE_WPA_PSK = 2,
+       WIFI_SECURITY_TYPE_WPA2_PSK = 3,
+       WIFI_SECURITY_TYPE_EAP = 4,
+} wifi_security_type_e;
+
+typedef enum {
+       WIFI_ENCRYPTION_TYPE_NONE = 0,
+       WIFI_ENCRYPTION_TYPE_WEP = 1,
+       WIFI_ENCRYPTION_TYPE_TKIP = 2,
+       WIFI_ENCRYPTION_TYPE_AES = 3,
+       WIFI_ENCRYPTION_TYPE_TKIP_AES_MIXED = 4,
+} wifi_encryption_type_e;
+
+static unsigned char ms_oui[3]      = { 0x00, 0x50, 0xf2 };
+static unsigned char ieee80211_oui[3]   = { 0x00, 0x0f, 0xac };
+
+static void __netconfig_get_security(unsigned char *bss_element, int length, wifi_security_type_e *sec_type, wifi_encryption_type_e *enc_type)
+{
+       int i;
+       unsigned char *data;
+       uint8_t *t_data;
+       int len;
+       __u16 count;
+
+       *sec_type = WIFI_SECURITY_TYPE_NONE;
+       *enc_type = WIFI_ENCRYPTION_TYPE_NONE;
+
+       while (length >= 2 && length >= bss_element[1]) {
+               if (bss_element[0] == 221 && (bss_element[1] >= 4 && memcmp(bss_element + 2, ms_oui, 3) == 0)) {
+                       data = bss_element + 2 + 4 + 2 + 4;
+                       len = bss_element[1] - 4 - 2 - 4;
+
+                       if (len < 2) {
+                               length -= bss_element[1] + 2;
+                               bss_element += bss_element[1] + 2;
+                               continue;
+                       }
+
+                       count = data[0] | (data[1] << 8);
+
+                       if (2 + (count * 4) > len) {
+                               length -= bss_element[1] + 2;
+                               bss_element += bss_element[1] + 2;
+                               continue;
+                       }
+
+                       for (i = 0; i < count; i++) {
+                               t_data = (data + 2 + (i * 4));
+
+                               if ((memcmp(t_data, ms_oui, 3) == 0) || (memcmp(t_data, ieee80211_oui, 3) == 0)) {
+                                       if (t_data[3] == 1 || t_data[3] == 5) { // 1 : WEP-40, 5 : WEP-104
+                                               *sec_type = WIFI_SECURITY_TYPE_WEP;
+                                               *enc_type = WIFI_ENCRYPTION_TYPE_WEP;
+                                               return;
+                                       } else if (t_data[3] == 2) { // 2 : TKIP
+                                               if (*sec_type != WIFI_SECURITY_TYPE_WPA2_PSK)
+                                                       *sec_type = WIFI_SECURITY_TYPE_WPA_PSK;
+                                               if (*enc_type == WIFI_ENCRYPTION_TYPE_AES)
+                                                       *enc_type = WIFI_ENCRYPTION_TYPE_TKIP_AES_MIXED;
+                                               else
+                                                       *enc_type = WIFI_ENCRYPTION_TYPE_TKIP;
+                                       } else if (t_data[3] == 4) { // 3 : CCMP
+                                               if (*sec_type != WIFI_SECURITY_TYPE_WPA2_PSK)
+                                                       *sec_type = WIFI_SECURITY_TYPE_WPA_PSK;
+                                               if (*enc_type == WIFI_ENCRYPTION_TYPE_TKIP)
+                                                       *enc_type = WIFI_ENCRYPTION_TYPE_TKIP_AES_MIXED;
+                                               else
+                                                       *enc_type = WIFI_ENCRYPTION_TYPE_AES;
+                                       }
+                               } //if
+                       } //for
+
+                       data += 2 + (count * 4);
+                       len -= 2 + (count * 4);
+
+                       if (len < 2) {
+                               length -= bss_element[1] + 2;
+                               bss_element += bss_element[1] + 2;
+                               continue;
+                       }
+
+                       count = data[0] | (data[1] << 8);
+
+                       if (2 + (count * 4) > len) {
+                               length -= bss_element[1] + 2;
+                               bss_element += bss_element[1] + 2;
+                               continue;
+                       }
+
+                       for (i = 0; i < count; i++) {
+                               t_data = (data + 2 + (i * 4));
+
+                               if ((memcmp(t_data, ms_oui, 3) == 0) || (memcmp(t_data, ieee80211_oui, 3) == 0)) {
+                                       if (t_data[3] == 1 || t_data[3] == 3 || t_data[3] == 5) { // 1 : IEEE 802.1X, 3 : FT/IEEE 802.1X, 5 : IEEE 802.1X/SHA-256
+                                               *sec_type = WIFI_SECURITY_TYPE_EAP;
+                                       } else if (t_data[3] == 2 || t_data[3] == 4 || t_data[3] == 6) {  // 2 : PSK, 4 : FT/PSK, 6 : PSK/SHA-256
+                                               if (*sec_type != WIFI_SECURITY_TYPE_WPA2_PSK)
+                                                       *sec_type = WIFI_SECURITY_TYPE_WPA_PSK;
+                                       }
+                               }
+                       }
+               } else if (bss_element[0] == 48 && (bss_element[1] >= 2 && bss_element[1] <= 255)) {
+                       data = bss_element + 2 + 2 + 4;
+                       len = bss_element[1] - 2 - 4;
+
+                       if (len < 2) {
+                               length -= bss_element[1] + 2;
+                               bss_element += bss_element[1] + 2;
+                               continue;
+                       }
+
+                       count = data[0] | (data[1] << 8);
+                       if (2 + (count + 4) > len) {
+                               length -= bss_element[1] + 2;
+                               bss_element += bss_element[1] + 2;
+                               continue;
+                       }
+
+                       for (i = 0; i < count; i++) {
+                               t_data = (data + 2 + (i * 4));
+
+                               if ((memcmp(t_data, ms_oui, 3) == 0) || (memcmp(t_data, ieee80211_oui, 3) == 0)) {
+                                       if (t_data[3] == 1 || t_data[3] == 5) { // 1 : WEP-40, 5 : WEP-104
+                                               *sec_type = WIFI_SECURITY_TYPE_WEP;
+                                               *enc_type = WIFI_ENCRYPTION_TYPE_WEP;
+                                               return;
+                                       } else if (t_data[3] == 2) { // 2 : TKIP
+                                               *sec_type = WIFI_SECURITY_TYPE_WPA2_PSK;
+                                               if (*enc_type == WIFI_ENCRYPTION_TYPE_AES)
+                                                       *enc_type = WIFI_ENCRYPTION_TYPE_TKIP_AES_MIXED;
+                                               else
+                                                       *enc_type = WIFI_ENCRYPTION_TYPE_TKIP;
+                                       } else if (t_data[3] == 4) { // 3 : CCMP
+                                               *sec_type = WIFI_SECURITY_TYPE_WPA2_PSK;
+                                               if (*enc_type == WIFI_ENCRYPTION_TYPE_TKIP)
+                                                       *enc_type = WIFI_ENCRYPTION_TYPE_TKIP_AES_MIXED;
+                                               else
+                                                       *enc_type = WIFI_ENCRYPTION_TYPE_AES;
+                                       }
+                               }
+                       }
+
+                       data += 2 + (count * 4);
+                       len -= 2 + (count * 4);
+
+                       if (len < 2) {
+                               length -= bss_element[1] + 2;
+                               bss_element += bss_element[1] + 2;
+                               continue;
+                       }
+
+                       count = data[0] | (data[1] << 8);
+                       if (2 + (count * 4) > len) {
+                               length -= bss_element[1] + 2;
+                               bss_element += bss_element[1] + 2;
+                               continue;
+                       }
+
+                       for (i = 0; i < count; i++) {
+                               t_data = (data + 2 + (i * 4));
+
+                               if ((memcmp(t_data, ms_oui, 3) == 0) || (memcmp(t_data, ieee80211_oui, 3) == 0)) {
+                                       if (t_data[3] == 1 || t_data[3] == 3 || t_data[3] == 5) { // 1 : IEEE 802.1X, 3 : FT/IEEE 802.1X, 5 : IEEE 802.1X/SHA-256
+                                               *sec_type = WIFI_SECURITY_TYPE_EAP;
+                                       } else if (t_data[3] == 2 || t_data[3] == 4 || t_data[3] == 6) {  // 2 : PSK, 4 : FT/PSK, 6 : PSK/SHA-256
+                                               *sec_type = WIFI_SECURITY_TYPE_WPA2_PSK;
+                                       }
+                               }
+                       } //for
+               } //else if
+
+               length -= bss_element[1] + 2;
+               bss_element += bss_element[1] + 2;
+       } //while
+
+       return;
+}
+
 static void __netconfig_get_vsie(unsigned char *bss_element, int length, char **dst)
 {
        int i = 0;
@@ -269,6 +456,8 @@ static int __netconfig_netlink_scan_cb(struct nl_msg *msg, void *user_data)
        struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
        char bssid[NETCONFIG_BSSID_LEN+1];
        char ssid[NETCONFIG_SSID_LEN+1] = {0, };
+       wifi_security_type_e sec_type = WIFI_SECURITY_TYPE_NONE;
+       wifi_encryption_type_e enc_type = WIFI_ENCRYPTION_TYPE_NONE;
        char *vsie = NULL;
        struct nlattr *tb[NL80211_ATTR_MAX + 1];
        struct nlattr *bss[NL80211_BSS_MAX + 1];
@@ -296,6 +485,8 @@ static int __netconfig_netlink_scan_cb(struct nl_msg *msg, void *user_data)
        __netconfig_macaddress_str(bssid, nla_data(bss[NL80211_BSS_BSSID]));
        __netconfig_found_ap(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]), nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]), ssid);
        __netconfig_get_vsie(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]), nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]), &vsie);
+       __netconfig_get_security(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]),
+                       nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]), &sec_type, &enc_type);
 
        /** Create AP info list. */
        if (ssid[0] != '\0') {
@@ -322,7 +513,12 @@ static int __netconfig_netlink_scan_cb(struct nl_msg *msg, void *user_data)
                        signal /= 100; /** mBm to dBm */
                        bss_info->signal = signal;
                }
-               DBG("%s %d %d %s [vsie: %s]", bss_info->bssid, bss_info->freq, bss_info->signal, bss_info->ssid, bss_info->vsie);
+
+               bss_info->security_type = sec_type;
+               bss_info->encryption_type = enc_type;
+               DBG("%s %d %d %s %d %d [vsie: %s]", bss_info->bssid, bss_info->freq,
+                               bss_info->signal, bss_info->ssid, bss_info->security_type,
+                               bss_info->encryption_type, bss_info->vsie);
 
                if (bss_info->ssid[0] == '\0')
                        g_free(bss_info);