Add Null Check to avoid potential crash
[platform/core/api/connection.git] / src / libnetwork.c
index 3f61754..0c826d9 100755 (executable)
@@ -18,6 +18,7 @@
 #include <string.h>
 #include <glib.h>
 #include <vconf/vconf.h>
+#include <arpa/inet.h>
 
 #include "net_connection_private.h"
 
@@ -41,6 +42,7 @@ struct _libnet_s {
        connection_closed_cb closed_cb;
        connection_set_default_cb set_default_cb;
        connection_reset_cb reset_profile_cb;
+       libnet_ethernet_cable_state_changed_cb ethernet_cable_state_changed_cb;
        void *opened_user_data;
        void *closed_user_data;
        void *set_default_user_data;
@@ -242,6 +244,19 @@ static void __libnet_default_cb(connection_error_e result)
        libnet.set_default_user_data = NULL;
 }
 
+static void __libnet_set_ethernet_cable_state_changed_cb(
+               libnet_ethernet_cable_state_changed_cb user_cb)
+{
+       libnet.ethernet_cable_state_changed_cb = user_cb;
+}
+
+static void __libnet_ethernet_cable_state_changed_cb(
+               connection_ethernet_cable_state_e state)
+{
+       if (libnet.ethernet_cable_state_changed_cb)
+               libnet.ethernet_cable_state_changed_cb(state);
+}
+
 static void __libnet_state_changed_cb(char *profile_name, connection_profile_state_e state)
 {
        if (profile_name == NULL)
@@ -366,12 +381,33 @@ static void __libnet_evt_cb(net_event_info_t*  event_cb, void* user_data)
                result = __libnet_convert_to_cp_error_type(event_cb->Error);
                CONNECTION_LOG(CONNECTION_INFO, "Got reset default profile RSP %d", result);
                __libnet_reset_profile_cb(result);
+
+       case NET_EVENT_ETHERNET_CABLE_ATTACHED:
+               CONNECTION_LOG(CONNECTION_INFO, "Got Ethernet cable Attached Indication\n");
+               __libnet_ethernet_cable_state_changed_cb(CONNECTION_ETHERNET_CABLE_ATTACHED);
+               break;
+       case NET_EVENT_ETHERNET_CABLE_DETACHED:
+               CONNECTION_LOG(CONNECTION_INFO, "Got Ethernet cable detached Indication\n");
+               __libnet_ethernet_cable_state_changed_cb(CONNECTION_ETHERNET_CABLE_DETACHED);
+               break;
        default :
                CONNECTION_LOG(CONNECTION_ERROR, "Error! Unknown Event\n\n");
                break;
        }
 }
 
+static int __libnet_check_address_type(int address_family, const char *address)
+{
+       struct in6_addr buf;
+       int err = 0;
+
+       err = inet_pton(address_family, address, &buf);
+       if(err > 0)
+               return 1;
+
+       return 0;
+}
+
 int __libnet_get_connected_count(struct _profile_list_s *profile_list)
 {
        int count = 0;
@@ -399,7 +435,7 @@ void __libnet_copy_connected_profile(net_profile_info_t **dest, struct _profile_
        }
 }
 
-bool _connection_libnet_init(void)
+int _connection_libnet_init(void)
 {
        int rv;
 
@@ -414,7 +450,7 @@ bool _connection_libnet_init(void)
                        profile_cb_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
        }
 
-       return true;
+       return NET_ERR_NONE;
 }
 
 bool _connection_libnet_deinit(void)
@@ -446,6 +482,9 @@ bool _connection_libnet_check_profile_validity(connection_profile_h profile)
        GSList *list;
        int i = 0;
 
+       if (profile == NULL)
+               return false;
+
        for (list = prof_handle_list; list; list = list->next)
                if (profile == list->data) return true;
 
@@ -516,6 +555,11 @@ int _connection_libnet_get_ethernet_state(connection_ethernet_state_e* state)
                return CONNECTION_ERROR_PERMISSION_DENIED;
        }
 
+       if (ethernet_profiles.count == 0) {
+               state = CONNECTION_ETHERNET_STATE_DEACTIVATED;
+               return true;
+       }
+
        switch (ethernet_profiles.profiles->ProfileState) {
        case NET_STATE_TYPE_ONLINE:
        case NET_STATE_TYPE_READY:
@@ -537,6 +581,35 @@ int _connection_libnet_get_ethernet_state(connection_ethernet_state_e* state)
        return CONNECTION_ERROR_NONE;
 }
 
