From c95902c230db8db65faf5a17c913e6c04ea9807e Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Wed, 16 Dec 2015 10:01:17 +0900 Subject: [PATCH 2/5] Initialize VPN CAPI for Tizen 3.0 Change-Id: Ic3138ffd60b4440cb01ef45d9b7ab8e0728b90cc Signed-off-by: Seonah Moon --- CMakeLists.txt | 40 ++ LICENSE-Apache.v2.0 | 202 ++++++ daemon/CMakeLists.txt | 58 ++ daemon/include/vpn_service_daemon.h | 38 ++ daemon/include/vpndbus.h | 58 ++ daemon/include/vpnsvc.h | 40 ++ daemon/interfaces/org.tizen.vpnsvc.xml | 46 ++ daemon/src/vpn_service_daemon.c | 931 +++++++++++++++++++++++++++ daemon/src/vpn_service_daemon_main.c | 67 ++ daemon/src/vpndbus.c | 240 +++++++ daemon/src/vpnsvc.c | 384 +++++++++++ daemon/vpnsvc-daemon.manifest | 66 ++ doc/vpn_doc.h | 65 ++ framework/CMakeLists.txt | 65 ++ framework/capi-vpnsvc.manifest | 5 + framework/capi-vpnsvc.pc.in | 14 + framework/include/capi_vpn_service_private.h | 83 +++ framework/src/capi_vpn_service.c | 911 ++++++++++++++++++++++++++ include/tizen_vpn_error.h | 51 ++ include/vpn_service.h | 442 +++++++++++++ packaging/capi-vpn-service.spec | 133 ++++ packaging/org.tizen.vpnsvc.service | 7 + packaging/vpnsvc-daemon.service | 13 + test/CMakeLists.txt | 41 ++ test/vpn_service_test.c | 342 ++++++++++ test/vpnsvc-test.manifest | 24 + 26 files changed, 4366 insertions(+) create mode 100755 CMakeLists.txt create mode 100755 LICENSE-Apache.v2.0 create mode 100755 daemon/CMakeLists.txt create mode 100755 daemon/include/vpn_service_daemon.h create mode 100755 daemon/include/vpndbus.h create mode 100755 daemon/include/vpnsvc.h create mode 100755 daemon/interfaces/org.tizen.vpnsvc.xml create mode 100755 daemon/src/vpn_service_daemon.c create mode 100755 daemon/src/vpn_service_daemon_main.c create mode 100755 daemon/src/vpndbus.c create mode 100755 daemon/src/vpnsvc.c create mode 100755 daemon/vpnsvc-daemon.manifest create mode 100755 doc/vpn_doc.h create mode 100755 framework/CMakeLists.txt create mode 100755 framework/capi-vpnsvc.manifest create mode 100755 framework/capi-vpnsvc.pc.in create mode 100755 framework/include/capi_vpn_service_private.h create mode 100755 framework/src/capi_vpn_service.c create mode 100755 include/tizen_vpn_error.h create mode 100755 include/vpn_service.h create mode 100755 packaging/capi-vpn-service.spec create mode 100755 packaging/org.tizen.vpnsvc.service create mode 100755 packaging/vpnsvc-daemon.service create mode 100755 test/CMakeLists.txt create mode 100755 test/vpn_service_test.c create mode 100755 test/vpnsvc-test.manifest diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..a8e110a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,40 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT("capi-vpn-service-pkg") + +############################# cmake packages ################################## + +INCLUDE(FindPkgConfig) + +############################# compiler flags ################################## + +SET(CMAKE_INSTALL_PREFIX /usr) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX ${PREFIX}/bin) +SET(LIBDIR ${PREFIX}/lib) +SET(INCLUDEDIR ${PREFIX}/include) + +# If supported for the target machine, emit position-independent code,suitable +# for dynamic linking and avoiding any limit on the size of the global offset +# table. This option makes a difference on the m68k, PowerPC and SPARC. +# (BJ: our ARM too?) +ADD_DEFINITIONS("-fPIC") + +# Set compiler warning flags + +#ADD_DEFINITIONS("-Werror") # Make all warnings into errors. +ADD_DEFINITIONS("-Wall") # Generate all warnings +ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings + +STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}") +ADD_DEFINITIONS("-DAPI_VERSION=\"$(API_VERSION)\"") +ADD_DEFINITIONS("-DSMACK_ENABLED") + +IF (CMAKE_BUILD_TYPE MATCHES "DEBUG") + ADD_DEFINITIONS("-DTIZEN_DEBUG_ENABLE") + ADD_DEFINITIONS("-DBUILD_TYPE_DEBUG") +ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG") + +ADD_SUBDIRECTORY(framework) +ADD_SUBDIRECTORY(daemon) +ADD_SUBDIRECTORY(test) + diff --git a/LICENSE-Apache.v2.0 b/LICENSE-Apache.v2.0 new file mode 100755 index 0000000..d645695 --- /dev/null +++ b/LICENSE-Apache.v2.0 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt new file mode 100755 index 0000000..09ffa1d --- /dev/null +++ b/daemon/CMakeLists.txt @@ -0,0 +1,58 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(PACKAGE_NAME vpnsvc-daemon) +SET(LIB_NAME ${PACKAGE_NAME}) +PROJECT(${LIB_NAME}) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") +SET(DAEMON_DIR "${CMAKE_SOURCE_DIR}/daemon") +SET(VERSION 0.1) + +SET(requires "dlog dbus-1 glib-2.0 gio-2.0 gio-unix-2.0 capi-base-common capi-appfw-package-manager") +SET(pc_requires "capi-base-common") + +SET(SRCS + src/vpnsvc.c + src/vpndbus.c + src/vpn_service_daemon.c + src/vpn_service_daemon_main.c +) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/framework/include + ${CMAKE_SOURCE_DIR}/daemon/include) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${PACKAGE_NAME} REQUIRED ${requires}) +FOREACH(flag ${${PACKAGE_NAME}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +# Compiler flags +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIC -Wall -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -I${DAEMON_DIR}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") +ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"") +ADD_DEFINITIONS("-DDATAFS=\"$ENV{DATADIR}\"") +ADD_DEFINITIONS("-DSLP_DEBUG") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib -pie") + +ADD_CUSTOM_COMMAND( + WORKING_DIRECTORY + OUTPUT ${DAEMON_DIR}/generated-code.c + COMMAND gdbus-codegen --interface-prefix org.tizen. + --generate-c-code generated-code + --c-generate-object-manager + --generate-docbook generated-code-docs + ${DAEMON_DIR}/interfaces/org.tizen.vpnsvc.xml + COMMENT "Generating GDBus .c/.h") + +ADD_EXECUTABLE(${PACKAGE_NAME} ${SRCS} ${DAEMON_DIR}/generated-code.c) +TARGET_LINK_LIBRARIES(${PACKAGE_NAME} ${${PACKAGE_NAME}_LDFLAGS} -lrt -ldl) + +INSTALL(TARGETS ${PACKAGE_NAME} DESTINATION bin) + diff --git a/daemon/include/vpn_service_daemon.h b/daemon/include/vpn_service_daemon.h new file mode 100755 index 0000000..9237184 --- /dev/null +++ b/daemon/include/vpn_service_daemon.h @@ -0,0 +1,38 @@ +/* + * VPN Service Module + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#ifndef __TIZEN_CAPI_VPN_SERVICE_DAEMON_H__ +#define __TIZEN_CAPI_VPN_SERVICE_DAEMON_H__ + +#include "capi_vpn_service_private.h" + +int vpn_daemon_init(const char* tun_name, size_t tun_name_len, int fd, vpnsvc_tun_s *handle_s); +int vpn_daemon_deinit(const char* dev_name); +int vpn_daemon_protect(int socket, const char* dev_name); +int vpn_daemon_up(int tun_index, const char* local_ip, const char* remote_ip, + const struct vpnsvc_route* routes, 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_daemon_down(int tun_index); +int vpn_daemon_block_networks(const struct vpnsvc_route* nets_vpn, size_t nr_nets_vpn, + const struct vpnsvc_route* nets_orig, size_t nr_nets_orig); +int vpn_daemon_unblock_networks(void); + +#endif /* __TIZEN_CAPI_VPN_SERVICE_DAEMON_H__ */ diff --git a/daemon/include/vpndbus.h b/daemon/include/vpndbus.h new file mode 100755 index 0000000..85b39f6 --- /dev/null +++ b/daemon/include/vpndbus.h @@ -0,0 +1,58 @@ +/* + * VPN Service Module + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __VPNSERVICE_VPNDBUS_H__ +#define __VPNSERVICE_VPNDBUS_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define VPNSERVICE_SERVICE "org.tizen.vpnsvc" +#define VPNSERVICE_INTERFACE "org.tizen.vpnsvc" +#define VPNSERVICE_PATH "/org/tizen/vpnsvc" + +typedef void (*vpnsvc_got_name_cb)(void); + +GDBusObjectManagerServer *vpnsvc_get_vpn_manager(void); +GDBusConnection *vpnsvc_gdbus_get_connection(void); +GCancellable *vpnsvc_gdbus_get_gdbus_cancellable(void); +void vpnsvc_gdbus_pending_call_ref(void); +void vpnsvc_gdbus_pending_call_unref(void); +int vpnsvc_create_gdbus_call(GDBusConnection *conn); + +gboolean vpnsvc_invoke_dbus_method_nonblock(const char *dest, const char *path, + const char *interface_name, const char *method, GVariant *params, + GAsyncReadyCallback notify_func); +GVariant *vpnsvc_invoke_dbus_method(const char *dest, const char *path, + const char *interface_name, const char *method, + GVariant *params); + +int vpnsvc_setup_gdbus(vpnsvc_got_name_cb cb); +void vpnsvc_cleanup_gdbus(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __VPNSERVICE_VPNDBUS_H__ */ diff --git a/daemon/include/vpnsvc.h b/daemon/include/vpnsvc.h new file mode 100755 index 0000000..b6467a8 --- /dev/null +++ b/daemon/include/vpnsvc.h @@ -0,0 +1,40 @@ +/* + * VPN Service Module + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __VPNSERVICE_VPNSVC_H__ +#define __VPNSERVICE_VPNSVC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#include "generated-code.h" + +void vpnsvc_create_and_init(void); +Vpnsvc *get_vpnsvc_object(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __VPNSERVICE_VPNSVC_H__ */ diff --git a/daemon/interfaces/org.tizen.vpnsvc.xml b/daemon/interfaces/org.tizen.vpnsvc.xml new file mode 100755 index 0000000..8c4d08d --- /dev/null +++ b/daemon/interfaces/org.tizen.vpnsvc.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/daemon/src/vpn_service_daemon.c b/daemon/src/vpn_service_daemon.c new file mode 100755 index 0000000..977426e --- /dev/null +++ b/daemon/src/vpn_service_daemon.c @@ -0,0 +1,931 @@ +/* + * VPN Service Module + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vpn_service_daemon.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "VPNSVC_DAEMON" + +#define CONNMAN_SERVICE "net.connman" +#define CONNMAN_INTERFACE_MANAGER "net.connman.Manager" +#define CONNMAN_INTERFACE_SERVICE "net.connman.Service" + + +/* for iptables */ +static char iptables_cmd[] = "/usr/sbin/iptables"; +static char iptables_filter_prefix[] = "CAPI_VPN_SERVICE_"; +static char iptables_filter_out[] = "OUTPUT"; +static char iptables_filter_in[] = "INPUT"; +static char iptables_filter_interface_wlan[] = "wlan0"; +/* static char iptables_register_fmt[] = "%s -N %s%s -w;" "%s -F %s%s -w;" "%s -A %s%s -j RETURN -w;" "%s -I %s -j %s%s -w;"; */ +static char iptables_register_fmt[] = "%s -N %s%s -w;" "%s -F %s%s -w;" "%s -A %s%s -j DROP -w;" "%s -A %s%s -j RETURN -w;" "%s -I %s -j %s%s -w;"; +static char iptables_unregister_fmt[] = "%s -D %s -j %s%s -w;" "%s -F %s%s -w;" "%s -X %s%s -w;"; +static char iptables_rule_fmt[] = "%s -%c %s%s -%c %s/%d -j ACCEPT -w;"; +static char iptables_rule_with_interface_fmt[] = "%s -%c %s%s -%c %s -%c %s/%d -j ACCEPT -w;"; +/*static char iptables_usage_fmt[] = "%s -L %s%s -n -v -w;";*/ + +typedef unsigned long int ipv4; /* Declare variable type for ipv4 net address. */ + +static GDBusConnection *global_connection = NULL; + +static ipv4 make_mask(int prefix) +{ + ipv4 mask = 0; + int i = 0; + + for (i = prefix; i > 0; i--) + mask += (ipv4) (1 << (32 - i)); + return mask; +} + +static in_addr_t host2net(ipv4 host) +{ + in_addr_t net; + + net = 0; + + net |= (host & 0x000000FF) << 24; + net |= (host & 0x0000FF00) << 8; + net |= (host & 0x00FF0000) >> 8; + net |= (host & 0xFF000000) >> 24; + + return net; +} + +static int add_routes(char* if_name, const struct vpnsvc_route* routes, size_t nr_routes) +{ + struct rtentry rt; + struct sockaddr_in addr; + int sk; + unsigned int i = 0; + + LOGD("Enter add_routes"); + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) { + LOGE("socket failed : %s", strerror(errno)); + 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].dest); + 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(routes[i].prefix)); + memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask)); + + rt.rt_dev = if_name; + + if (ioctl(sk, SIOCADDRT, &rt) < 0) { + LOGE("ioctl SIOCADDRT failed : %s", strerror(errno)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + } + + close(sk); + + return VPNSVC_ERROR_NONE; +} + +static void connman_connection_open(void) +{ + if (global_connection == NULL) { + GError *error = NULL; +#if !GLIB_CHECK_VERSION(2, 36, 0) + g_type_init(); +#endif + + global_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (global_connection == NULL) { + if (error != NULL) { + LOGE("Error connman connection open: %s", error->message); + g_error_free(error); + } + } + } +} + +static void connman_connection_close(GDBusConnection *connection) +{ + if (connection) + g_object_unref(connection); +} + +static GVariant *connman_method_call( + GDBusConnection *connection, char *service, char *path, + char *interface, char *method, GVariant *params) +{ + GError *error = NULL; + GVariant *message = NULL; + + message = g_dbus_connection_call_sync( + connection, service, path, interface, method, params, + NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (message == NULL) { + if (error != NULL) { + LOGE("error: g_dbus_connection_call_sync [%d: %s]", error->code, error->message); + g_error_free(error); + } else { + LOGE("error: g_dbus_connection_call_sync\n"); + } + } + + return message; +} + +static char *connman_default_profile(GDBusConnection *connection) +{ + gchar *key = NULL; + GVariantIter *value = NULL; + GVariant *message = NULL; + GVariantIter *iter = NULL; + char *profile = NULL; + + message = connman_method_call(connection, CONNMAN_SERVICE, "/", + CONNMAN_INTERFACE_MANAGER, "GetServices", NULL); + + if (message) { + g_variant_get(message, "(a(oa{sv}))", &iter); + while (g_variant_iter_loop(iter, "(oa{sv})", &key, &value)) { + profile = strdup(key); + break; + } + + if (value) + g_variant_iter_free(value); + if (key) + g_free(key); + + g_variant_iter_free(iter); + g_variant_unref(message); + } + + return profile; +} + +static char *connman_get_items(GDBusConnection *connection, char *profile, const char *keystr) +{ + GVariant *message = NULL; + GVariantIter *iter = NULL; + GVariantIter *next = NULL; + gchar *obj = NULL; + char *items = NULL; + + message = connman_method_call(connection, CONNMAN_SERVICE, "/", + CONNMAN_INTERFACE_MANAGER, "GetServices", NULL); + + if (message) { + g_variant_get(message, "(a(oa{sv}))", &iter); + while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) { + if (strcmp(obj, profile) == 0) { + GVariant *var; + gchar *key; + + while (g_variant_iter_loop(next, "{sv}", &key, &var)) { + if (g_strcmp0(key, keystr) == 0) { + GVariantIter *iter_item; + const gchar *value = NULL; + + g_variant_get(var, "as", &iter_item); + while (g_variant_iter_loop(iter_item, "s", &value)) { + if (items) { + char *tmp_items; + + tmp_items = (char *) malloc(strlen(items) + 1 + strlen(value) + 1); + if (items) { + sprintf(tmp_items, "%s,%s", items, value); + free(items); + items = tmp_items; + } + } else { + items = strdup(value); + } + } + g_variant_iter_free(iter_item); + break; + } + } + break; + } + } + g_variant_iter_free(iter); + g_variant_unref(message); + } + + return items; +} + +static void connman_set_items(GDBusConnection *connection, char *profile, + const char *keystr, char *items) +{ + GVariant *message = NULL; + GVariantBuilder *builder = NULL; + GVariant *params = NULL; + char *strings = strdup(items); + char *addr = NULL; + + builder = g_variant_builder_new(G_VARIANT_TYPE("as")); + if ((addr = strtok(strings, ", ")) != NULL) { + do { + g_variant_builder_add(builder, "s", addr); + } while ((addr = strtok(NULL, ", ")) != NULL); + } + free(strings); + params = g_variant_new("(sv)", keystr, + g_variant_builder_end(builder)); + g_variant_builder_unref(builder); + + message = connman_method_call(connection, CONNMAN_SERVICE, profile, + CONNMAN_INTERFACE_SERVICE, "SetProperty", params); + if (message) + g_variant_unref(message); + +} + +static char *connman_get_nameservers(GDBusConnection *connection, char *profile) +{ + return connman_get_items(connection, profile, "Nameservers"); +} + +static char *connman_get_nameservers_conf(GDBusConnection *connection, char *profile) +{ + return connman_get_items(connection, profile, "Nameservers.Configuration"); +} + +static void connman_set_nameservers(GDBusConnection *connection, char *profile, + char *nameservers) +{ + return connman_set_items(connection, profile, + "Nameservers.Configuration", nameservers); +} + +static char *connman_get_domains(GDBusConnection *connection, char *profile) +{ + return connman_get_items(connection, profile, "Domains"); +} + +static char *connman_get_domains_conf(GDBusConnection *connection, char *profile) +{ + return connman_get_items(connection, profile, "Domains.Configuration"); +} + +static void connman_set_domains(GDBusConnection *connection, char *profile, + char *domains) +{ + return connman_set_items(connection, profile, + "Domains.Configuration", domains); +} + +static int add_dns_servers(char** dns_servers, size_t nr_dns, size_t total_dns_string_cnt) +{ + char *profile = NULL; + char *items = NULL; + char *org_items = NULL; + char *new_items = NULL; + unsigned int i; + + connman_connection_open(); + + profile = connman_default_profile(global_connection); + if (profile == NULL) { + LOGE("connman_default_profile failed"); + connman_connection_close(global_connection); + return VPNSVC_ERROR_IPC_FAILED; + } + + LOGD("profile : %s\n", profile); + + /* add name servers */ + org_items = connman_get_nameservers(global_connection, profile); + + if (org_items) { + LOGD("original DNS : %s\n", org_items); + /* nr_dns = comma(,) count */ + items = (char *) calloc((total_dns_string_cnt + nr_dns + strlen(org_items) + 1), sizeof(char)); + if (items == NULL) { + LOGE("OOM while malloc\n"); + return VPNSVC_ERROR_OUT_OF_MEMORY; + } + strncpy(items, org_items, strlen(org_items)); + for (i = 0 ; i < nr_dns ; i++) { + strcat(items, ","); + strcat(items, dns_servers[i]); + } + free(org_items); + org_items = NULL; + } else { + /* nr_dns = comma(,) count + end null char */ + items = (char *) calloc(total_dns_string_cnt + nr_dns, sizeof(char)); + if (items == NULL) { + LOGE("OOM while malloc\n"); + return VPNSVC_ERROR_OUT_OF_MEMORY; + } + for (i = 0 ; i < nr_dns ; i++) { + strcat(items, dns_servers[i]); + if (i != nr_dns - 1) + strcat(items, ","); + } + } + + if (items) { + LOGD("adding DNS : %s\n", items); + connman_set_nameservers(global_connection, profile, items); + free(items); + items = NULL; + } + + /* print new DNSs */ + new_items = connman_get_nameservers_conf(global_connection, profile); + LOGD("new_dns : %s\n", new_items); + + if (new_items) + free(new_items); + free(profile); + return VPNSVC_ERROR_NONE; +} + +static int del_dns_servers() +{ + char *profile = NULL; + + connman_connection_open(); + + profile = connman_default_profile(global_connection); + if (profile == NULL) { + LOGE("connman_default_profile failed"); + connman_connection_close(global_connection); + return VPNSVC_ERROR_IPC_FAILED; + } + + LOGD("profile : %s", profile); + + /* del name servers */ + connman_set_nameservers(global_connection, profile, ""); + + if (profile) + free(profile); + + return VPNSVC_ERROR_NONE; +} + +static int add_dns_suffix(const char* dns_suffix, size_t dns_suffix_len) +{ + char *profile = NULL; + char *items = NULL; + char *org_items = NULL; + char *new_items = NULL; + + connman_connection_open(); + + profile = connman_default_profile(global_connection); + if (profile == NULL) { + LOGE("connman_default_profile failed"); + connman_connection_close(global_connection); + return VPNSVC_ERROR_IPC_FAILED; + } + + LOGD("profile : %s", profile); + + /* add name servers */ + org_items = connman_get_domains(global_connection, profile); + + if (org_items) { + LOGD("original DNS suffix : %s", org_items); + /* comma(,) and end null character included */ + items = (char *) calloc((dns_suffix_len + strlen(org_items) + 2), sizeof(char)); + if (items == NULL) { + LOGE("OOM while malloc"); + return VPNSVC_ERROR_OUT_OF_MEMORY; + } + strncpy(items, org_items, strlen(org_items)); + strcat(items, ","); + strcat(items, dns_suffix); + free(org_items); + org_items = NULL; + } else { + /* nr_dns = comma(,) count + end null char */ + items = (char *) calloc((dns_suffix_len + 1), sizeof(char)); + if (items == NULL) { + LOGE("OOM while malloc"); + return VPNSVC_ERROR_OUT_OF_MEMORY; + } + strcat(items, dns_suffix); + } + + if (items) { + LOGD("adding DNS suffix : %s\n", items); + connman_set_domains(global_connection, profile, items); + free(items); + items = NULL; + } + + /* print new domains */ + new_items = connman_get_domains_conf(global_connection, profile); + LOGD("new DNS suffix : %s\n", new_items); + + if (new_items) + free(new_items); + + if (profile) + free(profile); + + return VPNSVC_ERROR_NONE; +} + +static int del_dns_suffix() +{ + char *profile = NULL; + + connman_connection_open(); + + profile = connman_default_profile(global_connection); + if (profile == NULL) { + LOGE("connman_default_profile failed"); + connman_connection_close(global_connection); + return VPNSVC_ERROR_IPC_FAILED; + } + + LOGD("profile : %s", profile); + + /* del DNS suffix */ + connman_set_domains(global_connection, profile, ""); + + if (profile) + free(profile); + + return VPNSVC_ERROR_NONE; +} + + +static void iptables_exec(char *cmdline) +{ + FILE *fp = NULL; + + fp = popen(cmdline, "r"); + + if (fp != NULL) + pclose(fp); +} + +static void iptables_register(void) +{ + int size = 0; + char buf[8192], *filter; + + filter = iptables_filter_out; + snprintf(buf + size, sizeof(buf) - size, iptables_register_fmt, + iptables_cmd, iptables_filter_prefix, filter, + iptables_cmd, iptables_filter_prefix, filter, + iptables_cmd, iptables_filter_prefix, filter, + iptables_cmd, iptables_filter_prefix, filter, + iptables_cmd, filter, iptables_filter_prefix, filter); + size = strlen(buf); + filter = iptables_filter_in; + snprintf(buf + size, sizeof(buf) - size, iptables_register_fmt, + iptables_cmd, iptables_filter_prefix, filter, + iptables_cmd, iptables_filter_prefix, filter, + iptables_cmd, iptables_filter_prefix, filter, + iptables_cmd, iptables_filter_prefix, filter, + iptables_cmd, filter, iptables_filter_prefix, filter); + LOGD("iptable reg cmd : %s", buf); + iptables_exec(buf); +} + +static void iptables_unregister(void) +{ + int size = 0; + char buf[8192], *filter; + + filter = iptables_filter_out; + snprintf(buf + size, sizeof(buf) - size, iptables_unregister_fmt, + iptables_cmd, filter, iptables_filter_prefix, filter, + iptables_cmd, iptables_filter_prefix, filter, + iptables_cmd, iptables_filter_prefix, filter); + size = strlen(buf); + filter = iptables_filter_in; + snprintf(buf + size, sizeof(buf) - size, iptables_unregister_fmt, + iptables_cmd, filter, iptables_filter_prefix, filter, + iptables_cmd, iptables_filter_prefix, filter, + iptables_cmd, iptables_filter_prefix, filter); + LOGD("iptable unreg cmd : %s", buf); + iptables_exec(buf); +} + +static void iptables_rule(const char c, const char *addr, const int mask) +{ + int size = 0; + char buf[4096]; + + snprintf(buf + size, sizeof(buf) - size, iptables_rule_fmt, iptables_cmd, c, + iptables_filter_prefix, iptables_filter_out, 'd', addr, mask); + size = strlen(buf); + snprintf(buf + size, sizeof(buf) - size, iptables_rule_fmt, iptables_cmd, c, + iptables_filter_prefix, iptables_filter_in, 's', addr, mask); + LOGD("iptable cmd : %s", buf); + iptables_exec(buf); +} + +static void iptables_rule_interface(const char c, const char *addr, const int mask, const char *interface) +{ + int size = 0; + char buf[4096]; + + snprintf(buf + size, sizeof(buf) - size, + iptables_rule_with_interface_fmt, iptables_cmd, + c, iptables_filter_prefix, iptables_filter_out, + 'o', interface, 'd', addr, mask); + size = strlen(buf); + snprintf(buf + size, sizeof(buf) - size, + iptables_rule_with_interface_fmt, iptables_cmd, + c, iptables_filter_prefix, iptables_filter_in, + 'i', interface, 's', addr, mask); + LOGD("iptable cmd : %s", buf); + iptables_exec(buf); +} + +void iptables_add_orig(const char *addr, const int mask) +{ + iptables_rule_interface('I', addr, mask, iptables_filter_interface_wlan); +} + +void iptables_delete_orig(const char *addr, const int mask) +{ + iptables_rule_interface('D', addr, mask, iptables_filter_interface_wlan); +} + +void iptables_add(const char *addr, const int mask) +{ + iptables_rule('I', addr, mask); +} + +void iptables_delete(const char *addr, const int mask) +{ + iptables_rule('D', addr, mask); +} + +static int get_interface_index(const char *tun_name) +{ + struct ifreq ifr; + int sk = 0; + + LOGD("enter get_interface_index, tun_name : %s", tun_name); + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) { + LOGE("socket failed : %s", strerror(errno)); + return VPNSVC_ERROR_IO_ERROR; + } + + memset(&ifr, 0, sizeof(ifr)); + + if (*tun_name) + strncpy(ifr.ifr_name, tun_name, strlen(tun_name)); + + /* get an interface name by ifindex */ + if (ioctl(sk, SIOCGIFINDEX, &ifr) < 0) { + LOGE("ioctl SIOCGIFINDEX failed : %s", strerror(errno)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + close(sk); + + return ifr.ifr_ifindex; +} + + +int vpn_daemon_init(const char* tun_name, size_t tun_name_len, int fd, vpnsvc_tun_s *handle_s) +{ + struct ifreq ifr; + size_t len = 0; + + LOGD("enter vpn_daemon_init, tun_name : %s, tun_name_len : %d, fd : %d\n", tun_name, tun_name_len, fd); + + memset(&ifr, 0, sizeof(ifr)); + + /* Flags: IFF_TUN - TUN device (no Ethernet headers) + * IFF_TAP - TAP device + * + * IFF_NO_PI - Do not provide packet information + */ + + ifr.ifr_flags = IFF_TUN | IFF_NO_PI; + + if (*tun_name) + strncpy(ifr.ifr_name, tun_name, tun_name_len); + + LOGD("before init, ifindex : %d", ifr.ifr_ifindex); + + if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) { + LOGE("TUNSETIFF Failed : %s", strerror(errno)); + close(fd); + return VPNSVC_ERROR_IO_ERROR; + } + + if (ioctl(fd, TUNSETOWNER, 5000) < 0) { + LOGE("TUNSETOWNER Failed : %s", strerror(errno)); + close(fd); + return VPNSVC_ERROR_IO_ERROR; + } + + if (ioctl(fd, TUNSETPERSIST, 1) < 0) { + LOGE("TUNSETPERSIST Failed : %s", strerror(errno)); + close(fd); + return VPNSVC_ERROR_IO_ERROR; + } + + handle_s->fd = 0; /* server fd does not meaning */ + handle_s->index = get_interface_index(tun_name); + len = strlen(ifr.ifr_name); + strncpy(handle_s->name, ifr.ifr_name, len); + handle_s->name[len] = '\0'; + + return VPNSVC_ERROR_NONE; +} + +int vpn_daemon_deinit(const char* dev_name) +{ + char buf[100]; + FILE *fp = NULL; + + snprintf(buf, sizeof(buf), "/usr/sbin/ip link del %s", dev_name); + LOGD("link delete cmd : %s", buf); + + fp = popen(buf, "r"); + if (fp != NULL) { + pclose(fp); + return VPNSVC_ERROR_NONE; + } else { + return VPNSVC_ERROR_IO_ERROR; + } +} + +int vpn_daemon_protect(int socket_fd, const char* dev_name) +{ + int ret = VPNSVC_ERROR_NONE; + LOGD("enter vpn_daemon_protect, socket : %d, dev_name : %s\n", socket_fd, dev_name); + + ret = setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE, + dev_name, strlen(dev_name)); + + if (ret < 0) { + LOGD("setsockopt failed : %d, %s", ret, strerror(errno)); + ret = VPNSVC_ERROR_IO_ERROR; + } else { + ret = VPNSVC_ERROR_NONE; + } + + return ret; +} + +int vpn_daemon_up(int tun_index, const char* local_ip, const char* remote_ip, + const struct vpnsvc_route* routes, 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; + struct ifreq ifr_tun; + int sk; + int ret = VPNSVC_ERROR_NONE; + + LOGD("enter vpn_daemon_up"); + + LOGD("tun_index : %d", tun_index); + LOGD("local ip : %s", local_ip); + LOGD("remote ip : %s", remote_ip); + LOGD("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); + + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) { + LOGE("socket failed : %s", strerror(errno)); + return VPNSVC_ERROR_IO_ERROR; + } + + memset(&ifr_tun, 0, sizeof(ifr_tun)); + ifr_tun.ifr_ifindex = tun_index; + + /* get an interface name by ifindex */ + if (ioctl(sk, SIOCGIFNAME, &ifr_tun) < 0) { + LOGE("ioctl SIOCGIFNAME failed : %s", strerror(errno)); + 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) { + LOGE("ioctl SIOCSIFADDR failed : %s", strerror(errno)); + 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) { + LOGE("ioctl SIOCSIFDSTADDR failed : %s", strerror(errno)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + /* set the flags for vpn up */ + if (ioctl(sk, SIOCGIFFLAGS, &ifr_tun) < 0) { + LOGE("ioctl SIOCGIFFLAGS failed : %s", strerror(errno)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + ifr_tun.ifr_flags |= IFF_UP; + ifr_tun.ifr_flags |= IFF_RUNNING; + + if (ioctl(sk, SIOCSIFFLAGS, &ifr_tun) < 0) { + LOGE("ioctl SIOCSIFFLAGS failed : %s", strerror(errno)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + /* mtu setting */ + if (ioctl(sk, SIOCGIFMTU, &ifr_tun) < 0) { + LOGE("ioctl SIOCGIFMTU failed : %s", strerror(errno)); + 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) { + LOGE("ioctl SIOCSIFMTU failed : %s", strerror(errno)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + } + + close(sk); + + /* add routes */ + if (nr_routes > 0) { + ret = add_routes(ifr_tun.ifr_name, routes, nr_routes); + if (ret != VPNSVC_ERROR_NONE) { + LOGE("add_routes failed"); + return ret; + } + } + + /* add DNS servers */ + if (nr_dns > 0) { + ret = add_dns_servers(dns_servers, nr_dns, total_dns_string_cnt); + if (ret != VPNSVC_ERROR_NONE) { + LOGE("add_dns failed"); + return ret; + } + } + + /* add_dns_suffix */ + if (dns_suffix) { + ret = add_dns_suffix(dns_suffix, strlen(dns_suffix)); + if (ret != VPNSVC_ERROR_NONE) { + LOGE("add_dns_suffix failed"); + return ret; + } + } + + return ret; +} + +int vpn_daemon_down(int tun_index) +{ + struct ifreq ifr, addr_ifr; + struct sockaddr_in *addr = NULL; + int sk; + + sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (sk < 0) { + LOGE("socket failed : %s", strerror(errno)); + return VPNSVC_ERROR_IO_ERROR; + } + + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_ifindex = tun_index; + + if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) { + LOGE("ioctl SIOCGIFNAME failed : %s", strerror(errno)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) { + LOGE("ioctl SIOCGIFFLAGS failed : %s", strerror(errno)); + close(sk); + 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) + LOGD("ioctl SIOCSIFADDR (could not clear IP address) failed : %s", strerror(errno)); + + if (!(ifr.ifr_flags & IFF_UP)) { + LOGD("Interface already down"); + close(sk); + return VPNSVC_ERROR_NONE; + } + + ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC; + if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) { + LOGE("ioctl SIOCSIFFLAGS (interface down) failed : %s", strerror(errno)); + close(sk); + return VPNSVC_ERROR_IO_ERROR; + } + + close(sk); + + /* routes are will be removed automatically while down interfaces */ + /* remove dns servers */ + del_dns_servers(); + + /* remove dns suffix */ + del_dns_suffix(); + + return VPNSVC_ERROR_NONE; +} + +int vpn_daemon_block_networks(const struct vpnsvc_route* nets_vpn, size_t nr_nets_vpn, + const struct vpnsvc_route* nets_orig, size_t nr_nets_orig) { + unsigned int i; + + /* iptable chain regist */ + iptables_register(); + + for (i = 0; i < nr_nets_vpn; i++) { + LOGD("block[%d] ip/mask : %s/%d", i, nets_vpn[i].dest, nets_vpn[i].prefix); + iptables_add(nets_vpn[i].dest, nets_vpn[i].prefix); + } + + for (i = 0; i < nr_nets_orig; i++) { + LOGD("allow[%d] ip/mask : %s/%d", i, nets_orig[i].dest, nets_orig[i].prefix); + iptables_add_orig(nets_orig[i].dest, nets_orig[i].prefix); + } + + return VPNSVC_ERROR_NONE; +} + +int vpn_daemon_unblock_networks(void) +{ + iptables_unregister(); + + return VPNSVC_ERROR_NONE; +} diff --git a/daemon/src/vpn_service_daemon_main.c b/daemon/src/vpn_service_daemon_main.c new file mode 100755 index 0000000..1f14aaf --- /dev/null +++ b/daemon/src/vpn_service_daemon_main.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include /* exit, EXIT_FAILURE */ +#include + +#include "vpnsvc.h" +#include "vpndbus.h" + + +#ifdef LOG_TAG +#undef LOG_TAG +#endif + +#define LOG_TAG "VPNSVC_DAEMON" + +static GMainLoop *main_loop = NULL; + +static void __vpnsvc_got_name_cb(void) +{ + vpnsvc_create_and_init(); +} + +int main(void) +{ + int ret; + + LOGD("VPN Service"); + if (daemon(0, 0) != 0) + LOGD("Cannot start daemon"); + +#if !GLIB_CHECK_VERSION(2, 36, 0) + g_type_init(); +#endif + + main_loop = g_main_loop_new(NULL, FALSE); + if (main_loop == NULL) { + LOGE("Couldn't create GMainLoop\n"); + return 0; + } + + ret = vpnsvc_setup_gdbus(__vpnsvc_got_name_cb); + if (ret > 0) { + LOGE("_vpnsvc_setup_gdbus is failed\n"); + return 0; + } + + g_main_loop_run(main_loop); + + vpnsvc_cleanup_gdbus(); + + return 0; +} diff --git a/daemon/src/vpndbus.c b/daemon/src/vpndbus.c new file mode 100755 index 0000000..9c12f82 --- /dev/null +++ b/daemon/src/vpndbus.c @@ -0,0 +1,240 @@ +/* + * VPN Service Module + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include +#include + +#include "vpndbus.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "VPNSVC_DAEMON" + +#define DBUS_REPLY_TIMEOUT (120 * 1000) + +static GDBusObjectManagerServer *manager_server_vpn = NULL; +static guint owner_id = 0; +static vpnsvc_got_name_cb g_callback = NULL; + +struct gdbus_conn_data { + GDBusConnection *connection; + int conn_ref_count; + GCancellable *cancellable; +}; + +static struct gdbus_conn_data gconn_data = {NULL, 0, NULL}; + +GDBusObjectManagerServer *vpnsvc_get_vpn_manager(void) +{ + return manager_server_vpn; +} + +GDBusConnection *vpnsvc_gdbus_get_connection(void) +{ + return gconn_data.connection; +} + +GCancellable *vpnsvc_gdbus_get_gdbus_cancellable(void) +{ + return gconn_data.cancellable; +} + +void vpnsvc_gdbus_pending_call_ref(void) +{ + g_object_ref(gconn_data.connection); + + __sync_fetch_and_add(&gconn_data.conn_ref_count, 1); +} + +void vpnsvc_gdbus_pending_call_unref(void) +{ + if (gconn_data.conn_ref_count < 1) + return; + + g_object_unref(gconn_data.connection); + + if (__sync_sub_and_fetch(&gconn_data.conn_ref_count, 1) < 1) { + /* TODO: Check this + * gconn_data.connection = NULL; + */ + } +} + +int vpnsvc_create_gdbus_call(GDBusConnection *conn) +{ + if (gconn_data.connection != NULL) { + LOGE("Connection already set"); + return -1; + } + + gconn_data.connection = conn; + if (gconn_data.connection == NULL) { + LOGE("Failed to connect to the D-BUS daemon"); + return -1; + } + + gconn_data.cancellable = g_cancellable_new(); + + return 0; +} + + +gboolean vpnsvc_invoke_dbus_method_nonblock(const char *dest, const char *path, + const char *interface_name, const char *method, GVariant *params, + GAsyncReadyCallback notify_func) +{ + GDBusConnection *connection = NULL; + + LOGD("[GDBUS Async] %s %s %s", interface_name, method, path); + + connection = vpnsvc_gdbus_get_connection(); + if (connection == NULL) { + LOGE("Failed to get gdbus connection"); + return FALSE; + } + + g_dbus_connection_call(connection, + dest, + path, + interface_name, + method, + params, + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, + vpnsvc_gdbus_get_gdbus_cancellable(), + (GAsyncReadyCallback) notify_func, + NULL); + + if (notify_func != NULL) + vpnsvc_gdbus_pending_call_ref(); + + return TRUE; +} + +GVariant *vpnsvc_invoke_dbus_method(const char *dest, const char *path, + const char *interface_name, const char *method, GVariant *params) +{ + + GError *error = NULL; + GVariant *reply = NULL; + GDBusConnection *connection; + + connection = vpnsvc_gdbus_get_connection(); + if (connection == NULL) { + LOGE("Failed to get GDBusconnection"); + return reply; + } + + reply = g_dbus_connection_call_sync( + connection, + dest, + path, + interface_name, + method, + params, + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, + vpnsvc_gdbus_get_gdbus_cancellable(), + &error); + + if (reply == NULL) { + if (error != NULL) { + LOGE("g_dbus_connection_call_sync() failed" + "error [%d: %s]", error->code, error->message); + g_error_free(error); + } else { + LOGE("g_dbus_connection_call_sync() failed"); + } + + return NULL; + } + + return reply; +} + +static void __vpnsvc_got_bus_cb(GDBusConnection *conn, const gchar *name, + gpointer user_data) +{ + LOGD("connection: [%p] name: [%s] user_data: [%p]", conn, name, user_data); + + vpnsvc_create_gdbus_call(conn); +} + +static void __vpnsvc_got_name_cb(GDBusConnection *conn, const gchar *name, + gpointer user_data) +{ + LOGD("connection: [%p] name: [%s] user_data: [%p]", conn, name, user_data); + + if (g_callback != NULL) + g_callback(); +} + +static void __vpnsvc_lost_name_cb(GDBusConnection *conn, const gchar *name, + gpointer user_data) +{ + LOGD("connection: [%p] name: [%s] user_data: [%p]", conn, name, user_data); + /* May service name is already in use */ + LOGE("Service name is already in use"); + + /* The result of DBus name request is only permitted, + * such as DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER. + */ + exit(2); +} + +int vpnsvc_setup_gdbus(vpnsvc_got_name_cb cb) +{ + LOGD("VPN Service Setup!"); + + g_callback = cb; + + manager_server_vpn = g_dbus_object_manager_server_new( + VPNSERVICE_PATH); + if (manager_server_vpn == NULL) { + LOGE("Manager server for VPNSERVICE_PATH not created."); + exit(1); + } + + owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, VPNSERVICE_SERVICE, + G_BUS_NAME_OWNER_FLAGS_NONE, __vpnsvc_got_bus_cb, + __vpnsvc_got_name_cb, __vpnsvc_lost_name_cb, + NULL, NULL); + if (!owner_id) { + LOGE("Could not get system bus!"); + return -EIO; + } + + LOGI("Got system bus!"); + return 0; +} + +void vpnsvc_cleanup_gdbus(void) +{ + LOGD("VPN Service Cleanup!"); + + g_bus_unown_name(owner_id); + + return; +} diff --git a/daemon/src/vpnsvc.c b/daemon/src/vpnsvc.c new file mode 100755 index 0000000..d2a55fa --- /dev/null +++ b/daemon/src/vpnsvc.c @@ -0,0 +1,384 @@ +/* + * VPN Service Module + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include + +#include "vpnsvc.h" +#include "vpndbus.h" +#include "vpn_service_daemon.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "VPNSVC_DAEMON" + +static Vpnsvc *vpnsvc = NULL; + +/********************* + * Handler Functions * + ********************/ +gboolean handle_vpn_init(Vpnsvc *object, + GDBusMethodInvocation *invocation, + const gchar *arg_tun_name, + guint arg_tun_name_len) +{ + LOGD("handle_vpn_init"); + + vpnsvc_tun_s handle_s; + int result = VPNSVC_ERROR_NONE; + GDBusMessage *msg; + GUnixFDList *fd_list; + int fd_list_length; + const int *fds; + + LOGD("vpn_init, %s, %u\n", arg_tun_name, arg_tun_name_len); + + msg = g_dbus_method_invocation_get_message(invocation); + fd_list = g_dbus_message_get_unix_fd_list(msg); + fds = g_unix_fd_list_peek_fds(fd_list, &fd_list_length); + + if (fd_list_length <= 0) + LOGD("D-Bus Message doesn't contain any fd!"); + + LOGD("fd:%d\n", *fds); + + result = vpn_daemon_init(arg_tun_name, arg_tun_name_len, *fds, &handle_s); + + LOGD("handle_s.fd : %d, handle_s.index : %d, handle_s.name : %s", + handle_s.fd, handle_s.index, handle_s.name); + + vpnsvc_complete_vpn_init(object, invocation, result, handle_s.index, handle_s.name); + + return TRUE; +} + +gboolean handle_vpn_deinit(Vpnsvc *object, + GDBusMethodInvocation *invocation, + const gchar *arg_dev_name) +{ + int result = VPNSVC_ERROR_NONE; + + LOGD("handle_vpn_deinit"); + LOGD("vpn_deinit, %s\n", arg_dev_name); + + result = vpn_daemon_deinit(arg_dev_name); + + vpnsvc_complete_vpn_deinit(object, invocation, result); + + return TRUE; +} + +gboolean handle_vpn_protect(Vpnsvc *object, + GDBusMethodInvocation *invocation, + const gchar *arg_dev_name) +{ + int result = VPNSVC_ERROR_NONE; + int socket; + GDBusMessage *msg; + GUnixFDList *fd_list; + int fd_list_length; + const int *fds; + + LOGD("handle_vpn_protect"); + + msg = g_dbus_method_invocation_get_message(invocation); + fd_list = g_dbus_message_get_unix_fd_list(msg); + fds = g_unix_fd_list_peek_fds(fd_list, &fd_list_length); + if (fd_list_length <= 0) + LOGD("D-Bus Message doesn't contain any fd!"); + + socket = *fds; + LOGD("vpn_protect, %d, %s\n", socket, arg_dev_name); + + result = vpn_daemon_protect(socket, arg_dev_name); + + vpnsvc_complete_vpn_protect(object, invocation, result); + + return TRUE; +} + +gboolean handle_vpn_up(Vpnsvc *object, + GDBusMethodInvocation *invocation, + gint arg_tun_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) +{ + int result = VPNSVC_ERROR_NONE; + + LOGD("handle_vpn_up"); + + struct vpnsvc_route* routes = NULL; + 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; + + LOGD("tun_index : %d", arg_tun_index); + LOGD("local ip : %s", arg_local_ip); + LOGD("remote ip : %s", arg_remote_ip); + LOGD("dns_suffix : %s", arg_dns_suffix); + LOGD("mtu : %u", arg_mtu); + LOGD("arg_routes: %p", arg_routes); + LOGD("nr_routes : %u", arg_nr_routes); + LOGD("arg_dns_servers: %p", arg_dns_servers); + LOGD("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); + routes = (struct vpnsvc_route*)malloc(sizeof(struct vpnsvc_route)*arg_nr_routes); + if (routes == NULL) { + LOGE("malloc failed."); + result = VPNSVC_ERROR_OUT_OF_MEMORY; + goto done; + } + 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); + strncpy(routes[i].dest, route_dest, temp_dest_str_len); + routes[i].dest[temp_dest_str_len] = '\0'; + routes[i].prefix = route_prefix; + LOGD("routes[%d] : %s/%d", i, (routes[i].dest == NULL) ? "" : routes[i].dest, routes[i].prefix); + 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 **)malloc(arg_nr_dns*sizeof(char *)); + if (dns_servers == NULL) { + LOGE("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 *)malloc((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; + LOGD("dns_servers[%d] : %s", i, (dns_servers[i] == NULL) ? "" : dns_servers[i]); + i++; + } + } + } + + result = vpn_daemon_up(arg_tun_index, arg_local_ip, arg_remote_ip, + routes, arg_nr_routes, dns_servers, arg_nr_dns, + total_dns_string_cnt, arg_dns_suffix, arg_mtu); +done: + /* free pointers */ + if (routes) + free(routes); + + if (dns_servers) { + for (i = 0; i < arg_nr_dns; i++) { + if (dns_servers[i]) + free(dns_servers[i]); + } + free(dns_servers); + } + + vpnsvc_complete_vpn_up(object, invocation, result); + + return TRUE; +} + +gboolean handle_vpn_down(Vpnsvc *object, + GDBusMethodInvocation *invocation, + gint arg_tun_index) +{ + LOGD("handle_vpn_down"); + int result = VPNSVC_ERROR_NONE; + + LOGD("vpn_down, %d\n", arg_tun_index); + + result = vpn_daemon_down(arg_tun_index); + + vpnsvc_complete_vpn_down(object, invocation, result); + + return TRUE; +} + +gboolean handle_vpn_block_networks(Vpnsvc *object, + GDBusMethodInvocation *invocation, + GVariant *arg_nets_vpn, + guint arg_nr_nets_vpn, + GVariant *arg_nets_orig, + guint arg_nr_nets_orig) +{ + LOGD("handle_vpn_block_networks"); + int result = VPNSVC_ERROR_NONE; + + struct vpnsvc_route* nets_vpn = NULL; + struct vpnsvc_route* nets_orig = NULL; + + int i = 0; + GVariantIter iter; + gchar* route_dest; + gint route_prefix; + + LOGD("vpn_block_networks"); + + /* arg_nets_vpn check */ + if (arg_nr_nets_vpn > 0) { + if (arg_nets_vpn != NULL) { + GVariant *dict_nets_vpn = g_variant_get_variant(arg_nets_vpn); + nets_vpn = (struct vpnsvc_route*)malloc(sizeof(struct vpnsvc_route)*arg_nr_nets_vpn); + if (nets_vpn == NULL) { + LOGE("malloc failed."); + result = VPNSVC_ERROR_OUT_OF_MEMORY; + goto done; + } + g_variant_iter_init(&iter, dict_nets_vpn); + i = 0; + while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) { + int tmp_route_len = strlen(route_dest); + strncpy(nets_vpn[i].dest, route_dest, tmp_route_len); + nets_vpn[i].dest[tmp_route_len] = '\0'; + nets_vpn[i].prefix = route_prefix; + LOGD("nets_vpn[%d] : %s/%d", i, (nets_vpn[i].dest == NULL) ? "" : nets_vpn[i].dest, nets_vpn[i].prefix); + i++; + } + } + } + + /* arg_nets_orig check */ + if (arg_nr_nets_orig > 0) { + if (arg_nets_orig != NULL) { + GVariant *dict_nets_orig = g_variant_get_variant(arg_nets_orig); + nets_orig = (struct vpnsvc_route*)malloc(sizeof(struct vpnsvc_route)*arg_nr_nets_orig); + if (nets_orig == NULL) { + LOGE("malloc failed."); + result = VPNSVC_ERROR_OUT_OF_MEMORY; + goto done; + } + g_variant_iter_init(&iter, dict_nets_orig); + i = 0; + while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) { + int tmp_route_len = strlen(route_dest); + strncpy(nets_orig[i].dest, route_dest, tmp_route_len); + nets_orig[i].dest[tmp_route_len] = '\0'; + nets_orig[i].prefix = route_prefix; + LOGD("nets_orig[%d] : %s/%d", i, (nets_orig[i].dest == NULL) ? "" : nets_orig[i].dest, nets_orig[i].prefix); + i++; + } + } + } + + /* call function */ + result = vpn_daemon_block_networks(nets_vpn, arg_nr_nets_vpn, nets_orig, arg_nr_nets_orig); + +done: + if (nets_vpn) + free(nets_vpn); + + if (nets_orig) + free(nets_orig); + + vpnsvc_complete_vpn_block_networks(object, invocation, result); + + return TRUE; +} + +gboolean handle_vpn_unblock_networks(Vpnsvc *object, + GDBusMethodInvocation *invocation) +{ + int result = VPNSVC_ERROR_NONE; + + LOGD("handle_vpn_unblock_networks"); + LOGD("vpn_unblock_networks"); + + result = vpn_daemon_unblock_networks(); + + vpnsvc_complete_vpn_unblock_networks(object, invocation, result); + + return TRUE; +} + +/***************************** + * Initializations Functions * + ****************************/ +Vpnsvc *get_vpnsvc_object(void) +{ + return vpnsvc; +} + +void vpnsvc_create_and_init(void) +{ + LOGD("Create vpn object."); + GDBusInterfaceSkeleton *interface = NULL; + GDBusConnection *connection; + GDBusObjectManagerServer *server = vpnsvc_get_vpn_manager(); + if (server == NULL) + return; + + connection = vpnsvc_gdbus_get_connection(); + g_dbus_object_manager_server_set_connection(server, connection); + + /* Interface */ + vpnsvc = vpnsvc_skeleton_new(); + interface = G_DBUS_INTERFACE_SKELETON(vpnsvc); + + /* VPN Service */ + g_signal_connect(vpnsvc, "handle-vpn-init", + G_CALLBACK(handle_vpn_init), NULL); + g_signal_connect(vpnsvc, "handle-vpn-deinit", + G_CALLBACK(handle_vpn_deinit), NULL); + g_signal_connect(vpnsvc, "handle-vpn-protect", + G_CALLBACK(handle_vpn_protect), NULL); + g_signal_connect(vpnsvc, "handle-vpn-up", + G_CALLBACK(handle_vpn_up), NULL); + g_signal_connect(vpnsvc, "handle-vpn-down", + G_CALLBACK(handle_vpn_down), NULL); + g_signal_connect(vpnsvc, "handle-vpn-block-networks", + G_CALLBACK(handle_vpn_block_networks), NULL); + g_signal_connect(vpnsvc, "handle-vpn-unblock-networks", + G_CALLBACK(handle_vpn_unblock_networks), NULL); + + if (!g_dbus_interface_skeleton_export(interface, connection, + VPNSERVICE_PATH, NULL)) { + LOGE("Export VPNSERVICE_PATH for vpn failed"); + } + + return; +} + diff --git a/daemon/vpnsvc-daemon.manifest b/daemon/vpnsvc-daemon.manifest new file mode 100755 index 0000000..6b97c3a --- /dev/null +++ b/daemon/vpnsvc-daemon.manifest @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/vpn_doc.h b/doc/vpn_doc.h new file mode 100755 index 0000000..caa82e5 --- /dev/null +++ b/doc/vpn_doc.h @@ -0,0 +1,65 @@ +/* + * VPN Service Module + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + + +#ifndef __TIZEN_NETWORK_VPN_DOC_H__ +#define __TIZEN_NETWORK_VPN_DOC_H__ + +/** + * @defgroup CAPI_NETWORK_VPN_MODULE VPN + * @brief The VPN API provides functions for managing VPN. + * @ingroup CAPI_NETWORK_FRAMEWORK + * + * @section CAPI_NETWORK_VPN_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_NETWORK_VPN_MODULE_OVERVIEW Overview + * VPN allows your application to manage VPN features. + * The VPN Service enables your application to init and deinit a VPN device(tun interface), + * Routing management, DNS management and Firewall management. + */ + +/** + * @defgroup CAPI_NETWORK_VPN_SERVICE_MODULE VPN Service + * @brief The VPN API provides functions for managing VPN. + * @ingroup CAPI_NETWORK_VPN_MODULE + * + * @section CAPI_NETWORK_VPN_SERVICE_MODULE_HEADER Required Header + * \#include + * + * @section CAPI_NETWORK_VPN_SERVICE_MODULE_OVERVEW Overview + * The VPN Service functions for managing VPN. + * Using the VPN Service, you can implement features that allow the users of your application to: + * - Initialize / Deinitialize the VPN device + * - Routing management + * - DNS management + * - Firewall management + * @section CAPI_NETWORK_VPN_SERVICE_MODULE_FEATURE Related Features + * This API is related with the following features:\n + * - http://developer.samsung.com/tizen/feature/network.vpn\n + * + * It is recommended to design feature related codes in your application for reliability.\n + * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n + * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.\n + * More details on featuring your application can be found from Feature Element. + * + */ + +#endif /* __TIZEN_NETWORK_VPN_DOC_H__ */ diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt new file mode 100755 index 0000000..2622891 --- /dev/null +++ b/framework/CMakeLists.txt @@ -0,0 +1,65 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(PACKAGE_NAME capi-vpnsvc) +SET(LIB_NAME ${PACKAGE_NAME}) +PROJECT(${LIB_NAME}) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") +SET(VERSION 0.1) + +SET(requires "dlog dbus-1 glib-2.0 gio-2.0 gio-unix-2.0 capi-base-common capi-appfw-application capi-appfw-app-manager capi-system-info") +SET(pc_requires "capi-base-common") + +SET(SRCS + src/capi_vpn_service.c +) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/framework/include) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${PACKAGE_NAME} REQUIRED ${requires}) +FOREACH(flag ${${PACKAGE_NAME}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +# Compiler flags +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIC -Wall -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") +ADD_DEFINITIONS("-DFACTORYFS=\"$ENV{FACTORYFS}\"") +ADD_DEFINITIONS("-DDATAFS=\"$ENV{DATADIR}\"") +ADD_DEFINITIONS("-DSLP_DEBUG") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") + +ADD_LIBRARY(${PACKAGE_NAME} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${PACKAGE_NAME} ${${PACKAGE_NAME}_LDFLAGS} -lrt -ldl) + +INSTALL(TARGETS ${PACKAGE_NAME} DESTINATION lib) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/vpn_service.h DESTINATION include) +INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/tizen_vpn_error.h DESTINATION include) + +SET_TARGET_PROPERTIES(${PACKAGE_NAME} + PROPERTIES + VERSION ${FULLVER} + SOVERSION ${MAJORVER} + CLEAN_DIRECT_OUTPUT 1 +) + + +SET(PC_NAME ${PACKAGE_NAME}) +SET(PC_REQUIRED ${pc_requires}) +SET(PC_CFLAGS -I\${includedir}) +SET(PC_LDFLAGS -l${PACKAGE_NAME}) + +CONFIGURE_FILE( + ${PACKAGE_NAME}.pc.in + ${CMAKE_CURRENT_SOURCE_DIR}/${PACKAGE_NAME}.pc + @ONLY +) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${PACKAGE_NAME}.pc DESTINATION lib/pkgconfig) diff --git a/framework/capi-vpnsvc.manifest b/framework/capi-vpnsvc.manifest new file mode 100755 index 0000000..97e8c31 --- /dev/null +++ b/framework/capi-vpnsvc.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/framework/capi-vpnsvc.pc.in b/framework/capi-vpnsvc.pc.in new file mode 100755 index 0000000..fbe305b --- /dev/null +++ b/framework/capi-vpnsvc.pc.in @@ -0,0 +1,14 @@ + +# Package Information for pkg-config + +prefix=@PREFIX@ +exec_prefix=/usr +libdir=/usr/lib +includedir=/usr/include + +Name: @PC_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: @PC_REQUIRED@ +Libs: -L${libdir} @PC_LDFLAGS@ +Cflags: -I${includedir} diff --git a/framework/include/capi_vpn_service_private.h b/framework/include/capi_vpn_service_private.h new file mode 100755 index 0000000..0f56377 --- /dev/null +++ b/framework/include/capi_vpn_service_private.h @@ -0,0 +1,83 @@ +/* + * VPN Service Module + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef __VPN_SERVICE_H__ +#define __VPN_SERVICE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vpn_service.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define DBUS_DAEMON_SERVICE_NAME "org.freedesktop.DBus" +#define DBUS_DAEMON_OBJECT_NAME "/org/freedesktop/DBus" +#define DBUS_DAEMON_INTERFACE_NAME "org.freedesktop.DBus" +#define DBUS_DAEMON_START_SERVICE_METHOD_NAME "StartServiceByName" + +#define VPNSVC_DBUS_SERVICE_NAME "org.tizen.vpnsvc" +#define VPNSVC_DBUS_INTERFACE_NAME "org.tizen.vpnsvc" +#define VPNSVC_DBUS_INTERFACE_OBJ_NAME "/org/tizen/vpnsvc" + +#define _MAX_FILE_PATH_LEN 512 +#define _USER_SETTING_DEFAULT_MTU 1500 +#define _USER_SETTING_DEFAULT_SESSION "VPN_Session" + +#define VPN_SERVICE_FEATURE "http://tizen.org/feature/network.vpn" + +#define CHECK_FEATURE_SUPPORTED(feature_name) \ + do { \ + int feature_rv = _vpnsvc_check_feature_supported(feature_name); \ + if (feature_rv != VPNSVC_ERROR_NONE) \ + return feature_rv; \ + } while(0) + +/** + * @brief This data structure has a fido data and its length. + */ +typedef struct _vpnsvc_tun_s { + GDBusConnection *connection; /**< D-Bus Connection */ + int fd; /**< tun socket fd */ + int index; /**< tun index (if.if_index) */ + char name[VPNSVC_TUN_IF_NAME_LEN]; /**< tun name (if.if_name) */ + char session[VPNSVC_SESSION_STRING_LEN];/**< session name (user setting) */ + unsigned int mtu; /**< mtu (user setting) */ +} vpnsvc_tun_s; + +int _vpnsvc_check_feature_supported(const char *feature_name); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/framework/src/capi_vpn_service.c b/framework/src/capi_vpn_service.c new file mode 100755 index 0000000..9f59ade --- /dev/null +++ b/framework/src/capi_vpn_service.c @@ -0,0 +1,911 @@ +/* + * VPN Service Module + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + + +#include "capi_vpn_service_private.h" +#include +#include +#include +#include + +#define DBUS_REPLY_TIMEOUT (120 * 1000) + +GVariant *op = NULL; + +static __thread bool is_feature_checked = false; +static __thread bool feature_supported = false; + +int _vpnsvc_check_feature_supported(const char *feature_name) +{ + if (is_feature_checked) { + if (!feature_supported) { + LOGE("%s feature is disabled", feature_name); + return VPNSVC_ERROR_NOT_SUPPORTED; + } + } else { + if (!system_info_get_platform_bool(feature_name, &feature_supported)) { + is_feature_checked = true; + if (!feature_supported) { + LOGE("%s feature is disabled", feature_name); + return VPNSVC_ERROR_NOT_SUPPORTED; + } + } else { + LOGE("Error - Feature getting from System Info"); + return VPNSVC_ERROR_IO_ERROR; + } + } + + return VPNSVC_ERROR_NONE; +} + +static void _vpnsvc_init_vpnsvc_tun_s(vpnsvc_tun_s **s) +{ + LOGD(" tun_s: %p", s); + + if (s == NULL) return; + if (*s != NULL) { + LOGE("Can't Initialize vpnsvc_tun_s: %p", *s); + return; + } + *s = (vpnsvc_tun_s*)g_malloc0(sizeof(vpnsvc_tun_s)); + + if ((*s)->connection == NULL) { + GDBusConnection *connection = NULL; + GError* error = NULL; + +#if !GLIB_CHECK_VERSION(2, 36, 0) + g_type_init(); +#endif + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (error != NULL) { + LOGE("Error creating Connection: %s", error->message); + g_error_free(error); + } else { + LOGD("Created Connection: %p", connection); + (*s)->connection = connection; + } + } + + /* Setting Default User Settings */ + (*s)->mtu = _USER_SETTING_DEFAULT_MTU; + strncpy((*s)->session, _USER_SETTING_DEFAULT_SESSION, VPNSVC_SESSION_STRING_LEN); + (*s)->session[VPNSVC_SESSION_STRING_LEN-1] = '\0'; +} + +static void _vpnsvc_deinit_vpnsvc_tun_s(vpnsvc_tun_s *s) +{ + if (s == NULL) return; + + if (s->connection) + s->connection = NULL; + + s->fd = 0; + s->index = 0; + memset(s->name, 0, VPNSVC_TUN_IF_NAME_LEN); + memset(s->session, 0, VPNSVC_SESSION_STRING_LEN); + + if (s) + g_free(s); +} + +/***************************************************************************** +* Global Functions Definition +*****************************************************************************/ +GVariant *_vpnsvc_invoke_dbus_method(GDBusConnection *connection, + const char *dest, const char *path, + const char *interface_name, const char *method, + GVariant *params, int *dbus_error) +{ + GError *error = NULL; + GVariant *reply = NULL; + *dbus_error = VPNSVC_ERROR_NONE; + + LOGD("Method Call() dest=%s path=%s iface=%s method=%s", dest, path, interface_name, method); + + if (connection == NULL) { + LOGD("GDBusconnection is NULL"); + *dbus_error = VPNSVC_ERROR_IO_ERROR; + return reply; + } + + reply = g_dbus_connection_call_sync(connection, + dest, + path, + interface_name, + method, + params, + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, + NULL, + &error); + + if (reply == NULL) { + if (error != NULL) { + LOGE("g_dbus_connection_call_sync() failed" + "error [%d: %s]", error->code, error->message); + *dbus_error = VPNSVC_ERROR_IO_ERROR; + g_error_free(error); + } else { + LOGE("g_dbus_connection_call_sync() failed"); + *dbus_error = VPNSVC_ERROR_IPC_FAILED; + } + + return NULL; + } + + return reply; +} +GVariant *_vpnsvc_invoke_dbus_method_with_fd(GDBusConnection *connection, + const char *dest, const char *path, + const char *interface_name, const char *method, + GVariant *params, int fd, int *dbus_error) +{ + GError *error = NULL; + GVariant *reply = NULL; + GUnixFDList *fd_list = NULL; + *dbus_error = VPNSVC_ERROR_NONE; + + LOGD("Method Call() dest=%s path=%s iface=%s method=%s fd=%d", dest, path, interface_name, method, fd); + + if (connection == NULL) { + LOGD("GDBusconnection is NULL"); + *dbus_error = VPNSVC_ERROR_IO_ERROR; + return reply; + } + + /* Setting the fd_list */ + fd_list = g_unix_fd_list_new(); + if (fd_list == NULL) { + LOGE("g_unix_fd_list_new() failed!"); + return NULL; + } + g_unix_fd_list_append(fd_list, fd, &error); + if (error != NULL) { + LOGE("g_unix_fd_list_append() failed" + "error [%d: %s]", error->code, error->message); + *dbus_error = VPNSVC_ERROR_IO_ERROR; + g_error_free(error); + return NULL; + } + + reply = g_dbus_connection_call_with_unix_fd_list_sync(connection, + dest, + path, + interface_name, + method, + params, + NULL, + G_DBUS_CALL_FLAGS_NONE, + DBUS_REPLY_TIMEOUT, + fd_list, + NULL, + NULL, + &error); + + if (reply == NULL) { + if (error != NULL) { + LOGE("g_dbus_connection_call_sync() failed" + "error [%d: %s]", error->code, error->message); + *dbus_error = VPNSVC_ERROR_IO_ERROR; + g_error_free(error); + } else { + LOGE("g_dbus_connection_call_sync() failed"); + *dbus_error = VPNSVC_ERROR_IPC_FAILED; + } + + return NULL; + } + + return reply; +} + +int vpnsvc_init(const char* tun_name, vpnsvc_tun_h *handle) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + int result = VPNSVC_ERROR_NONE; + int dbus_result; + int tun_fd = 0; + + LOGD("enter vpnsvc_init, tun_name : %s", tun_name); + LOGD("handle : %p\n", handle); + + /* parameter check */ + if (tun_name == NULL || strlen(tun_name) <= 0) { + LOGE("tun_name is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } else if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } else if (*handle != NULL) { + LOGE("handle already created"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + vpnsvc_tun_s *tmp_s = NULL; + _vpnsvc_init_vpnsvc_tun_s(&tmp_s); + + op = _vpnsvc_invoke_dbus_method(tmp_s->connection, + DBUS_DAEMON_SERVICE_NAME, + DBUS_DAEMON_OBJECT_NAME, + DBUS_DAEMON_INTERFACE_NAME, + DBUS_DAEMON_START_SERVICE_METHOD_NAME, + g_variant_new("(su)", VPNSVC_DBUS_SERVICE_NAME, 0), + &dbus_result); + + if (op == NULL) { + _vpnsvc_deinit_vpnsvc_tun_s(tmp_s); + LOGD("Service [%s] Start Failed!", VPNSVC_DBUS_SERVICE_NAME); + return VPNSVC_ERROR_IPC_FAILED; + } else { + unsigned int status = 0; + g_variant_get(op, "(u)", &status); + if (1 == status) { /* DBUS_START_REPLY_SUCCESS */ + LOGD("Service [%s] Started Successfully!", VPNSVC_DBUS_SERVICE_NAME); + } else if (2 == status) { /* DBUS_START_REPLY_ALREADY_RUNNING */ + LOGD("Service [%s] Already Running!", VPNSVC_DBUS_SERVICE_NAME); + } else { + LOGD("Service [%s] Not Started! Status[%d]", VPNSVC_DBUS_SERVICE_NAME, status); + g_variant_unref(op); + op = NULL; + _vpnsvc_deinit_vpnsvc_tun_s(tmp_s); + return VPNSVC_ERROR_IO_ERROR; + } + g_variant_unref(op); + op = NULL; + } + + if ((tun_fd = open("/dev/net/tun", O_RDWR)) < 0) { + LOGE("tun device open fail\n"); + _vpnsvc_deinit_vpnsvc_tun_s(tmp_s); + return VPNSVC_ERROR_IO_ERROR; + } + + LOGD("client tun_fd : %d", tun_fd); + + op = _vpnsvc_invoke_dbus_method_with_fd(tmp_s->connection, + VPNSVC_DBUS_SERVICE_NAME, + VPNSVC_DBUS_INTERFACE_OBJ_NAME, + VPNSVC_DBUS_INTERFACE_NAME, + "vpn_init", + g_variant_new("(su)", tun_name, strlen(tun_name)), + tun_fd, + &dbus_result); + + if (op == NULL) { + close(tun_fd); + _vpnsvc_deinit_vpnsvc_tun_s(tmp_s); + return VPNSVC_ERROR_IPC_FAILED; + } else { + int tmp_index; + char* tmp_name; + + g_variant_get(op, "(iis)", &result, &tmp_index, &tmp_name); + if (result != VPNSVC_ERROR_NONE) { + LOGE("vpnsvc_init() failed"); + _vpnsvc_deinit_vpnsvc_tun_s(tmp_s); + result = VPNSVC_ERROR_IPC_FAILED; + } else { + LOGD("vpnsvc_init() succeed"); + tmp_s->fd = tun_fd; /* client fd must be set */ + tmp_s->index = tmp_index; + strncpy(tmp_s->name, tmp_name, VPNSVC_TUN_IF_NAME_LEN); + tmp_s->name[VPNSVC_TUN_IF_NAME_LEN-1] = '\0'; + *handle = tmp_s; + LOGD("handle : %p, handle->fd : %d, handle->index : %d, handle->name : %s", + (*handle), ((vpnsvc_tun_s*)*handle)->fd, ((vpnsvc_tun_s*)*handle)->index, ((vpnsvc_tun_s*)*handle)->name); + } + if (op) { + g_variant_unref(op); + op = NULL; + } + } + + return result; +} + +int vpnsvc_deinit(vpnsvc_tun_h handle) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + int result = VPNSVC_ERROR_NONE; + int dbus_result; + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + LOGD("enter vpnsvc_deinit, tun_fd : %d", tun_s->fd); + + if (tun_s->fd > 0) { + op = _vpnsvc_invoke_dbus_method(tun_s->connection, + VPNSVC_DBUS_SERVICE_NAME, + VPNSVC_DBUS_INTERFACE_OBJ_NAME, + VPNSVC_DBUS_INTERFACE_NAME, + "vpn_deinit", + g_variant_new("(s)", tun_s->name), + &dbus_result); + + if (op == NULL) { + return VPNSVC_ERROR_IPC_FAILED; + } else { + g_variant_get(op, "(i)", &result); + if (result != VPNSVC_ERROR_NONE) + LOGE("vpn_deinit() failed"); + else + LOGD("vpn_deinit() succeed"); + } + + if (close(tun_s->fd) != 0) { + LOGE("tun fd close : %s", strerror(errno)); + return VPNSVC_ERROR_IO_ERROR; + } else + LOGD("tun fd close success"); + + /* free allocared handle memory */ + _vpnsvc_deinit_vpnsvc_tun_s(tun_s); + } + + return result; +} + +int vpnsvc_protect(vpnsvc_tun_h handle, int socket_fd, const char* dev_name) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + int result = VPNSVC_ERROR_NONE; + int dbus_result; + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + LOGD("enter vpnsvc_protect, socket : %d, dev_name : %s", socket_fd, dev_name); + + if (tun_s->connection == NULL) { + LOGE("Connection Object is NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + /* call vpnsvc_protect */ + op = _vpnsvc_invoke_dbus_method_with_fd(tun_s->connection, + VPNSVC_DBUS_SERVICE_NAME, + VPNSVC_DBUS_INTERFACE_OBJ_NAME, + VPNSVC_DBUS_INTERFACE_NAME, + "vpn_protect", + g_variant_new("(s)", dev_name), + socket_fd, + &dbus_result); + + if (op == NULL) { + return VPNSVC_ERROR_IPC_FAILED; + } else { + g_variant_get(op, "(i)", &result); + + if (result != VPNSVC_ERROR_NONE) + LOGE("vpn_protect() failed"); + else + LOGD("vpn_protect() succeed"); + } + + return result; +} + +int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ip, + const struct vpnsvc_route* routes, size_t nr_routes, + const char** dns_servers, size_t nr_dns_servers, + const char* dns_suffix) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + int result = VPNSVC_ERROR_NONE; + int dbus_result; + GVariantBuilder route_builder, dns_builder; + size_t i = 0; + GVariant *route_param = NULL; + GVariant *dns_param = NULL; + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + LOGD("enter vpnsvc_up"); + + if (tun_s->index <= 0) { + LOGE("invalid handle"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } else if (tun_s->connection == NULL) { + LOGE("Connection Object is NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + if (local_ip == NULL || remote_ip == NULL) { + LOGE("local and remote ip are invalid"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + LOGD("tun_index %d", tun_s->index); + LOGD("local_ip : %s, remote_ip : %s", local_ip, remote_ip); + + /* make a route parameter */ + g_variant_builder_init(&route_builder, G_VARIANT_TYPE("a{si}")); + for (i = 0 ; i < nr_routes ; i++) { + if (strlen(routes[i].dest) <= 0) { + LOGE("invalid routes[%d].dest", i); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + g_variant_builder_add(&route_builder, "{si}", routes[i].dest, routes[i].prefix); + LOGD("routes[%d].dest : %s", i, routes[i].dest); + LOGD("routes[%d].prefix : %d", i, routes[i].prefix); + } + route_param = g_variant_builder_end(&route_builder); + + /* make a dns parameter */ + g_variant_builder_init(&dns_builder, G_VARIANT_TYPE("as")); + for (i = 0 ; i < nr_dns_servers ; i++) { + if (strlen(dns_servers[i]) <= 0) { + LOGE("invalid dns_servers[%d]", i); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + LOGD("dns_servers[%d] : %s", i, dns_servers[i]); + g_variant_builder_add(&dns_builder, "s", dns_servers[i]); + } + dns_param = g_variant_builder_end(&dns_builder); + + LOGD("dns_suffix : %s", dns_suffix); + + op = _vpnsvc_invoke_dbus_method(tun_s->connection, + VPNSVC_DBUS_SERVICE_NAME, + VPNSVC_DBUS_INTERFACE_OBJ_NAME, + VPNSVC_DBUS_INTERFACE_NAME, + "vpn_up", + g_variant_new("(issvuvusu)", tun_s->index, local_ip, \ + remote_ip, route_param, nr_routes, dns_param, nr_dns_servers, \ + dns_suffix, tun_s->mtu), + &dbus_result); + + if (op == NULL) { + return VPNSVC_ERROR_IPC_FAILED; + } else { + g_variant_get(op, "(i)", &result); + if (result != VPNSVC_ERROR_NONE) + LOGE("vpn_up() failed"); + else + LOGD("vpn_up() succeed"); + } + + return result; +} + +int vpnsvc_down(vpnsvc_tun_h handle) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + int result = VPNSVC_ERROR_NONE; + int dbus_result; + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + LOGD("enter vpnsvc_down"); + + if (tun_s == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } else if (tun_s->index <= 0) { + LOGE("invalid handle"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } else if (tun_s->connection == NULL) { + LOGE("Connection Object is NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + op = _vpnsvc_invoke_dbus_method(tun_s->connection, + VPNSVC_DBUS_SERVICE_NAME, + VPNSVC_DBUS_INTERFACE_OBJ_NAME, + VPNSVC_DBUS_INTERFACE_NAME, + "vpn_down", + g_variant_new("(i)", tun_s->index), + &dbus_result); + + if (op == NULL) { + return VPNSVC_ERROR_IPC_FAILED; + } else { + g_variant_get(op, "(i)", &result); + if (result != VPNSVC_ERROR_NONE) + LOGE("vpn_down() failed"); + else + LOGD("vpn_down() succeed"); + } + + return result; + +} + +/* this API must not be use IPC */ +int vpnsvc_read(vpnsvc_tun_h handle, int timeout_ms) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + fd_set read_set; + struct timeval tv; + int ret, retVal; + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + if (tun_s->fd <= 0) { + LOGE("invalid handle"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + /* listen for events */ + FD_ZERO(&read_set); + FD_SET(tun_s->fd, &read_set); + tv.tv_usec = timeout_ms*1000; + retVal = select(tun_s->fd +1, &read_set, NULL, NULL, &tv); + + if (retVal) { + LOGD("Data is available now.\n"); + ret = VPNSVC_ERROR_NONE; + } else if (retVal == 0) { + LOGD("No data within %d ms\n", timeout_ms); + ret = VPNSVC_ERROR_TIMEOUT; + } else { + LOGE("select failed\n"); + ret = VPNSVC_ERROR_IO_ERROR; + } + + return ret; +} + +/* this API must not be use IPC */ +int vpnsvc_write(vpnsvc_tun_h handle, const char* data, size_t size) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + if (tun_s->fd <= 0) { + LOGE("invalid handle"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + return write(tun_s->fd, data, size); +} + +API int vpnsvc_block_networks(vpnsvc_tun_h handle, + const struct vpnsvc_route* allow_routes_vpn, + size_t nr_allow_routes_vpn, + const struct vpnsvc_route* allow_routes_orig, + size_t nr_allow_routes_orig) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + int result = VPNSVC_ERROR_NONE; + int dbus_result; + GVariantBuilder nets_builder; + size_t i = 0; + GVariant *nets_param_vpn; + GVariant *nets_param_orig; + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + LOGD("enter vpnsvc_block_networks"); + + if (tun_s->connection == NULL) { + LOGE("Connection Object is NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + /* make a route parameter for allowed VPN interface routes */ + g_variant_builder_init(&nets_builder, G_VARIANT_TYPE("a{si}")); + for (i = 0 ; i < nr_allow_routes_vpn ; i++) { + g_variant_builder_add(&nets_builder, "{si}", allow_routes_vpn[i].dest, allow_routes_vpn[i].prefix); + LOGD("routes[%d].dest : %s", i, allow_routes_vpn[i].dest); + LOGD("routes[%d].prefix : %d", i, allow_routes_vpn[i].prefix); + } + nets_param_vpn = g_variant_builder_end(&nets_builder); + + /* make a route parameter for allowed Original interface Routes */ + g_variant_builder_init(&nets_builder, G_VARIANT_TYPE("a{si}")); + for (i = 0 ; i < nr_allow_routes_orig ; i++) { + g_variant_builder_add(&nets_builder, "{si}", allow_routes_orig[i].dest, allow_routes_orig[i].prefix); + LOGD("routes[%d].dest : %s", i, allow_routes_orig[i].dest); + LOGD("routes[%d].prefix : %d", i, allow_routes_orig[i].prefix); + } + nets_param_orig = g_variant_builder_end(&nets_builder); + + op = _vpnsvc_invoke_dbus_method(tun_s->connection, + VPNSVC_DBUS_SERVICE_NAME, + VPNSVC_DBUS_INTERFACE_OBJ_NAME, + VPNSVC_DBUS_INTERFACE_NAME, + "vpn_block_networks", + g_variant_new("(vuvu)", nets_param_vpn, nr_allow_routes_vpn, + nets_param_orig, nr_allow_routes_orig), + &dbus_result); + + if (op == NULL) { + return VPNSVC_ERROR_IPC_FAILED; + } else { + g_variant_get(op, "(i)", &result); + if (result != VPNSVC_ERROR_NONE) + LOGE("vpn_block_networks() failed"); + else + LOGD("vpn_block_networks() succeed"); + } + + return result; +} + +int vpnsvc_unblock_networks(vpnsvc_tun_h handle) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + int result = VPNSVC_ERROR_NONE; + int dbus_result; + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + LOGD("enter vpnsvc_unblock_networks"); + + if (tun_s == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } else if (tun_s->connection == NULL) { + LOGE("Connection Object is NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + op = _vpnsvc_invoke_dbus_method(tun_s->connection, + VPNSVC_DBUS_SERVICE_NAME, + VPNSVC_DBUS_INTERFACE_OBJ_NAME, + VPNSVC_DBUS_INTERFACE_NAME, + "vpn_unblock_networks", + g_variant_new("()"), + &dbus_result); + + if (op == NULL) { + return VPNSVC_ERROR_IPC_FAILED; + } else { + g_variant_get(op, "(i)", &result); + if (result != VPNSVC_ERROR_NONE) + LOGE("vpn_unblock_networks() failed"); + else + LOGD("vpn_unblock_networks() succeed"); + } + + return result; +} + +int vpnsvc_get_tun_fd(vpnsvc_tun_h handle) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + if (tun_s->fd <= 0) { + LOGE("invalid handle"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + return tun_s->fd; +} + +int vpnsvc_get_tun_index(vpnsvc_tun_h handle) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + if (tun_s->index <= 0) { + LOGE("invalid handle"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + return tun_s->index; +} + +int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char* tun_name) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + if (strlen(tun_s->name) <= 0) { + LOGE("invalid handle"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + strncpy(tun_name, tun_s->name, VPNSVC_TUN_IF_NAME_LEN); + tun_name[VPNSVC_TUN_IF_NAME_LEN-1] = '\0'; + + return VPNSVC_ERROR_NONE; +} + +int vpnsvc_set_mtu(vpnsvc_tun_h handle, int mtu) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + if (mtu <= 0) { + LOGE("Incorrect MTU Size = %d", mtu); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + tun_s->mtu = mtu; + return VPNSVC_ERROR_NONE; +} + +int vpnsvc_set_blocking(vpnsvc_tun_h handle, bool blocking) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + int flags; + + if (tun_s->fd <= 0) { + LOGE("The Tunnel File Descriptor fd = %d", tun_s->fd); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + flags = fcntl(tun_s->fd, F_GETFL); + if (flags < 0) { + LOGD("File Descriptor Flags GET Failed fd = %d", tun_s->fd); + flags = 0; + } + + if (blocking == false) + flags = flags | O_NONBLOCK; + else + flags = flags & (~O_NONBLOCK); + + if (fcntl(tun_s->fd, F_SETFL, flags) < 0) { + LOGE("Failed fd = %d F_SETFL(flags) = %d", tun_s->fd, flags); + return VPNSVC_ERROR_IO_ERROR; + } + return VPNSVC_ERROR_NONE; +} + +int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + if (session == NULL) { + LOGE("Session Name string is NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + strncpy(tun_s->session, session, VPNSVC_SESSION_STRING_LEN); + tun_s->session[VPNSVC_SESSION_STRING_LEN-1] = '\0'; + + return VPNSVC_ERROR_NONE; +} + +int vpnsvc_get_session(vpnsvc_tun_h handle, char* session) +{ + CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); + + vpnsvc_tun_s *tun_s = NULL; + + /* parameter check */ + if (handle == NULL) { + LOGE("handle is a NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + tun_s = (vpnsvc_tun_s*)handle; + + if (session == NULL) { + LOGE("Session Name string is NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + strncpy(session, tun_s->session, VPNSVC_SESSION_STRING_LEN); + session[VPNSVC_SESSION_STRING_LEN-1] = '\0'; + + return VPNSVC_ERROR_NONE; +} diff --git a/include/tizen_vpn_error.h b/include/tizen_vpn_error.h new file mode 100755 index 0000000..bbd32e4 --- /dev/null +++ b/include/tizen_vpn_error.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef __TIZEN_COMMON_VPN_ERROR_H__ +#define __TIZEN_COMMON_VPN_ERROR_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup CAPI_COMMON_VPN_ERROR Common VPN Error + * @brief This file provides error codes that are common for the whole TIZEN VPN API. + * @section CAPI_COMMON_VPN_ERROR_HEADER Required Header + * \#include + * @ingroup CAPI_COMMON_ERROR + * @{ + */ + +#define TIZEN_ERROR_MIN_VPN_ERROR (-268435456) /* = -268435455(0x0FFFFFFF) -1 */ + +/* Check if slp error or not */ +#define TIZEN_ERROR_IS_VPN_ERROR(x) (TIZEN_ERROR_MIN_VPN_ERROR >= (x) && (x) < 0) + +/* Tizen VPN Service Error */ +#define TIZEN_ERROR_VPNSVC -0x10000000 + +/** + * @} + */ +#ifdef __cplusplus +} +#endif + +#endif /**<__TIZEN_COMMON_VPN_ERROR_H__ */ diff --git a/include/vpn_service.h b/include/vpn_service.h new file mode 100755 index 0000000..3d6f6c5 --- /dev/null +++ b/include/vpn_service.h @@ -0,0 +1,442 @@ +/* +* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __TIZEN_VPN_SERVICE_H__ +#define __TIZEN_VPN_SERVICE_H__ + +/** + * @file vpn_service.h + */ + +/** + *@defgroup VPNSVC_FRAMEWORK VPN_SERVICE + *@brief The VPN service APIs to manage VPN features such as VPN device (TUN interface) initialization, routing management, DNS management and firewall management. + *@section VPNSVC_FRAMEWORK_OVERVIEW Overview + * + * + * + * + *
APIDescription>
@ref VPNSVC_FRAMEWORK Provides functions to vpnsvc_init/vpnsvc_deinit/vpnsvc_protect/vpnsvc_up/vpnsvc_down/vpnsvc_read/vpnsvc_write/vpnsvc_block_networks/vpnsvc_unblock_networks.
+ **/ + +#include +#include +#include +#include +#include +#include + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "CAPI_VPNSVC" + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +/** + * @brief IPv4 address string length (includes end null character) + */ +#define VPNSVC_IP4_STRING_LEN 16 + +/** + * @brief TUN interface name length (IFNAMSIZ) + */ +#define VPNSVC_TUN_IF_NAME_LEN 16 + +/** + * @brief Session name string length (includes end null character) + */ +#define VPNSVC_SESSION_STRING_LEN 32 + + +/** + * @brief Enumeration for VPN service error types + * @details Indicate formats of error type field + * @ingroup VPNSVC_FRAMEWORK + */ +typedef enum +{ + VPNSVC_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */ + VPNSVC_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + VPNSVC_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + VPNSVC_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + VPNSVC_ERROR_NO_SUCH_FILE = TIZEN_ERROR_NO_SUCH_FILE, /**< No such file or directory */ + VPNSVC_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< IO error */ + VPNSVC_ERROR_TIMEOUT = TIZEN_ERROR_TIMED_OUT, /**< Time out error or no answer */ + VPNSVC_ERROR_IPC_FAILED = TIZEN_ERROR_VPNSVC | 0x02, /**< Failed to communicate with server */ + VPNSVC_ERROR_LICENSE_FAILED = TIZEN_ERROR_VPNSVC | 0x03, /**< Failed to verify license */ + VPNSVC_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED /**< Not Supported */ +} vpnsvc_error_e; + + +/** + * @brief The structure containing the route information + * @details This structure can be used for both vpnsvc_up() and vpnsvc_block_networks() functions. + * + * @since_tizen 3.0 + * @see vpnsvc_up() + * @see vpnsvc_block_networks() + */ +struct vpnsvc_route { + char dest[VPNSVC_IP4_STRING_LEN]; /**< Destination address of the route */ + int prefix; /**< The prefix of route */ +}; + +/** + * @brief The VPN tun interface handle + * @details This handle can be obtained by calling vpnsvc_init() and destroyed(NULL) by calling vpnsvc_deinit(). + * @since_tizen 3.0 + * @see vpnsvc_init() + * @see vpnsvc_deinit() + */ +typedef void* vpnsvc_tun_h; + + +/** + * @brief Initializes TUN interface (/dev/net/tun) + * @detail You should call vpnsvc_get_tun_name() for checking the actual initialized TUN interface name. (In case of duplicated interface name) + * + * @since_tizen 3.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/vpnservicea + * @remarks The license needed if you want to use this VPN API + * + * @param[in] tun_name The interface name + * @param[out] handle The VPN tun interface handle + * + * @return 0 on success. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_IO_ERROR I/O Error (e.g. socket I/O error) + * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon + * @retval #VPNSVC_ERROR_PERMISSION_DENIED Permission Denied + * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * @post Please call vpnsvc_deinit() if you want to de-initialize VPN tun interface. + * @post Please call vpnsvc_get_tun_fd() if you want to know the fd of tun interface. + * @post Please call vpnsvc_get_tun_index() if you want to know the fd of tun interface index(ifr.ifr_ifindex). + * @post Please call vpnsvc_get_tun_name() if you want to know the name of tun interface(ifr.ifr_name). + * @see vpnsvc_deinit() + * @see vpnsvc_get_tun_fd() + * @see vpnsvc_get_tun_index() + * @see vpnsvc_get_tun_name() + */ +API int vpnsvc_init(const char* tun_name, vpnsvc_tun_h *handle); + +/** + * @brief De-Initializes TUN interface + * + * @since_tizen 3.0 + * @remarks The license needed if you want to use this VPN API + * + * @param[in] handle The VPN tun interface handle + * + * @return 0 on success. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon + * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @pre Before calling this function, VPN tun interface should be initialized already. + * @see vpnsvc_init() + */ +API int vpnsvc_deinit(vpnsvc_tun_h handle); + +/** + * @brief Prevents the underlying VPN traffic to be routed to the VPN itself + * @details The specific socket will be bound to the network interface using by this function. + * + * @since_tizen 3.0 + * @remarks The license needed if you want to use this VPN API + * + * @param[in] handle The VPN tun interface handle + * @param[in] socket_fd The opened socket file descriptor + * @param[in] dev_name The network interface name (i.e. eth0 or ppp0, not to confuse with tunXXX) through which the VPN is working + * + * @return 0 on success. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_IO_ERROR I/O Error (e.g. socket I/O error) + * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon + * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + */ +API int vpnsvc_protect(vpnsvc_tun_h handle, int socket_fd, const char* dev_name); + +/** + * @brief Sets-up TUN interface and brings it up. Installs specified routes/DNS servers/DNS suffix + * + * @since_tizen 3.0 + * @remarks The license needed if you want to use this VPN API + * + * @param[in] handle The VPN tun interface handle + * @param[in] local_ip The local IP address + * @param[in] remote_ip The remote IP address + * @param[in] routes The list of routes for applying to routing table (see vpnsvc_route struct) - Optional + * @param[in] nr_routes The number of routes - Optional + * @param[in] dns_servers The list of DNS server names - Optional + * @param[in] nr_dns_servers The number of DNS server names - Optional + * @param[in] dns_suffix The DNS suffix - Optional + * + * @return 0 on success. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon + * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @pre The VPN tun interface should be initialized already. + * @post If you want to set interface down, please call vpnsvc_down(). + * @see #vpnsvc_route + * @see vpnsvc_init() + * @see vpnsvc_down() + */ +API int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ip, + const struct vpnsvc_route* routes, size_t nr_routes, + const char** dns_servers, size_t nr_dns_servers, + const char* dns_suffix); + +/** + * @brief Brings the TUN interface down and restores original DNS servers/domains + * + * @since_tizen 3.0 + * @remarks The license needed if you want to use this VPN API. + * + * @param[in] handle The VPN tun interface handle + * + * @return 0 on success. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon + * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @pre The VPN tun interface should be initialized already. + * @post Please call vpnsvc_deinit() if you want to de-initialize VPN tun interface. + * @see vpnsvc_up() + * @see vpnsvc_deinit() + */ +API int vpnsvc_down(vpnsvc_tun_h handle); + +/** + * @brief Waits for the read event on TUN descriptor, but no more than the indicated timeout in milliseconds + * + * @since_tizen 3.0 + * + * @param[in] handle The VPN tun interface handle + * @param[in] timeout_ms The value of timeout (milliseconds) + * + * @return 0 on success. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_IO_ERROR I/O Error (e.g. socket I/O error) + * @retval #VPNSVC_ERROR_TIMEOUT Timeout (no answer in timeout_ms) + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @pre The VPN interface should be initialized already. + * @see vpnsvc_init() + * @see vpnsvc_up() + */ +API int vpnsvc_read(vpnsvc_tun_h handle, int timeout_ms); + +/** + * @brief Writes the data supplied into the TUN interface + * + * @since_tizen 3.0 + * + * @param[in] handle The VPN tun interface handle + * @param[in] data Data writing to tun interface + * @param[in] size The size of data + * + * @return On success, the number of bytes written is returned (zero indicates nothing was written). Otherwise, a negative error value. + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * @retval In case of negative error, please refer to standard posix write API's error code. + * + * @pre The VPN interface should be initialized already. + * @see vpnsvc_init() + * @see vpnsvc_up() + */ +API int vpnsvc_write(vpnsvc_tun_h handle, const char* data, size_t size); + +/** + * @brief Blocks all traffics except specified allowing networks + * + * @since_tizen 3.0 + * @remarks The license needed if you want to use this VPN API + * + * @param[in] handle The VPN tun interface handle + * @param[in] allow_routes_vpn The list of allowing networks over VPN interface (Please see vpnsvc_route structure). + * @param[in] nr_allow_routes_vpn The number of allowing networks over VPN interface + * @param[in] allow_routes_orig The list of allowing networks over the original interface (Please see vpnsvc_route structure). + * @param[in] nr_allow_routes_orig The number of allowing networks over the original interface + * + * @return 0 on success. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon + * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @post Please call vpnsvc_unblock_networks() if you want to allow all traffics. + * @see vpnsvc_unblock_networks() + */ +API int vpnsvc_block_networks(vpnsvc_tun_h handle, + const struct vpnsvc_route* allow_routes_vpn, + size_t nr_allow_routes_vpn, + const struct vpnsvc_route* allow_routes_orig, + size_t nr_allow_routes_orig); + +/** + * @brief Removes any restrictions imposed by vpnsvc_block_networks() + * + * @since_tizen 3.0 + * @remarks The license needed if you want to use this VPN API + * + * @param[in] handle The VPN tun interface handle + * + * @return 0 on success. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon + * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + */ +API int vpnsvc_unblock_networks(vpnsvc_tun_h handle); + +/** + * @brief Gets the fd of the VPN tun interface + * + * @since_tizen 3.0 + * + * @param[in] handle The VPN tun interface handle + * + * @return The fd value of VPN tun interface. Otherwise, a negative error value. + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + */ +API int vpnsvc_get_tun_fd(vpnsvc_tun_h handle); + +/** + * @brief Gets the index of VPN tun interface (if.if_index) + * + * @since_tizen 3.0 + * + * @param[in] handle The VPN tun interface handle + * + * @return The index of the VPN tun interface. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @pre Before calling this function, VPN tun interface should be initialized already. + * @see vpnsvc_init() + */ +API int vpnsvc_get_tun_index(vpnsvc_tun_h handle); + +/** + * @brief Gets the name of VPN tun interface (if.if_name) + * + * @since_tizen 3.0 + * + * @param[in] handle The VPN tun interface handle + * @param[out] tun_name The name of VPN tun interface name + * + * @return 0 on success. Otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @pre Before calling this function, VPN tun interface should be initialized already. + * @see vpnsvc_init() + */ +API int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char* tun_name); + +/** + * @brief Sets the MTU of the VPN tun interface (if.if_name) + * + * @since_tizen 3.0 + * + * @param[in] handle The VPN tun interface handle + * @param[in] mtu The MTU (Maximum Transmission Unit) value to be set for VPN tun interface. Default MTU size is 1500. + * + * @return 0 on success. Otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @pre Before calling this function, VPN tun interface should be initialized already. + * @see vpnsvc_init() + */ +API int vpnsvc_set_mtu(vpnsvc_tun_h handle, int mtu); + +/** + * @brief Sets blocking mode of the file descriptor of VPN tun interface + * + * @since_tizen 3.0 + * + * @param[in] handle The VPN tun interface handle + * @param[in] blocking The blocking mode flag; True = BLOCKING, False = NON_BLOCKING + * + * @return 0 on success. Otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_IO_ERROR Failed to set the blocking flags + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @pre Before calling this function, VPN tun interface should be initialized already. + * @see vpnsvc_init() + */ +API int vpnsvc_set_blocking(vpnsvc_tun_h handle, bool blocking); + +/** + * @brief Sets the session name for the VPN + * + * @since_tizen 3.0 + * + * @param[in] handle The VPN tun interface handle + * @param[in] session The Session Name + * + * @return 0 on success. Otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @pre Before calling this function, VPN tun interface should be initialized already. + * @see vpnsvc_init() + */ +API int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session); + +/** + * @brief Gets the session name for the VPN + * + * @since_tizen 3.0 + * + * @param[in] handle The VPN tun interface handle + * @param[out] session The Session Name returned + * + * @return 0 on success. Otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * + * @pre Before calling this function, VPN tun interface should be initialized already. + * @see vpnsvc_init() + */ +API int vpnsvc_get_session(vpnsvc_tun_h handle, char* session); + +#endif /* __TIZEN_CAPI_VPN_SERVICE_H__ */ diff --git a/packaging/capi-vpn-service.spec b/packaging/capi-vpn-service.spec new file mode 100755 index 0000000..1075804 --- /dev/null +++ b/packaging/capi-vpn-service.spec @@ -0,0 +1,133 @@ +Name: vpnsvc-pkg +Summary: VPN service library in TIZEN C API +Version: 1.0.5 +Release: 1 +Group: System/Network +License: Apache License, Version 2.0 +URL: N/A +Source0: %{name}-%{version}.tar.gz +Source1: vpnsvc-daemon.service +Source2: org.tizen.vpnsvc.service +BuildRequires: cmake +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(capi-base-common) +BuildRequires: pkgconfig(capi-appfw-application) +BuildRequires: pkgconfig(capi-appfw-package-manager) +BuildRequires: pkgconfig(capi-appfw-app-manager) +BuildRequires: pkgconfig(capi-system-info) +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description +capi-vpn-service framework, service + +%package -n capi-vpnsvc +Summary: VPN service library in TIZEN C API +Group: Development/Libraries +#Requires: capi-vpnsvc + +%description -n capi-vpnsvc +capi-vpnsvc CAPI package + +%package -n capi-vpnsvc-devel +Summary: VPN service library in TIZEN C API (Development) +Group: Development/Libraries + +%description -n capi-vpnsvc-devel +capi-vpnsvc CAPI devel package + +%package -n vpnsvc-test +Summary: Vpnsvc test +Group: Development/Libraries + +%description -n vpnsvc-test +vpnsvc test package + +%package -n vpnsvc-daemon +Summary: Vpnsvc daemon +Group: Development/Libraries +Requires: systemd +Requires(preun): systemd +Requires(post): systemd +Requires(postun): systemd + +%description -n vpnsvc-daemon +vpnsvc daemon package + +%prep +%setup -q + +%build +%if 0%{?sec_build_binary_debug_enable} +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" +%endif + +%if 0%{?tizen_build_binary_release_type_eng} +export CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_ENGINEER_MODE" +export FFLAGS="$FFLAGS -DTIZEN_ENGINEER_MODE" +%endif + +export LDFLAGS+="-Wl,--rpath=%{_libdir}" + +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +%cmake . -DVERSION=%{version} \ + -DFULLVER=%{version} \ + -DMAJORVER=${MAJORVER} \ + -DCMAKE_BUILD_TYPE=%{?build_type:%build_type}%{!?build_type:RELEASE} \ + -DTIZEN_ENGINEER_MODE=%{?tizen_build_binary_release_type_eng:1}%{!?tizen_build_binary_release_type_eng:0} \ + -DCMAKE_VERBOSE_MAKEFILE=ON + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} + +mkdir -p %{buildroot}/%{_datadir}/license +cp LICENSE-Apache.v2.0 %{buildroot}/%{_datadir}/license/capi-vpnsvc +#cp LICENSE.APLv2 %{buildroot}/usr/share/license/fpasmtztransport + +%make_install +mkdir -p %{buildroot}%{_libdir}/systemd/system +install -m 0644 %{SOURCE1} %{buildroot}%{_libdir}/systemd/system/vpnsvc-daemon.service +mkdir -p %{buildroot}%{_datadir}/dbus-1/system-services +install -m 0644 %{SOURCE2} %{buildroot}%{_datadir}/dbus-1/system-services/org.tizen.vpnsvc.service + +%clean +rm -rf %{buildroot} + +%post -n capi-vpnsvc +ln -s %{_libdir}/libcapi-vpnsvc.so.0 %{_libdir}/libcapi-vpnsvc.so + +%postun +if [ $1 == 0 ]; then + # unistall + systemctl daemon-reload +fi + +%files -n vpnsvc-daemon +%manifest daemon/vpnsvc-daemon.manifest +%attr(0755,root,root) %{_bindir}/vpnsvc-daemon +%defattr(-,root,root,-) +%{_libdir}/systemd/system/vpnsvc-daemon.service +%{_datadir}/dbus-1/system-services/org.tizen.vpnsvc.service + +%files -n capi-vpnsvc +%manifest framework/capi-vpnsvc.manifest +%{_libdir}/libcapi-vpnsvc.so.* +%{_datadir}/license/capi-vpnsvc + +%files -n capi-vpnsvc-devel +%{_includedir}/*.h +%{_libdir}/pkgconfig/capi-vpnsvc.pc +%{_libdir}/libcapi-vpnsvc.so + +%files -n vpnsvc-test +%manifest test/vpnsvc-test.manifest +/usr/sbin/vpnsvc-test + diff --git a/packaging/org.tizen.vpnsvc.service b/packaging/org.tizen.vpnsvc.service new file mode 100755 index 0000000..079da3c --- /dev/null +++ b/packaging/org.tizen.vpnsvc.service @@ -0,0 +1,7 @@ +[D-BUS Service] +Name=org.tizen.vpnsvc +Exec=/bin/false +User=root +Group=root +SystemdService=vpnsvc-daemon.service + diff --git a/packaging/vpnsvc-daemon.service b/packaging/vpnsvc-daemon.service new file mode 100755 index 0000000..eab09e2 --- /dev/null +++ b/packaging/vpnsvc-daemon.service @@ -0,0 +1,13 @@ +[Unit] +Description=Start vpn-service-daemon for vpn-service + +[Service] +User=root +Group=root +SmackProcessLabel=vpnsvc +Type=dbus +BusName=org.tizen.vpnsvc +RemainAfterExit=yes +ExecStart=/usr/bin/vpnsvc-daemon +Restart=always +RestartSec=0 diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100755 index 0000000..87a4496 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,41 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET(PACKAGE_NAME vpnsvc-test) +SET(LIB_NAME ${PACKAGE_NAME}) +PROJECT(${LIB_NAME}) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "\${prefix}") +SET(LIBDIR "\${prefix}/lib") +SET(INCLUDEDIR "\${prefix}/include") +SET(VERSION 0.1) + +SET(TEST_ROOT "${CMAKE_SOURCE_DIR}/test") + +SET(requires "dlog dbus-glib-1 capi-base-common capi-appfw-application") +SET(pc_requires "capi-base-common") + +SET(TEST_SRCS + vpn_service_test.c) + + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/framework/include) + +INCLUDE(FindPkgConfig) +pkg_check_modules(${PACKAGE_NAME} REQUIRED ${requires}) +FOREACH(flag ${${PACKAGE_NAME}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +# Compiler flags +SET(EXTRA_C_FLAGS "${EXTRA_CFLAGS} -fPIC -Wall -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_C_FLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") + +ADD_DEFINITIONS("-DSLP_DEBUG") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib") + +ADD_EXECUTABLE(${PACKAGE_NAME} ${TEST_SRCS}) +TARGET_LINK_LIBRARIES(${PACKAGE_NAME} ${${PACKAGE_NAME}_LDFLAGS} "-ldl" capi-vpnsvc) + +INSTALL(TARGETS ${PACKAGE_NAME} DESTINATION sbin) diff --git a/test/vpn_service_test.c b/test/vpn_service_test.c new file mode 100755 index 0000000..bf768ac --- /dev/null +++ b/test/vpn_service_test.c @@ -0,0 +1,342 @@ +/* + * VPN Service Module + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include + +#include "capi_vpn_service_private.h" + +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "VPNSVC_TEST" + +#define TEST_VPN_IF_NAME "vpnsvc_test" + +#define TEST_CONSOLE_PRINT(FMT, ARG...) fprintf(stderr, FMT, ##ARG); \ + fprintf(stderr, "\n") +#define TEST_CONSOLE_INPUT(BUFFER, LENGTH) \ + do {\ + if (fgets(BUFFER, sizeof BUFFER, stdin) == NULL) \ + perror("fgets() failed!!!");\ + } while (0); + +vpnsvc_tun_h handle = NULL; + +int test_vpnsvc_init() +{ + char *name = TEST_VPN_IF_NAME; + int ret = VPNSVC_ERROR_NONE; + + printf("test vpnsvc_init\n"); + + ret = vpnsvc_init(name, &handle); + + if (ret != VPNSVC_ERROR_NONE) { + printf("vpnsvc_init failed : %d\n", ret); + } else { + char result_name[VPNSVC_TUN_IF_NAME_LEN] = {0, }; + printf("vpnsvc_init Succeed : %d\n", ret); + + printf("tun_fd : %d\n", vpnsvc_get_tun_fd(handle)); + printf("tun_index : %d\n", vpnsvc_get_tun_index(handle)); + ret = vpnsvc_get_tun_name(handle, result_name); + if (ret == VPNSVC_ERROR_NONE) + printf("tun_name : %s\n", result_name); + } + + return 0; +} + +int test_vpnsvc_deinit() +{ + printf("test vpnsvc_deinit\n"); + + if (handle) + vpnsvc_deinit(handle); + + handle = NULL; + + return 0; + +} + +int test_vpnsvc_protect() +{ + int sock, ret; + + printf("test vpnsvc_protect\n"); + + if (!handle) { + printf("invalid handle\n"); + return -1; + } + + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { + printf("socket failed\n"); + return -2; + } + + ret = vpnsvc_protect(handle, sock, "wlan0"); + if (ret != VPNSVC_ERROR_NONE) + printf("vpnsvc_protect failed!\n"); + else + printf("vpnsvc_protect Succeed!\n"); + + close(sock); + + return 0; +} + +int test_vpnsvc_up() +{ + int ret; + char local[VPNSVC_IP4_STRING_LEN] = {'\0',}; + char remote[VPNSVC_IP4_STRING_LEN] = {'\0',}; + struct vpnsvc_route routes[2]; + int nr_routes = 2; + const char *dns_server[2]; + int nr_dns = 2; + char dns_suffix[100] = "tizen.org"; + + if (!handle) { + printf("invalid handle\n"); + return -1; + } + + strncpy(local, "192.168.0.82", VPNSVC_IP4_STRING_LEN); + strncpy(remote, "192.168.0.1", VPNSVC_IP4_STRING_LEN); + + memset(routes, 0, sizeof(routes)); + strncpy(routes[0].dest, "192.168.0.10", VPNSVC_IP4_STRING_LEN); + routes[0].prefix = 32; + strncpy(routes[1].dest, "192.168.0.11", VPNSVC_IP4_STRING_LEN); + routes[1].prefix = 32; + + char *dns1 = "1.1.1.1"; + char *dns2 = "2.2.2.2"; + + dns_server[0] = dns1; + dns_server[1] = dns2; + + ret = vpnsvc_up(handle, local, remote, routes, nr_routes, dns_server, nr_dns, dns_suffix); + if (ret != VPNSVC_ERROR_NONE) + printf("vpnsvc_up failed!\n"); + else + printf("vpnsvc_up Succeed!\n"); + + return 0; +} + +int test_vpnsvc_down() +{ + int ret; + + if (!handle) { + printf("invalid handle\n"); + return -1; + } + + ret = vpnsvc_down(handle); + + if (ret != VPNSVC_ERROR_NONE) + printf("vpnsvc_down failed!\n"); + else + printf("vpnsvc_down Succeed!\n"); + + return 0; + +} + +int test_vpnsvc_read() +{ + return 0; +} + +int test_vpnsvc_write() +{ + return 0; +} + +int test_vpnsvc_block_networks() +{ + struct vpnsvc_route block_nets[2]; + int block_nr_nets = 2; + struct vpnsvc_route allow_nets[2]; + int allow_nr_nets = 2; + int ret; + + if (!handle) { + printf("invalid handle\n"); + return -1; + } + + memset(block_nets, 0, sizeof(block_nets)); + strncpy(block_nets[0].dest, "125.209.222.141", VPNSVC_IP4_STRING_LEN); + block_nets[0].prefix = 32; + strncpy(block_nets[1].dest, "180.70.134.19", VPNSVC_IP4_STRING_LEN); + block_nets[1].prefix = 32; + + memset(allow_nets, 0, sizeof(allow_nets)); + strncpy(allow_nets[0].dest, "216.58.221.142", VPNSVC_IP4_STRING_LEN); /* google.com */ + allow_nets[0].prefix = 32; + strncpy(allow_nets[1].dest, "206.190.36.45", VPNSVC_IP4_STRING_LEN); /* yahoo.com */ + allow_nets[1].prefix = 32; + + ret = vpnsvc_block_networks(handle, block_nets, block_nr_nets, allow_nets, allow_nr_nets); + + if (ret != VPNSVC_ERROR_NONE) + printf("vpnsvc_block_networks failed!\n"); + else + printf("vpnsvc_block_networks Succeed!\n"); + + return 0; + +} + +int test_vpnsvc_unblock_networks() +{ + int ret; + + if (!handle) { + printf("invalid handle\n"); + return -1; + } + + ret = vpnsvc_unblock_networks(handle); + + if (ret != VPNSVC_ERROR_NONE) + printf("vpnsvc_unblock_networks failed!\n"); + else + printf("vpnsvc_unblock_networks Succeed!\n"); + + return 0; +} + +int test_vpnsvc_set_mtu() +{ + int ret; + + ret = vpnsvc_set_mtu(handle, 9000); + + if (ret != VPNSVC_ERROR_NONE) + printf("vpnsvc_set_mtu failed!\n"); + else + printf("vpnsvc_set_mtu Succeed!\n"); + + return 0; +} + +bool g_blocking = false; + +int test_vpnsvc_set_blocking() +{ + int ret; + g_blocking = !g_blocking; + + printf("Blocking Parameter: %s\n", g_blocking ? "true" : "false"); + ret = vpnsvc_set_blocking(handle, g_blocking); + + if (ret != VPNSVC_ERROR_NONE) + printf("vpnsvc_set_blocking failed!\n"); + else + printf("vpnsvc_set_blocking Succeed!\n"); + + return 0; +} + +int test_vpnsvc_set_session() +{ + int ret; + char *set_session = "vpnsvc_test VPN Session"; + char get_session[VPNSVC_SESSION_STRING_LEN]; + + ret = vpnsvc_set_session(handle, set_session); + + if (ret != VPNSVC_ERROR_NONE) { + printf("vpnsvc_set_session failed!\n"); + } else { + ret = vpnsvc_get_session(handle, get_session); + printf("Session Name = %s\n", get_session); + printf("vpnsvc_set_session Succeed!\n"); + } + + return 0; +} + +int test_exit() +{ + exit(0); +} + + +int (*test_function_table[])(void) = { + test_vpnsvc_init, + test_vpnsvc_deinit, + test_vpnsvc_protect, + test_vpnsvc_up, + test_vpnsvc_down, + test_vpnsvc_read, + test_vpnsvc_write, + test_vpnsvc_block_networks, + test_vpnsvc_unblock_networks, + test_vpnsvc_set_mtu, + test_vpnsvc_set_blocking, + test_vpnsvc_set_session, + test_exit, +}; + +int main() +{ + char input[3] = {0,}; + + printf("capi_vpn_service test\n"); + while (1) { + __fpurge(stdin); + printf("1 : vpnsvc_init\n"); + printf("2 : vpnsvc_deinit\n"); + printf("3 : vpnsvc_protect\n"); + printf("4 : vpnsvc_up\n"); + printf("5 : vpnsvc_down\n"); + printf("6 : vpnsvc_read\n"); + printf("7 : vpnsvc_write\n"); + printf("8 : vpnsvc_block_networks\n"); + printf("9 : vpnsvc_unblock_networks\n"); + printf("10 : vpnsvc_set_mtu\n"); + printf("11 : vpnsvc_set_blocking\n"); + printf("12 : vpnsvc_set_session\n"); + printf("q : quit\n"); + + TEST_CONSOLE_INPUT(input, 3); + unsigned int comm = strtoul(input, NULL, 0); + if (comm <= 0 || comm > (sizeof(test_function_table) / sizeof(int))) { + if (input[0] == 'q') { + test_exit(); + return 0; + } + + printf("Invalid index. Retry\n"); + continue; + } + + test_function_table[comm-1](); + } + return 0; +} diff --git a/test/vpnsvc-test.manifest b/test/vpnsvc-test.manifest new file mode 100755 index 0000000..80de6fa --- /dev/null +++ b/test/vpnsvc-test.manifest @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + -- 2.7.4 From 29bc3d69e7d7d74602e3a24f71b3b537bc92f31c Mon Sep 17 00:00:00 2001 From: "taesub.kim" Date: Mon, 21 Dec 2015 11:45:31 +0900 Subject: [PATCH 3/5] [ACR-472] Modified comments of ACR #1 Change-Id: I5382ed630a717e495b8e35e46b2b3ee241593af5 Signed-off-by: Taesub Kim --- doc/vpn_doc.h | 10 ++-- include/vpn_service.h | 127 ++++++++++++++------------------------------------ 2 files changed, 39 insertions(+), 98 deletions(-) diff --git a/doc/vpn_doc.h b/doc/vpn_doc.h index caa82e5..7978be8 100755 --- a/doc/vpn_doc.h +++ b/doc/vpn_doc.h @@ -24,15 +24,15 @@ /** * @defgroup CAPI_NETWORK_VPN_MODULE VPN - * @brief The VPN API provides functions for managing VPN. + * @brief The Virtual Private Network (VPN) API provides functions for managing VPN. * @ingroup CAPI_NETWORK_FRAMEWORK * * @section CAPI_NETWORK_VPN_MODULE_HEADER Required Header - * \#include + * \#include * * @section CAPI_NETWORK_VPN_MODULE_OVERVIEW Overview * VPN allows your application to manage VPN features. - * The VPN Service enables your application to init and deinit a VPN device(tun interface), + * The VPN Service enables your application to init and deinit a VPN device(TUN(namely netowrk TUNel) interface), * Routing management, DNS management and Firewall management. */ @@ -42,7 +42,7 @@ * @ingroup CAPI_NETWORK_VPN_MODULE * * @section CAPI_NETWORK_VPN_SERVICE_MODULE_HEADER Required Header - * \#include + * \#include * * @section CAPI_NETWORK_VPN_SERVICE_MODULE_OVERVEW Overview * The VPN Service functions for managing VPN. @@ -53,7 +53,7 @@ * - Firewall management * @section CAPI_NETWORK_VPN_SERVICE_MODULE_FEATURE Related Features * This API is related with the following features:\n - * - http://developer.samsung.com/tizen/feature/network.vpn\n + * - http://tizen.org/feature/network.vpn\n * * It is recommended to design feature related codes in your application for reliability.\n * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.\n diff --git a/include/vpn_service.h b/include/vpn_service.h index 3d6f6c5..0487dcc 100755 --- a/include/vpn_service.h +++ b/include/vpn_service.h @@ -32,17 +32,18 @@ * **/ +/** + * @addtogroup CAPI_NETWORK_VPN_MODULE + * @{ + */ + #include -#include -#include -#include #include #include -#ifdef LOG_TAG -#undef LOG_TAG -#endif -#define LOG_TAG "CAPI_VPNSVC" +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus #ifndef API #define API __attribute__ ((visibility("default"))) @@ -50,16 +51,19 @@ /** * @brief IPv4 address string length (includes end null character) + * @since_tizen 3.0 */ #define VPNSVC_IP4_STRING_LEN 16 /** - * @brief TUN interface name length (IFNAMSIZ) + * @brief TUN interface name length + * @since_tizen 3.0 */ #define VPNSVC_TUN_IF_NAME_LEN 16 /** * @brief Session name string length (includes end null character) + * @since_tizen 3.0 */ #define VPNSVC_SESSION_STRING_LEN 32 @@ -79,7 +83,6 @@ typedef enum VPNSVC_ERROR_IO_ERROR = TIZEN_ERROR_IO_ERROR, /**< IO error */ VPNSVC_ERROR_TIMEOUT = TIZEN_ERROR_TIMED_OUT, /**< Time out error or no answer */ VPNSVC_ERROR_IPC_FAILED = TIZEN_ERROR_VPNSVC | 0x02, /**< Failed to communicate with server */ - VPNSVC_ERROR_LICENSE_FAILED = TIZEN_ERROR_VPNSVC | 0x03, /**< Failed to verify license */ VPNSVC_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED /**< Not Supported */ } vpnsvc_error_e; @@ -87,7 +90,6 @@ typedef enum /** * @brief The structure containing the route information * @details This structure can be used for both vpnsvc_up() and vpnsvc_block_networks() functions. - * * @since_tizen 3.0 * @see vpnsvc_up() * @see vpnsvc_block_networks() @@ -99,7 +101,7 @@ struct vpnsvc_route { /** * @brief The VPN tun interface handle - * @details This handle can be obtained by calling vpnsvc_init() and destroyed(NULL) by calling vpnsvc_deinit(). + * @details This handle can be obtained by calling vpnsvc_init() and destroyed() by calling vpnsvc_deinit(). * @since_tizen 3.0 * @see vpnsvc_init() * @see vpnsvc_deinit() @@ -108,24 +110,20 @@ typedef void* vpnsvc_tun_h; /** - * @brief Initializes TUN interface (/dev/net/tun) + * @brief Initializes TUN interface * @detail You should call vpnsvc_get_tun_name() for checking the actual initialized TUN interface name. (In case of duplicated interface name) - * * @since_tizen 3.0 * @privlevel public - * @privilege %http://tizen.org/privilege/vpnservicea - * @remarks The license needed if you want to use this VPN API - * + * @privilege %http://tizen.org/privilege/vpnservice + * @remarks The @a handle should be released using vpnsvc_deinit(). * @param[in] tun_name The interface name * @param[out] handle The VPN tun interface handle - * * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IO_ERROR I/O Error (e.g. socket I/O error) * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon * @retval #VPNSVC_ERROR_PERMISSION_DENIED Permission Denied - * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported * @post Please call vpnsvc_deinit() if you want to de-initialize VPN tun interface. * @post Please call vpnsvc_get_tun_fd() if you want to know the fd of tun interface. @@ -140,19 +138,13 @@ API int vpnsvc_init(const char* tun_name, vpnsvc_tun_h *handle); /** * @brief De-Initializes TUN interface - * * @since_tizen 3.0 - * @remarks The license needed if you want to use this VPN API - * * @param[in] handle The VPN tun interface handle - * * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon - * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ @@ -161,30 +153,22 @@ API int vpnsvc_deinit(vpnsvc_tun_h handle); /** * @brief Prevents the underlying VPN traffic to be routed to the VPN itself * @details The specific socket will be bound to the network interface using by this function. - * * @since_tizen 3.0 - * @remarks The license needed if you want to use this VPN API - * * @param[in] handle The VPN tun interface handle * @param[in] socket_fd The opened socket file descriptor * @param[in] dev_name The network interface name (i.e. eth0 or ppp0, not to confuse with tunXXX) through which the VPN is working - * * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IO_ERROR I/O Error (e.g. socket I/O error) * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon - * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported */ API int vpnsvc_protect(vpnsvc_tun_h handle, int socket_fd, const char* dev_name); /** * @brief Sets-up TUN interface and brings it up. Installs specified routes/DNS servers/DNS suffix - * * @since_tizen 3.0 - * @remarks The license needed if you want to use this VPN API - * * @param[in] handle The VPN tun interface handle * @param[in] local_ip The local IP address * @param[in] remote_ip The remote IP address @@ -193,14 +177,11 @@ API int vpnsvc_protect(vpnsvc_tun_h handle, int socket_fd, const char* dev_name) * @param[in] dns_servers The list of DNS server names - Optional * @param[in] nr_dns_servers The number of DNS server names - Optional * @param[in] dns_suffix The DNS suffix - Optional - * * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon - * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @pre The VPN tun interface should be initialized already. * @post If you want to set interface down, please call vpnsvc_down(). * @see #vpnsvc_route @@ -214,19 +195,13 @@ API int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ /** * @brief Brings the TUN interface down and restores original DNS servers/domains - * * @since_tizen 3.0 - * @remarks The license needed if you want to use this VPN API. - * * @param[in] handle The VPN tun interface handle - * * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon - * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @pre The VPN tun interface should be initialized already. * @post Please call vpnsvc_deinit() if you want to de-initialize VPN tun interface. * @see vpnsvc_up() @@ -236,19 +211,15 @@ API int vpnsvc_down(vpnsvc_tun_h handle); /** * @brief Waits for the read event on TUN descriptor, but no more than the indicated timeout in milliseconds - * * @since_tizen 3.0 - * * @param[in] handle The VPN tun interface handle * @param[in] timeout_ms The value of timeout (milliseconds) - * * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IO_ERROR I/O Error (e.g. socket I/O error) * @retval #VPNSVC_ERROR_TIMEOUT Timeout (no answer in timeout_ms) * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @pre The VPN interface should be initialized already. * @see vpnsvc_init() * @see vpnsvc_up() @@ -257,18 +228,15 @@ API int vpnsvc_read(vpnsvc_tun_h handle, int timeout_ms); /** * @brief Writes the data supplied into the TUN interface - * * @since_tizen 3.0 - * * @param[in] handle The VPN tun interface handle * @param[in] data Data writing to tun interface * @param[in] size The size of data - * * @return On success, the number of bytes written is returned (zero indicates nothing was written). Otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported * @retval In case of negative error, please refer to standard posix write API's error code. - * * @pre The VPN interface should be initialized already. * @see vpnsvc_init() * @see vpnsvc_up() @@ -277,22 +245,16 @@ API int vpnsvc_write(vpnsvc_tun_h handle, const char* data, size_t size); /** * @brief Blocks all traffics except specified allowing networks - * * @since_tizen 3.0 - * @remarks The license needed if you want to use this VPN API - * * @param[in] handle The VPN tun interface handle * @param[in] allow_routes_vpn The list of allowing networks over VPN interface (Please see vpnsvc_route structure). * @param[in] nr_allow_routes_vpn The number of allowing networks over VPN interface * @param[in] allow_routes_orig The list of allowing networks over the original interface (Please see vpnsvc_route structure). * @param[in] nr_allow_routes_orig The number of allowing networks over the original interface - * * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon - * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @post Please call vpnsvc_unblock_networks() if you want to allow all traffics. * @see vpnsvc_unblock_networks() */ @@ -304,81 +266,63 @@ API int vpnsvc_block_networks(vpnsvc_tun_h handle, /** * @brief Removes any restrictions imposed by vpnsvc_block_networks() - * * @since_tizen 3.0 - * @remarks The license needed if you want to use this VPN API - * * @param[in] handle The VPN tun interface handle - * * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon - * @retval #VPNSVC_ERROR_LICENSE_FAILED Failed to verify license * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * */ API int vpnsvc_unblock_networks(vpnsvc_tun_h handle); /** * @brief Gets the fd of the VPN tun interface - * * @since_tizen 3.0 - * * @param[in] handle The VPN tun interface handle - * * @return The fd value of VPN tun interface. Otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported */ API int vpnsvc_get_tun_fd(vpnsvc_tun_h handle); /** - * @brief Gets the index of VPN tun interface (if.if_index) - * + * @brief Gets the index of VPN tun interface * @since_tizen 3.0 - * * @param[in] handle The VPN tun interface handle - * * @return The index of the VPN tun interface. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ API int vpnsvc_get_tun_index(vpnsvc_tun_h handle); /** - * @brief Gets the name of VPN tun interface (if.if_name) - * + * @brief Gets the name of VPN tun interface * @since_tizen 3.0 - * + * @remarks The @a tun_name should be released using free() * @param[in] handle The VPN tun interface handle * @param[out] tun_name The name of VPN tun interface name - * * @return 0 on success. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ API int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char* tun_name); /** - * @brief Sets the MTU of the VPN tun interface (if.if_name) - * + * @brief Sets the MTU of the VPN tun interface * @since_tizen 3.0 - * * @param[in] handle The VPN tun interface handle * @param[in] mtu The MTU (Maximum Transmission Unit) value to be set for VPN tun interface. Default MTU size is 1500. - * * @return 0 on success. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ @@ -386,18 +330,14 @@ API int vpnsvc_set_mtu(vpnsvc_tun_h handle, int mtu); /** * @brief Sets blocking mode of the file descriptor of VPN tun interface - * * @since_tizen 3.0 - * * @param[in] handle The VPN tun interface handle * @param[in] blocking The blocking mode flag; True = BLOCKING, False = NON_BLOCKING - * * @return 0 on success. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IO_ERROR Failed to set the blocking flags * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ @@ -405,38 +345,39 @@ API int vpnsvc_set_blocking(vpnsvc_tun_h handle, bool blocking); /** * @brief Sets the session name for the VPN - * * @since_tizen 3.0 - * + * @remarks a tun_name should be released using free() * @param[in] handle The VPN tun interface handle * @param[in] session The Session Name - * * @return 0 on success. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session); +API int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session_name); /** * @brief Gets the session name for the VPN - * * @since_tizen 3.0 - * * @param[in] handle The VPN tun interface handle * @param[out] session The Session Name returned - * * @return 0 on success. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_get_session(vpnsvc_tun_h handle, char* session); +API int vpnsvc_get_session(vpnsvc_tun_h handle, char* session_name); + +#ifdef __cplusplus +} +#endif // __cplusplus + +/** +* @} +*/ #endif /* __TIZEN_CAPI_VPN_SERVICE_H__ */ -- 2.7.4 From 1695270f78fe22b99fb256eb0a822897dce1657a Mon Sep 17 00:00:00 2001 From: "taesub.kim" Date: Mon, 11 Jan 2016 09:32:58 +0900 Subject: [PATCH 4/5] [ACR-472] Modified comments of ACR #2 Change-Id: I346d6c7325741f9ac44ba452e56a8a9ad55af869 Signed-off-by: Taesub Kim Signed-off-by: Deepak Kumar Sahu --- daemon/include/vpn_service_daemon.h | 10 ++-- daemon/src/vpn_service_daemon.c | 23 ++++---- daemon/src/vpnsvc.c | 75 ++++++++++------------- framework/src/capi_vpn_service.c | 82 ++++++++++++++----------- include/vpn_service.h | 115 ++++++++++++++++++------------------ test/vpn_service_test.c | 80 ++++++++++++++++--------- 6 files changed, 206 insertions(+), 179 deletions(-) diff --git a/daemon/include/vpn_service_daemon.h b/daemon/include/vpn_service_daemon.h index 9237184..755ce3e 100755 --- a/daemon/include/vpn_service_daemon.h +++ b/daemon/include/vpn_service_daemon.h @@ -27,12 +27,12 @@ int vpn_daemon_init(const char* tun_name, size_t tun_name_len, int fd, vpnsvc_tu int vpn_daemon_deinit(const char* dev_name); int vpn_daemon_protect(int socket, const char* dev_name); int vpn_daemon_up(int tun_index, const char* local_ip, const char* remote_ip, - const struct vpnsvc_route* routes, 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); + const 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_daemon_down(int tun_index); -int vpn_daemon_block_networks(const struct vpnsvc_route* nets_vpn, size_t nr_nets_vpn, - const struct vpnsvc_route* nets_orig, size_t nr_nets_orig); +int vpn_daemon_block_networks(const char* nets_vpn[], int prefix_vpn[], size_t nr_nets_vpn, + const char* nets_orig[], int prefix_orig[], size_t nr_nets_orig); int vpn_daemon_unblock_networks(void); #endif /* __TIZEN_CAPI_VPN_SERVICE_DAEMON_H__ */ diff --git a/daemon/src/vpn_service_daemon.c b/daemon/src/vpn_service_daemon.c index 977426e..e664124 100755 --- a/daemon/src/vpn_service_daemon.c +++ b/daemon/src/vpn_service_daemon.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "vpn_service_daemon.h" @@ -81,7 +82,7 @@ static in_addr_t host2net(ipv4 host) return net; } -static int add_routes(char* if_name, const struct vpnsvc_route* routes, size_t nr_routes) +static int add_routes(char* if_name, const char* routes[], int prefix[], size_t nr_routes) { struct rtentry rt; struct sockaddr_in addr; @@ -102,7 +103,7 @@ static int add_routes(char* if_name, const struct vpnsvc_route* routes, size_t n memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr(routes[i].dest); + addr.sin_addr.s_addr = inet_addr(routes[i]); memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst)); memset(&addr, 0, sizeof(addr)); @@ -114,7 +115,7 @@ static int add_routes(char* if_name, const struct vpnsvc_route* routes, size_t n 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(routes[i].prefix)); + addr.sin_addr.s_addr = host2net(make_mask(prefix[i])); memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask)); rt.rt_dev = if_name; @@ -724,7 +725,7 @@ int vpn_daemon_protect(int socket_fd, const char* dev_name) } int vpn_daemon_up(int tun_index, const char* local_ip, const char* remote_ip, - const struct vpnsvc_route* routes, size_t nr_routes, + const 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) { @@ -816,7 +817,7 @@ int vpn_daemon_up(int tun_index, const char* local_ip, const char* remote_ip, /* add routes */ if (nr_routes > 0) { - ret = add_routes(ifr_tun.ifr_name, routes, nr_routes); + ret = add_routes(ifr_tun.ifr_name, routes, prefix, nr_routes); if (ret != VPNSVC_ERROR_NONE) { LOGE("add_routes failed"); return ret; @@ -903,21 +904,21 @@ int vpn_daemon_down(int tun_index) return VPNSVC_ERROR_NONE; } -int vpn_daemon_block_networks(const struct vpnsvc_route* nets_vpn, size_t nr_nets_vpn, - const struct vpnsvc_route* nets_orig, size_t nr_nets_orig) { +int vpn_daemon_block_networks(const char* nets_vpn[], int prefix_vpn[], size_t nr_nets_vpn, + const char* nets_orig[], int prefix_orig[], size_t nr_nets_orig) { unsigned int i; /* iptable chain regist */ iptables_register(); for (i = 0; i < nr_nets_vpn; i++) { - LOGD("block[%d] ip/mask : %s/%d", i, nets_vpn[i].dest, nets_vpn[i].prefix); - iptables_add(nets_vpn[i].dest, nets_vpn[i].prefix); + LOGD("block[%d] ip/mask : %s/%d", i, nets_vpn[i], prefix_vpn[i]); + iptables_add(nets_vpn[i], prefix_vpn[i]); } for (i = 0; i < nr_nets_orig; i++) { - LOGD("allow[%d] ip/mask : %s/%d", i, nets_orig[i].dest, nets_orig[i].prefix); - iptables_add_orig(nets_orig[i].dest, nets_orig[i].prefix); + LOGD("allow[%d] ip/mask : %s/%d", i, nets_orig[i], prefix_orig[i]); + iptables_add_orig(nets_orig[i], prefix_orig[i]); } return VPNSVC_ERROR_NONE; diff --git a/daemon/src/vpnsvc.c b/daemon/src/vpnsvc.c index d2a55fa..ce858da 100755 --- a/daemon/src/vpnsvc.c +++ b/daemon/src/vpnsvc.c @@ -132,7 +132,8 @@ gboolean handle_vpn_up(Vpnsvc *object, LOGD("handle_vpn_up"); - struct vpnsvc_route* routes = NULL; + char* routes[arg_nr_routes]; + int prefix[arg_nr_routes]; char **dns_servers = NULL; unsigned int i = 0; @@ -157,20 +158,17 @@ gboolean handle_vpn_up(Vpnsvc *object, if (arg_nr_routes > 0) { if (arg_routes != NULL) { GVariant *dict = g_variant_get_variant(arg_routes); - routes = (struct vpnsvc_route*)malloc(sizeof(struct vpnsvc_route)*arg_nr_routes); - if (routes == NULL) { - LOGE("malloc failed."); - result = VPNSVC_ERROR_OUT_OF_MEMORY; - goto done; - } 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); - strncpy(routes[i].dest, route_dest, temp_dest_str_len); - routes[i].dest[temp_dest_str_len] = '\0'; - routes[i].prefix = route_prefix; - LOGD("routes[%d] : %s/%d", i, (routes[i].dest == NULL) ? "" : routes[i].dest, routes[i].prefix); + routes[i] = malloc((sizeof(char) * temp_dest_str_len)+1); + memset(routes[i], 0, sizeof(char) * temp_dest_str_len); + strncpy(routes[i], route_dest, temp_dest_str_len); + routes[i][temp_dest_str_len] = '\0'; + prefix[i] = route_prefix; + LOGD("routes[%d] = %s \t", i, (routes[i] == NULL) ? "" : routes[i]); + LOGD("prefix[%d] = %d ", i, prefix[i]); i++; } } @@ -202,13 +200,10 @@ gboolean handle_vpn_up(Vpnsvc *object, } result = vpn_daemon_up(arg_tun_index, arg_local_ip, arg_remote_ip, - routes, arg_nr_routes, dns_servers, arg_nr_dns, + routes, prefix, arg_nr_routes, dns_servers, arg_nr_dns, total_dns_string_cnt, arg_dns_suffix, arg_mtu); done: /* free pointers */ - if (routes) - free(routes); - if (dns_servers) { for (i = 0; i < arg_nr_dns; i++) { if (dns_servers[i]) @@ -248,8 +243,11 @@ gboolean handle_vpn_block_networks(Vpnsvc *object, LOGD("handle_vpn_block_networks"); int result = VPNSVC_ERROR_NONE; - struct vpnsvc_route* nets_vpn = NULL; - struct vpnsvc_route* nets_orig = NULL; + char *nets_vpn[arg_nr_nets_vpn]; + int prefix_vpn[arg_nr_nets_vpn]; + + char *nets_orig[arg_nr_nets_vpn]; + int prefix_orig[arg_nr_nets_vpn]; int i = 0; GVariantIter iter; @@ -262,20 +260,17 @@ gboolean handle_vpn_block_networks(Vpnsvc *object, if (arg_nr_nets_vpn > 0) { if (arg_nets_vpn != NULL) { GVariant *dict_nets_vpn = g_variant_get_variant(arg_nets_vpn); - nets_vpn = (struct vpnsvc_route*)malloc(sizeof(struct vpnsvc_route)*arg_nr_nets_vpn); - if (nets_vpn == NULL) { - LOGE("malloc failed."); - result = VPNSVC_ERROR_OUT_OF_MEMORY; - goto done; - } g_variant_iter_init(&iter, dict_nets_vpn); i = 0; while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) { int tmp_route_len = strlen(route_dest); - strncpy(nets_vpn[i].dest, route_dest, tmp_route_len); - nets_vpn[i].dest[tmp_route_len] = '\0'; - nets_vpn[i].prefix = route_prefix; - LOGD("nets_vpn[%d] : %s/%d", i, (nets_vpn[i].dest == NULL) ? "" : nets_vpn[i].dest, nets_vpn[i].prefix); + nets_vpn[i] = malloc(sizeof(char) * tmp_route_len + 1); + memset(nets_vpn[i], 0, sizeof(char) * tmp_route_len); + strncpy(nets_vpn[i], route_dest, tmp_route_len); + nets_vpn[i][tmp_route_len] = '\0'; + prefix_vpn[i] = route_prefix; + LOGD("nets_vpn[%d] = %s \t", i, (nets_vpn[i] == NULL) ? "" : nets_vpn[i]); + LOGD("prefix_vpn[%d] = %d ", i, prefix_vpn[i]); i++; } } @@ -285,34 +280,24 @@ gboolean handle_vpn_block_networks(Vpnsvc *object, if (arg_nr_nets_orig > 0) { if (arg_nets_orig != NULL) { GVariant *dict_nets_orig = g_variant_get_variant(arg_nets_orig); - nets_orig = (struct vpnsvc_route*)malloc(sizeof(struct vpnsvc_route)*arg_nr_nets_orig); - if (nets_orig == NULL) { - LOGE("malloc failed."); - result = VPNSVC_ERROR_OUT_OF_MEMORY; - goto done; - } g_variant_iter_init(&iter, dict_nets_orig); i = 0; while (g_variant_iter_loop(&iter, "{si}", &route_dest, &route_prefix)) { int tmp_route_len = strlen(route_dest); - strncpy(nets_orig[i].dest, route_dest, tmp_route_len); - nets_orig[i].dest[tmp_route_len] = '\0'; - nets_orig[i].prefix = route_prefix; - LOGD("nets_orig[%d] : %s/%d", i, (nets_orig[i].dest == NULL) ? "" : nets_orig[i].dest, nets_orig[i].prefix); + nets_orig[i] = malloc(sizeof(char) * tmp_route_len + 1); + memset(nets_orig[i], 0, sizeof(char) * tmp_route_len); + strncpy(nets_orig[i], route_dest, tmp_route_len); + nets_orig[i][tmp_route_len] = '\0'; + prefix_orig[i] = route_prefix; + LOGD("nets_orig[%d] = %s \t", i, (nets_orig[i] == NULL) ? "" : nets_orig[i]); + LOGD("prefix_orig[%d] = %d ", i, prefix_orig[i]); i++; } } } /* call function */ - result = vpn_daemon_block_networks(nets_vpn, arg_nr_nets_vpn, nets_orig, arg_nr_nets_orig); - -done: - if (nets_vpn) - free(nets_vpn); - - if (nets_orig) - free(nets_orig); + result = vpn_daemon_block_networks(nets_vpn, prefix_vpn, arg_nr_nets_vpn, nets_orig, prefix_orig, arg_nr_nets_orig); vpnsvc_complete_vpn_block_networks(object, invocation, result); diff --git a/framework/src/capi_vpn_service.c b/framework/src/capi_vpn_service.c index 9f59ade..bca72e6 100755 --- a/framework/src/capi_vpn_service.c +++ b/framework/src/capi_vpn_service.c @@ -418,9 +418,9 @@ int vpnsvc_protect(vpnsvc_tun_h handle, int socket_fd, const char* dev_name) } int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ip, - const struct vpnsvc_route* routes, size_t nr_routes, - const char** dns_servers, size_t nr_dns_servers, - const char* dns_suffix) + const char* dest[], int prefix[], size_t nr_routes, + const char** dns_servers, size_t nr_dns_servers, + const char* dns_suffix) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -460,13 +460,13 @@ int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ip, /* make a route parameter */ g_variant_builder_init(&route_builder, G_VARIANT_TYPE("a{si}")); for (i = 0 ; i < nr_routes ; i++) { - if (strlen(routes[i].dest) <= 0) { - LOGE("invalid routes[%d].dest", i); + if (strlen(dest[i]) <= 0) { + LOGE("invalid dest[%d]", i); return VPNSVC_ERROR_INVALID_PARAMETER; } - g_variant_builder_add(&route_builder, "{si}", routes[i].dest, routes[i].prefix); - LOGD("routes[%d].dest : %s", i, routes[i].dest); - LOGD("routes[%d].prefix : %d", i, routes[i].prefix); + g_variant_builder_add(&route_builder, "{si}", dest[i], prefix[i]); + LOGD("dest[%d] : %s", i, dest[i]); + LOGD("prefix[i] : %d", i, prefix[i]); } route_param = g_variant_builder_end(&route_builder); @@ -621,11 +621,15 @@ int vpnsvc_write(vpnsvc_tun_h handle, const char* data, size_t size) return write(tun_s->fd, data, size); } -API int vpnsvc_block_networks(vpnsvc_tun_h handle, - const struct vpnsvc_route* allow_routes_vpn, - size_t nr_allow_routes_vpn, - const struct vpnsvc_route* allow_routes_orig, - size_t nr_allow_routes_orig) + +int vpnsvc_block_networks(vpnsvc_tun_h handle, + const char* dest_vpn[], + int prefix_vpn[], + size_t nr_allow_routes_vpn, + const char* dest_orig[], + int prefix_orig[], + size_t nr_allow_routes_orig) + { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -653,18 +657,18 @@ API int vpnsvc_block_networks(vpnsvc_tun_h handle, /* make a route parameter for allowed VPN interface routes */ g_variant_builder_init(&nets_builder, G_VARIANT_TYPE("a{si}")); for (i = 0 ; i < nr_allow_routes_vpn ; i++) { - g_variant_builder_add(&nets_builder, "{si}", allow_routes_vpn[i].dest, allow_routes_vpn[i].prefix); - LOGD("routes[%d].dest : %s", i, allow_routes_vpn[i].dest); - LOGD("routes[%d].prefix : %d", i, allow_routes_vpn[i].prefix); + g_variant_builder_add(&nets_builder, "{si}", dest_vpn[i], prefix_vpn[i]); + LOGD("dest_vpn[%d] : %s", i, dest_vpn[i]); + LOGD("prefix_vpn[%d] : %d", i, prefix_vpn[i]); } nets_param_vpn = g_variant_builder_end(&nets_builder); /* make a route parameter for allowed Original interface Routes */ g_variant_builder_init(&nets_builder, G_VARIANT_TYPE("a{si}")); for (i = 0 ; i < nr_allow_routes_orig ; i++) { - g_variant_builder_add(&nets_builder, "{si}", allow_routes_orig[i].dest, allow_routes_orig[i].prefix); - LOGD("routes[%d].dest : %s", i, allow_routes_orig[i].dest); - LOGD("routes[%d].prefix : %d", i, allow_routes_orig[i].prefix); + g_variant_builder_add(&nets_builder, "{si}", dest_orig[i], prefix_orig[i]); + LOGD("dest_orig[%d] : %s", i, dest_orig[i]); + LOGD("prefix_orig[%d] : %d", i, prefix_orig[i]); } nets_param_orig = g_variant_builder_end(&nets_builder); @@ -736,15 +740,15 @@ int vpnsvc_unblock_networks(vpnsvc_tun_h handle) return result; } -int vpnsvc_get_tun_fd(vpnsvc_tun_h handle) +int vpnsvc_get_tun_fd(vpnsvc_tun_h handle, int* tun_fd) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); vpnsvc_tun_s *tun_s = NULL; /* parameter check */ - if (handle == NULL) { - LOGE("handle is a NULL"); + if (handle == NULL || tun_fd == NULL) { + LOGE("Invalid parameter"); return VPNSVC_ERROR_INVALID_PARAMETER; } tun_s = (vpnsvc_tun_s*)handle; @@ -754,20 +758,23 @@ int vpnsvc_get_tun_fd(vpnsvc_tun_h handle) return VPNSVC_ERROR_INVALID_PARAMETER; } - return tun_s->fd; + *tun_fd = (int)(tun_s->fd); + + return VPNSVC_ERROR_NONE; } -int vpnsvc_get_tun_index(vpnsvc_tun_h handle) +int vpnsvc_get_tun_index(vpnsvc_tun_h handle, int* tun_index) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); vpnsvc_tun_s *tun_s = NULL; /* parameter check */ - if (handle == NULL) { - LOGE("handle is a NULL"); + if (handle == NULL || tun_index == NULL) { + LOGE("Invalid parameter"); return VPNSVC_ERROR_INVALID_PARAMETER; } + tun_s = (vpnsvc_tun_s*)handle; if (tun_s->index <= 0) { @@ -775,14 +782,17 @@ int vpnsvc_get_tun_index(vpnsvc_tun_h handle) return VPNSVC_ERROR_INVALID_PARAMETER; } - return tun_s->index; + *tun_index = (int)(tun_s->index); + + return VPNSVC_ERROR_NONE; } -int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char* tun_name) +int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char** tun_name) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); vpnsvc_tun_s *tun_s = NULL; + char la_tun_name[VPNSVC_TUN_IF_NAME_LEN + 1] = { 0, }; /* parameter check */ if (handle == NULL) { @@ -796,8 +806,13 @@ int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char* tun_name) return VPNSVC_ERROR_INVALID_PARAMETER; } - strncpy(tun_name, tun_s->name, VPNSVC_TUN_IF_NAME_LEN); - tun_name[VPNSVC_TUN_IF_NAME_LEN-1] = '\0'; + if (tun_name == NULL) { + LOGE("tun name string is NULL"); + return VPNSVC_ERROR_INVALID_PARAMETER; + } + + g_strlcpy(la_tun_name, tun_s->name, VPNSVC_TUN_IF_NAME_LEN + 1); + *tun_name = g_strdup(la_tun_name); return VPNSVC_ERROR_NONE; } @@ -886,11 +901,12 @@ int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session) return VPNSVC_ERROR_NONE; } -int vpnsvc_get_session(vpnsvc_tun_h handle, char* session) +int vpnsvc_get_session(vpnsvc_tun_h handle, char** session) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); vpnsvc_tun_s *tun_s = NULL; + char la_session[VPNSVC_SESSION_STRING_LEN + 1] = { 0, }; /* parameter check */ if (handle == NULL) { @@ -904,8 +920,8 @@ int vpnsvc_get_session(vpnsvc_tun_h handle, char* session) return VPNSVC_ERROR_INVALID_PARAMETER; } - strncpy(session, tun_s->session, VPNSVC_SESSION_STRING_LEN); - session[VPNSVC_SESSION_STRING_LEN-1] = '\0'; + g_strlcpy(la_session, tun_s->session, VPNSVC_SESSION_STRING_LEN + 1); + *session = g_strdup(la_session); return VPNSVC_ERROR_NONE; } diff --git a/include/vpn_service.h b/include/vpn_service.h index 0487dcc..5374e51 100755 --- a/include/vpn_service.h +++ b/include/vpn_service.h @@ -1,5 +1,5 @@ /* -* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved +* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,40 +38,46 @@ */ #include -#include #include #ifdef __cplusplus extern "C" { #endif // __cplusplus +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "CAPI_VPNSVC" + #ifndef API #define API __attribute__ ((visibility("default"))) #endif /** - * @brief IPv4 address string length (includes end null character) + * @brief IPv4 address string length (includes end null character). * @since_tizen 3.0 */ #define VPNSVC_IP4_STRING_LEN 16 /** - * @brief TUN interface name length + * @brief TUN interface name length. * @since_tizen 3.0 */ #define VPNSVC_TUN_IF_NAME_LEN 16 /** - * @brief Session name string length (includes end null character) + * @brief Session name string length (includes end null character). * @since_tizen 3.0 */ #define VPNSVC_SESSION_STRING_LEN 32 +#ifndef TIZEN_ERROR_VPNSVC +#define TIZEN_ERROR_VPNSVC -0x03200000 +#endif /** - * @brief Enumeration for VPN service error types + * @brief Enumeration for VPN service error types. * @details Indicate formats of error type field - * @ingroup VPNSVC_FRAMEWORK */ typedef enum { @@ -88,34 +94,21 @@ typedef enum /** - * @brief The structure containing the route information - * @details This structure can be used for both vpnsvc_up() and vpnsvc_block_networks() functions. - * @since_tizen 3.0 - * @see vpnsvc_up() - * @see vpnsvc_block_networks() - */ -struct vpnsvc_route { - char dest[VPNSVC_IP4_STRING_LEN]; /**< Destination address of the route */ - int prefix; /**< The prefix of route */ -}; - -/** - * @brief The VPN tun interface handle - * @details This handle can be obtained by calling vpnsvc_init() and destroyed() by calling vpnsvc_deinit(). + * @brief The VPN tun interface handle. + * @details This handle can be obtained by calling vpnsvc_init() and destroyed by calling vpnsvc_deinit(). * @since_tizen 3.0 * @see vpnsvc_init() * @see vpnsvc_deinit() */ typedef void* vpnsvc_tun_h; - /** - * @brief Initializes TUN interface + * @brief Initializes TUN interface. * @detail You should call vpnsvc_get_tun_name() for checking the actual initialized TUN interface name. (In case of duplicated interface name) * @since_tizen 3.0 * @privlevel public * @privilege %http://tizen.org/privilege/vpnservice - * @remarks The @a handle should be released using vpnsvc_deinit(). + * @remarks The @a handle should be released using vpnsvc_deinit(). * @param[in] tun_name The interface name * @param[out] handle The VPN tun interface handle * @return 0 on success. otherwise, a negative error value. @@ -127,8 +120,8 @@ typedef void* vpnsvc_tun_h; * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported * @post Please call vpnsvc_deinit() if you want to de-initialize VPN tun interface. * @post Please call vpnsvc_get_tun_fd() if you want to know the fd of tun interface. - * @post Please call vpnsvc_get_tun_index() if you want to know the fd of tun interface index(ifr.ifr_ifindex). - * @post Please call vpnsvc_get_tun_name() if you want to know the name of tun interface(ifr.ifr_name). + * @post Please call vpnsvc_get_tun_index() if you want to know the fd of tun interface index. + * @post Please call vpnsvc_get_tun_name() if you want to know the name of tun interface. * @see vpnsvc_deinit() * @see vpnsvc_get_tun_fd() * @see vpnsvc_get_tun_index() @@ -137,7 +130,7 @@ typedef void* vpnsvc_tun_h; API int vpnsvc_init(const char* tun_name, vpnsvc_tun_h *handle); /** - * @brief De-Initializes TUN interface + * @brief De-Initializes TUN interface. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle * @return 0 on success. otherwise, a negative error value. @@ -151,8 +144,8 @@ API int vpnsvc_init(const char* tun_name, vpnsvc_tun_h *handle); API int vpnsvc_deinit(vpnsvc_tun_h handle); /** - * @brief Prevents the underlying VPN traffic to be routed to the VPN itself - * @details The specific socket will be bound to the network interface using by this function. + * @brief Protect a socket from VPN connections. + * @details After protecting, data sent through this socket will go directly to the underlying network. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle * @param[in] socket_fd The opened socket file descriptor @@ -167,15 +160,16 @@ API int vpnsvc_deinit(vpnsvc_tun_h handle); API int vpnsvc_protect(vpnsvc_tun_h handle, int socket_fd, const char* dev_name); /** - * @brief Sets-up TUN interface and brings it up. Installs specified routes/DNS servers/DNS suffix + * @brief Sets-up TUN interface and brings it up. Installs specified routes/DNS servers/DNS suffix. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle * @param[in] local_ip The local IP address * @param[in] remote_ip The remote IP address - * @param[in] routes The list of routes for applying to routing table (see vpnsvc_route struct) - Optional - * @param[in] nr_routes The number of routes - Optional + * @param[in] dest Destination address of the route + * @param[in] prefix The prefix of route + * @param[in] nr_routes The number of routes * @param[in] dns_servers The list of DNS server names - Optional - * @param[in] nr_dns_servers The number of DNS server names - Optional + * @param[in] nr_dns_servers The number of DNS server names - Optionl * @param[in] dns_suffix The DNS suffix - Optional * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success @@ -184,17 +178,16 @@ API int vpnsvc_protect(vpnsvc_tun_h handle, int socket_fd, const char* dev_name) * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported * @pre The VPN tun interface should be initialized already. * @post If you want to set interface down, please call vpnsvc_down(). - * @see #vpnsvc_route * @see vpnsvc_init() * @see vpnsvc_down() */ API int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ip, - const struct vpnsvc_route* routes, size_t nr_routes, + const char *dest[], int prefix[], size_t nr_routes, const char** dns_servers, size_t nr_dns_servers, const char* dns_suffix); /** - * @brief Brings the TUN interface down and restores original DNS servers/domains + * @brief Brings the TUN interface down and restores original DNS servers/domains. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle * @return 0 on success. otherwise, a negative error value. @@ -210,7 +203,7 @@ API int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ API int vpnsvc_down(vpnsvc_tun_h handle); /** - * @brief Waits for the read event on TUN descriptor, but no more than the indicated timeout in milliseconds + * @brief Reads the data event on TUN descriptor. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle * @param[in] timeout_ms The value of timeout (milliseconds) @@ -227,7 +220,7 @@ API int vpnsvc_down(vpnsvc_tun_h handle); API int vpnsvc_read(vpnsvc_tun_h handle, int timeout_ms); /** - * @brief Writes the data supplied into the TUN interface + * @brief Writes the data supplied into the TUN interface. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle * @param[in] data Data writing to tun interface @@ -244,52 +237,60 @@ API int vpnsvc_read(vpnsvc_tun_h handle, int timeout_ms); API int vpnsvc_write(vpnsvc_tun_h handle, const char* data, size_t size); /** - * @brief Blocks all traffics except specified allowing networks + * @brief Blocks all traffics except specified allowing networks. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle - * @param[in] allow_routes_vpn The list of allowing networks over VPN interface (Please see vpnsvc_route structure). + * @param[in] dest_vpn Allowing networks over VPN interface. + * @param[in] prefix_vpn The prefix of VPN interface * @param[in] nr_allow_routes_vpn The number of allowing networks over VPN interface - * @param[in] allow_routes_orig The list of allowing networks over the original interface (Please see vpnsvc_route structure). + * @param[in] dest_orig Allowing networks over the original interface. + * @param[in] prefix_orig The prefix of Original interface. * @param[in] nr_allow_routes_orig The number of allowing networks over the original interface * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported * @post Please call vpnsvc_unblock_networks() if you want to allow all traffics. * @see vpnsvc_unblock_networks() */ API int vpnsvc_block_networks(vpnsvc_tun_h handle, - const struct vpnsvc_route* allow_routes_vpn, + const char *dest_vpn[], + int prefix_vpn[], size_t nr_allow_routes_vpn, - const struct vpnsvc_route* allow_routes_orig, + const char *dest_orig[], + int prefix_orig[], size_t nr_allow_routes_orig); /** - * @brief Removes any restrictions imposed by vpnsvc_block_networks() + * @brief Removes any restrictions imposed by vpnsvc_block_networks(). * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported */ API int vpnsvc_unblock_networks(vpnsvc_tun_h handle); /** - * @brief Gets the fd of the VPN tun interface + * @brief Gets the fd of the VPN tun interface. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle + * @param[out] tun_fd The tun fd * @return The fd value of VPN tun interface. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported */ -API int vpnsvc_get_tun_fd(vpnsvc_tun_h handle); +API int vpnsvc_get_tun_fd(vpnsvc_tun_h handle, int* tun_fd); /** - * @brief Gets the index of VPN tun interface + * @brief Gets the index of VPN tun interface. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle + * @param[out] tun_index The tun index * @return The index of the VPN tun interface. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter @@ -297,10 +298,10 @@ API int vpnsvc_get_tun_fd(vpnsvc_tun_h handle); * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_get_tun_index(vpnsvc_tun_h handle); +API int vpnsvc_get_tun_index(vpnsvc_tun_h handle, int* tun_index); /** - * @brief Gets the name of VPN tun interface + * @brief Gets the name of VPN tun interface. * @since_tizen 3.0 * @remarks The @a tun_name should be released using free() * @param[in] handle The VPN tun interface handle @@ -312,10 +313,10 @@ API int vpnsvc_get_tun_index(vpnsvc_tun_h handle); * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char* tun_name); +API int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char** tun_name); /** - * @brief Sets the MTU of the VPN tun interface + * @brief Sets the MTU of the VPN tun interface. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle * @param[in] mtu The MTU (Maximum Transmission Unit) value to be set for VPN tun interface. Default MTU size is 1500. @@ -329,7 +330,7 @@ API int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char* tun_name); API int vpnsvc_set_mtu(vpnsvc_tun_h handle, int mtu); /** - * @brief Sets blocking mode of the file descriptor of VPN tun interface + * @brief Sets blocking mode of the file descriptor of VPN tun interface. * @since_tizen 3.0 * @param[in] handle The VPN tun interface handle * @param[in] blocking The blocking mode flag; True = BLOCKING, False = NON_BLOCKING @@ -344,9 +345,8 @@ API int vpnsvc_set_mtu(vpnsvc_tun_h handle, int mtu); API int vpnsvc_set_blocking(vpnsvc_tun_h handle, bool blocking); /** - * @brief Sets the session name for the VPN + * @brief Sets the session name for the VPN. * @since_tizen 3.0 - * @remarks a tun_name should be released using free() * @param[in] handle The VPN tun interface handle * @param[in] session The Session Name * @return 0 on success. Otherwise, a negative error value. @@ -356,11 +356,12 @@ API int vpnsvc_set_blocking(vpnsvc_tun_h handle, bool blocking); * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session_name); +API int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session); /** - * @brief Gets the session name for the VPN + * @brief Gets the session name for the VPN. * @since_tizen 3.0 + * @remarks The @a session should be released using free() * @param[in] handle The VPN tun interface handle * @param[out] session The Session Name returned * @return 0 on success. Otherwise, a negative error value. @@ -370,7 +371,7 @@ API int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session_name); * @pre Before calling this function, VPN tun interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_get_session(vpnsvc_tun_h handle, char* session_name); +API int vpnsvc_get_session(vpnsvc_tun_h handle, char** session); #ifdef __cplusplus } diff --git a/test/vpn_service_test.c b/test/vpn_service_test.c index bf768ac..10354cb 100755 --- a/test/vpn_service_test.c +++ b/test/vpn_service_test.c @@ -44,6 +44,7 @@ int test_vpnsvc_init() { char *name = TEST_VPN_IF_NAME; int ret = VPNSVC_ERROR_NONE; + int int_value; printf("test vpnsvc_init\n"); @@ -52,12 +53,20 @@ int test_vpnsvc_init() if (ret != VPNSVC_ERROR_NONE) { printf("vpnsvc_init failed : %d\n", ret); } else { - char result_name[VPNSVC_TUN_IF_NAME_LEN] = {0, }; + char* result_name = NULL; printf("vpnsvc_init Succeed : %d\n", ret); - printf("tun_fd : %d\n", vpnsvc_get_tun_fd(handle)); - printf("tun_index : %d\n", vpnsvc_get_tun_index(handle)); - ret = vpnsvc_get_tun_name(handle, result_name); + if (vpnsvc_get_tun_fd(handle, &int_value) == VPNSVC_ERROR_NONE) + printf("tun_fd : %d\n", int_value); + else + printf("Fail to get tun_fd\n"); + + if (vpnsvc_get_tun_index(handle, &int_value) == VPNSVC_ERROR_NONE) + printf("tun_index : %d\n", int_value); + else + printf("Fail to get tun_index\n"); + + ret = vpnsvc_get_tun_name(handle, &result_name); if (ret == VPNSVC_ERROR_NONE) printf("tun_name : %s\n", result_name); } @@ -110,7 +119,8 @@ int test_vpnsvc_up() int ret; char local[VPNSVC_IP4_STRING_LEN] = {'\0',}; char remote[VPNSVC_IP4_STRING_LEN] = {'\0',}; - struct vpnsvc_route routes[2]; + char *routes[2]; + int prefix[2]; int nr_routes = 2; const char *dns_server[2]; int nr_dns = 2; @@ -124,11 +134,17 @@ int test_vpnsvc_up() strncpy(local, "192.168.0.82", VPNSVC_IP4_STRING_LEN); strncpy(remote, "192.168.0.1", VPNSVC_IP4_STRING_LEN); - memset(routes, 0, sizeof(routes)); - strncpy(routes[0].dest, "192.168.0.10", VPNSVC_IP4_STRING_LEN); - routes[0].prefix = 32; - strncpy(routes[1].dest, "192.168.0.11", VPNSVC_IP4_STRING_LEN); - routes[1].prefix = 32; + routes[0] = malloc(sizeof(char) * VPNSVC_IP4_STRING_LEN); + routes[1] = malloc(sizeof(char) * VPNSVC_IP4_STRING_LEN); + + memset(routes[0], 0, sizeof(char) * VPNSVC_IP4_STRING_LEN); + memset(routes[1], 0, sizeof(char) * VPNSVC_IP4_STRING_LEN); + + strncpy(routes[0], "192.168.0.10", VPNSVC_IP4_STRING_LEN); + prefix[0] = 32; + + strncpy(routes[1], "192.168.0.11", VPNSVC_IP4_STRING_LEN); + prefix[1] = 32; char *dns1 = "1.1.1.1"; char *dns2 = "2.2.2.2"; @@ -136,7 +152,7 @@ int test_vpnsvc_up() dns_server[0] = dns1; dns_server[1] = dns2; - ret = vpnsvc_up(handle, local, remote, routes, nr_routes, dns_server, nr_dns, dns_suffix); + ret = vpnsvc_up(handle, local, remote, routes, prefix, nr_routes, dns_server, nr_dns, dns_suffix); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_up failed!\n"); else @@ -177,9 +193,11 @@ int test_vpnsvc_write() int test_vpnsvc_block_networks() { - struct vpnsvc_route block_nets[2]; + char* block_nets[2]; + int block_prefix[2]; int block_nr_nets = 2; - struct vpnsvc_route allow_nets[2]; + char* allow_nets[2]; + int allow_prefix[2]; int allow_nr_nets = 2; int ret; @@ -188,19 +206,25 @@ int test_vpnsvc_block_networks() return -1; } - memset(block_nets, 0, sizeof(block_nets)); - strncpy(block_nets[0].dest, "125.209.222.141", VPNSVC_IP4_STRING_LEN); - block_nets[0].prefix = 32; - strncpy(block_nets[1].dest, "180.70.134.19", VPNSVC_IP4_STRING_LEN); - block_nets[1].prefix = 32; - - memset(allow_nets, 0, sizeof(allow_nets)); - strncpy(allow_nets[0].dest, "216.58.221.142", VPNSVC_IP4_STRING_LEN); /* google.com */ - allow_nets[0].prefix = 32; - strncpy(allow_nets[1].dest, "206.190.36.45", VPNSVC_IP4_STRING_LEN); /* yahoo.com */ - allow_nets[1].prefix = 32; - - ret = vpnsvc_block_networks(handle, block_nets, block_nr_nets, allow_nets, allow_nr_nets); + block_nets[0] = malloc(sizeof(char) * VPNSVC_IP4_STRING_LEN); + block_nets[1] = malloc(sizeof(char) * VPNSVC_IP4_STRING_LEN); + memset(block_nets[0], 0, sizeof(char) * VPNSVC_IP4_STRING_LEN); + memset(block_nets[1], 0, sizeof(char) * VPNSVC_IP4_STRING_LEN); + strncpy(block_nets[0], "125.209.222.141", VPNSVC_IP4_STRING_LEN); + block_prefix[0] = 32; + strncpy(block_nets[1], "180.70.134.19", VPNSVC_IP4_STRING_LEN); + block_prefix[1] = 32; + + allow_nets[0] = malloc(sizeof(char) * VPNSVC_IP4_STRING_LEN); + allow_nets[1] = malloc(sizeof(char) * VPNSVC_IP4_STRING_LEN); + memset(allow_nets[0], 0, sizeof(char) * VPNSVC_IP4_STRING_LEN); + memset(allow_nets[1], 0, sizeof(char) * VPNSVC_IP4_STRING_LEN); + strncpy(allow_nets[0], "216.58.221.142", VPNSVC_IP4_STRING_LEN); + allow_prefix[0] = 32; + strncpy(allow_nets[1], "206.190.36.45", VPNSVC_IP4_STRING_LEN); + allow_prefix[1] = 32; + + ret = vpnsvc_block_networks(handle, block_nets, block_prefix, block_nr_nets, allow_nets, allow_prefix, allow_nr_nets); if (ret != VPNSVC_ERROR_NONE) printf("vpnsvc_block_networks failed!\n"); @@ -266,14 +290,14 @@ int test_vpnsvc_set_session() { int ret; char *set_session = "vpnsvc_test VPN Session"; - char get_session[VPNSVC_SESSION_STRING_LEN]; + char *get_session = NULL; ret = vpnsvc_set_session(handle, set_session); if (ret != VPNSVC_ERROR_NONE) { printf("vpnsvc_set_session failed!\n"); } else { - ret = vpnsvc_get_session(handle, get_session); + ret = vpnsvc_get_session(handle, &get_session); printf("Session Name = %s\n", get_session); printf("vpnsvc_set_session Succeed!\n"); } -- 2.7.4 From 8fa084a53f3b463ea7e7b1be1a8e82d88c13e279 Mon Sep 17 00:00:00 2001 From: "taesub.kim" Date: Tue, 26 Jan 2016 18:29:19 +0900 Subject: [PATCH 5/5] [ACR-472] Modified comments of ACR #3 http://10.113.136.204/jira/browse/ACR-472 Change-Id: Ia1bf286b701f244f946f6f1215b836f82c70181c Signed-off-by: Taesub Kim --- daemon/include/vpn_service_daemon.h | 6 +- daemon/interfaces/org.tizen.vpnsvc.xml | 8 +- daemon/src/vpn_service_daemon.c | 28 ++-- daemon/src/vpnsvc.c | 20 +-- doc/vpn_doc.h | 20 +-- framework/CMakeLists.txt | 1 - framework/include/capi_vpn_service_private.h | 3 +- framework/src/capi_vpn_service.c | 83 +++++----- include/tizen_vpn_error.h | 51 ------ include/vpn_service.h | 235 ++++++++++----------------- include/vpn_service_internal.h | 100 ++++++++++++ test/vpn_service_test.c | 18 +- 12 files changed, 272 insertions(+), 301 deletions(-) delete mode 100755 include/tizen_vpn_error.h create mode 100755 include/vpn_service_internal.h diff --git a/daemon/include/vpn_service_daemon.h b/daemon/include/vpn_service_daemon.h index 755ce3e..b55e71c 100755 --- a/daemon/include/vpn_service_daemon.h +++ b/daemon/include/vpn_service_daemon.h @@ -23,14 +23,14 @@ #include "capi_vpn_service_private.h" -int vpn_daemon_init(const char* tun_name, size_t tun_name_len, int fd, vpnsvc_tun_s *handle_s); +int vpn_daemon_init(const char* if_name, size_t if_name_len, int fd, vpnsvc_tun_s *handle_s); int vpn_daemon_deinit(const char* dev_name); int vpn_daemon_protect(int socket, const char* dev_name); -int vpn_daemon_up(int tun_index, const char* local_ip, const char* remote_ip, +int vpn_daemon_up(int if_index, const char* local_ip, const char* remote_ip, const 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_daemon_down(int tun_index); +int vpn_daemon_down(int if_index); int vpn_daemon_block_networks(const char* nets_vpn[], int prefix_vpn[], size_t nr_nets_vpn, const char* nets_orig[], int prefix_orig[], size_t nr_nets_orig); int vpn_daemon_unblock_networks(void); diff --git a/daemon/interfaces/org.tizen.vpnsvc.xml b/daemon/interfaces/org.tizen.vpnsvc.xml index 8c4d08d..8349623 100755 --- a/daemon/interfaces/org.tizen.vpnsvc.xml +++ b/daemon/interfaces/org.tizen.vpnsvc.xml @@ -1,8 +1,8 @@ - - + + @@ -16,7 +16,7 @@ - + @@ -28,7 +28,7 @@ - + diff --git a/daemon/src/vpn_service_daemon.c b/daemon/src/vpn_service_daemon.c index e664124..94cc958 100755 --- a/daemon/src/vpn_service_daemon.c +++ b/daemon/src/vpn_service_daemon.c @@ -609,12 +609,12 @@ void iptables_delete(const char *addr, const int mask) iptables_rule('D', addr, mask); } -static int get_interface_index(const char *tun_name) +static int get_interface_index(const char *if_name) { struct ifreq ifr; int sk = 0; - LOGD("enter get_interface_index, tun_name : %s", tun_name); + LOGD("enter get_interface_index, if_name : %s", if_name); sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (sk < 0) { @@ -624,8 +624,8 @@ static int get_interface_index(const char *tun_name) memset(&ifr, 0, sizeof(ifr)); - if (*tun_name) - strncpy(ifr.ifr_name, tun_name, strlen(tun_name)); + if (*if_name) + strncpy(ifr.ifr_name, if_name, strlen(if_name)); /* get an interface name by ifindex */ if (ioctl(sk, SIOCGIFINDEX, &ifr) < 0) { @@ -640,12 +640,12 @@ static int get_interface_index(const char *tun_name) } -int vpn_daemon_init(const char* tun_name, size_t tun_name_len, int fd, vpnsvc_tun_s *handle_s) +int vpn_daemon_init(const char* if_name, size_t if_name_len, int fd, vpnsvc_tun_s *handle_s) { struct ifreq ifr; size_t len = 0; - LOGD("enter vpn_daemon_init, tun_name : %s, tun_name_len : %d, fd : %d\n", tun_name, tun_name_len, fd); + LOGD("enter vpn_daemon_init, if_name : %s, if_name_len : %d, fd : %d\n", if_name, if_name_len, fd); memset(&ifr, 0, sizeof(ifr)); @@ -657,8 +657,8 @@ int vpn_daemon_init(const char* tun_name, size_t tun_name_len, int fd, vpnsvc_tu ifr.ifr_flags = IFF_TUN | IFF_NO_PI; - if (*tun_name) - strncpy(ifr.ifr_name, tun_name, tun_name_len); + if (*if_name) + strncpy(ifr.ifr_name, if_name, if_name_len); LOGD("before init, ifindex : %d", ifr.ifr_ifindex); @@ -681,7 +681,7 @@ int vpn_daemon_init(const char* tun_name, size_t tun_name_len, int fd, vpnsvc_tu } handle_s->fd = 0; /* server fd does not meaning */ - handle_s->index = get_interface_index(tun_name); + handle_s->index = get_interface_index(if_name); len = strlen(ifr.ifr_name); strncpy(handle_s->name, ifr.ifr_name, len); handle_s->name[len] = '\0'; @@ -724,7 +724,7 @@ int vpn_daemon_protect(int socket_fd, const char* dev_name) return ret; } -int vpn_daemon_up(int tun_index, const char* local_ip, const char* remote_ip, +int vpn_daemon_up(int if_index, const char* local_ip, const char* remote_ip, const 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) { @@ -737,7 +737,7 @@ int vpn_daemon_up(int tun_index, const char* local_ip, const char* remote_ip, LOGD("enter vpn_daemon_up"); - LOGD("tun_index : %d", tun_index); + LOGD("if_index : %d", if_index); LOGD("local ip : %s", local_ip); LOGD("remote ip : %s", remote_ip); LOGD("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); @@ -750,7 +750,7 @@ int vpn_daemon_up(int tun_index, const char* local_ip, const char* remote_ip, } memset(&ifr_tun, 0, sizeof(ifr_tun)); - ifr_tun.ifr_ifindex = tun_index; + ifr_tun.ifr_ifindex = if_index; /* get an interface name by ifindex */ if (ioctl(sk, SIOCGIFNAME, &ifr_tun) < 0) { @@ -845,7 +845,7 @@ int vpn_daemon_up(int tun_index, const char* local_ip, const char* remote_ip, return ret; } -int vpn_daemon_down(int tun_index) +int vpn_daemon_down(int if_index) { struct ifreq ifr, addr_ifr; struct sockaddr_in *addr = NULL; @@ -858,7 +858,7 @@ int vpn_daemon_down(int tun_index) } memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_ifindex = tun_index; + ifr.ifr_ifindex = if_index; if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) { LOGE("ioctl SIOCGIFNAME failed : %s", strerror(errno)); diff --git a/daemon/src/vpnsvc.c b/daemon/src/vpnsvc.c index ce858da..e97d65b 100755 --- a/daemon/src/vpnsvc.c +++ b/daemon/src/vpnsvc.c @@ -38,8 +38,8 @@ static Vpnsvc *vpnsvc = NULL; ********************/ gboolean handle_vpn_init(Vpnsvc *object, GDBusMethodInvocation *invocation, - const gchar *arg_tun_name, - guint arg_tun_name_len) + const gchar *arg_if_name, + guint arg_if_name_len) { LOGD("handle_vpn_init"); @@ -50,7 +50,7 @@ gboolean handle_vpn_init(Vpnsvc *object, int fd_list_length; const int *fds; - LOGD("vpn_init, %s, %u\n", arg_tun_name, arg_tun_name_len); + LOGD("vpn_init, %s, %u\n", arg_if_name, arg_if_name_len); msg = g_dbus_method_invocation_get_message(invocation); fd_list = g_dbus_message_get_unix_fd_list(msg); @@ -61,7 +61,7 @@ gboolean handle_vpn_init(Vpnsvc *object, LOGD("fd:%d\n", *fds); - result = vpn_daemon_init(arg_tun_name, arg_tun_name_len, *fds, &handle_s); + result = vpn_daemon_init(arg_if_name, arg_if_name_len, *fds, &handle_s); LOGD("handle_s.fd : %d, handle_s.index : %d, handle_s.name : %s", handle_s.fd, handle_s.index, handle_s.name); @@ -118,7 +118,7 @@ gboolean handle_vpn_protect(Vpnsvc *object, gboolean handle_vpn_up(Vpnsvc *object, GDBusMethodInvocation *invocation, - gint arg_tun_index, + gint arg_if_index, const gchar *arg_local_ip, const gchar *arg_remote_ip, GVariant *arg_routes, @@ -144,7 +144,7 @@ gboolean handle_vpn_up(Vpnsvc *object, gchar* route_dest; gint route_prefix; - LOGD("tun_index : %d", arg_tun_index); + LOGD("if_index : %d", arg_if_index); LOGD("local ip : %s", arg_local_ip); LOGD("remote ip : %s", arg_remote_ip); LOGD("dns_suffix : %s", arg_dns_suffix); @@ -199,7 +199,7 @@ gboolean handle_vpn_up(Vpnsvc *object, } } - result = vpn_daemon_up(arg_tun_index, arg_local_ip, arg_remote_ip, + result = vpn_daemon_up(arg_if_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: @@ -219,14 +219,14 @@ done: gboolean handle_vpn_down(Vpnsvc *object, GDBusMethodInvocation *invocation, - gint arg_tun_index) + gint arg_if_index) { LOGD("handle_vpn_down"); int result = VPNSVC_ERROR_NONE; - LOGD("vpn_down, %d\n", arg_tun_index); + LOGD("vpn_down, %d\n", arg_if_index); - result = vpn_daemon_down(arg_tun_index); + result = vpn_daemon_down(arg_if_index); vpnsvc_complete_vpn_down(object, invocation, result); diff --git a/doc/vpn_doc.h b/doc/vpn_doc.h index 7978be8..4c8073b 100755 --- a/doc/vpn_doc.h +++ b/doc/vpn_doc.h @@ -14,38 +14,24 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ - #ifndef __TIZEN_NETWORK_VPN_DOC_H__ #define __TIZEN_NETWORK_VPN_DOC_H__ -/** - * @defgroup CAPI_NETWORK_VPN_MODULE VPN - * @brief The Virtual Private Network (VPN) API provides functions for managing VPN. - * @ingroup CAPI_NETWORK_FRAMEWORK - * - * @section CAPI_NETWORK_VPN_MODULE_HEADER Required Header - * \#include - * - * @section CAPI_NETWORK_VPN_MODULE_OVERVIEW Overview - * VPN allows your application to manage VPN features. - * The VPN Service enables your application to init and deinit a VPN device(TUN(namely netowrk TUNel) interface), - * Routing management, DNS management and Firewall management. - */ /** * @defgroup CAPI_NETWORK_VPN_SERVICE_MODULE VPN Service - * @brief The VPN API provides functions for managing VPN. - * @ingroup CAPI_NETWORK_VPN_MODULE + * @brief The Virtual Private Network (VPN) API provides functions for managing VPN. + * @ingroup CAPI_NETWORK_FRAMEWORK * * @section CAPI_NETWORK_VPN_SERVICE_MODULE_HEADER Required Header * \#include * * @section CAPI_NETWORK_VPN_SERVICE_MODULE_OVERVEW Overview * The VPN Service functions for managing VPN. + * There can be only one VPN connection running at the same time. The existing interface is deactivated when a new one is created. * Using the VPN Service, you can implement features that allow the users of your application to: * - Initialize / Deinitialize the VPN device * - Routing management diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 2622891..b78e4d4 100755 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -41,7 +41,6 @@ TARGET_LINK_LIBRARIES(${PACKAGE_NAME} ${${PACKAGE_NAME}_LDFLAGS} -lrt -ldl) INSTALL(TARGETS ${PACKAGE_NAME} DESTINATION lib) INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/vpn_service.h DESTINATION include) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/tizen_vpn_error.h DESTINATION include) SET_TARGET_PROPERTIES(${PACKAGE_NAME} PROPERTIES diff --git a/framework/include/capi_vpn_service_private.h b/framework/include/capi_vpn_service_private.h index 0f56377..9b74d77 100755 --- a/framework/include/capi_vpn_service_private.h +++ b/framework/include/capi_vpn_service_private.h @@ -35,6 +35,7 @@ #include #include "vpn_service.h" +#include "vpn_service_internal.h" #ifdef __cplusplus extern "C" { @@ -69,7 +70,7 @@ typedef struct _vpnsvc_tun_s { GDBusConnection *connection; /**< D-Bus Connection */ int fd; /**< tun socket fd */ int index; /**< tun index (if.if_index) */ - char name[VPNSVC_TUN_IF_NAME_LEN]; /**< tun name (if.if_name) */ + char name[VPNSVC_VPN_IF_NAME_LEN]; /**< tun name (if.if_name) */ char session[VPNSVC_SESSION_STRING_LEN];/**< session name (user setting) */ unsigned int mtu; /**< mtu (user setting) */ } vpnsvc_tun_s; diff --git a/framework/src/capi_vpn_service.c b/framework/src/capi_vpn_service.c index bca72e6..1997a24 100755 --- a/framework/src/capi_vpn_service.c +++ b/framework/src/capi_vpn_service.c @@ -24,6 +24,11 @@ #include #include +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "CAPI_VPNSVC" + #define DBUS_REPLY_TIMEOUT (120 * 1000) GVariant *op = NULL; @@ -98,7 +103,7 @@ static void _vpnsvc_deinit_vpnsvc_tun_s(vpnsvc_tun_s *s) s->fd = 0; s->index = 0; - memset(s->name, 0, VPNSVC_TUN_IF_NAME_LEN); + memset(s->name, 0, VPNSVC_VPN_IF_NAME_LEN); memset(s->session, 0, VPNSVC_SESSION_STRING_LEN); if (s) @@ -217,20 +222,20 @@ GVariant *_vpnsvc_invoke_dbus_method_with_fd(GDBusConnection *connection, return reply; } -int vpnsvc_init(const char* tun_name, vpnsvc_tun_h *handle) +EXPORT_API int vpnsvc_init(const char* if_name, vpnsvc_h *handle) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); int result = VPNSVC_ERROR_NONE; int dbus_result; - int tun_fd = 0; + int if_fd = 0; - LOGD("enter vpnsvc_init, tun_name : %s", tun_name); + LOGD("enter vpnsvc_init, if_name : %s", if_name); LOGD("handle : %p\n", handle); /* parameter check */ - if (tun_name == NULL || strlen(tun_name) <= 0) { - LOGE("tun_name is a NULL"); + if (if_name == NULL || strlen(if_name) <= 0) { + LOGE("if_name is a NULL"); return VPNSVC_ERROR_INVALID_PARAMETER; } else if (handle == NULL) { LOGE("handle is a NULL"); @@ -273,25 +278,25 @@ int vpnsvc_init(const char* tun_name, vpnsvc_tun_h *handle) op = NULL; } - if ((tun_fd = open("/dev/net/tun", O_RDWR)) < 0) { + if ((if_fd = open("/dev/net/tun", O_RDWR)) < 0) { LOGE("tun device open fail\n"); _vpnsvc_deinit_vpnsvc_tun_s(tmp_s); return VPNSVC_ERROR_IO_ERROR; } - LOGD("client tun_fd : %d", tun_fd); + LOGD("client if_fd : %d", if_fd); op = _vpnsvc_invoke_dbus_method_with_fd(tmp_s->connection, VPNSVC_DBUS_SERVICE_NAME, VPNSVC_DBUS_INTERFACE_OBJ_NAME, VPNSVC_DBUS_INTERFACE_NAME, "vpn_init", - g_variant_new("(su)", tun_name, strlen(tun_name)), - tun_fd, + g_variant_new("(su)", if_name, strlen(if_name)), + if_fd, &dbus_result); if (op == NULL) { - close(tun_fd); + close(if_fd); _vpnsvc_deinit_vpnsvc_tun_s(tmp_s); return VPNSVC_ERROR_IPC_FAILED; } else { @@ -305,10 +310,10 @@ int vpnsvc_init(const char* tun_name, vpnsvc_tun_h *handle) result = VPNSVC_ERROR_IPC_FAILED; } else { LOGD("vpnsvc_init() succeed"); - tmp_s->fd = tun_fd; /* client fd must be set */ + tmp_s->fd = if_fd; /* client fd must be set */ tmp_s->index = tmp_index; - strncpy(tmp_s->name, tmp_name, VPNSVC_TUN_IF_NAME_LEN); - tmp_s->name[VPNSVC_TUN_IF_NAME_LEN-1] = '\0'; + strncpy(tmp_s->name, tmp_name, VPNSVC_VPN_IF_NAME_LEN); + tmp_s->name[VPNSVC_VPN_IF_NAME_LEN-1] = '\0'; *handle = tmp_s; LOGD("handle : %p, handle->fd : %d, handle->index : %d, handle->name : %s", (*handle), ((vpnsvc_tun_s*)*handle)->fd, ((vpnsvc_tun_s*)*handle)->index, ((vpnsvc_tun_s*)*handle)->name); @@ -322,7 +327,7 @@ int vpnsvc_init(const char* tun_name, vpnsvc_tun_h *handle) return result; } -int vpnsvc_deinit(vpnsvc_tun_h handle) +EXPORT_API int vpnsvc_deinit(vpnsvc_h handle) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -337,7 +342,7 @@ int vpnsvc_deinit(vpnsvc_tun_h handle) } tun_s = (vpnsvc_tun_s*)handle; - LOGD("enter vpnsvc_deinit, tun_fd : %d", tun_s->fd); + LOGD("enter vpnsvc_deinit, if_fd : %d", tun_s->fd); if (tun_s->fd > 0) { op = _vpnsvc_invoke_dbus_method(tun_s->connection, @@ -371,7 +376,7 @@ int vpnsvc_deinit(vpnsvc_tun_h handle) return result; } -int vpnsvc_protect(vpnsvc_tun_h handle, int socket_fd, const char* dev_name) +EXPORT_API int vpnsvc_protect(vpnsvc_h handle, int socket_fd, const char* dev_name) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -417,7 +422,7 @@ int vpnsvc_protect(vpnsvc_tun_h handle, int socket_fd, const char* dev_name) return result; } -int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ip, +EXPORT_API int vpnsvc_up(vpnsvc_h handle, const char* local_ip, const char* remote_ip, const char* dest[], int prefix[], size_t nr_routes, const char** dns_servers, size_t nr_dns_servers, const char* dns_suffix) @@ -454,7 +459,7 @@ int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ip, return VPNSVC_ERROR_INVALID_PARAMETER; } - LOGD("tun_index %d", tun_s->index); + LOGD("if_index %d", tun_s->index); LOGD("local_ip : %s, remote_ip : %s", local_ip, remote_ip); /* make a route parameter */ @@ -507,7 +512,7 @@ int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ip, return result; } -int vpnsvc_down(vpnsvc_tun_h handle) +EXPORT_API int vpnsvc_down(vpnsvc_h handle) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -558,7 +563,7 @@ int vpnsvc_down(vpnsvc_tun_h handle) } /* this API must not be use IPC */ -int vpnsvc_read(vpnsvc_tun_h handle, int timeout_ms) +EXPORT_API int vpnsvc_read(vpnsvc_h handle, int timeout_ms) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -600,7 +605,7 @@ int vpnsvc_read(vpnsvc_tun_h handle, int timeout_ms) } /* this API must not be use IPC */ -int vpnsvc_write(vpnsvc_tun_h handle, const char* data, size_t size) +EXPORT_API int vpnsvc_write(vpnsvc_h handle, const char* data, size_t size) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -622,7 +627,7 @@ int vpnsvc_write(vpnsvc_tun_h handle, const char* data, size_t size) } -int vpnsvc_block_networks(vpnsvc_tun_h handle, +EXPORT_API int vpnsvc_block_networks(vpnsvc_h handle, const char* dest_vpn[], int prefix_vpn[], size_t nr_allow_routes_vpn, @@ -694,7 +699,7 @@ int vpnsvc_block_networks(vpnsvc_tun_h handle, return result; } -int vpnsvc_unblock_networks(vpnsvc_tun_h handle) +EXPORT_API int vpnsvc_unblock_networks(vpnsvc_h handle) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -740,14 +745,14 @@ int vpnsvc_unblock_networks(vpnsvc_tun_h handle) return result; } -int vpnsvc_get_tun_fd(vpnsvc_tun_h handle, int* tun_fd) +EXPORT_API int vpnsvc_get_if_fd(vpnsvc_h handle, int* if_fd) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); vpnsvc_tun_s *tun_s = NULL; /* parameter check */ - if (handle == NULL || tun_fd == NULL) { + if (handle == NULL || if_fd == NULL) { LOGE("Invalid parameter"); return VPNSVC_ERROR_INVALID_PARAMETER; } @@ -758,19 +763,19 @@ int vpnsvc_get_tun_fd(vpnsvc_tun_h handle, int* tun_fd) return VPNSVC_ERROR_INVALID_PARAMETER; } - *tun_fd = (int)(tun_s->fd); + *if_fd = (int)(tun_s->fd); return VPNSVC_ERROR_NONE; } -int vpnsvc_get_tun_index(vpnsvc_tun_h handle, int* tun_index) +EXPORT_API int vpnsvc_get_if_index(vpnsvc_h handle, int* if_index) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); vpnsvc_tun_s *tun_s = NULL; /* parameter check */ - if (handle == NULL || tun_index == NULL) { + if (handle == NULL || if_index == NULL) { LOGE("Invalid parameter"); return VPNSVC_ERROR_INVALID_PARAMETER; } @@ -782,17 +787,17 @@ int vpnsvc_get_tun_index(vpnsvc_tun_h handle, int* tun_index) return VPNSVC_ERROR_INVALID_PARAMETER; } - *tun_index = (int)(tun_s->index); + *if_index = (int)(tun_s->index); return VPNSVC_ERROR_NONE; } -int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char** tun_name) +EXPORT_API int vpnsvc_get_if_name(vpnsvc_h handle, char** if_name) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); vpnsvc_tun_s *tun_s = NULL; - char la_tun_name[VPNSVC_TUN_IF_NAME_LEN + 1] = { 0, }; + char la_if_name[VPNSVC_VPN_IF_NAME_LEN + 1] = { 0, }; /* parameter check */ if (handle == NULL) { @@ -806,18 +811,18 @@ int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char** tun_name) return VPNSVC_ERROR_INVALID_PARAMETER; } - if (tun_name == NULL) { + if (if_name == NULL) { LOGE("tun name string is NULL"); return VPNSVC_ERROR_INVALID_PARAMETER; } - g_strlcpy(la_tun_name, tun_s->name, VPNSVC_TUN_IF_NAME_LEN + 1); - *tun_name = g_strdup(la_tun_name); + g_strlcpy(la_if_name, tun_s->name, VPNSVC_VPN_IF_NAME_LEN + 1); + *if_name = g_strdup(la_if_name); return VPNSVC_ERROR_NONE; } -int vpnsvc_set_mtu(vpnsvc_tun_h handle, int mtu) +EXPORT_API int vpnsvc_set_mtu(vpnsvc_h handle, int mtu) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -839,7 +844,7 @@ int vpnsvc_set_mtu(vpnsvc_tun_h handle, int mtu) return VPNSVC_ERROR_NONE; } -int vpnsvc_set_blocking(vpnsvc_tun_h handle, bool blocking) +EXPORT_API int vpnsvc_set_blocking(vpnsvc_h handle, bool blocking) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -877,7 +882,7 @@ int vpnsvc_set_blocking(vpnsvc_tun_h handle, bool blocking) return VPNSVC_ERROR_NONE; } -int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session) +EXPORT_API int vpnsvc_set_session(vpnsvc_h handle, const char* session) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); @@ -901,7 +906,7 @@ int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session) return VPNSVC_ERROR_NONE; } -int vpnsvc_get_session(vpnsvc_tun_h handle, char** session) +EXPORT_API int vpnsvc_get_session(vpnsvc_h handle, char** session) { CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE); diff --git a/include/tizen_vpn_error.h b/include/tizen_vpn_error.h deleted file mode 100755 index bbd32e4..0000000 --- a/include/tizen_vpn_error.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the License); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#ifndef __TIZEN_COMMON_VPN_ERROR_H__ -#define __TIZEN_COMMON_VPN_ERROR_H__ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup CAPI_COMMON_VPN_ERROR Common VPN Error - * @brief This file provides error codes that are common for the whole TIZEN VPN API. - * @section CAPI_COMMON_VPN_ERROR_HEADER Required Header - * \#include - * @ingroup CAPI_COMMON_ERROR - * @{ - */ - -#define TIZEN_ERROR_MIN_VPN_ERROR (-268435456) /* = -268435455(0x0FFFFFFF) -1 */ - -/* Check if slp error or not */ -#define TIZEN_ERROR_IS_VPN_ERROR(x) (TIZEN_ERROR_MIN_VPN_ERROR >= (x) && (x) < 0) - -/* Tizen VPN Service Error */ -#define TIZEN_ERROR_VPNSVC -0x10000000 - -/** - * @} - */ -#ifdef __cplusplus -} -#endif - -#endif /**<__TIZEN_COMMON_VPN_ERROR_H__ */ diff --git a/include/vpn_service.h b/include/vpn_service.h index 5374e51..31a248b 100755 --- a/include/vpn_service.h +++ b/include/vpn_service.h @@ -17,41 +17,20 @@ #ifndef __TIZEN_VPN_SERVICE_H__ #define __TIZEN_VPN_SERVICE_H__ -/** - * @file vpn_service.h - */ - -/** - *@defgroup VPNSVC_FRAMEWORK VPN_SERVICE - *@brief The VPN service APIs to manage VPN features such as VPN device (TUN interface) initialization, routing management, DNS management and firewall management. - *@section VPNSVC_FRAMEWORK_OVERVIEW Overview - * - * - * - * - *
APIDescription>
@ref VPNSVC_FRAMEWORK Provides functions to vpnsvc_init/vpnsvc_deinit/vpnsvc_protect/vpnsvc_up/vpnsvc_down/vpnsvc_read/vpnsvc_write/vpnsvc_block_networks/vpnsvc_unblock_networks.
- **/ - -/** - * @addtogroup CAPI_NETWORK_VPN_MODULE - * @{ - */ - #include -#include #ifdef __cplusplus extern "C" { #endif // __cplusplus -#ifdef LOG_TAG -#undef LOG_TAG -#endif -#define LOG_TAG "CAPI_VPNSVC" +/** + * @file vpn_service.h + */ -#ifndef API -#define API __attribute__ ((visibility("default"))) -#endif +/** + * @addtogroup CAPI_NETWORK_VPN_SERVICE_MODULE + * @{ + */ /** * @brief IPv4 address string length (includes end null character). @@ -60,10 +39,10 @@ extern "C" { #define VPNSVC_IP4_STRING_LEN 16 /** - * @brief TUN interface name length. + * @brief VPN interface name length. * @since_tizen 3.0 */ -#define VPNSVC_TUN_IF_NAME_LEN 16 +#define VPNSVC_VPN_IF_NAME_LEN 16 /** * @brief Session name string length (includes end null character). @@ -71,10 +50,6 @@ extern "C" { */ #define VPNSVC_SESSION_STRING_LEN 32 -#ifndef TIZEN_ERROR_VPNSVC -#define TIZEN_ERROR_VPNSVC -0x03200000 -#endif - /** * @brief Enumeration for VPN service error types. * @details Indicate formats of error type field @@ -94,23 +69,24 @@ typedef enum /** - * @brief The VPN tun interface handle. + * @brief The VPN interface handle. * @details This handle can be obtained by calling vpnsvc_init() and destroyed by calling vpnsvc_deinit(). * @since_tizen 3.0 * @see vpnsvc_init() * @see vpnsvc_deinit() */ -typedef void* vpnsvc_tun_h; +typedef void* vpnsvc_h; /** - * @brief Initializes TUN interface. - * @detail You should call vpnsvc_get_tun_name() for checking the actual initialized TUN interface name. (In case of duplicated interface name) + * @brief Initializes VPN interface. + * @detail You should call vpnsvc_get_if_name() for checking the actual initialized VPN interface name. (In case of duplicated interface name) * @since_tizen 3.0 * @privlevel public - * @privilege %http://tizen.org/privilege/vpnservice + * @privilege %http://tizen.org/privilege/vpnservice \n + * %http://tizen.org/privilege/internet * @remarks The @a handle should be released using vpnsvc_deinit(). - * @param[in] tun_name The interface name - * @param[out] handle The VPN tun interface handle + * @param[in] if_name The VPN interface name + * @param[out] handle The VPN interface handle * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter @@ -118,38 +94,38 @@ typedef void* vpnsvc_tun_h; * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon * @retval #VPNSVC_ERROR_PERMISSION_DENIED Permission Denied * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * @post Please call vpnsvc_deinit() if you want to de-initialize VPN tun interface. - * @post Please call vpnsvc_get_tun_fd() if you want to know the fd of tun interface. - * @post Please call vpnsvc_get_tun_index() if you want to know the fd of tun interface index. - * @post Please call vpnsvc_get_tun_name() if you want to know the name of tun interface. + * @post Please call vpnsvc_deinit() if you want to de-initialize VPN interface. + * @post Please call vpnsvc_get_if_fd() if you want to know the fd of VPN interface. + * @post Please call vpnsvc_get_if_index() if you want to know the fd of VPN interface index. + * @post Please call vpnsvc_get_if_name() if you want to know the name of VPN interface. * @see vpnsvc_deinit() - * @see vpnsvc_get_tun_fd() - * @see vpnsvc_get_tun_index() - * @see vpnsvc_get_tun_name() + * @see vpnsvc_get_if_fd() + * @see vpnsvc_get_if_index() + * @see vpnsvc_get_if_name() */ -API int vpnsvc_init(const char* tun_name, vpnsvc_tun_h *handle); +int vpnsvc_init(const char* if_name, vpnsvc_h *handle); /** - * @brief De-Initializes TUN interface. + * @brief De-Initializes VPN interface. * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle + * @param[in] handle The VPN interface handle * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * @pre Before calling this function, VPN tun interface should be initialized already. + * @pre Before calling this function, VPN interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_deinit(vpnsvc_tun_h handle); +int vpnsvc_deinit(vpnsvc_h handle); /** * @brief Protect a socket from VPN connections. * @details After protecting, data sent through this socket will go directly to the underlying network. * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle + * @param[in] handle The VPN interface handle * @param[in] socket_fd The opened socket file descriptor - * @param[in] dev_name The network interface name (i.e. eth0 or ppp0, not to confuse with tunXXX) through which the VPN is working + * @param[in] dev_name The network interface name (e.g., interface name such as eth0, ppp0, etc) through which the VPN is working * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter @@ -157,55 +133,12 @@ API int vpnsvc_deinit(vpnsvc_tun_h handle); * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported */ -API int vpnsvc_protect(vpnsvc_tun_h handle, int socket_fd, const char* dev_name); +int vpnsvc_protect(vpnsvc_h handle, int socket_fd, const char* dev_name); /** - * @brief Sets-up TUN interface and brings it up. Installs specified routes/DNS servers/DNS suffix. + * @brief Reads the data event on VPN interface descriptor. * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle - * @param[in] local_ip The local IP address - * @param[in] remote_ip The remote IP address - * @param[in] dest Destination address of the route - * @param[in] prefix The prefix of route - * @param[in] nr_routes The number of routes - * @param[in] dns_servers The list of DNS server names - Optional - * @param[in] nr_dns_servers The number of DNS server names - Optionl - * @param[in] dns_suffix The DNS suffix - Optional - * @return 0 on success. otherwise, a negative error value. - * @retval #VPNSVC_ERROR_NONE Success - * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon - * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * @pre The VPN tun interface should be initialized already. - * @post If you want to set interface down, please call vpnsvc_down(). - * @see vpnsvc_init() - * @see vpnsvc_down() - */ -API int vpnsvc_up(vpnsvc_tun_h handle, const char* local_ip, const char* remote_ip, - const char *dest[], int prefix[], size_t nr_routes, - const char** dns_servers, size_t nr_dns_servers, - const char* dns_suffix); - -/** - * @brief Brings the TUN interface down and restores original DNS servers/domains. - * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle - * @return 0 on success. otherwise, a negative error value. - * @retval #VPNSVC_ERROR_NONE Success - * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter - * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon - * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * @pre The VPN tun interface should be initialized already. - * @post Please call vpnsvc_deinit() if you want to de-initialize VPN tun interface. - * @see vpnsvc_up() - * @see vpnsvc_deinit() - */ -API int vpnsvc_down(vpnsvc_tun_h handle); - -/** - * @brief Reads the data event on TUN descriptor. - * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle + * @param[in] handle The VPN interface handle * @param[in] timeout_ms The value of timeout (milliseconds) * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success @@ -215,15 +148,14 @@ API int vpnsvc_down(vpnsvc_tun_h handle); * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported * @pre The VPN interface should be initialized already. * @see vpnsvc_init() - * @see vpnsvc_up() */ -API int vpnsvc_read(vpnsvc_tun_h handle, int timeout_ms); +int vpnsvc_read(vpnsvc_h handle, int timeout_ms); /** - * @brief Writes the data supplied into the TUN interface. + * @brief Writes the data supplied into the VPN interface. * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle - * @param[in] data Data writing to tun interface + * @param[in] handle The VPN interface handle + * @param[in] data Data writing to VPN interface * @param[in] size The size of data * @return On success, the number of bytes written is returned (zero indicates nothing was written). Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success @@ -232,19 +164,18 @@ API int vpnsvc_read(vpnsvc_tun_h handle, int timeout_ms); * @retval In case of negative error, please refer to standard posix write API's error code. * @pre The VPN interface should be initialized already. * @see vpnsvc_init() - * @see vpnsvc_up() */ -API int vpnsvc_write(vpnsvc_tun_h handle, const char* data, size_t size); +int vpnsvc_write(vpnsvc_h handle, const char* data, size_t size); /** * @brief Blocks all traffics except specified allowing networks. * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle + * @param[in] handle The VPN interface handle * @param[in] dest_vpn Allowing networks over VPN interface. - * @param[in] prefix_vpn The prefix of VPN interface + * @param[in] prefix_vpn The prefix of VPN interface, netmask length (also called a prefix). * @param[in] nr_allow_routes_vpn The number of allowing networks over VPN interface * @param[in] dest_orig Allowing networks over the original interface. - * @param[in] prefix_orig The prefix of Original interface. + * @param[in] prefix_orig The prefix of Original interface, netmask length (also called a prefix). * @param[in] nr_allow_routes_orig The number of allowing networks over the original interface * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success @@ -254,7 +185,7 @@ API int vpnsvc_write(vpnsvc_tun_h handle, const char* data, size_t size); * @post Please call vpnsvc_unblock_networks() if you want to allow all traffics. * @see vpnsvc_unblock_networks() */ -API int vpnsvc_block_networks(vpnsvc_tun_h handle, +int vpnsvc_block_networks(vpnsvc_h handle, const char *dest_vpn[], int prefix_vpn[], size_t nr_allow_routes_vpn, @@ -265,120 +196,120 @@ API int vpnsvc_block_networks(vpnsvc_tun_h handle, /** * @brief Removes any restrictions imposed by vpnsvc_block_networks(). * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle + * @param[in] handle The VPN interface handle * @return 0 on success. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported */ -API int vpnsvc_unblock_networks(vpnsvc_tun_h handle); +int vpnsvc_unblock_networks(vpnsvc_h handle); /** - * @brief Gets the fd of the VPN tun interface. + * @brief Gets the fd of the VPN interface. * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle - * @param[out] tun_fd The tun fd - * @return The fd value of VPN tun interface. Otherwise, a negative error value. + * @param[in] handle The VPN interface handle + * @param[out] if_fd The vpn interface fd + * @return The fd value of VPN interface. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported */ -API int vpnsvc_get_tun_fd(vpnsvc_tun_h handle, int* tun_fd); +int vpnsvc_get_if_fd(vpnsvc_h handle, int* if_fd); /** - * @brief Gets the index of VPN tun interface. + * @brief Gets the index of VPN interface. * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle - * @param[out] tun_index The tun index - * @return The index of the VPN tun interface. otherwise, a negative error value. + * @param[in] handle The VPN interface handle + * @param[out] if_index The VPN interface index + * @return The index of the VPN interface. otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * @pre Before calling this function, VPN tun interface should be initialized already. + * @pre Before calling this function, VPN interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_get_tun_index(vpnsvc_tun_h handle, int* tun_index); +int vpnsvc_get_if_index(vpnsvc_h handle, int* if_index); /** - * @brief Gets the name of VPN tun interface. + * @brief Gets the name of VPN interface. * @since_tizen 3.0 - * @remarks The @a tun_name should be released using free() - * @param[in] handle The VPN tun interface handle - * @param[out] tun_name The name of VPN tun interface name + * @remarks The @a if_name should be released using free() + * @param[in] handle The VPN interface handle + * @param[out] if_name The name of VPN interface name * @return 0 on success. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * @pre Before calling this function, VPN tun interface should be initialized already. + * @pre Before calling this function, VPN interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_get_tun_name(vpnsvc_tun_h handle, char** tun_name); +int vpnsvc_get_if_name(vpnsvc_h handle, char** if_name); /** - * @brief Sets the MTU of the VPN tun interface. + * @brief Sets the MTU of the VPN interface. * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle - * @param[in] mtu The MTU (Maximum Transmission Unit) value to be set for VPN tun interface. Default MTU size is 1500. + * @param[in] handle The VPN interface handle + * @param[in] mtu The MTU (Maximum Transmission Unit) value to be set for VPN interface. Default MTU size is 1500. * @return 0 on success. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * @pre Before calling this function, VPN tun interface should be initialized already. + * @pre Before calling this function, VPN interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_set_mtu(vpnsvc_tun_h handle, int mtu); +int vpnsvc_set_mtu(vpnsvc_h handle, int mtu); /** - * @brief Sets blocking mode of the file descriptor of VPN tun interface. + * @brief Sets blocking mode of the file descriptor of VPN interface. * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle - * @param[in] blocking The blocking mode flag; True = BLOCKING, False = NON_BLOCKING + * @param[in] handle The VPN interface handle + * @param[in] blocking The blocking mode flag; True = BLOCKING, False = NON_BLOCKING (Default : BLOCKING) * @return 0 on success. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_IO_ERROR Failed to set the blocking flags * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * @pre Before calling this function, VPN tun interface should be initialized already. + * @pre Before calling this function, VPN interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_set_blocking(vpnsvc_tun_h handle, bool blocking); +int vpnsvc_set_blocking(vpnsvc_h handle, bool blocking); /** - * @brief Sets the session name for the VPN. + * @brief Sets the session name for the VPN. (It will be displayed in system-managed dialogs and notifications.) * @since_tizen 3.0 - * @param[in] handle The VPN tun interface handle + * @param[in] handle The VPN interface handle * @param[in] session The Session Name * @return 0 on success. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * @pre Before calling this function, VPN tun interface should be initialized already. + * @pre Before calling this function, VPN interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_set_session(vpnsvc_tun_h handle, const char* session); +int vpnsvc_set_session(vpnsvc_h handle, const char* session); /** * @brief Gets the session name for the VPN. * @since_tizen 3.0 * @remarks The @a session should be released using free() - * @param[in] handle The VPN tun interface handle + * @param[in] handle The VPN interface handle * @param[out] session The Session Name returned * @return 0 on success. Otherwise, a negative error value. * @retval #VPNSVC_ERROR_NONE Success * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported - * @pre Before calling this function, VPN tun interface should be initialized already. + * @pre Before calling this function, VPN interface should be initialized already. * @see vpnsvc_init() */ -API int vpnsvc_get_session(vpnsvc_tun_h handle, char** session); - -#ifdef __cplusplus -} -#endif // __cplusplus +int vpnsvc_get_session(vpnsvc_h handle, char** session); /** * @} */ +#ifdef __cplusplus +} +#endif // __cplusplus + #endif /* __TIZEN_CAPI_VPN_SERVICE_H__ */ diff --git a/include/vpn_service_internal.h b/include/vpn_service_internal.h new file mode 100755 index 0000000..9df6386 --- /dev/null +++ b/include/vpn_service_internal.h @@ -0,0 +1,100 @@ +/* +opyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __TIZEN_VPN_SERVICE_INTERNAL_H__ +#define __TIZEN_VPN_SERVICE_INTERNAL_H__ + +/** + * @addtogroup CAPI_NETWORK_VPN_MODULE + * @{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @file vpn_service_internal.h + */ + +/** + * @internal + * @brief Sets-up TUN interface and brings it up. Installs specified routes/DNS servers/DNS suffix. + * @since_tizen 3.0 + * @privlevel platform + * @privilege %http://tizen.org/privilege/vpnservice.admin + * @param[in] handle The VPN tun interface handle + * @param[in] local_ip The local IP address + * @param[in] remote_ip The remote IP address + * @param[in] dest Destination address of the route + * @param[in] prefix The prefix of route + * @param[in] nr_routes The number of routes + * @param[in] dns_servers The list of DNS server names - Optional + * @param[in] nr_dns_servers The number of DNS server names - Optionl + * @param[in] dns_suffix The DNS suffix - Optional + * @return 0 on success. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon + * @retval #VPNSVC_ERROR_PERMISSION_DENIED Permission Denied + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * @pre The VPN tun interface should be initialized already. + * @post If you want to set interface down, please call vpnsvc_down(). + * @see vpnsvc_init() + * @see vpnsvc_down() + */ +int vpnsvc_up(vpnsvc_h handle, const char* local_ip, const char* remote_ip, + const char *dest[], int prefix[], size_t nr_routes, + const char** dns_servers, size_t nr_dns_servers, + const char* dns_suffix); + +/** + * @internal + * @brief Brings the TUN interface down and restores original DNS servers/domains. + * @since_tizen 3.0 + * @privlevel platform + * @privilege %http://tizen.org/privilege/vpnservice.admin + * @param[in] handle The VPN tun interface handle + * @return 0 on success. otherwise, a negative error value. + * @retval #VPNSVC_ERROR_NONE Success + * @retval #VPNSVC_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #VPNSVC_ERROR_IPC_FAILED Cannot connect to service daemon + * @retval #VPNSVC_ERROR_PERMISSION_DENIED Permission Denied + * @retval #VPNSVC_ERROR_NOT_SUPPORTED Not Supported + * @pre The VPN tun interface should be initialized already. + * @post Please call vpnsvc_deinit() if you want to de-initialize VPN tun interface. + * @see vpnsvc_up() + * @see vpnsvc_deinit() + */ +int vpnsvc_down(vpnsvc_h handle); + + +#ifdef __cplusplus +} +#endif // __cplusplus + +/** +* @} +*/ + +#endif /* __TIZEN_CAPI_VPN_SERVICE_H__ */ + + + + + diff --git a/test/vpn_service_test.c b/test/vpn_service_test.c index 10354cb..ac29509 100755 --- a/test/vpn_service_test.c +++ b/test/vpn_service_test.c @@ -38,7 +38,7 @@ perror("fgets() failed!!!");\ } while (0); -vpnsvc_tun_h handle = NULL; +vpnsvc_h handle = NULL; int test_vpnsvc_init() { @@ -56,19 +56,19 @@ int test_vpnsvc_init() char* result_name = NULL; printf("vpnsvc_init Succeed : %d\n", ret); - if (vpnsvc_get_tun_fd(handle, &int_value) == VPNSVC_ERROR_NONE) - printf("tun_fd : %d\n", int_value); + if (vpnsvc_get_if_fd(handle, &int_value) == VPNSVC_ERROR_NONE) + printf("if_fd : %d\n", int_value); else - printf("Fail to get tun_fd\n"); + printf("Fail to get if_fd\n"); - if (vpnsvc_get_tun_index(handle, &int_value) == VPNSVC_ERROR_NONE) - printf("tun_index : %d\n", int_value); + if (vpnsvc_get_if_index(handle, &int_value) == VPNSVC_ERROR_NONE) + printf("if_index : %d\n", int_value); else - printf("Fail to get tun_index\n"); + printf("Fail to get if_index\n"); - ret = vpnsvc_get_tun_name(handle, &result_name); + ret = vpnsvc_get_if_name(handle, &result_name); if (ret == VPNSVC_ERROR_NONE) - printf("tun_name : %s\n", result_name); + printf("if_name : %s\n", result_name); } return 0; -- 2.7.4