From 3ba845042eed53582955078cd19d512978453df1 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Wed, 7 Sep 2016 18:38:58 +0900 Subject: [PATCH] Add setup methods to enable vpn-service - Update settings (local ip, remote ip, mtu) - Add/Remove route - Add/Remove dns server Change-Id: I3807033fa1cc520f7e207bc1dd4ab58cefcea74b Signed-off-by: Seonah Moon --- include/vpnsvc-internal.h | 15 +- interfaces/netconfig-iface-vpnsvc.xml | 41 +- packaging/net-config.spec | 2 +- resources/etc/dbus-1/system.d/net-config.conf | 3 + src/vpnsvc-internal.c | 485 +++++++++++------- src/vpnsvc.c | 176 +++---- 6 files changed, 416 insertions(+), 306 deletions(-) diff --git a/include/vpnsvc-internal.h b/include/vpnsvc-internal.h index ce68b92..789c209 100755 --- a/include/vpnsvc-internal.h +++ b/include/vpnsvc-internal.h @@ -23,6 +23,9 @@ #include +#define VPNSVC_VPN_IFACE_NAME_LEN 16 +#define VPNSVC_SESSION_STRING_LEN 32 + typedef struct _vpnsvc_tun_s { GDBusConnection *connection; /**< D-Bus Connection */ int fd; /**< tun socket fd */ @@ -35,14 +38,16 @@ typedef struct _vpnsvc_tun_s { int vpn_service_init(const char* iface_name, size_t iface_name_len, int fd, vpnsvc_tun_s *handle_s); int vpn_service_deinit(const char* dev_name); int vpn_service_protect(int socket, const char* dev_name); -int vpn_service_up(int iface_index, const char* local_ip, const char* remote_ip, - char* routes[], int prefix[], size_t nr_routes, - char** dns_servers, size_t nr_dns, size_t total_dns_string_cnt, - const char* dns_suffix, const unsigned int mtu); -int vpn_service_down(int iface_index); +int vpn_service_up(const char *iface_name); +int vpn_service_down(const char *iface_name); int vpn_service_block_networks(char* nets_vpn[], int prefix_vpn[], size_t nr_nets_vpn, char* nets_orig[], int prefix_orig[], size_t nr_nets_orig); int vpn_service_unblock_networks(void); +int vpn_service_update_settings(int iface_index, const char *local_ip, + const char *remote_ip, const unsigned int mtu); +int vpn_service_add_route(char *iface_name, const char *route, int prefix); +int vpn_service_remove_route(char *iface_name, const char *route, int prefix); +int vpn_service_add_dns_server(char *iface_name, const char *dns_server); #endif /* __NETCONFIG_VPN_SERVICE_INTERNAL_H__ */ diff --git a/interfaces/netconfig-iface-vpnsvc.xml b/interfaces/netconfig-iface-vpnsvc.xml index ee76ba7..3612d1c 100755 --- a/interfaces/netconfig-iface-vpnsvc.xml +++ b/interfaces/netconfig-iface-vpnsvc.xml @@ -17,19 +17,11 @@ - - - - - - - - - + - + @@ -42,6 +34,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packaging/net-config.spec b/packaging/net-config.spec index 3350a98..1de2c15 100755 --- a/packaging/net-config.spec +++ b/packaging/net-config.spec @@ -1,6 +1,6 @@ Name: net-config Summary: TIZEN Network Configuration service -Version: 1.1.90 +Version: 1.1.91 Release: 2 Group: System/Network License: Apache-2.0 diff --git a/resources/etc/dbus-1/system.d/net-config.conf b/resources/etc/dbus-1/system.d/net-config.conf index 50e52e3..55db8da 100755 --- a/resources/etc/dbus-1/system.d/net-config.conf +++ b/resources/etc/dbus-1/system.d/net-config.conf @@ -64,5 +64,8 @@ + + + diff --git a/src/vpnsvc-internal.c b/src/vpnsvc-internal.c index a3b4132..5f7e3f1 100755 --- a/src/vpnsvc-internal.c +++ b/src/vpnsvc-internal.c @@ -91,108 +91,6 @@ static in_addr_t host2net(ipv4 host) return net; } -static int add_routes(char* iface_name, char* routes[], int prefix[], size_t nr_routes) -{ - struct rtentry rt; - struct sockaddr_in addr; - int sk; - unsigned int i = 0; - char buf[BUF_SIZE_FOR_ERR] = { 0 }; - - DBG("Enter add_routes"); - - sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (sk < 0) { - ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - return VPNSVC_ERROR_IO_ERROR; - } - - for (i = 0; i < nr_routes; i++) { - memset(&rt, 0, sizeof(rt)); - rt.rt_flags = RTF_UP; - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr(routes[i]); - memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst)); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway)); - - /* set mask using by prefix length */ - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_addr.s_addr = host2net(make_mask(prefix[i])); - memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask)); - - rt.rt_dev = iface_name; - - if (ioctl(sk, SIOCADDRT, &rt) < 0) { - ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - close(sk); - return VPNSVC_ERROR_IO_ERROR; - } - } - - close(sk); - - return VPNSVC_ERROR_NONE; -} - -static int add_dns_routes(char* if_name, char** dns_servers, size_t nr_dns) -{ - struct rtentry rt; - struct sockaddr_in addr; - int sk; - unsigned int i = 0; - char buf[BUF_SIZE_FOR_ERR] = { 0 }; - - DBG("Enter add_routes"); - - sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (sk < 0) { - ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - return VPNSVC_ERROR_IO_ERROR; - } - - for (i = 0; i < nr_dns; i++) { - memset(&rt, 0, sizeof(rt)); - rt.rt_flags = RTF_UP; - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr(dns_servers[i]); - memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst)); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway)); - - /* set mask using by prefix length */ - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = INADDR_ANY; - addr.sin_addr.s_addr = host2net(make_mask(32)); - memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask)); - - rt.rt_dev = if_name; - - if (ioctl(sk, SIOCADDRT, &rt) < 0) { - ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - close(sk); - return VPNSVC_ERROR_IO_ERROR; - } - } - - close(sk); - - return VPNSVC_ERROR_NONE; -} - static void connman_connection_open(void) { if (global_connection == NULL) { @@ -748,6 +646,41 @@ static int get_interface_index(const char *iface_name) return ifr.ifr_ifindex; } +static int check_interface_precondition(const char *iface_name) +{ + + int sk; + struct ifreq ifr_tun; + char buf[BUF_SIZE_FOR_ERR] = { 0 }; + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) { + ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + return VPNSVC_ERROR_IO_ERROR; + } + + memset(&ifr_tun, 0, sizeof(ifr_tun)); + g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name)); + + /* local ip */ + if (ioctl(sk, SIOCGIFADDR, &ifr_tun) < 0) { + ERR("Fail to get local IP address: %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + close(sk); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + /* remote ip */ + if (ioctl(sk, SIOCGIFDSTADDR, &ifr_tun) < 0) { + ERR("Fail to get remote IP address: %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + close(sk); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + close(sk); + + return VPNSVC_ERROR_NONE; +} + int vpn_service_init(const char* iface_name, size_t iface_name_len, int fd, vpnsvc_tun_s *handle_s) { @@ -835,25 +768,20 @@ int vpn_service_protect(int socket_fd, const char* dev_name) return ret; } -int vpn_service_up(int iface_index, const char* local_ip, const char* remote_ip, - char* routes[], int prefix[], size_t nr_routes, - char** dns_servers, size_t nr_dns, size_t total_dns_string_cnt, - const char* dns_suffix, const unsigned int mtu) { - - struct sockaddr_in local_addr; - struct sockaddr_in remote_addr; +int vpn_service_up(const char *iface_name) +{ struct ifreq ifr_tun; int sk; int ret = VPNSVC_ERROR_NONE; char buf[BUF_SIZE_FOR_ERR] = { 0 }; DBG("enter vpn_daemon_up"); + DBG("iface_name : %s", iface_name); - DBG("iface_index : %d", iface_index); - DBG("local ip : %s", local_ip); - DBG("remote ip : %s", remote_ip); - DBG("route pointer : %p, nr_routes : %d, dns_server pointer : %p, nr_dns : %d, dns_suffix : %s, mtu : %d", routes, nr_routes, dns_servers, nr_dns, dns_suffix, mtu); + ret = check_interface_precondition(iface_name); + if (ret != VPNSVC_ERROR_NONE) + return ret; sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) { @@ -862,36 +790,7 @@ int vpn_service_up(int iface_index, const char* local_ip, const char* remote_ip, } memset(&ifr_tun, 0, sizeof(ifr_tun)); - ifr_tun.ifr_ifindex = iface_index; - - /* get an interface name by ifindex */ - if (ioctl(sk, SIOCGIFNAME, &ifr_tun) < 0) { - ERR("ioctl SIOCGIFNAME failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - close(sk); - return VPNSVC_ERROR_IO_ERROR; - } - - /* local ip setting */ - memset(&local_addr, 0, sizeof(local_addr)); - local_addr.sin_addr.s_addr = inet_addr(local_ip); /* network byte order */ - local_addr.sin_family = AF_INET; - memcpy(&ifr_tun.ifr_addr, &local_addr, sizeof(ifr_tun.ifr_addr)); - if (ioctl(sk, SIOCSIFADDR, &ifr_tun) < 0) { - ERR("ioctl SIOCSIFADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - close(sk); - return VPNSVC_ERROR_IO_ERROR; - } - - /* remote ip setting */ - memset(&remote_addr, 0, sizeof(remote_addr)); - remote_addr.sin_addr.s_addr = inet_addr(remote_ip); /*network byte order*/ - remote_addr.sin_family = AF_INET; - memcpy(&ifr_tun.ifr_dstaddr, &remote_addr, sizeof(ifr_tun.ifr_dstaddr)); - if (ioctl(sk, SIOCSIFDSTADDR, &ifr_tun) < 0) { - ERR("ioctl SIOCSIFDSTADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - close(sk); - return VPNSVC_ERROR_IO_ERROR; - } + g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name)); /* set the flags for vpn up */ if (ioctl(sk, SIOCGIFFLAGS, &ifr_tun) < 0) { @@ -909,42 +808,8 @@ int vpn_service_up(int iface_index, const char* local_ip, const char* remote_ip, return VPNSVC_ERROR_IO_ERROR; } - /* mtu setting */ - if (ioctl(sk, SIOCGIFMTU, &ifr_tun) < 0) { - ERR("ioctl SIOCGIFMTU failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - close(sk); - return VPNSVC_ERROR_IO_ERROR; - } - - if (mtu > 0 && ifr_tun.ifr_mtu != (int)mtu) { - ifr_tun.ifr_mtu = mtu; - if (ioctl(sk, SIOCSIFMTU, &ifr_tun) < 0) { - ERR("ioctl SIOCSIFMTU failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - close(sk); - return VPNSVC_ERROR_IO_ERROR; - } - } - close(sk); - /* add routes */ - if (nr_routes > 0) { - ret = add_routes(ifr_tun.ifr_name, routes, prefix, nr_routes); - if (ret != VPNSVC_ERROR_NONE) { - ERR("add_routes failed"); - return ret; - } - } - - /* add DNS routes */ - if (nr_dns > 0) { - ret = add_dns_routes(ifr_tun.ifr_name, dns_servers, nr_dns); - if (ret != VPNSVC_ERROR_NONE) { - ERR("add_dns failed"); - return ret; - } - } - #if 0 /* add DNS servers */ if (nr_dns > 0) { @@ -973,10 +838,9 @@ int vpn_service_up(int iface_index, const char* local_ip, const char* remote_ip, -int vpn_service_down(int iface_index) +int vpn_service_down(const char *iface_name) { - struct ifreq ifr, addr_ifr; - struct sockaddr_in *addr = NULL; + struct ifreq ifr; int sk; char buf[BUF_SIZE_FOR_ERR] = { 0 }; @@ -987,13 +851,7 @@ int vpn_service_down(int iface_index) } memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_ifindex = iface_index; - - if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) { - ERR("ioctl SIOCGIFNAME failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - close(sk); - return VPNSVC_ERROR_IO_ERROR; - } + g_strlcpy((char *)ifr.ifr_name, iface_name, sizeof(ifr.ifr_name)); if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) { ERR("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); @@ -1001,13 +859,6 @@ int vpn_service_down(int iface_index) return VPNSVC_ERROR_IO_ERROR; } - memset(&addr_ifr, 0, sizeof(addr_ifr)); - memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1); - addr = (struct sockaddr_in *)&addr_ifr.ifr_addr; - addr->sin_family = AF_INET; - if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0) - DBG("ioctl SIOCSIFADDR (could not clear IP address) failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); - if (!(ifr.ifr_flags & IFF_UP)) { DBG("Interface already down"); close(sk); @@ -1063,3 +914,249 @@ int vpn_service_unblock_networks(void) return VPNSVC_ERROR_NONE; } +int vpn_service_update_settings(int iface_index, const char *local_ip, + const char *remote_ip, const unsigned int mtu) +{ + int sk; + struct ifreq ifr_tun; + struct sockaddr_in local_addr; + struct sockaddr_in remote_addr; + char buf[BUF_SIZE_FOR_ERR] = { 0 }; + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) { + ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + return VPNSVC_ERROR_IO_ERROR; + } + + memset(&ifr_tun, 0, sizeof(ifr_tun)); + ifr_tun.ifr_ifindex = iface_index; + + /* get an interface name by ifindex */ + if (ioctl(sk, SIOCGIFNAME, &ifr_tun) < 0) { + ERR("ioctl SIOCGIFNAME failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + /* local ip setting */ + memset(&local_addr, 0, sizeof(local_addr)); + local_addr.sin_addr.s_addr = inet_addr(local_ip); /* network byte order */ + local_addr.sin_family = AF_INET; + memcpy(&ifr_tun.ifr_addr, &local_addr, sizeof(ifr_tun.ifr_addr)); + if (ioctl(sk, SIOCSIFADDR, &ifr_tun) < 0) { + ERR("ioctl SIOCSIFADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + /* remote ip setting */ + memset(&remote_addr, 0, sizeof(remote_addr)); + remote_addr.sin_addr.s_addr = inet_addr(remote_ip); /*network byte order*/ + remote_addr.sin_family = AF_INET; + memcpy(&ifr_tun.ifr_dstaddr, &remote_addr, sizeof(ifr_tun.ifr_dstaddr)); + if (ioctl(sk, SIOCSIFDSTADDR, &ifr_tun) < 0) { + ERR("ioctl SIOCSIFDSTADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + /* mtu setting */ + if (mtu > 0 && ifr_tun.ifr_mtu != (int)mtu) { + ifr_tun.ifr_mtu = mtu; + if (ioctl(sk, SIOCSIFMTU, &ifr_tun) < 0) { + ERR("ioctl SIOCSIFMTU failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + } + + close(sk); + + return VPNSVC_ERROR_NONE; +} + +int vpn_service_add_route(char *iface_name, const char *route, int prefix) +{ + struct rtentry rt; + struct sockaddr_in addr; + int sk; + char buf[BUF_SIZE_FOR_ERR] = { 0 }; + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) { + ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + return VPNSVC_ERROR_IO_ERROR; + } + + memset(&rt, 0, sizeof(rt)); + rt.rt_flags = RTF_UP; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(route); + memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst)); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway)); + + /* set mask using by prefix length */ + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_addr.s_addr = host2net(make_mask(prefix)); + memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask)); + + rt.rt_dev = iface_name; + + if (ioctl(sk, SIOCADDRT, &rt) < 0) { + ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + close(sk); + + return VPNSVC_ERROR_NONE; +} + +int vpn_service_remove_route(char *iface_name, const char *route, int prefix) +{ + struct rtentry rt; + struct sockaddr_in addr; + int sk; + char buf[BUF_SIZE_FOR_ERR] = { 0 }; + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) { + ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + return VPNSVC_ERROR_IO_ERROR; + } + + memset(&rt, 0, sizeof(rt)); + rt.rt_flags = RTF_UP; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(route); + memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst)); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway)); + + /* set mask using by prefix length */ + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_addr.s_addr = host2net(make_mask(prefix)); + memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask)); + + rt.rt_dev = iface_name; + + if (ioctl(sk, SIOCDELRT, &rt) < 0) { + ERR("ioctl SIOCDERLT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + close(sk); + + return VPNSVC_ERROR_NONE; + +} + +int vpn_service_add_dns_server(char *iface_name, const char *dns_server) +{ + struct rtentry rt; + struct sockaddr_in addr; + int sk; + char buf[BUF_SIZE_FOR_ERR] = { 0 }; + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) { + ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + return VPNSVC_ERROR_IO_ERROR; + } + + memset(&rt, 0, sizeof(rt)); + rt.rt_flags = RTF_UP; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(dns_server); + memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst)); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway)); + + /* set mask using by prefix length */ + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_addr.s_addr = host2net(make_mask(32)); + memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask)); + + rt.rt_dev = iface_name; + + if (ioctl(sk, SIOCADDRT, &rt) < 0) { + ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + close(sk); + + return VPNSVC_ERROR_NONE; +} + +int vpn_service_remove_dns_server(char *iface_name, const char *dns_server) +{ + struct rtentry rt; + struct sockaddr_in addr; + int sk; + char buf[BUF_SIZE_FOR_ERR] = { 0 }; + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) { + ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + return VPNSVC_ERROR_IO_ERROR; + } + + memset(&rt, 0, sizeof(rt)); + rt.rt_flags = RTF_UP; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(dns_server); + memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst)); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway)); + + /* set mask using by prefix length */ + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_addr.s_addr = host2net(make_mask(32)); + memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask)); + + rt.rt_dev = iface_name; + + if (ioctl(sk, SIOCDELRT, &rt) < 0) { + ERR("ioctl SIOCDELRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + close(sk); + + return VPNSVC_ERROR_NONE; +} diff --git a/src/vpnsvc.c b/src/vpnsvc.c index f83bd2e..8b126ed 100755 --- a/src/vpnsvc.c +++ b/src/vpnsvc.c @@ -117,103 +117,13 @@ gboolean handle_vpn_protect(Vpnsvc *object, gboolean handle_vpn_up(Vpnsvc *object, GDBusMethodInvocation *invocation, - gint arg_iface_index, - const gchar *arg_local_ip, - const gchar *arg_remote_ip, - GVariant *arg_routes, - guint arg_nr_routes, - GVariant *arg_dns_servers, - guint arg_nr_dns, - const gchar *arg_dns_suffix, - guint arg_mtu) + const gchar *arg_iface_name) { DBG("handle_vpn_up"); int result = VPNSVC_ERROR_NONE; - char *routes[arg_nr_routes]; - int prefix[arg_nr_routes]; - char **dns_servers = NULL; - - unsigned int i = 0; - size_t total_dns_string_cnt = 0; - gchar* temp_dns_server; - GVariantIter iter; - - gchar* route_dest; - gint route_prefix; - - DBG("iface_index : %d", arg_iface_index); - DBG("local ip : %s", arg_local_ip); - DBG("remote ip : %s", arg_remote_ip); - DBG("dns_suffix : %s", arg_dns_suffix); - DBG("mtu : %u", arg_mtu); - DBG("arg_routes: %p", arg_routes); - DBG("nr_routes : %u", arg_nr_routes); - DBG("arg_dns_servers: %p", arg_dns_servers); - DBG("nr_dns : %u", arg_nr_dns); - - /* arg_routes check */ - if (arg_nr_routes > 0) { - if (arg_routes != NULL) { - GVariant *dict = g_variant_get_variant(arg_routes); - g_variant_iter_init(&iter, dict); - i = 0; - while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) { - int temp_dest_str_len = strlen(route_dest); - routes[i] = g_try_malloc0((sizeof(char) * temp_dest_str_len)+1); - strncpy(routes[i], route_dest, temp_dest_str_len); - routes[i][temp_dest_str_len] = '\0'; - prefix[i] = route_prefix; - DBG("routes[%d] = %s \t", i, (routes[i] == NULL) ? "" : routes[i]); - DBG("prefix[%d] = %d ", i, prefix[i]); - i++; - } - } - } - - - /* arg_nr_dns check */ - if (arg_nr_dns > 0) { - if (arg_dns_servers != NULL) { - GVariant *array = g_variant_get_variant(arg_dns_servers); - dns_servers = (char **)g_try_malloc0(arg_nr_dns*sizeof(char *)); - if (dns_servers == NULL) { - ERR("malloc failed."); - result = VPNSVC_ERROR_OUT_OF_MEMORY; - goto done; - } - g_variant_iter_init(&iter, array); - i = 0; - while (g_variant_iter_loop(&iter, "s", &temp_dns_server)) { - int temp_dns_str_len = strlen(temp_dns_server); - dns_servers[i] = (char *)g_try_malloc0((temp_dns_str_len + 1) * sizeof(char)); - strncpy(dns_servers[i], temp_dns_server, strlen(temp_dns_server)); - dns_servers[i][temp_dns_str_len] = '\0'; - total_dns_string_cnt += temp_dns_str_len; - DBG("dns_servers[%d] : %s", i, (dns_servers[i] == NULL) ? "" : dns_servers[i]); - i++; - } - } - } - - result = vpn_service_up(arg_iface_index, arg_local_ip, arg_remote_ip, - routes, prefix, arg_nr_routes, dns_servers, arg_nr_dns, - total_dns_string_cnt, arg_dns_suffix, arg_mtu); -done: - /* free pointers */ - for (i = 0; i < arg_nr_routes; i++) { - if (routes[i]) - g_free(routes[i]); - } - - if (dns_servers) { - for (i = 0; i < arg_nr_dns; i++) { - if (dns_servers[i]) - g_free(dns_servers[i]); - } - g_free(dns_servers); - } + result = vpn_service_up(arg_iface_name); vpnsvc_complete_vpn_up(object, invocation, result); @@ -222,15 +132,13 @@ done: gboolean handle_vpn_down(Vpnsvc *object, GDBusMethodInvocation *invocation, - gint arg_iface_index) + const gchar *arg_iface_name) { DBG("handle_vpn_down"); int result = VPNSVC_ERROR_NONE; - DBG("vpn_down, %d\n", arg_iface_index); - - result = vpn_service_down(arg_iface_index); + result = vpn_service_down(arg_iface_name); vpnsvc_complete_vpn_down(object, invocation, result); @@ -328,6 +236,74 @@ gboolean handle_vpn_unblock_networks(Vpnsvc *object, return TRUE; } +gboolean handle_vpn_update_settings(Vpnsvc *object, + GDBusMethodInvocation *invocation, + gint arg_iface_index, + const gchar *arg_local_ip, + const gchar *arg_remote_ip, + guint arg_mtu) +{ + int result = VPNSVC_ERROR_NONE; + DBG("handle_vpn_update_settings"); + + result = vpn_service_update_settings(arg_iface_index, arg_local_ip, arg_remote_ip, arg_mtu); + + vpnsvc_complete_vpn_update_settings(object, invocation, result); + + return TRUE; +} + +gboolean handle_vpn_add_route(Vpnsvc *object, + GDBusMethodInvocation *invocation, + gchar *arg_iface_name, + const gchar *arg_route, + gint arg_prefix) +{ + DBG("handle_vpn_add_route"); + + int result = VPNSVC_ERROR_NONE; + + result = vpn_service_add_route(arg_iface_name, arg_route, arg_prefix); + + vpnsvc_complete_vpn_add_route(object, invocation, result); + + return TRUE; +} + +gboolean handle_vpn_remove_route(Vpnsvc *object, + GDBusMethodInvocation *invocation, + gchar *arg_iface_name, + const gchar *arg_route, + gint arg_prefix) + +{ + DBG("handle_vpn_remove_route"); + + int result = VPNSVC_ERROR_NONE; + + result = vpn_service_remove_route(arg_iface_name, arg_route, arg_prefix); + + vpnsvc_complete_vpn_remove_route(object, invocation, result); + + return TRUE; +} + +gboolean handle_vpn_add_dns_server(Vpnsvc *object, + GDBusMethodInvocation *invocation, + gchar *arg_iface_name, + const gchar *arg_dns_server) +{ + DBG("handle_vpn_add_dns_server"); + + int result = VPNSVC_ERROR_NONE; + + result = vpn_service_add_dns_server(arg_iface_name, arg_dns_server); + + vpnsvc_complete_vpn_add_dns_server(object, invocation, result); + + return TRUE; +} + /***************************** * Initializations Functions * ****************************/ @@ -367,6 +343,14 @@ void vpnsvc_create_and_init(void) G_CALLBACK(handle_vpn_block_networks), NULL); g_signal_connect(vpnsvc, "handle-vpn-unblock-networks", G_CALLBACK(handle_vpn_unblock_networks), NULL); + g_signal_connect(vpnsvc, "handle-vpn-update-settings", + G_CALLBACK(handle_vpn_update_settings), NULL); + g_signal_connect(vpnsvc, "handle-vpn-add-route", + G_CALLBACK(handle_vpn_add_route), NULL); + g_signal_connect(vpnsvc, "handle-vpn-remove-route", + G_CALLBACK(handle_vpn_remove_route), NULL); + g_signal_connect(vpnsvc, "handle-vpn-add-dns-server", + G_CALLBACK(handle_vpn_add_dns_server), NULL); if (!g_dbus_interface_skeleton_export(interface_vpn, connection, NETCONFIG_VPNSVC_PATH, NULL)) { -- 2.34.1