4 * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include "capi_vpn_service_private.h"
23 #include <system_info.h>
24 #include <gio/gunixfdlist.h>
29 #define LOG_TAG "CAPI_VPNSVC"
31 #define DBUS_REPLY_TIMEOUT (120 * 1000)
32 #define BUF_SIZE_FOR_ERR 100
33 #define MAX_NUM_ROUTES 255
37 static __thread GSList *vpn_handle_list = NULL;
38 static __thread bool is_feature_checked = false;
39 static __thread bool feature_supported = false;
41 int _vpnsvc_check_feature_supported(const char *feature_name)
43 if (is_feature_checked) {
44 if (!feature_supported) {
45 LOGE("%s feature is disabled", feature_name);
46 return VPNSVC_ERROR_NOT_SUPPORTED;
49 if (!system_info_get_platform_bool(feature_name, &feature_supported)) {
50 is_feature_checked = true;
51 if (!feature_supported) {
52 LOGE("%s feature is disabled", feature_name);
53 return VPNSVC_ERROR_NOT_SUPPORTED;
56 LOGE("Error - Feature getting from System Info");
57 return VPNSVC_ERROR_IO_ERROR;
61 return VPNSVC_ERROR_NONE;
64 static bool _vpn_check_handle_validity(vpnsvc_h vpnsvc)
69 if (g_slist_find(vpn_handle_list, vpnsvc) != NULL)
75 static bool _vpn_check_ip_address_validity(const char *addr)
77 if(strlen(addr) < VPNSVC_IP4_MIN_STRING_LEN
78 || strlen(addr) > VPNSVC_IP4_MAX_STRING_LEN)
84 static void _vpnsvc_init_vpnsvc_tun_s(vpnsvc_tun_s **s)
86 LOGD(" tun_s: %p", s);
88 if (s == NULL) return;
90 LOGE("Can't Initialize vpnsvc_tun_s: %p", *s);
93 *s = (vpnsvc_tun_s*)g_malloc0(sizeof(vpnsvc_tun_s));
95 if ((*s)->connection == NULL) {
96 GDBusConnection *connection = NULL;
99 #if !GLIB_CHECK_VERSION(2, 36, 0)
103 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
105 LOGE("Error creating Connection: %s", error->message);
108 LOGD("Created Connection: %p", connection);
109 (*s)->connection = connection;
113 /* Setting Default User Settings */
115 (*s)->mtu = _USER_SETTING_DEFAULT_MTU;
116 strncpy((*s)->session, _USER_SETTING_DEFAULT_SESSION, VPNSVC_SESSION_STRING_LEN);
117 (*s)->session[VPNSVC_SESSION_STRING_LEN-1] = '\0';
118 (*s)->dns_suffix = NULL;
121 static void _vpnsvc_deinit_vpnsvc_tun_s(vpnsvc_tun_s *s)
123 if (s == NULL) return;
126 s->connection = NULL;
132 memset(s->name, 0, VPNSVC_VPN_IFACE_NAME_LEN);
133 memset(s->session, 0, VPNSVC_SESSION_STRING_LEN);
134 memset(s->local_ip, 0, VPNSVC_IP4_STRING_LEN);
135 memset(s->remote_ip, 0, VPNSVC_IP4_STRING_LEN);
138 g_free(s->dns_suffix);
139 s->dns_suffix = NULL;
146 /*****************************************************************************
147 * Global Functions Definition
148 *****************************************************************************/
149 GVariant *_vpnsvc_invoke_dbus_method(GDBusConnection *connection,
150 const char *dest, const char *path,
151 const char *interface_name, const char *method,
152 GVariant *params, int *dbus_error)
154 GError *error = NULL;
155 GVariant *reply = NULL;
156 *dbus_error = VPNSVC_ERROR_NONE;
158 LOGD("Method Call() dest=%s path=%s iface=%s method=%s", dest, path, interface_name, method);
160 if (connection == NULL) {
161 LOGD("GDBusconnection is NULL");
162 *dbus_error = VPNSVC_ERROR_IO_ERROR;
166 reply = g_dbus_connection_call_sync(connection,
173 G_DBUS_CALL_FLAGS_NONE,
180 LOGE("g_dbus_connection_call_sync() failed "
181 "error [%d: %s]", error->code, error->message);
182 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
183 *dbus_error = VPNSVC_ERROR_PERMISSION_DENIED;
185 *dbus_error = VPNSVC_ERROR_IO_ERROR;
188 LOGE("g_dbus_connection_call_sync() failed");
189 *dbus_error = VPNSVC_ERROR_IPC_FAILED;
197 GVariant *_vpnsvc_invoke_dbus_method_with_fd(GDBusConnection *connection,
198 const char *dest, const char *path,
199 const char *interface_name, const char *method,
200 GVariant *params, int fd, int *dbus_error)
202 GError *error = NULL;
203 GVariant *reply = NULL;
204 GUnixFDList *fd_list = NULL;
205 *dbus_error = VPNSVC_ERROR_NONE;
207 LOGD("Method Call() dest=%s path=%s iface=%s method=%s fd=%d", dest, path, interface_name, method, fd);
209 if (connection == NULL) {
210 LOGD("GDBusconnection is NULL");
211 *dbus_error = VPNSVC_ERROR_IO_ERROR;
215 /* Setting the fd_list */
216 fd_list = g_unix_fd_list_new();
217 if (fd_list == NULL) {
218 LOGE("g_unix_fd_list_new() failed!");
222 g_unix_fd_list_append(fd_list, fd, &error);
224 LOGE("g_unix_fd_list_append() failed"
225 "error [%d: %s]", error->code, error->message);
226 *dbus_error = VPNSVC_ERROR_IO_ERROR;
231 reply = g_dbus_connection_call_with_unix_fd_list_sync(connection,
238 G_DBUS_CALL_FLAGS_NONE,
247 LOGE("g_dbus_connection_call_with_unix_fd_list_sync() failed "
248 "error [%d: %s]", error->code, error->message);
249 if (error->code == G_DBUS_ERROR_ACCESS_DENIED)
250 *dbus_error = VPNSVC_ERROR_PERMISSION_DENIED;
252 *dbus_error = VPNSVC_ERROR_IO_ERROR;
255 LOGE("g_dbus_connection_call_with_unix_fd_list_sync() failed");
256 *dbus_error = VPNSVC_ERROR_IPC_FAILED;
265 EXPORT_API int vpnsvc_create(vpnsvc_h *handle)
267 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
269 LOGD("enter vpnsvc_create");
271 /* parameter check */
272 if (handle == NULL) {
273 LOGE("handle is a NULL");
274 return VPNSVC_ERROR_INVALID_PARAMETER;
277 if (_vpn_check_handle_validity(*handle)) {
278 LOGE("Invalid parameter");
279 return VPNSVC_ERROR_INVALID_PARAMETER;
282 vpnsvc_tun_s *tmp_s = NULL;
283 _vpnsvc_init_vpnsvc_tun_s(&tmp_s);
285 LOGD("handle : %p", (*handle));
287 return VPNSVC_ERROR_NONE;
290 EXPORT_API int vpnsvc_destroy(vpnsvc_h handle)
292 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
294 int result = VPNSVC_ERROR_NONE;
295 vpnsvc_tun_s *tun_s = NULL;
297 /* parameter check */
298 if (handle == NULL) {
299 LOGE("handle is a NULL");
300 return VPNSVC_ERROR_INVALID_PARAMETER;
302 tun_s = (vpnsvc_tun_s*)handle;
304 LOGD("enter vpnsvc_destroy");
306 _vpnsvc_deinit_vpnsvc_tun_s(tun_s);
311 EXPORT_API int vpnsvc_init(const char* iface_name, vpnsvc_h *handle)
313 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
315 int result = VPNSVC_ERROR_NONE;
319 LOGD("enter vpnsvc_init, iface_name : %s", iface_name);
321 /* parameter check */
322 if (iface_name == NULL || strlen(iface_name) <= 0) {
323 LOGE("iface_name is a NULL");
324 return VPNSVC_ERROR_INVALID_PARAMETER;
325 } else if (handle == NULL || _vpn_check_handle_validity(*handle)) {
326 LOGE("Invalid parameter");
327 return VPNSVC_ERROR_INVALID_PARAMETER;
330 vpnsvc_tun_s *tmp_s = NULL;
331 _vpnsvc_init_vpnsvc_tun_s(&tmp_s);
333 if ((iface_fd = open("/dev/net/tun", O_RDWR)) < 0) {
334 LOGE("tun device open fail\n");
335 _vpnsvc_deinit_vpnsvc_tun_s(tmp_s);
336 return VPNSVC_ERROR_IO_ERROR;
339 LOGD("client iface_fd : %d", iface_fd);
341 op = _vpnsvc_invoke_dbus_method(tmp_s->connection,
342 NETCONFIG_SERVICE_NAME,
343 NETCONFIG_NETWORK_PATH,
344 NETCONFIG_NETWORK_INTERFACE,
345 "CheckInternetPrivilege",
349 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED) {
351 _vpnsvc_deinit_vpnsvc_tun_s(tmp_s);
352 return VPNSVC_ERROR_PERMISSION_DENIED;
355 op = _vpnsvc_invoke_dbus_method_with_fd(tmp_s->connection,
356 NETCONFIG_SERVICE_NAME,
357 NETCONFIG_VPNSVC_PATH,
358 NETCONFIG_VPNSVC_INTERFACE_NAME,
360 g_variant_new("(su)", iface_name, strlen(iface_name)),
364 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED) {
366 _vpnsvc_deinit_vpnsvc_tun_s(tmp_s);
367 return VPNSVC_ERROR_PERMISSION_DENIED;
372 _vpnsvc_deinit_vpnsvc_tun_s(tmp_s);
373 return VPNSVC_ERROR_IPC_FAILED;
378 g_variant_get(op, "(iis)", &result, &tmp_index, &tmp_name);
379 if (result != VPNSVC_ERROR_NONE) {
380 LOGE("vpnsvc_init() failed");
382 _vpnsvc_deinit_vpnsvc_tun_s(tmp_s);
383 result = VPNSVC_ERROR_PERMISSION_DENIED;
385 LOGD("vpnsvc_init() succeed");
386 tmp_s->fd = iface_fd; /* client fd must be set */
387 tmp_s->index = tmp_index;
388 strncpy(tmp_s->name, tmp_name, VPNSVC_VPN_IFACE_NAME_LEN);
389 tmp_s->name[VPNSVC_VPN_IFACE_NAME_LEN-1] = '\0';
391 vpn_handle_list = g_slist_prepend(vpn_handle_list, *handle);
392 LOGD("handle : %p, handle->fd : %d, handle->index : %d, handle->name : %s",
393 (*handle), ((vpnsvc_tun_s*)*handle)->fd, ((vpnsvc_tun_s*)*handle)->index, ((vpnsvc_tun_s*)*handle)->name);
403 EXPORT_API int vpnsvc_deinit(vpnsvc_h handle)
405 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
407 int result = VPNSVC_ERROR_NONE;
409 vpnsvc_tun_s *tun_s = NULL;
410 char buf[BUF_SIZE_FOR_ERR] = { 0 };
412 /* parameter check */
413 if (handle == NULL) {
414 LOGE("handle is a NULL");
415 return VPNSVC_ERROR_INVALID_PARAMETER;
417 tun_s = (vpnsvc_tun_s*)handle;
419 LOGD("enter vpnsvc_deinit, iface_fd : %d", tun_s->fd);
422 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
423 NETCONFIG_SERVICE_NAME,
424 NETCONFIG_NETWORK_PATH,
425 NETCONFIG_NETWORK_INTERFACE,
426 "CheckInternetPrivilege",
430 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
431 return VPNSVC_ERROR_PERMISSION_DENIED;
433 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
434 NETCONFIG_SERVICE_NAME,
435 NETCONFIG_VPNSVC_PATH,
436 NETCONFIG_VPNSVC_INTERFACE_NAME,
438 g_variant_new("(s)", tun_s->name),
441 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
442 return VPNSVC_ERROR_PERMISSION_DENIED;
445 return VPNSVC_ERROR_IPC_FAILED;
447 g_variant_get(op, "(i)", &result);
448 if (result != VPNSVC_ERROR_NONE)
449 LOGE("vpn_deinit() failed");
451 LOGD("vpn_deinit() succeed");
454 if (close(tun_s->fd) != 0) {
455 LOGE("tun fd close : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
456 return VPNSVC_ERROR_IO_ERROR;
458 LOGD("tun fd close success");
460 /* free allocared handle memory */
461 vpn_handle_list = g_slist_remove(vpn_handle_list, tun_s);
462 _vpnsvc_deinit_vpnsvc_tun_s(tun_s);
468 EXPORT_API int vpnsvc_protect(vpnsvc_h handle, int socket_fd, const char* iface_name)
470 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
472 int result = VPNSVC_ERROR_NONE;
474 vpnsvc_tun_s *tun_s = NULL;
476 /* parameter check */
477 if (handle == NULL || socket_fd < 0 || iface_name == NULL)
478 return VPNSVC_ERROR_INVALID_PARAMETER;
480 tun_s = (vpnsvc_tun_s*)handle;
482 LOGD("enter vpnsvc_protect, socket : %d, dev_name : %s", socket_fd, iface_name);
484 if (tun_s->connection == NULL) {
485 LOGE("Connection Object is NULL");
486 return VPNSVC_ERROR_INVALID_PARAMETER;
489 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
490 NETCONFIG_SERVICE_NAME,
491 NETCONFIG_NETWORK_PATH,
492 NETCONFIG_NETWORK_INTERFACE,
493 "CheckInternetPrivilege",
497 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
498 return VPNSVC_ERROR_PERMISSION_DENIED;
500 /* call vpnsvc_protect */
501 op = _vpnsvc_invoke_dbus_method_with_fd(tun_s->connection,
502 NETCONFIG_SERVICE_NAME,
503 NETCONFIG_VPNSVC_PATH,
504 NETCONFIG_VPNSVC_INTERFACE_NAME,
506 g_variant_new("(s)", iface_name),
510 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
511 return VPNSVC_ERROR_PERMISSION_DENIED;
514 return VPNSVC_ERROR_IPC_FAILED;
516 g_variant_get(op, "(i)", &result);
518 if (result != VPNSVC_ERROR_NONE)
519 LOGE("vpn_protect() failed");
521 LOGD("vpn_protect() succeed");
527 EXPORT_API int vpnsvc_up(vpnsvc_h handle)
529 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
531 int result = VPNSVC_ERROR_NONE;
533 vpnsvc_tun_s *tun_s = NULL;
535 /* parameter check */
536 if (handle == NULL) {
537 LOGE("handle is a NULL");
538 return VPNSVC_ERROR_INVALID_PARAMETER;
540 tun_s = (vpnsvc_tun_s*)handle;
542 LOGD("enter vpnsvc_up");
544 if (tun_s->connection == NULL) {
545 LOGE("Connection Object is NULL");
546 return VPNSVC_ERROR_INVALID_PARAMETER;
547 } else if (tun_s->name[0] == 0) {
548 LOGE("invalid handle");
549 return VPNSVC_ERROR_INVALID_PARAMETER;
552 LOGD("iface_index %d, iface_name %s", tun_s->index, tun_s->name);
554 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
555 NETCONFIG_SERVICE_NAME,
556 NETCONFIG_NETWORK_PATH,
557 NETCONFIG_NETWORK_INTERFACE,
558 "CheckInternetPrivilege",
562 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
563 return VPNSVC_ERROR_PERMISSION_DENIED;
565 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
566 NETCONFIG_SERVICE_NAME,
567 NETCONFIG_VPNSVC_PATH,
568 NETCONFIG_VPNSVC_INTERFACE_NAME,
570 g_variant_new("(s)", tun_s->name),
573 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
574 return VPNSVC_ERROR_PERMISSION_DENIED;
577 return VPNSVC_ERROR_IPC_FAILED;
579 g_variant_get(op, "(i)", &result);
580 if (result != VPNSVC_ERROR_NONE)
581 LOGE("vpn_up() failed");
583 LOGD("vpn_up() succeed");
589 EXPORT_API int vpnsvc_down(vpnsvc_h handle)
591 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
593 int result = VPNSVC_ERROR_NONE;
595 vpnsvc_tun_s *tun_s = NULL;
597 /* parameter check */
598 if (handle == NULL) {
599 LOGE("handle is a NULL");
600 return VPNSVC_ERROR_INVALID_PARAMETER;
602 tun_s = (vpnsvc_tun_s*)handle;
604 LOGD("enter vpnsvc_down");
606 if (tun_s->connection == NULL) {
607 LOGE("Connection Object is NULL");
608 return VPNSVC_ERROR_INVALID_PARAMETER;
611 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
612 NETCONFIG_SERVICE_NAME,
613 NETCONFIG_NETWORK_PATH,
614 NETCONFIG_NETWORK_INTERFACE,
615 "CheckInternetPrivilege",
619 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
620 return VPNSVC_ERROR_PERMISSION_DENIED;
622 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
623 NETCONFIG_SERVICE_NAME,
624 NETCONFIG_VPNSVC_PATH,
625 NETCONFIG_VPNSVC_INTERFACE_NAME,
627 g_variant_new("(s)", tun_s->name),
630 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
631 return VPNSVC_ERROR_PERMISSION_DENIED;
634 return VPNSVC_ERROR_IPC_FAILED;
636 g_variant_get(op, "(i)", &result);
637 if (result != VPNSVC_ERROR_NONE)
638 LOGE("vpn_down() failed");
640 LOGD("vpn_down() succeed");
647 /* this API must not be use IPC */
648 EXPORT_API int vpnsvc_read(vpnsvc_h handle, int timeout_ms)
650 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
655 vpnsvc_tun_s *tun_s = NULL;
657 /* parameter check */
658 if (handle == NULL) {
659 LOGE("handle is a NULL");
660 return VPNSVC_ERROR_INVALID_PARAMETER;
663 if (timeout_ms < 0) {
664 LOGE("handle is a NULL");
665 return VPNSVC_ERROR_INVALID_PARAMETER;
668 tun_s = (vpnsvc_tun_s*)handle;
670 if (tun_s->fd <= 0) {
671 LOGE("invalid handle");
672 return VPNSVC_ERROR_INVALID_PARAMETER;
675 /* listen for events */
677 FD_SET(tun_s->fd, &read_set);
679 tv.tv_usec = timeout_ms*1000;
680 retVal = select(tun_s->fd +1, &read_set, NULL, NULL, &tv);
683 LOGD("Data is available now.\n");
684 ret = VPNSVC_ERROR_NONE;
685 } else if (retVal == 0) {
686 LOGD("No data within %d ms\n", timeout_ms);
687 ret = VPNSVC_ERROR_TIMEOUT;
689 LOGE("select failed\n");
690 ret = VPNSVC_ERROR_IO_ERROR;
696 /* this API must not be use IPC */
697 EXPORT_API int vpnsvc_write(vpnsvc_h handle, const char* data, size_t size)
699 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
701 vpnsvc_tun_s *tun_s = NULL;
703 /* parameter check */
704 if (handle == NULL) {
705 LOGE("handle is a NULL");
706 return VPNSVC_ERROR_INVALID_PARAMETER;
709 tun_s = (vpnsvc_tun_s*)handle;
711 if (tun_s->fd <= 0) {
712 LOGE("invalid handle");
713 return VPNSVC_ERROR_INVALID_PARAMETER;
716 return write(tun_s->fd, data, size);
720 EXPORT_API int vpnsvc_block_networks(vpnsvc_h handle,
721 char* routes_dest_vpn_addr[],
722 int routes_vpn_prefix[],
723 size_t num_allow_routes_vpn,
724 char* routes_dest_orig_addr[],
725 int routes_orig_prefix[],
726 size_t num_allow_routes_orig)
729 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
731 int result = VPNSVC_ERROR_NONE;
733 GVariantBuilder nets_builder;
735 GVariant *nets_param_vpn;
736 GVariant *nets_param_orig;
737 vpnsvc_tun_s *tun_s = NULL;
739 /* parameter check */
740 if (handle == NULL) {
741 LOGE("handle is a NULL");
742 return VPNSVC_ERROR_INVALID_PARAMETER;
745 if (num_allow_routes_vpn > MAX_NUM_ROUTES || num_allow_routes_orig > MAX_NUM_ROUTES) {
746 LOGE("too many routes");
747 return VPNSVC_ERROR_INVALID_PARAMETER;
750 tun_s = (vpnsvc_tun_s*)handle;
752 LOGD("enter vpnsvc_block_networks");
754 if (tun_s->connection == NULL) {
755 LOGE("Connection Object is NULL");
756 return VPNSVC_ERROR_INVALID_PARAMETER;
758 /* make a route parameter for allowed VPN interface routes */
759 g_variant_builder_init(&nets_builder, G_VARIANT_TYPE("a{si}"));
760 for (i = 0 ;i < num_allow_routes_vpn ; i++) {
761 g_variant_builder_add(&nets_builder, "{si}", routes_dest_vpn_addr[i], routes_vpn_prefix[i]);
762 LOGD("dest_vpn[%d] : %s", i, routes_dest_vpn_addr[i]);
763 LOGD("prefix_vpn[%d] : %d", i, routes_vpn_prefix[i]);
765 nets_param_vpn = g_variant_builder_end(&nets_builder);
767 /* make a route parameter for allowed Original interface Routes */
768 g_variant_builder_init(&nets_builder, G_VARIANT_TYPE("a{si}"));
769 for (i = 0 ;i < num_allow_routes_orig ; i++) {
770 g_variant_builder_add(&nets_builder, "{si}", routes_dest_orig_addr[i], routes_orig_prefix[i]);
771 LOGD("dest_orig[%d] : %s", i, routes_dest_orig_addr[i]);
772 LOGD("prefix_orig[%d] : %d", i, routes_orig_prefix[i]);
774 nets_param_orig = g_variant_builder_end(&nets_builder);
776 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
777 NETCONFIG_SERVICE_NAME,
778 NETCONFIG_NETWORK_PATH,
779 NETCONFIG_NETWORK_INTERFACE,
780 "CheckInternetPrivilege",
784 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
785 return VPNSVC_ERROR_PERMISSION_DENIED;
787 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
788 NETCONFIG_SERVICE_NAME,
789 NETCONFIG_VPNSVC_PATH,
790 NETCONFIG_VPNSVC_INTERFACE_NAME,
791 "vpn_block_networks",
792 g_variant_new("(vuvu)", nets_param_vpn, num_allow_routes_vpn,
793 nets_param_orig, num_allow_routes_orig),
796 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
797 return VPNSVC_ERROR_PERMISSION_DENIED;
800 return VPNSVC_ERROR_IPC_FAILED;
802 g_variant_get(op, "(i)", &result);
803 if (result != VPNSVC_ERROR_NONE)
804 LOGE("vpn_block_networks() failed");
806 LOGD("vpn_block_networks() succeed");
812 EXPORT_API int vpnsvc_unblock_networks(vpnsvc_h handle)
814 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
816 int result = VPNSVC_ERROR_NONE;
818 vpnsvc_tun_s *tun_s = NULL;
820 /* parameter check */
821 if (handle == NULL) {
822 LOGE("handle is a NULL");
823 return VPNSVC_ERROR_INVALID_PARAMETER;
825 tun_s = (vpnsvc_tun_s*)handle;
827 LOGD("enter vpnsvc_unblock_networks");
828 if (tun_s->connection == NULL) {
829 LOGE("Connection Object is NULL");
830 return VPNSVC_ERROR_INVALID_PARAMETER;
833 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
834 NETCONFIG_SERVICE_NAME,
835 NETCONFIG_NETWORK_PATH,
836 NETCONFIG_NETWORK_INTERFACE,
837 "CheckInternetPrivilege",
841 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
842 return VPNSVC_ERROR_PERMISSION_DENIED;
844 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
845 NETCONFIG_SERVICE_NAME,
846 NETCONFIG_VPNSVC_PATH,
847 NETCONFIG_VPNSVC_INTERFACE_NAME,
848 "vpn_unblock_networks",
852 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
853 return VPNSVC_ERROR_PERMISSION_DENIED;
856 return VPNSVC_ERROR_IPC_FAILED;
858 g_variant_get(op, "(i)", &result);
859 if (result != VPNSVC_ERROR_NONE)
860 LOGE("vpn_unblock_networks() failed");
862 LOGD("vpn_unblock_networks() succeed");
868 EXPORT_API int vpnsvc_update_settings(vpnsvc_h handle)
870 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
872 int result = VPNSVC_ERROR_NONE;
874 vpnsvc_tun_s *tun_s = NULL;
876 /* parameter check */
877 if (handle == NULL) {
878 LOGE("handle is a NULL");
879 return VPNSVC_ERROR_INVALID_PARAMETER;
882 tun_s = (vpnsvc_tun_s*)handle;
884 if (!_vpn_check_ip_address_validity(tun_s->local_ip))
885 return VPNSVC_ERROR_INVALID_PARAMETER;
887 if (!_vpn_check_ip_address_validity(tun_s->remote_ip))
888 return VPNSVC_ERROR_INVALID_PARAMETER;
890 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
891 NETCONFIG_SERVICE_NAME,
892 NETCONFIG_VPNSVC_PATH,
893 NETCONFIG_VPNSVC_INTERFACE_NAME,
894 "vpn_update_settings",
895 g_variant_new("(issu)", tun_s->index, tun_s->local_ip, tun_s->remote_ip, tun_s->mtu),
897 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
898 return VPNSVC_ERROR_PERMISSION_DENIED;
901 return VPNSVC_ERROR_IPC_FAILED;
903 g_variant_get(op, "(i)", &result);
904 if (result != VPNSVC_ERROR_NONE)
905 LOGE("vpn_update_settings() failed");
907 LOGD("vpn_update_settings() succeed");
913 EXPORT_API int vpnsvc_get_iface_fd(vpnsvc_h handle, int* iface_fd)
915 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
917 vpnsvc_tun_s *tun_s = NULL;
919 /* parameter check */
920 if (handle == NULL || iface_fd == NULL) {
921 LOGE("Invalid parameter");
922 return VPNSVC_ERROR_INVALID_PARAMETER;
924 tun_s = (vpnsvc_tun_s*)handle;
926 if (tun_s->fd <= 0) {
927 LOGE("invalid handle");
928 return VPNSVC_ERROR_INVALID_PARAMETER;
931 *iface_fd = (int)(tun_s->fd);
933 return VPNSVC_ERROR_NONE;
936 EXPORT_API int vpnsvc_get_iface_index(vpnsvc_h handle, int* iface_index)
938 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
940 vpnsvc_tun_s *tun_s = NULL;
942 /* parameter check */
943 if (handle == NULL || iface_index == NULL) {
944 LOGE("Invalid parameter");
945 return VPNSVC_ERROR_INVALID_PARAMETER;
948 tun_s = (vpnsvc_tun_s*)handle;
950 if (tun_s->index <= 0) {
951 LOGE("invalid handle");
952 return VPNSVC_ERROR_INVALID_PARAMETER;
955 *iface_index = (int)(tun_s->index);
957 return VPNSVC_ERROR_NONE;
960 EXPORT_API int vpnsvc_get_iface_name(vpnsvc_h handle, char** iface_name)
962 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
964 vpnsvc_tun_s *tun_s = NULL;
965 char la_iface_name[VPNSVC_VPN_IFACE_NAME_LEN + 1] = { 0, };
967 /* parameter check */
968 if (handle == NULL || iface_name == NULL) {
969 LOGE("handle is a NULL");
970 return VPNSVC_ERROR_INVALID_PARAMETER;
972 tun_s = (vpnsvc_tun_s*)handle;
974 if (strlen(tun_s->name) <= 0) {
975 LOGE("invalid handle");
976 return VPNSVC_ERROR_INVALID_PARAMETER;
979 g_strlcpy(la_iface_name, tun_s->name, VPNSVC_VPN_IFACE_NAME_LEN + 1);
980 *iface_name = g_strdup(la_iface_name);
982 return VPNSVC_ERROR_NONE;
985 EXPORT_API int vpnsvc_set_iface_name(vpnsvc_h handle, const char *iface_name)
987 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
989 vpnsvc_tun_s *tun_s = NULL;
991 /* parameter check */
992 if (handle == NULL) {
993 LOGE("handle is a NULL");
994 return VPNSVC_ERROR_INVALID_PARAMETER;
996 tun_s = (vpnsvc_tun_s*)handle;
998 if (iface_name == NULL) {
999 LOGE("Remote IP address is NULL");
1000 return VPNSVC_ERROR_INVALID_PARAMETER;
1003 g_strlcpy(tun_s->name, iface_name, VPNSVC_VPN_IFACE_NAME_LEN);
1005 return VPNSVC_ERROR_NONE;
1009 EXPORT_API int vpnsvc_set_mtu(vpnsvc_h handle, int mtu)
1011 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
1013 int result = VPNSVC_ERROR_NONE;
1014 vpnsvc_tun_s *tun_s = NULL;
1016 /* parameter check */
1017 if (handle == NULL) {
1018 LOGE("handle is a NULL");
1019 return VPNSVC_ERROR_INVALID_PARAMETER;
1021 tun_s = (vpnsvc_tun_s*)handle;
1024 LOGE("Incorrect MTU Size = %d", mtu);
1025 return VPNSVC_ERROR_INVALID_PARAMETER;
1033 EXPORT_API int vpnsvc_set_blocking(vpnsvc_h handle, bool blocking)
1035 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
1037 vpnsvc_tun_s *tun_s = NULL;
1039 /* parameter check */
1040 if (handle == NULL) {
1041 LOGE("handle is a NULL");
1042 return VPNSVC_ERROR_INVALID_PARAMETER;
1044 tun_s = (vpnsvc_tun_s*)handle;
1048 if (tun_s->fd <= 0) {
1049 LOGE("The Tunnel File Descriptor fd = %d", tun_s->fd);
1050 return VPNSVC_ERROR_INVALID_PARAMETER;
1053 flags = fcntl(tun_s->fd, F_GETFL);
1055 LOGD("File Descriptor Flags GET Failed fd = %d", tun_s->fd);
1059 if (blocking == false)
1060 flags = flags | O_NONBLOCK;
1062 flags = flags & (~O_NONBLOCK);
1064 if (fcntl(tun_s->fd, F_SETFL, flags) < 0) {
1065 LOGE("Failed fd = %d F_SETFL(flags) = %d", tun_s->fd, flags);
1066 return VPNSVC_ERROR_IO_ERROR;
1068 return VPNSVC_ERROR_NONE;
1071 EXPORT_API int vpnsvc_set_session(vpnsvc_h handle, const char* session)
1073 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
1075 vpnsvc_tun_s *tun_s = NULL;
1077 /* parameter check */
1078 if (handle == NULL) {
1079 LOGE("handle is a NULL");
1080 return VPNSVC_ERROR_INVALID_PARAMETER;
1082 tun_s = (vpnsvc_tun_s*)handle;
1084 if (session == NULL) {
1085 LOGE("Session Name string is NULL");
1086 return VPNSVC_ERROR_INVALID_PARAMETER;
1089 if (strlen(session) >= VPNSVC_SESSION_STRING_LEN) {
1090 LOGE("Session name is longer than 32");
1091 return VPNSVC_ERROR_INVALID_PARAMETER;
1094 strncpy(tun_s->session, session, VPNSVC_SESSION_STRING_LEN);
1095 tun_s->session[VPNSVC_SESSION_STRING_LEN - 1] = '\0';
1097 return VPNSVC_ERROR_NONE;
1100 EXPORT_API int vpnsvc_get_session(vpnsvc_h handle, char** session)
1102 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
1104 vpnsvc_tun_s *tun_s = NULL;
1105 char la_session[VPNSVC_SESSION_STRING_LEN + 1] = { 0, };
1107 /* parameter check */
1108 if (handle == NULL) {
1109 LOGE("handle is a NULL");
1110 return VPNSVC_ERROR_INVALID_PARAMETER;
1112 tun_s = (vpnsvc_tun_s*)handle;
1114 if (session == NULL) {
1115 LOGE("Session Name string is NULL");
1116 return VPNSVC_ERROR_INVALID_PARAMETER;
1119 g_strlcpy(la_session, tun_s->session, VPNSVC_SESSION_STRING_LEN + 1);
1120 *session = g_strdup(la_session);
1122 return VPNSVC_ERROR_NONE;
1125 EXPORT_API int vpnsvc_set_local_ip_address(vpnsvc_h handle, const char *local_ip)
1127 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
1129 vpnsvc_tun_s *tun_s = NULL;
1131 /* parameter check */
1132 if (handle == NULL) {
1133 LOGE("handle is a NULL");
1134 return VPNSVC_ERROR_INVALID_PARAMETER;
1136 tun_s = (vpnsvc_tun_s*)handle;
1138 if (local_ip == NULL) {
1139 LOGE("Local IP address is NULL");
1140 return VPNSVC_ERROR_INVALID_PARAMETER;
1143 g_strlcpy(tun_s->local_ip, local_ip, VPNSVC_IP4_STRING_LEN);
1145 return VPNSVC_ERROR_NONE;
1148 EXPORT_API int vpnsvc_set_remote_ip_address(vpnsvc_h handle, const char *remote_ip)
1150 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
1152 vpnsvc_tun_s *tun_s = NULL;
1154 /* parameter check */
1155 if (handle == NULL) {
1156 LOGE("handle is a NULL");
1157 return VPNSVC_ERROR_INVALID_PARAMETER;
1159 tun_s = (vpnsvc_tun_s*)handle;
1161 if (remote_ip == NULL) {
1162 LOGE("Remote IP address is NULL");
1163 return VPNSVC_ERROR_INVALID_PARAMETER;
1166 g_strlcpy(tun_s->remote_ip, remote_ip, VPNSVC_IP4_STRING_LEN);
1168 return VPNSVC_ERROR_NONE;
1171 EXPORT_API int vpnsvc_add_route(vpnsvc_h handle, const char *route_address, int prefix)
1173 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
1175 int result = VPNSVC_ERROR_NONE;
1177 vpnsvc_tun_s *tun_s = NULL;
1179 /* parameter check */
1180 if (handle == NULL) {
1181 LOGE("handle is a NULL");
1182 return VPNSVC_ERROR_INVALID_PARAMETER;
1184 tun_s = (vpnsvc_tun_s*)handle;
1186 if (route_address == NULL) {
1187 LOGE("remove_address is NULL");
1188 return VPNSVC_ERROR_INVALID_PARAMETER;
1191 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
1192 NETCONFIG_SERVICE_NAME,
1193 NETCONFIG_VPNSVC_PATH,
1194 NETCONFIG_VPNSVC_INTERFACE_NAME,
1196 g_variant_new("(ssi)", tun_s->name, route_address, prefix),
1198 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
1199 return VPNSVC_ERROR_PERMISSION_DENIED;
1202 return VPNSVC_ERROR_IPC_FAILED;
1204 g_variant_get(op, "(i)", &result);
1205 if (result != VPNSVC_ERROR_NONE)
1206 LOGE("vpn_add_route() failed");
1208 LOGD("vpn_add_route() succeed");
1214 EXPORT_API int vpnsvc_remove_route(vpnsvc_h handle, const char *route_address, int prefix)
1216 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
1218 int result = VPNSVC_ERROR_NONE;
1220 vpnsvc_tun_s *tun_s = NULL;
1222 /* parameter check */
1223 if (handle == NULL) {
1224 LOGE("handle is a NULL");
1225 return VPNSVC_ERROR_INVALID_PARAMETER;
1227 tun_s = (vpnsvc_tun_s*)handle;
1229 if (route_address == NULL) {
1230 LOGE("route_address is NULL");
1231 return VPNSVC_ERROR_INVALID_PARAMETER;
1234 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
1235 NETCONFIG_SERVICE_NAME,
1236 NETCONFIG_VPNSVC_PATH,
1237 NETCONFIG_VPNSVC_INTERFACE_NAME,
1239 g_variant_new("(ssi)", tun_s->name, route_address, prefix),
1241 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
1242 return VPNSVC_ERROR_PERMISSION_DENIED;
1245 return VPNSVC_ERROR_IPC_FAILED;
1247 g_variant_get(op, "(i)", &result);
1248 if (result != VPNSVC_ERROR_NONE)
1249 LOGE("vpn_remove_route() failed");
1251 LOGD("vpn_remove_route() succeed");
1257 EXPORT_API int vpnsvc_add_dns_server(vpnsvc_h handle, const char *dns_server)
1259 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
1261 int result = VPNSVC_ERROR_NONE;
1263 vpnsvc_tun_s *tun_s = NULL;
1265 /* parameter check */
1266 if (handle == NULL) {
1267 LOGE("handle is a NULL");
1268 return VPNSVC_ERROR_INVALID_PARAMETER;
1270 tun_s = (vpnsvc_tun_s*)handle;
1272 if (dns_server == NULL) {
1273 LOGE("dns_server is NULL");
1274 return VPNSVC_ERROR_INVALID_PARAMETER;
1277 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
1278 NETCONFIG_SERVICE_NAME,
1279 NETCONFIG_VPNSVC_PATH,
1280 NETCONFIG_VPNSVC_INTERFACE_NAME,
1281 "vpn_add_dns_server",
1282 g_variant_new("(ss)", tun_s->name, dns_server),
1284 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
1285 return VPNSVC_ERROR_PERMISSION_DENIED;
1288 return VPNSVC_ERROR_IPC_FAILED;
1290 g_variant_get(op, "(i)", &result);
1291 if (result != VPNSVC_ERROR_NONE)
1292 LOGE("vpn_add_dns_server() failed");
1294 LOGD("vpn_add_dns_server() succeed");
1300 EXPORT_API int vpnsvc_remove_dns_server(vpnsvc_h handle, const char *dns_server)
1302 CHECK_FEATURE_SUPPORTED(VPN_SERVICE_FEATURE);
1304 int result = VPNSVC_ERROR_NONE;
1306 vpnsvc_tun_s *tun_s = NULL;
1308 /* parameter check */
1309 if (handle == NULL) {
1310 LOGE("handle is a NULL");
1311 return VPNSVC_ERROR_INVALID_PARAMETER;
1313 tun_s = (vpnsvc_tun_s*)handle;
1315 if (dns_server == NULL) {
1316 LOGE("dns_server is NULL");
1317 return VPNSVC_ERROR_INVALID_PARAMETER;
1319 op = _vpnsvc_invoke_dbus_method(tun_s->connection,
1320 NETCONFIG_SERVICE_NAME,
1321 NETCONFIG_VPNSVC_PATH,
1322 NETCONFIG_VPNSVC_INTERFACE_NAME,
1323 "vpn_remove_dns_server",
1324 g_variant_new("(ss)", tun_s->name, dns_server),
1326 if (dbus_result == VPNSVC_ERROR_PERMISSION_DENIED)
1327 return VPNSVC_ERROR_PERMISSION_DENIED;
1330 return VPNSVC_ERROR_IPC_FAILED;
1332 g_variant_get(op, "(i)", &result);
1333 if (result != VPNSVC_ERROR_NONE)
1334 LOGE("vpn_remove_dns_server() failed");
1336 LOGD("vpn_remove_dns_server() succeed");