+int _connection_libnet_get_ethernet_cable_state(connection_ethernet_cable_state_e* state)
+{
+       int rv = 0;
+       int status = 0;
+
+       rv = net_get_ethernet_cable_state(&status);
+       if (rv == NET_ERR_ACCESS_DENIED) {
+               CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
+               return CONNECTION_ERROR_PERMISSION_DENIED;
+       } else if (rv != NET_ERR_NONE) {
+               CONNECTION_LOG(CONNECTION_ERROR, "Failed to get ethernet cable state[%d]", rv);
+               return CONNECTION_ERROR_OPERATION_FAILED;
+       }
+
+       if(status == 1)
+               *state = CONNECTION_ETHERNET_CABLE_ATTACHED;
+       else
+               *state = CONNECTION_ETHERNET_CABLE_DETACHED;
+       return CONNECTION_ERROR_NONE;
+}
+
+int _connection_libnet_set_ethernet_cable_state_changed_cb(
+               libnet_ethernet_cable_state_changed_cb callback)
+{
+       __libnet_set_ethernet_cable_state_changed_cb(callback);
+
+       return CONNECTION_ERROR_NONE;
+}
+
 int _connection_libnet_get_bluetooth_state(connection_bt_state_e* state)
 {
        int i = 0;
@@ -884,18 +957,30 @@ int _connection_libnet_close_profile(connection_profile_h profile, connection_cl
 int _connection_libnet_add_route(const char *interface_name, const char *host_address)
 {
        int rv;
-       char *endstr = strrchr(host_address, '.');
+       char *endstr = NULL;
+       int address_family = 0;
 
-       if (endstr == NULL ||
-           strcmp(endstr, ".0") == 0 ||
-           strncmp(host_address, "0.", 2) == 0 ||
-           strstr(host_address, ".0.") != NULL ||
-           strstr(host_address, "255") != NULL) {
-               CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n");
+       if(__libnet_check_address_type(AF_INET, host_address))
+               address_family = AF_INET;
+       else
                return CONNECTION_ERROR_INVALID_PARAMETER;
+
+       switch(address_family) {
+               case AF_INET:
+                       endstr = strrchr(host_address, '.');
+                       if (endstr == NULL ||
+                                       strcmp(endstr, ".0") == 0 ||
+                                       strncmp(host_address, "0.", 2) == 0 ||
+                                       strstr(host_address, "255") != NULL) {
+                               CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n");
+                               return CONNECTION_ERROR_INVALID_PARAMETER;
+                       }
+                       break;
+               default:
+                       return CONNECTION_ERROR_OPERATION_FAILED;
        }
 
-       rv = net_add_route(host_address, interface_name);
+       rv = net_add_route(host_address, interface_name, address_family);
        if (rv == NET_ERR_ACCESS_DENIED) {
                CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
                return CONNECTION_ERROR_PERMISSION_DENIED;
@@ -909,17 +994,97 @@ int _connection_libnet_remove_route(const char *interface_name, const char *host
 {
        int rv;
        char *endstr = strrchr(host_address, '.');
+       int address_family = 0;
 
-       if (endstr == NULL ||
-           strcmp(endstr, ".0") == 0 ||
-           strncmp(host_address, "0.", 2) == 0 ||
-           strstr(host_address, ".0.") != NULL ||
-           strstr(host_address, "255") != NULL) {
-               CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed");
+       if (__libnet_check_address_type(AF_INET, host_address))
+               address_family = AF_INET;
+       else
                return CONNECTION_ERROR_INVALID_PARAMETER;
+
+       switch(address_family) {
+               case AF_INET:
+                       endstr = strrchr(host_address, '.');
+                       if (endstr == NULL ||
+                               strcmp(endstr, ".0") == 0 ||
+                               strncmp(host_address, "0.", 2) == 0 ||
+                               strstr(host_address, ".0.") != NULL ||strstr(host_address, "255") != NULL) {
+                               CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed");
+                               return CONNECTION_ERROR_INVALID_PARAMETER;
+                       }
+                       break;
+               default:
+                       return CONNECTION_ERROR_OPERATION_FAILED;
+       }
+
+       rv = net_remove_route(host_address, interface_name, address_family);
+       if (rv == NET_ERR_ACCESS_DENIED) {
+               CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
+               return CONNECTION_ERROR_PERMISSION_DENIED;
+       } else if (rv != NET_ERR_NONE)
+               return CONNECTION_ERROR_OPERATION_FAILED;
+
+       return CONNECTION_ERROR_NONE;
+}
+
+int _connection_libnet_add_route_ipv6(const char *interface_name, const char *host_address, const char *gateway)
+{
+       int rv;
+       int address_family = 0;
+
+       address_family = AF_INET6;
+/*     if(__libnet_check_address_type(AF_INET6, host_address))
+               address_family = AF_INET6;
+       else
+               return CONNECTION_ERROR_INVALID_PARAMETER;*/
+
+       switch(address_family) {
+               case AF_INET6:
+                       if (strncmp(host_address, "fe80:", 5) == 0 ||
+                               strncmp(host_address, "ff00:", 5) == 0 ||
+                               strncmp(host_address, "::", 2) == 0) {
+                               CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n");
+                               return CONNECTION_ERROR_INVALID_PARAMETER;
+                       }
+                       break;
+               default:
+                       return CONNECTION_ERROR_OPERATION_FAILED;
+       }
+
+       rv = net_add_route_ipv6(host_address, interface_name, address_family, gateway);
+       if (rv == NET_ERR_ACCESS_DENIED) {
+               CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
+               return CONNECTION_ERROR_PERMISSION_DENIED;
+       } else if (rv != NET_ERR_NONE)
+               return CONNECTION_ERROR_OPERATION_FAILED;
+
+       return CONNECTION_ERROR_NONE;
+}
+
+int _connection_libnet_remove_route_ipv6(const char *interface_name, const char *host_address, const char *gateway)
+{
+       int rv;
+       int address_family = 0;
+
+       address_family = AF_INET6;
+/*     if (__libnet_check_address_type(AF_INET6, host_address))
+               address_family = AF_INET6;
+       else
+               return CONNECTION_ERROR_INVALID_PARAMETER;*/
+
+       switch(address_family) {
+               case AF_INET6:
+                       if (strncmp(host_address, "fe80:", 5) == 0 ||
+                               strncmp(host_address, "ff00:", 5) == 0 ||
+                               strncmp(host_address, "::", 2) == 0) {
+                               CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n");
+                               return CONNECTION_ERROR_INVALID_PARAMETER;
+                       }
+                       break;
+               default:
+                       return CONNECTION_ERROR_OPERATION_FAILED;
        }
 
-       rv = net_remove_route(host_address, interface_name);
+       rv = net_remove_route_ipv6(host_address, interface_name, address_family, gateway);
        if (rv == NET_ERR_ACCESS_DENIED) {
                CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
                return CONNECTION_ERROR_PERMISSION_DENIED;