From: taesub.kim Date: Wed, 27 May 2015 08:52:27 +0000 (+0900) Subject: Add support for ipv6 X-Git-Tag: accepted/tizen/common/20150601.145712^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F90%2F39990%2F1;p=platform%2Fcore%2Fconnectivity%2Fnet-config.git Add support for ipv6 Change-Id: Id54b62f84f86c902097d042d56b31f4a2cdb4d96 Signed-off-by: Taesub Kim --- diff --git a/include/neterror.h b/include/neterror.h index 98b0f4b..91b3484 100644 --- a/include/neterror.h +++ b/include/neterror.h @@ -44,6 +44,8 @@ typedef enum { NETCONFIG_ERROR_FAILED_GET_SIM_AUTH_WRONG_DATA = 0x0C, NETCONFIG_ERROR_FAILED_GET_SIM_AUTH_DELAY = 0x0D, NETCONFIG_ERROR_MAX = 0x0E, + NETCONFIG_ERROR_INVALID_PARAMETER = 0x0F, + NETCONFIG_ERROR_PERMISSION_DENIED = 0x10, } NETCONFIG_ERROR; GQuark netconfig_error_quark(void); @@ -65,5 +67,7 @@ void netconfig_error_fail_req_sim_auth(GError **error); void netconfig_error_fail_req_sim_auth_wrong_param(GError **error); void netconfig_error_fail_get_sim_auth_wrong_data(GError **error); void netconfig_error_fail_get_sim_auth_delay(GError **error); +void netconfig_error_invalid_parameter(GError **error); +void netconfig_error_permission_denied(GError **error); #endif /* __NETCONFIG_ERROR_H__ */ diff --git a/include/network-monitor.h b/include/network-monitor.h old mode 100755 new mode 100644 diff --git a/include/util.h b/include/util.h index c6c9b8d..7bd1b03 100644 --- a/include/util.h +++ b/include/util.h @@ -47,6 +47,8 @@ gboolean netconfig_is_wifi_tethering_on(void); gboolean netconfig_execute_file(const char *file_path, char *const args[], char *const env[]); +int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len); +int netconfig_del_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len); gboolean netconfig_iface_wifi_launch_direct(NetconfigWifi *wifi, GError **error); void netconfig_set_wifi_mac_address(void); diff --git a/interfaces/netconfig-iface-network-state.xml b/interfaces/netconfig-iface-network-state.xml index c5ba188..5c7d29c 100644 --- a/interfaces/netconfig-iface-network-state.xml +++ b/interfaces/netconfig-iface-network-state.xml @@ -5,12 +5,16 @@ + + + + diff --git a/src/neterror.c b/src/neterror.c index 0c55268..676760a 100644 --- a/src/neterror.c +++ b/src/neterror.c @@ -87,3 +87,15 @@ void netconfig_error_fail_get_sim_auth_delay(GError **error) g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_FAILED_GET_SIM_AUTH_DELAY, NETCONFIG_ERROR_INTERFACE".FailGetSimAuthDelay"); } + +void netconfig_error_invalid_parameter(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_INVALID_PARAMETER, + NETCONFIG_ERROR_INTERFACE ".InvalidParameter"); +} + +void netconfig_error_permission_denied(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_PERMISSION_DENIED, + NETCONFIG_ERROR_INTERFACE ".PermissionDenied"); +} diff --git a/src/network-monitor.c b/src/network-monitor.c old mode 100755 new mode 100644 diff --git a/src/network-state.c b/src/network-state.c index f753213..1dbe3ae 100644 --- a/src/network-state.c +++ b/src/network-state.c @@ -19,6 +19,9 @@ #include #include +#include +#include +#include #include "wifi.h" #include "log.h" @@ -40,12 +43,12 @@ gboolean netconfig_iface_network_state_add_route( NetconfigNetworkState *master, gchar *ip_addr, gchar *netmask, - gchar *interface, gboolean *result, GError **error); + gchar *interface, gchar *gateway, gint32 address_family, gboolean *result, GError **error); gboolean netconfig_iface_network_state_remove_route( NetconfigNetworkState *master, gchar *ip_addr, gchar *netmask, - gchar *interface, gboolean *result, GError **error); + gchar *interface, gchar *gateway, gint32 address_family, gboolean *result, GError **error); gboolean netconfig_iface_network_state_ethernet_cable_state( NetconfigNetworkState *master, gint32 *state, GError **error); @@ -627,73 +630,138 @@ void netconfig_network_notify_ethernet_cable_state(const char *key) gboolean netconfig_iface_network_state_add_route( NetconfigNetworkState *master, gchar *ip_addr, gchar *netmask, - gchar *interface, gboolean *result, GError **error) + gchar *interface, gchar *gateway, gint32 address_family, gboolean *result, GError **error) { - gboolean ret = FALSE; - gboolean rv = FALSE; const char *path = ROUTE_EXEC_PATH; - char *const args[] = {"route", "add", - "-net", ip_addr, - "netmask", netmask, - "dev", interface, - 0}; + char *const args[] = { "/sbin/route", "add", "-net", ip_addr, + "netmask", netmask, "dev", interface, NULL }; char *const envs[] = { NULL }; + const char* buf = NULL; + char* ch = NULL; + int prefix_len = 0; + int pos = 0; + + DBG("ip_addr(%s), netmask(%s), interface(%s), gateway(%s)", ip_addr, netmask, interface, gateway); + + switch(address_family) { + case AF_INET: + if (ip_addr == NULL || netmask == NULL || interface == NULL) { + ERR("Invalid parameter"); + netconfig_error_invalid_parameter(error); + *result = FALSE; + return FALSE; + } + if (netconfig_execute_file(path, args, envs) < 0) { + DBG("Failed to add a new route"); + netconfig_error_permission_denied(error); + *result = FALSE; + return FALSE; + } + break; + case AF_INET6: + if (ip_addr == NULL || interface == NULL || gateway == NULL) { + ERR("Invalid parameter"); + netconfig_error_invalid_parameter(error); + *result = FALSE; + return FALSE; + } - DBG("ip_addr(%s), netmask(%s), interface(%s)", ip_addr, netmask, interface); - - if (ip_addr == NULL || netmask == NULL || interface == NULL) { - DBG("Invalid parameter!"); - goto done; - } + buf = ip_addr; + ch = strchr(buf, '/'); + pos = ch - buf + 1; + if (ch) { + prefix_len = atoi(ch + 1); + ip_addr[pos-1] = '\0'; + } else { + prefix_len = 128; + } - rv = netconfig_execute_file(path, args, envs); - if (rv != TRUE) { - DBG("Failed to add a new route"); - goto done; + if (netconfig_add_route_ipv6(ip_addr, interface, gateway, prefix_len) < 0) { + DBG("Failed to add a new route"); + netconfig_error_permission_denied(error); + *result = FALSE; + return FALSE; + } + break; + default: + DBG("Unknown Address Family"); + netconfig_error_invalid_parameter(error); + *result = FALSE; + return FALSE; } DBG("Successfully added a new route"); - ret = TRUE; - -done: - *result = ret; - return ret; + *result = TRUE; + return TRUE; } gboolean netconfig_iface_network_state_remove_route( NetconfigNetworkState *master, gchar *ip_addr, gchar *netmask, - gchar *interface, gboolean *result, GError **error) + gchar *interface, gchar *gateway, gint32 address_family, gboolean *result, GError **error) { - gboolean ret = FALSE; - gboolean rv = FALSE; const char *path = ROUTE_EXEC_PATH; - char *const args[] = {"route", "del", - "-net", ip_addr, - "netmask", netmask, - "dev", interface, - 0}; + char *const args[] = { "/sbin/route", "del", "-net", ip_addr, + "netmask", netmask, "dev", interface, NULL }; char *const envs[] = { NULL }; + const char* buf = NULL; + char* ch = NULL; + int prefix_len = 0; + int pos = 0; + + DBG("ip_addr(%s), netmask(%s), interface(%s), gateway(%s)", ip_addr, netmask, interface, gateway); + + switch(address_family) { + case AF_INET: + if (ip_addr == NULL || netmask == NULL || interface == NULL) { + DBG("Invalid parameter!"); + netconfig_error_invalid_parameter(error); + *result = FALSE; + return FALSE; + } + if (netconfig_execute_file(path, args, envs) < 0) { + DBG("Failed to remove the route"); + netconfig_error_permission_denied(error); + *result = FALSE; + return FALSE; + } + break; + case AF_INET6: + if (ip_addr == NULL || interface == NULL || gateway == NULL) { + DBG("Invalid parameter!"); + netconfig_error_invalid_parameter(error); + *result = FALSE; + return FALSE; + } - DBG("ip_addr(%s), netmask(%s), interface(%s)", ip_addr, netmask, interface); - - if (ip_addr == NULL || netmask == NULL || interface == NULL) { - DBG("Invalid parameter!"); - goto done; - } + buf = ip_addr; + ch = strchr(buf, '/'); + pos = ch - buf + 1; + if (ch) { + prefix_len = atoi(ch + 1); + ip_addr[pos-1] = '\0'; + } else { + prefix_len = 128; + } - rv = netconfig_execute_file(path, args, envs); - if (rv != TRUE) { - DBG("Failed to remove a new route"); - goto done; + if (netconfig_del_route_ipv6(ip_addr, interface, gateway, prefix_len) < 0) { + DBG("Failed to remove the route"); + netconfig_error_permission_denied(error); + *result = FALSE; + return FALSE; + } + break; + default: + DBG("Unknown Address Family"); + netconfig_error_invalid_parameter(error); + *result = FALSE; + return FALSE; } - DBG("Successfully remove a new route"); - ret = TRUE; + DBG("Successfully removed the route"); + *result = TRUE; -done: - *result = ret; - return ret; + return TRUE; } gboolean netconfig_iface_network_state_ethernet_cable_state( diff --git a/src/utils/util.c b/src/utils/util.c index 02ee0c2..cfcd11d 100644 --- a/src/utils/util.c +++ b/src/utils/util.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -332,6 +334,110 @@ gboolean netconfig_execute_file(const char *file_path, return FALSE; } +int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len) +{ + struct in6_rtmsg rt; + int fd = 0; + int err = 0; + + memset(&rt, 0, sizeof(rt)); + + rt.rtmsg_dst_len = prefix_len; + + rt.rtmsg_flags = RTF_UP | RTF_HOST; + + if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) { + err = -errno; + return err; + } + + if (gateway != NULL) { + rt.rtmsg_flags |= RTF_GATEWAY; + if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) { + err = -errno; + return err; + } + } + + rt.rtmsg_metric = 1; + + fd = socket(AF_INET6, SOCK_DGRAM, 0); + if (fd < 0) + return -1; + + rt.rtmsg_ifindex = 0; + + if (interface) { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, interface); + ioctl(fd, SIOCGIFINDEX, &ifr); + rt.rtmsg_ifindex = ifr.ifr_ifindex; + } + + if ((err = ioctl(fd, SIOCADDRT, &rt)) < 0) { + DBG("Failed to add route: %d\n", err); + close(fd); + return -1; + } + + close(fd); + + return 1; +} + +int netconfig_del_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len) +{ + struct in6_rtmsg rt; + int fd = 0; + int err = 0; + + memset(&rt, 0, sizeof(rt)); + + rt.rtmsg_dst_len = prefix_len; + + rt.rtmsg_flags = RTF_UP | RTF_HOST; + + if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) { + err = -errno; + return err; + } + + if (gateway != NULL) { + rt.rtmsg_flags |= RTF_GATEWAY; + if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) { + err = -errno; + return err; + } + } + + rt.rtmsg_metric = 1; + + fd = socket(AF_INET6, SOCK_DGRAM, 0); + if (fd < 0) + return -1; + + rt.rtmsg_ifindex = 0; + + if (interface) { + struct ifreq ifr; + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, interface); + ioctl(fd, SIOCGIFINDEX, &ifr); + rt.rtmsg_ifindex = ifr.ifr_ifindex; + } + + if ((err = ioctl(fd, SIOCDELRT, &rt)) < 0) { + DBG("Failed to add route: %d\n", err); + close(fd); + return -1; + } + + close(fd); + + return 1; +} + gboolean netconfig_iface_wifi_launch_direct(NetconfigWifi *wifi, GError **error) { gboolean ret = TRUE;