From 3994e96eb14f7f478acf8047ce1f0f60c3900917 Mon Sep 17 00:00:00 2001 From: Niraj Kumar Goit Date: Fri, 10 Aug 2018 09:04:23 +0530 Subject: [PATCH] Added support to set and get IP configuration details. Change-Id: I08320822454355853883991cad0d8b0ae58f5e36 Signed-off-by: Niraj Kumar Goit --- include/wifi-config.h | 8 ++ src/wifi-config.c | 233 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 223 insertions(+), 18 deletions(-) diff --git a/include/wifi-config.h b/include/wifi-config.h index 86002a0..dd871a1 100755 --- a/include/wifi-config.h +++ b/include/wifi-config.h @@ -34,6 +34,14 @@ extern "C" { #define WIFI_CONFIG_FAVORITE "Favorite" #define WIFI_CONFIG_AUTOCONNECT "AutoConnect" #define WIFI_CONFIG_HIDDEN "Hidden" +#define WIFI_CONFIG_IPV4_METHOD "IPv4.method" +#define WIFI_CONFIG_IPV6_METHOD "IPv6.method" +#define WIFI_CONFIG_IPV4_DNS_METHOD "Nameservers.IPv4method" +#define WIFI_CONFIG_IPV6_DNS_METHOD "Nameservers.IPv6method" +#define WIFI_CONFIG_IPV4_ADDRESS "IPv4.local_address" +#define WIFI_CONFIG_IPV4_SUBNET_MASK "IPv4.netmask_prefixlen" +#define WIFI_CONFIG_IPV4_GATEWAY_ADDRESS "IPv4.gateway" +#define WIFI_CONFIG_DNS_ADDRESS "Nameservers" #define WIFI_CONFIG_FAILURE "Failure" #define WIFI_CONFIG_PROXYADDRESS "ProxyAddress" #define WIFI_CONFIG_PROXY_METHOD "Proxy.Method" diff --git a/src/wifi-config.c b/src/wifi-config.c index 2d9f5f8..4d82734 100755 --- a/src/wifi-config.c +++ b/src/wifi-config.c @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include #include @@ -50,6 +53,8 @@ #define WIFI_MAC_ADD_LENGTH 17 #define WIFI_MAC_ADD_PATH "/sys/class/net/wlan0/address" +#define NET_DNS_ADDR_MAX 2 + struct wifi_eap_config { gchar *anonymous_identity; gchar *ca_cert; @@ -62,6 +67,17 @@ struct wifi_eap_config { gchar *subject_match; }; +typedef struct { + gchar *ip_address; + gchar *subnet_mask; + gchar *gateway_address; + gchar *dns_address[NET_DNS_ADDR_MAX]; + int prefix_length; + int dns_count; + gchar *ip_type; + gchar *dns_type; +} wifi_ip_info_s; + struct wifi_config { gchar *name; gchar *ssid; @@ -72,6 +88,7 @@ struct wifi_config { gchar *is_hidden; gchar *proxy_address; struct wifi_eap_config *eap_config; + wifi_ip_info_s *ip_info; gchar *last_error; }; @@ -99,6 +116,21 @@ static void __free_wifi_configuration(struct wifi_config *conf) g_free(conf->eap_config->subject_match); g_free(conf->eap_config); } + + if (conf->ip_info) { + g_free(conf->ip_info->ip_type); + g_free(conf->ip_info->ip_address); + g_free(conf->ip_info->subnet_mask); + g_free(conf->ip_info->gateway_address); + g_free(conf->ip_info->dns_type); + + int i = 0, count = conf->ip_info->dns_count; + while (i < count) { + g_free(conf->ip_info->dns_address[i]); + i++; + } + g_free(conf->ip_info); + } g_free(conf); } @@ -313,6 +345,58 @@ static gboolean _load_configuration(const gchar *config_id, struct wifi_config * config->is_hidden = g_strdup("FALSE"); DBG("is_hidden [%s]", config->is_hidden); + config->ip_info->ip_type = g_key_file_get_string(keyfile, group_name, + WIFI_CONFIG_IPV4_METHOD, NULL); + if (config->ip_info->ip_type) + DBG("IPv4.Method:%s", config->ip_info->ip_type); + + config->ip_info->ip_address = g_key_file_get_string(keyfile, group_name, + WIFI_CONFIG_IPV4_ADDRESS, NULL); + if (config->ip_info->ip_address) + DBG("IPv4.Address:%s", config->ip_info->ip_address); + + int prefix_len; + in_addr_t addr; + struct in_addr netmask; + char *mask; + prefix_len = g_key_file_get_integer(keyfile, group_name, + WIFI_CONFIG_IPV4_SUBNET_MASK, NULL); + addr = 0xffffffff << (32 - prefix_len); + netmask.s_addr = htonl(addr); + mask = inet_ntoa(netmask); + config->ip_info->subnet_mask = g_strdup(mask); + if (config->ip_info->subnet_mask) + DBG("IPv4.SubnetMask:%s", config->ip_info->subnet_mask); + + config->ip_info->gateway_address = g_key_file_get_string(keyfile, + group_name, WIFI_CONFIG_IPV4_GATEWAY_ADDRESS, + NULL); + if (config->ip_info->gateway_address) + DBG("IPv4.gateway:%s", config->ip_info->gateway_address); + + config->ip_info->dns_type = g_key_file_get_string(keyfile, group_name, + WIFI_CONFIG_IPV4_DNS_METHOD, NULL); + if (config->ip_info->dns_type) + DBG("DNS.IPv4Method:%s", config->ip_info->dns_type); + + char **nameservers; + gsize length; + nameservers = g_key_file_get_string_list(keyfile, group_name, + WIFI_CONFIG_DNS_ADDRESS, &length, NULL); + if (nameservers) { + if (length > 0) { + config->ip_info->dns_count = length; + int i = 0; + while (i < NET_DNS_ADDR_MAX && nameservers[i]) { + config->ip_info->dns_address[i] = g_strdup(nameservers[i]); + DBG("DNSAddress[%d]:%s", i+1, config->ip_info->dns_address[i]); + i += 1; + } + } + g_strfreev(nameservers); + } + + if (g_strcmp0(config->security_type, WIFI_SECURITY_EAP) == 0) { config->eap_config->anonymous_identity = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_ANONYMOUS_IDENTITY, NULL); config->eap_config->ca_cert = g_key_file_get_string(keyfile, group_name, WIFI_CONFIG_EAP_CACERT, NULL); @@ -963,9 +1047,11 @@ gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context, g_return_val_if_fail(wifi != NULL, TRUE); conf = g_new0(struct wifi_config, 1); + conf->ip_info = g_new0(wifi_ip_info_s, 1); ret = _load_configuration(config_id, conf); if (ret != TRUE) { + g_free(conf->ip_info); g_free(conf); ERR("Fail to _load_configuration"); netconfig_error_no_profile(context); @@ -982,23 +1068,65 @@ gboolean handle_load_configuration(Wifi *wifi, GDBusMethodInvocation *context, else g_variant_builder_add(b, "{sv}", WIFI_CONFIG_PROXYADDRESS, g_variant_new_string("NONE")); + if (conf->ip_info->ip_type != NULL) + g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_METHOD, g_variant_new_string(conf->ip_info->ip_type)); + + if (conf->ip_info->ip_address != NULL) + g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_ADDRESS, g_variant_new_string(conf->ip_info->ip_address)); + + if (conf->ip_info->subnet_mask != NULL) + g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_SUBNET_MASK, g_variant_new_string(conf->ip_info->subnet_mask)); + + if (conf->ip_info->gateway_address != NULL) + g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_GATEWAY_ADDRESS, g_variant_new_string(conf->ip_info->gateway_address)); + + if (conf->ip_info->dns_type != NULL) + g_variant_builder_add(b, "{sv}", WIFI_CONFIG_IPV4_DNS_METHOD, g_variant_new_string(conf->ip_info->dns_type)); + + int i = 0, count = conf->ip_info->dns_count; + while (i < count) { + if (conf->ip_info->dns_address[i] != NULL) + g_variant_builder_add(b, "{sv}", WIFI_CONFIG_DNS_ADDRESS, g_variant_new_string(conf->ip_info->dns_address[i])); + + i += 1; + } + if (conf->last_error != NULL) g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string(conf->last_error)); else g_variant_builder_add(b, "{sv}", WIFI_CONFIG_FAILURE, g_variant_new_string("ERROR_NONE")); - g_free(conf->proxy_address); - g_free(conf->last_error); - g_free(conf->name); - g_free(conf->security_type); - g_free(conf->is_hidden); - g_free(conf); + __free_wifi_configuration(conf); wifi_complete_load_configuration(wifi, context, g_variant_builder_end(b)); g_variant_builder_unref(b); return TRUE; } +static unsigned char __netconfig_convert_netmask_to_prefixlen( + const char *netmask) +{ + unsigned char bits; + in_addr_t mask; + in_addr_t host; + + if (!netmask) + return 32; + + mask = inet_network(netmask); + host = ~mask; + + /* a valid netmask must be 2^n - 1 */ + if ((host & (host + 1)) != 0) + return -1; + + bits = 0; + for (; mask; mask <<= 1) + ++bits; + + return bits; +} + gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context, const gchar *config_id, GVariant *configuration) { @@ -1009,6 +1137,7 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context, GVariant *value; gchar *field; gchar *group_name = NULL; + int order = 0; if ((wifi == NULL) || (config_id == NULL) || (configuration == NULL)) { ERR("Invalid parameter"); @@ -1017,6 +1146,7 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context, } conf = g_new0(struct wifi_config, 1); + conf->ip_info = g_new0(wifi_ip_info_s, 1); g_variant_get(configuration, "a{sv}", &iter); while (g_variant_iter_loop(iter, "{sv}", &field, &value)) { @@ -1048,6 +1178,50 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context, } else { conf->is_hidden = NULL; } + } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_METHOD) == 0) { + if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) { + conf->ip_info->ip_type = g_strdup(g_variant_get_string(value, NULL)); + DBG("IP config type [%s]", conf->ip_info->ip_type); + } else { + conf->ip_info->ip_type = NULL; + } + } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_ADDRESS) == 0) { + if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) { + conf->ip_info->ip_address = g_strdup(g_variant_get_string(value, NULL)); + DBG("IP address [%s]", conf->ip_info->ip_address); + } else { + conf->ip_info->ip_address = NULL; + } + } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_SUBNET_MASK) == 0) { + if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) { + conf->ip_info->subnet_mask = g_strdup(g_variant_get_string(value, NULL)); + DBG("Subnet Mask [%s]", conf->ip_info->subnet_mask); + } else { + conf->ip_info->subnet_mask = NULL; + } + } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_GATEWAY_ADDRESS) == 0) { + if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) { + conf->ip_info->gateway_address = g_strdup(g_variant_get_string(value, NULL)); + DBG("Gateway address [%s]", conf->ip_info->gateway_address); + } else { + conf->ip_info->gateway_address = NULL; + } + } else if (g_strcmp0(field, WIFI_CONFIG_IPV4_DNS_METHOD) == 0) { + if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) { + conf->ip_info->dns_type = g_strdup(g_variant_get_string(value, NULL)); + DBG("DNS config type [%s]", conf->ip_info->dns_type); + } else { + conf->ip_info->dns_type = NULL; + } + } else if (g_strcmp0(field, WIFI_CONFIG_DNS_ADDRESS) == 0) { + if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) { + conf->ip_info->dns_address[order] = g_strdup(g_variant_get_string(value, NULL)); + DBG("DNS address [%s]", conf->ip_info->dns_address[order]); + conf->ip_info->dns_count = order + 1; + order++; + } else { + conf->ip_info->dns_address[order++] = NULL; + } } else if (g_strcmp0(field, WIFI_CONFIG_PROXYADDRESS) == 0) { if (g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) { conf->proxy_address = g_strdup(g_variant_get_string(value, NULL)); @@ -1062,12 +1236,7 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context, ret = __get_group_name(WIFI_CONFIG_PREFIX, config_id, &group_name); if (ret != TRUE) { - g_free(conf->name); - g_free(conf->ssid); - g_free(conf->passphrase); - g_free(conf->is_hidden); - g_free(conf->proxy_address); - g_free(conf); + __free_wifi_configuration(conf); ERR("Fail to get_wifi_config_group_name"); netconfig_error_fail_save_congifuration(context); return TRUE; @@ -1107,6 +1276,39 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context, g_key_file_set_boolean(keyfile, group_name, WIFI_CONFIG_HIDDEN, hidden); } + if (conf->ip_info->ip_type != NULL) + g_key_file_set_string(keyfile, group_name, + WIFI_CONFIG_IPV4_METHOD, conf->ip_info->ip_type); + + if (conf->ip_info->ip_address != NULL) + g_key_file_set_string(keyfile, group_name, + WIFI_CONFIG_IPV4_ADDRESS, conf->ip_info->ip_address); + + if (conf->ip_info->subnet_mask != NULL) { + unsigned char prefix_len; + prefix_len = __netconfig_convert_netmask_to_prefixlen( + conf->ip_info->subnet_mask); + g_key_file_set_integer(keyfile, group_name, + WIFI_CONFIG_IPV4_SUBNET_MASK, prefix_len); + } + + if (conf->ip_info->gateway_address != NULL) + g_key_file_set_string(keyfile, group_name, + WIFI_CONFIG_IPV4_GATEWAY_ADDRESS, conf->ip_info->gateway_address); + + if (conf->ip_info->dns_type != NULL) + g_key_file_set_string(keyfile, group_name, + WIFI_CONFIG_IPV4_DNS_METHOD, conf->ip_info->dns_type); + + int i = 0, count = conf->ip_info->dns_count; + while (i < count) { + if (conf->ip_info->dns_address[i] != NULL) + g_key_file_set_string(keyfile, group_name, WIFI_CONFIG_DNS_ADDRESS, + conf->ip_info->dns_address[i]); + + i += 1; + } + ret = _save_configuration(config_id, keyfile); if (ret == TRUE) { INFO("Success to save configuration [%s]", config_id); @@ -1118,12 +1320,7 @@ gboolean handle_save_configuration(Wifi *wifi, GDBusMethodInvocation *context, g_key_file_free(keyfile); g_free(group_name); - g_free(conf->name); - g_free(conf->ssid); - g_free(conf->passphrase); - g_free(conf->is_hidden); - g_free(conf->proxy_address); - g_free(conf); + __free_wifi_configuration(conf); g_variant_iter_free(iter); -- 2.7.4