Add setup methods to enable vpn-service 14/87314/4
authorSeonah Moon <seonah1.moon@samsung.com>
Wed, 7 Sep 2016 09:38:58 +0000 (18:38 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Tue, 27 Sep 2016 05:56:06 +0000 (14:56 +0900)
- Update settings (local ip, remote ip, mtu)
- Add/Remove route
- Add/Remove dns server

Change-Id: I3807033fa1cc520f7e207bc1dd4ab58cefcea74b
Signed-off-by: Seonah Moon <seonah1.moon@samsung.com>
include/vpnsvc-internal.h
interfaces/netconfig-iface-vpnsvc.xml
packaging/net-config.spec
resources/etc/dbus-1/system.d/net-config.conf
src/vpnsvc-internal.c
src/vpnsvc.c

index ce68b92..789c209 100755 (executable)
@@ -23,6 +23,9 @@
 
 #include <vpn_service.h>
 
+#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__ */
 
index ee76ba7..3612d1c 100755 (executable)
                        <arg type="i" name="result" direction="out"/>
                </method>
                <method name="vpn_up">
-                       <arg type="i" name="iface_index" direction="in"/>
-                       <arg type="s" name="local_ip" direction="in"/>
-                       <arg type="s" name="remote_ip" direction="in"/>
-                       <arg type="v" name="routes" direction="in"/>
-                       <arg type="u" name="nr_routes" direction="in"/>
-                       <arg type="v" name="dns_servers" direction="in"/>
-                       <arg type="u" name="nr_dns" direction="in"/>
-                       <arg type="s" name="dns_suffix" direction="in"/>
-                       <arg type="u" name="mtu" direction="in"/>
+                       <arg type="s" name="iface_name" direction="in"/>
                        <arg type="i" name="result" direction="out"/>
                </method>
                <method name="vpn_down">
-                       <arg type="i" name="iface_index" direction="in"/>
+                       <arg type="s" name="iface_name" direction="in"/>
                        <arg type="i" name="result" direction="out"/>
                </method>
                <method name="vpn_block_networks">
                <method name="vpn_unblock_networks">
                        <arg type="i" name="result" direction="out"/>
                </method>
+               <method name="vpn_update_settings">
+                       <arg type="i" name="iface_index" direction="in"/>
+                       <arg type="s" name="local_ip" direction="in"/>
+                       <arg type="s" name="remote_ip" direction="in"/>
+                       <arg type="u" name="mtu" direction="in"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="vpn_add_route">
+                       <arg type="s" name="iface_name" direction="in"/>
+                       <arg type="s" name="route" direction="in"/>
+                       <arg type="i" name="prefix" direction="in"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="vpn_remove_route">
+                       <arg type="s" name="iface_name" direction="in"/>
+                       <arg type="s" name="route" direction="in"/>
+                       <arg type="i" name="prefix" direction="in"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="vpn_add_dns_server">
+                       <arg type="s" name="iface_name" direction="in"/>
+                       <arg type="s" name="dns_server" direction="in"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
+               <method name="vpn_remove_dns_server">
+                       <arg type="s" name="iface_name" direction="in"/>
+                       <arg type="s" name="dns_server" direction="in"/>
+                       <arg type="i" name="result" direction="out"/>
+               </method>
        </interface>
 </node>
 
index 3350a98..1de2c15 100755 (executable)
@@ -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
index 50e52e3..55db8da 100755 (executable)
@@ -64,5 +64,8 @@
                <check send_destination="net.netconfig" send_interface="net.netconfig.vpnsvc" send_member="vpn_down" privilege="http://tizen.org/privilege/vpnservice" />
                <check send_destination="net.netconfig" send_interface="net.netconfig.vpnsvc" send_member="vpn_block_networks" privilege="http://tizen.org/privilege/vpnservice" />
                <check send_destination="net.netconfig" send_interface="net.netconfig.vpnsvc" send_member="vpn_unblock_networks" privilege="http://tizen.org/privilege/vpnservice" />
+               <check send_destination="net.netconfig" send_interface="net.netconfig.vpnsvc" send_member="vpn_update_settings" privilege="http://tizen.org/privilege/vpnservice" />
+               <check send_destination="net.netconfig" send_interface="net.netconfig.vpnsvc" send_member="vpn_add_route" privilege="http://tizen.org/privilege/vpnservice" />
+               <check send_destination="net.netconfig" send_interface="net.netconfig.vpnsvc" send_member="vpn_add_dns_server" privilege="http://tizen.org/privilege/vpnservice" />
        </policy>
 </busconfig>
index a3b4132..5f7e3f1 100755 (executable)
@@ -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;
+}
index f83bd2e..8b126ed 100755 (executable)
@@ -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)) {