2 * Network Configuration - VPN Service Internal Module
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.
22 #include <net/route.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
28 #include <sys/ioctl.h>
30 #include <arpa/inet.h>
34 #include <linux/if_tun.h>
36 #include "vpnsvc-internal.h"
40 #define BUF_SIZE_FOR_CMD 1024
41 #define BUF_SIZE_FOR_ERR 100
43 #define CONNMAN_SERVICE "net.connman"
44 #define CONNMAN_INTERFACE_MANAGER "net.connman.Manager"
45 #define CONNMAN_INTERFACE_SERVICE "net.connman.Service"
49 static char iptables_cmd[] = "/usr/sbin/iptables";
50 static char iptables_filter_prefix[] = "CAPI_VPN_SERVICE_";
51 static char iptables_filter_out[] = "OUTPUT";
52 static char iptables_filter_in[] = "INPUT";
53 static char iptables_filter_interface_wlan[] = "wlan0";
54 static char iptables_nat_chain_name[] = "CAPI_VPN_SERVICE_NAT_OUTPUT";
56 #define IPTABLES_FMT_CREATE_CHAIN "%s -N %s%s -w"
57 #define IPTABLES_FMT_APPEND_DROP_RULE "%s -A %s%s -j DROP -w"
58 #define IPTABLES_FMT_APPEND_RETURN_RULE "%s -A %s%s -j RETURN -w"
59 #define IPTABLES_FMT_INSERT_RULE "%s -I %s -j %s%s -w"
60 #define IPTABLES_FMT_DEL_RULE "%s -D %s -j %s%s -w"
61 #define IPTABLES_FMT_FLUSH_CHAIN "%s -F %s%s -w"
62 #define IPTABLES_FMT_DEL_CHAIN "%s -X %s%s -w"
63 #define IPTABLES_FMT_APPEND_ACCEPT_RULE "%s -%c %s%s -%c %s/%d -j ACCEPT -w"
64 #define IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF "%s -%c %s%s -%c %s -%c %s/%d -j ACCEPT -w"
65 #define IPTABLES_FMT_DEL_RULE_FROM_NAT "%s -t nat -D %s -j %s -w"
66 #define IPTABLES_FMT_FLUSH_CHAIN_FROM_NAT "%s -t nat -F %s -w"
67 #define IPTABLES_FMT_DEL_CHAIN_FROM_NAT "%s -t nat -X %s -w"
69 /*static char iptables_usage_fmt[] = "%s -L %s%s -n -v -w;";*/
70 /* iptables -t nat -A CAPI_VPN_SERVICE_OUTPUT -p udp -d <vpn dns address> --dport 53 -j DNAT --to <vpn defice address:53> */
72 typedef unsigned long int ipv4; /* Declare variable type for ipv4 net address. */
74 static GDBusConnection *global_connection = NULL;
76 static ipv4 make_mask(int prefix)
81 for (i = prefix; i > 0; i--)
82 mask += (ipv4) (1 << (32 - i));
86 static in_addr_t host2net(ipv4 host)
92 net |= (host & 0x000000FF) << 24;
93 net |= (host & 0x0000FF00) << 8;
94 net |= (host & 0x00FF0000) >> 8;
95 net |= (host & 0xFF000000) >> 24;
100 static void connman_connection_open(void)
102 if (global_connection == NULL) {
103 GError *error = NULL;
104 #if !GLIB_CHECK_VERSION(2, 36, 0)
108 global_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
109 if (global_connection == NULL) {
111 ERR("Error connman connection open: %s", error->message);
118 static void connman_connection_close(GDBusConnection *connection)
121 g_object_unref(connection);
124 static GVariant *connman_method_call(
125 GDBusConnection *connection, char *service, char *path,
126 char *interface, char *method, GVariant *params)
128 GError *error = NULL;
129 GVariant *message = NULL;
131 message = g_dbus_connection_call_sync(
132 connection, service, path, interface, method, params,
133 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
135 if (message == NULL) {
137 ERR("error: g_dbus_connection_call_sync [%d: %s]", error->code, error->message);
140 ERR("error: g_dbus_connection_call_sync\n");
147 static char *connman_default_profile(GDBusConnection *connection)
150 GVariantIter *value = NULL;
151 GVariant *message = NULL;
152 GVariantIter *iter = NULL;
153 char *profile = NULL;
155 message = connman_method_call(connection, CONNMAN_SERVICE, "/",
156 CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
159 g_variant_get(message, "(a(oa{sv}))", &iter);
160 while (g_variant_iter_loop(iter, "(oa{sv})", &key, &value)) {
161 profile = strdup(key);
166 g_variant_iter_free(value);
170 g_variant_iter_free(iter);
171 g_variant_unref(message);
178 static char *connman_get_items(GDBusConnection *connection, char *profile, const char *keystr)
180 GVariant *message = NULL;
181 GVariantIter *iter = NULL;
182 GVariantIter *next = NULL;
186 message = connman_method_call(connection, CONNMAN_SERVICE, "/",
187 CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
190 g_variant_get(message, "(a(oa{sv}))", &iter);
191 while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
192 if (strcmp(obj, profile) == 0) {
196 while (g_variant_iter_loop(next, "{sv}", &key, &var)) {
197 if (g_strcmp0(key, keystr) == 0) {
198 GVariantIter *iter_item;
199 const gchar *value = NULL;
201 g_variant_get(var, "as", &iter_item);
202 while (g_variant_iter_loop(iter_item, "s", &value)) {
206 tmp_items = (char *) malloc(strlen(items) + 1 + strlen(value) + 1);
208 snprintf(tmp_items, strlen(tmp_items), "%s,%s", items, value);
213 items = strdup(value);
216 g_variant_iter_free(iter_item);
223 g_variant_iter_free(iter);
224 g_variant_unref(message);
231 static void connman_set_items(GDBusConnection *connection, char *profile,
232 const char *keystr, char *items)
234 GVariant *message = NULL;
235 GVariantBuilder *builder = NULL;
236 GVariant *params = NULL;
237 char *strings = strdup(items);
241 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
242 if ((addr = strtok_r(strings, ", ", &temp)) != NULL) {
244 g_variant_builder_add(builder, "s", addr);
245 } while ((addr = strtok_r(NULL, ", ", &temp)) != NULL);
248 params = g_variant_new("(sv)", keystr,
249 g_variant_builder_end(builder));
250 g_variant_builder_unref(builder);
252 message = connman_method_call(connection, CONNMAN_SERVICE, profile,
253 CONNMAN_INTERFACE_SERVICE, "SetProperty", params);
255 g_variant_unref(message);
260 static char *connman_get_nameservers(GDBusConnection *connection, char *profile)
262 return connman_get_items(connection, profile, "Nameservers");
265 static char *connman_get_nameservers_conf(GDBusConnection *connection, char *profile)
267 return connman_get_items(connection, profile, "Nameservers.Configuration");
271 static void connman_set_nameservers(GDBusConnection *connection, char *profile,
274 return connman_set_items(connection, profile,
275 "Nameservers.Configuration", nameservers);
279 static char *connman_get_domains(GDBusConnection *connection, char *profile)
281 return connman_get_items(connection, profile, "Domains");
284 static char *connman_get_domains_conf(GDBusConnection *connection, char *profile)
286 return connman_get_items(connection, profile, "Domains.Configuration");
290 static void connman_set_domains(GDBusConnection *connection, char *profile,
293 return connman_set_items(connection, profile,
294 "Domains.Configuration", domains);
298 static int add_dns_servers(char** dns_servers, size_t nr_dns, size_t total_dns_string_cnt)
300 char *profile = NULL;
302 char *org_items = NULL;
303 char *new_items = NULL;
306 connman_connection_open();
308 profile = connman_default_profile(global_connection);
309 if (profile == NULL) {
310 ERR("connman_default_profile failed");
311 connman_connection_close(global_connection);
312 return VPNSVC_ERROR_IPC_FAILED;
315 DBG("profile : %s\n", profile);
317 /* add name servers */
318 org_items = connman_get_nameservers(global_connection, profile);
321 DBG("original DNS : %s\n", org_items);
322 /* nr_dns = comma(,) count */
323 items = (char *) calloc((total_dns_string_cnt + nr_dns + strlen(org_items) + 1), sizeof(char));
325 ERR("OOM while malloc\n");
326 return VPNSVC_ERROR_OUT_OF_MEMORY;
328 strncpy(items, org_items, strlen(org_items));
329 for (i = 0 ; i < nr_dns ; i++) {
330 strncat(items, ",", 1);
331 strncat(items, dns_servers[i], strlen(dns_servers[i]));
336 /* nr_dns = comma(,) count + end null char */
337 items = (char *) calloc(total_dns_string_cnt + nr_dns, sizeof(char));
339 ERR("OOM while malloc\n");
340 return VPNSVC_ERROR_OUT_OF_MEMORY;
342 for (i = 0 ; i < nr_dns ; i++) {
343 strncat(items, dns_servers[i], strlen(dns_servers[i]));
345 strncat(items, ",", 1);
350 DBG("adding DNS : %s\n", items);
351 connman_set_nameservers(global_connection, profile, items);
357 new_items = connman_get_nameservers_conf(global_connection, profile);
358 DBG("new_dns : %s\n", new_items);
363 return VPNSVC_ERROR_NONE;
367 static int del_dns_servers()
369 char *profile = NULL;
371 connman_connection_open();
373 profile = connman_default_profile(global_connection);
374 if (profile == NULL) {
375 ERR("connman_default_profile failed");
376 connman_connection_close(global_connection);
377 return VPNSVC_ERROR_IPC_FAILED;
380 DBG("profile : %s", profile);
382 /* del name servers */
383 connman_set_nameservers(global_connection, profile, "");
388 return VPNSVC_ERROR_NONE;
392 static int add_dns_suffix(const char* dns_suffix, size_t dns_suffix_len)
394 char *profile = NULL;
396 char *org_items = NULL;
397 char *new_items = NULL;
399 connman_connection_open();
401 profile = connman_default_profile(global_connection);
402 if (profile == NULL) {
403 ERR("connman_default_profile failed");
404 connman_connection_close(global_connection);
405 return VPNSVC_ERROR_IPC_FAILED;
408 DBG("profile : %s", profile);
410 /* add name servers */
411 org_items = connman_get_domains(global_connection, profile);
414 DBG("original DNS suffix : %s", org_items);
415 /* comma(,) and end null character included */
416 items = (char *) calloc((dns_suffix_len + strlen(org_items) + 2), sizeof(char));
418 ERR("OOM while malloc");
419 return VPNSVC_ERROR_OUT_OF_MEMORY;
421 strncpy(items, org_items, strlen(org_items));
422 strncat(items, ",", 1);
423 strncat(items, dns_suffix, dns_suffix_len);
427 /* nr_dns = comma(,) count + end null char */
428 items = (char *) calloc((dns_suffix_len + 1), sizeof(char));
430 ERR("OOM while malloc");
431 return VPNSVC_ERROR_OUT_OF_MEMORY;
433 strncat(items, dns_suffix, dns_suffix_len);
437 DBG("adding DNS suffix : %s\n", items);
438 connman_set_domains(global_connection, profile, items);
443 /* print new domains */
444 new_items = connman_get_domains_conf(global_connection, profile);
445 DBG("new DNS suffix : %s\n", new_items);
453 return VPNSVC_ERROR_NONE;
457 static int del_dns_suffix()
459 char *profile = NULL;
461 connman_connection_open();
463 profile = connman_default_profile(global_connection);
464 if (profile == NULL) {
465 ERR("connman_default_profile failed");
466 connman_connection_close(global_connection);
467 return VPNSVC_ERROR_IPC_FAILED;
470 DBG("profile : %s", profile);
473 connman_set_domains(global_connection, profile, "");
478 return VPNSVC_ERROR_NONE;
481 static int _check_config_str(void)
486 len = confstr(_CS_PATH, NULL, 0);
490 if ((buf = malloc(len)) == NULL)
493 if (confstr(_CS_PATH, buf, len) == 0) {
504 static void dns_nat_register(char **vpn_dns_address, size_t nr_dns, char *vpn_device_address)
509 snprintf(buf + size, sizeof(buf) - size, iptables_nat_register_init_fmt,
510 iptables_cmd, iptables_nat_chain_name,
511 iptables_cmd, iptables_nat_chain_name,
512 iptables_cmd, iptables_filter_out, iptables_nat_chain_name);
515 for (i = 0 ; i < nr_dns ; i++) {
516 snprintf(buf + size, sizeof(buf) - size, iptables_nat_register_rule_fmt,
517 iptables_cmd, iptables_nat_chain_name, vpn_dns_address[i], vpn_device_address);
520 DBG("iptable dns nat reg cmd : %s", buf);
525 static void dns_nat_unregister(void)
527 char buf[BUF_SIZE_FOR_CMD];
529 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE_FROM_NAT,
530 iptables_cmd, iptables_filter_out, iptables_nat_chain_name);
531 if (netconfig_execute_cmd(buf))
532 ERR("Failed to execute command: %s", buf);
534 memset(buf, '0', sizeof(buf));
535 snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN_FROM_NAT,
536 iptables_cmd, iptables_nat_chain_name);
537 if (netconfig_execute_cmd(buf))
538 ERR("Failed to execute command: %s", buf);
540 memset(buf, '0', sizeof(buf));
541 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN_FROM_NAT,
542 iptables_cmd, iptables_nat_chain_name);
543 if (netconfig_execute_cmd(buf))
544 ERR("Failed to execute command: %s", buf);
547 static void iptables_register(void)
549 char buf[BUF_SIZE_FOR_CMD] = {0, };
552 filter = iptables_filter_out;
554 snprintf(buf, sizeof(buf), IPTABLES_FMT_CREATE_CHAIN,
555 iptables_cmd, iptables_filter_prefix, filter);
556 if (netconfig_execute_cmd(buf))
557 ERR("Failed to execute command: %s", buf);
559 memset(buf, '0', sizeof(buf));
560 snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
561 iptables_cmd, iptables_filter_prefix, filter);
562 if (netconfig_execute_cmd(buf))
563 ERR("Failed to execute command: %s", buf);
565 memset(buf, '0', sizeof(buf));
566 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_DROP_RULE,
567 iptables_cmd, iptables_filter_prefix, filter);
568 if (netconfig_execute_cmd(buf))
569 ERR("Failed to execute command: %s", buf);
571 memset(buf, '0', sizeof(buf));
572 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_RETURN_RULE,
573 iptables_cmd, iptables_filter_prefix, filter);
574 if (netconfig_execute_cmd(buf))
575 ERR("Failed to execute command: %s", buf);
577 memset(buf, '0', sizeof(buf));
578 snprintf(buf, sizeof(buf), IPTABLES_FMT_INSERT_RULE,
579 iptables_cmd, filter, iptables_filter_prefix, filter);
581 filter = iptables_filter_in;
583 memset(buf, '0', sizeof(buf));
584 snprintf(buf, sizeof(buf), IPTABLES_FMT_CREATE_CHAIN,
585 iptables_cmd, iptables_filter_prefix, filter);
586 if (netconfig_execute_cmd(buf))
587 ERR("Failed to execute command: %s", buf);
589 memset(buf, '0', sizeof(buf));
590 snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
591 iptables_cmd, iptables_filter_prefix, filter);
592 if (netconfig_execute_cmd(buf))
593 ERR("Failed to execute command: %s", buf);
595 memset(buf, '0', sizeof(buf));
596 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_DROP_RULE,
597 iptables_cmd, iptables_filter_prefix, filter);
598 if (netconfig_execute_cmd(buf))
599 ERR("Failed to execute command: %s", buf);
601 memset(buf, '0', sizeof(buf));
602 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_RETURN_RULE,
603 iptables_cmd, iptables_filter_prefix, filter);
604 if (netconfig_execute_cmd(buf))
605 ERR("Failed to execute command: %s", buf);
607 memset(buf, '0', sizeof(buf));
608 snprintf(buf, sizeof(buf), IPTABLES_FMT_INSERT_RULE,
609 iptables_cmd, filter, iptables_filter_prefix, filter);
612 static void iptables_unregister(void)
614 char buf[BUF_SIZE_FOR_CMD] = {0, };
617 filter = iptables_filter_out;
619 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE,
620 iptables_cmd, filter, iptables_filter_prefix, filter);
621 if (netconfig_execute_cmd(buf))
622 ERR("Failed to execute command: %s", buf);
624 memset(buf, '0', sizeof(buf));
625 snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
626 iptables_cmd, iptables_filter_prefix, filter);
627 if (netconfig_execute_cmd(buf))
628 ERR("Failed to execute command: %s", buf);
630 memset(buf, '0', sizeof(buf));
631 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN,
632 iptables_cmd, iptables_filter_prefix, filter);
633 if (netconfig_execute_cmd(buf))
634 ERR("Failed to execute command: %s", buf);
636 filter = iptables_filter_in;
638 memset(buf, '0', sizeof(buf));
639 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE,
640 iptables_cmd, filter, iptables_filter_prefix, filter);
641 if (netconfig_execute_cmd(buf))
642 ERR("Failed to execute command: %s", buf);
644 memset(buf, '0', sizeof(buf));
645 snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
646 iptables_cmd, iptables_filter_prefix, filter);
647 if (netconfig_execute_cmd(buf))
648 ERR("Failed to execute command: %s", buf);
650 memset(buf, '0', sizeof(buf));
651 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN,
652 iptables_cmd, iptables_filter_prefix, filter);
653 if (netconfig_execute_cmd(buf))
654 ERR("Failed to execute command: %s", buf);
657 static void iptables_rule(const char c, const char *addr, const int mask)
659 char buf[BUF_SIZE_FOR_CMD];
661 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE,
662 iptables_cmd, c, iptables_filter_prefix,
663 iptables_filter_out, 'd', addr, mask);
664 if (netconfig_execute_cmd(buf))
665 ERR("Failed to execute command: %s", buf);
667 memset(buf, '0', sizeof(buf));
668 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE,
669 iptables_cmd, c, iptables_filter_prefix,
670 iptables_filter_in, 's', addr, mask);
671 if (netconfig_execute_cmd(buf))
672 ERR("Failed to execute command: %s", buf);
675 static void iptables_rule_interface(const char c, const char *addr, const int mask, const char *interface)
677 char buf[BUF_SIZE_FOR_CMD];
679 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF,
680 iptables_cmd, c, iptables_filter_prefix, iptables_filter_out,
681 'o', interface, 'd', addr, mask);
682 if (netconfig_execute_cmd(buf))
683 ERR("Failed to execute command: %s", buf);
685 memset(buf, '0', sizeof(buf));
686 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF,
687 iptables_cmd, c, iptables_filter_prefix, iptables_filter_in,
688 'i', interface, 's', addr, mask);
689 if (netconfig_execute_cmd(buf))
690 ERR("Failed to execute command: %s", buf);
693 void iptables_add_orig(const char *addr, const int mask)
695 iptables_rule_interface('I', addr, mask, iptables_filter_interface_wlan);
698 void iptables_delete_orig(const char *addr, const int mask)
700 iptables_rule_interface('D', addr, mask, iptables_filter_interface_wlan);
703 void iptables_add(const char *addr, const int mask)
705 iptables_rule('I', addr, mask);
708 void iptables_delete(const char *addr, const int mask)
710 iptables_rule('D', addr, mask);
713 static int get_interface_index(const char *iface_name)
717 char buf[BUF_SIZE_FOR_ERR] = { 0 };
719 DBG("enter get_interface_index, iface_name : %s", iface_name);
721 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
723 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
724 return VPNSVC_ERROR_IO_ERROR;
727 memset(&ifr, 0, sizeof(ifr));
730 strncpy(ifr.ifr_name, iface_name, strlen(iface_name));
732 /* get an interface name by ifindex */
733 if (ioctl(sk, SIOCGIFINDEX, &ifr) < 0) {
734 ERR("ioctl SIOCGIFINDEX failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
736 return VPNSVC_ERROR_IO_ERROR;
741 return ifr.ifr_ifindex;
744 static int check_interface_precondition(const char *iface_name)
748 struct ifreq ifr_tun;
749 char buf[BUF_SIZE_FOR_ERR] = { 0 };
751 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
753 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
754 return VPNSVC_ERROR_IO_ERROR;
757 memset(&ifr_tun, 0, sizeof(ifr_tun));
758 g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name));
761 if (ioctl(sk, SIOCGIFADDR, &ifr_tun) < 0) {
762 ERR("Fail to get local IP address: %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
764 return VPNSVC_ERROR_INVALID_PARAMETER;
768 if (ioctl(sk, SIOCGIFDSTADDR, &ifr_tun) < 0) {
769 ERR("Fail to get remote IP address: %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
771 return VPNSVC_ERROR_INVALID_PARAMETER;
776 return VPNSVC_ERROR_NONE;
780 int vpn_service_init(const char* iface_name, size_t iface_name_len, int fd, vpnsvc_tun_s *handle_s)
784 char buf[BUF_SIZE_FOR_ERR] = { 0 };
786 DBG("enter vpn_daemon_init, iface_name : %s, iface_name_len : %d, fd : %d\n", iface_name, iface_name_len, fd);
788 memset(&ifr, 0, sizeof(ifr));
790 /* Flags: IFF_TUN - TUN device (no Ethernet headers)
791 * IFF_TAP - TAP device
793 * IFF_NO_PI - Do not provide packet information
796 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
799 strncpy(ifr.ifr_name, iface_name, iface_name_len);
801 DBG("before init, ifindex : %d", ifr.ifr_ifindex);
803 if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
804 ERR("TUNSETIFF Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
806 return VPNSVC_ERROR_IO_ERROR;
809 if (ioctl(fd, TUNSETOWNER, 5000) < 0) {
810 ERR("TUNSETOWNER Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
812 return VPNSVC_ERROR_IO_ERROR;
815 if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
816 ERR("TUNSETPERSIST Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
818 return VPNSVC_ERROR_IO_ERROR;
821 handle_s->fd = 0; /* server fd does not meaning */
822 handle_s->index = get_interface_index(iface_name);
823 len = strlen(ifr.ifr_name);
824 strncpy(handle_s->name, ifr.ifr_name, len);
825 handle_s->name[len] = '\0';
827 return VPNSVC_ERROR_NONE;
830 int vpn_service_deinit(const char* dev_name)
835 if (_check_config_str() != 0) {
836 ERR("Failed to get configuration string");
837 return VPNSVC_ERROR_IO_ERROR;
840 snprintf(buf, sizeof(buf), "/usr/sbin/ip link del %s", dev_name);
842 cmd = g_try_malloc0(strlen(buf) + 1);
843 strncpy(cmd, buf, strlen(buf));
845 DBG("link delete cmd : %s", cmd);
847 fp = popen(cmd, "r");
852 return VPNSVC_ERROR_NONE;
854 return VPNSVC_ERROR_IO_ERROR;
858 int vpn_service_protect(int socket_fd, const char* dev_name)
860 int ret = VPNSVC_ERROR_NONE;
861 char buf[BUF_SIZE_FOR_ERR] = { 0 };
862 DBG("enter vpn_daemon_protect, socket : %d, dev_name : %s\n", socket_fd, dev_name);
864 ret = setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE,
865 dev_name, strlen(dev_name));
868 DBG("setsockopt failed : %d, %s", ret, strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
869 ret = VPNSVC_ERROR_IO_ERROR;
871 ret = VPNSVC_ERROR_NONE;
877 int vpn_service_up(const char *iface_name)
879 struct ifreq ifr_tun;
881 int ret = VPNSVC_ERROR_NONE;
882 char buf[BUF_SIZE_FOR_ERR] = { 0 };
884 DBG("enter vpn_daemon_up");
885 DBG("iface_name : %s", iface_name);
888 ret = check_interface_precondition(iface_name);
889 if (ret != VPNSVC_ERROR_NONE)
892 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
894 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
895 return VPNSVC_ERROR_IO_ERROR;
898 memset(&ifr_tun, 0, sizeof(ifr_tun));
899 g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name));
901 /* set the flags for vpn up */
902 if (ioctl(sk, SIOCGIFFLAGS, &ifr_tun) < 0) {
903 ERR("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
905 return VPNSVC_ERROR_IO_ERROR;
908 ifr_tun.ifr_flags |= IFF_UP;
909 ifr_tun.ifr_flags |= IFF_RUNNING;
911 if (ioctl(sk, SIOCSIFFLAGS, &ifr_tun) < 0) {
912 ERR("ioctl SIOCSIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
914 return VPNSVC_ERROR_IO_ERROR;
920 /* add DNS servers */
922 ret = add_dns_servers(dns_servers, nr_dns, total_dns_string_cnt);
923 if (ret != VPNSVC_ERROR_NONE) {
924 ERR("add_dns failed");
931 ret = add_dns_suffix(dns_suffix, strlen(dns_suffix));
932 if (ret != VPNSVC_ERROR_NONE) {
933 ERR("add_dns_suffix failed");
939 dns_nat_register(dns_servers, nr_dns, local_ip);
947 int vpn_service_down(const char *iface_name)
951 char buf[BUF_SIZE_FOR_ERR] = { 0 };
953 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
955 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
956 return VPNSVC_ERROR_IO_ERROR;
959 memset(&ifr, 0, sizeof(ifr));
960 g_strlcpy((char *)ifr.ifr_name, iface_name, sizeof(ifr.ifr_name));
962 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
963 ERR("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
965 return VPNSVC_ERROR_IO_ERROR;
968 if (!(ifr.ifr_flags & IFF_UP)) {
969 DBG("Interface already down");
971 return VPNSVC_ERROR_NONE;
974 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
975 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
976 ERR("ioctl SIOCSIFFLAGS (interface down) failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
978 return VPNSVC_ERROR_IO_ERROR;
983 /* routes are will be removed automatically while down interfaces */
984 /* remove dns servers */
987 /* remove dns suffix */
990 /* remove dns filter */
991 dns_nat_unregister();
993 return VPNSVC_ERROR_NONE;
996 int vpn_service_block_networks(char* nets_vpn[], int prefix_vpn[], size_t nr_nets_vpn,
997 char* nets_orig[], int prefix_orig[], size_t nr_nets_orig) {
1000 /* iptable chain regist */
1001 iptables_register();
1003 for (i = 0; i < nr_nets_vpn; i++) {
1004 DBG("block[%d] ip/mask : %s/%d", i, nets_vpn[i], prefix_vpn[i]);
1005 iptables_add(nets_vpn[i], prefix_vpn[i]);
1008 for (i = 0; i < nr_nets_orig; i++) {
1009 DBG("allow[%d] ip/mask : %s/%d", i, nets_orig[i], prefix_orig[i]);
1010 iptables_add_orig(nets_orig[i], prefix_orig[i]);
1013 return VPNSVC_ERROR_NONE;
1016 int vpn_service_unblock_networks(void)
1018 iptables_unregister();
1020 return VPNSVC_ERROR_NONE;
1023 int vpn_service_update_settings(int iface_index, const char *local_ip,
1024 const char *remote_ip, const unsigned int mtu)
1027 struct ifreq ifr_tun;
1028 struct sockaddr_in local_addr;
1029 struct sockaddr_in remote_addr;
1030 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1032 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1034 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1035 return VPNSVC_ERROR_IO_ERROR;
1038 memset(&ifr_tun, 0, sizeof(ifr_tun));
1039 ifr_tun.ifr_ifindex = iface_index;
1041 /* get an interface name by ifindex */
1042 if (ioctl(sk, SIOCGIFNAME, &ifr_tun) < 0) {
1043 ERR("ioctl SIOCGIFNAME failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1045 return VPNSVC_ERROR_IO_ERROR;
1048 /* local ip setting */
1049 memset(&local_addr, 0, sizeof(local_addr));
1050 local_addr.sin_addr.s_addr = inet_addr(local_ip); /* network byte order */
1051 local_addr.sin_family = AF_INET;
1052 memcpy(&ifr_tun.ifr_addr, &local_addr, sizeof(ifr_tun.ifr_addr));
1053 if (ioctl(sk, SIOCSIFADDR, &ifr_tun) < 0) {
1054 ERR("ioctl SIOCSIFADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1056 return VPNSVC_ERROR_IO_ERROR;
1059 /* remote ip setting */
1060 memset(&remote_addr, 0, sizeof(remote_addr));
1061 remote_addr.sin_addr.s_addr = inet_addr(remote_ip); /*network byte order*/
1062 remote_addr.sin_family = AF_INET;
1063 memcpy(&ifr_tun.ifr_dstaddr, &remote_addr, sizeof(ifr_tun.ifr_dstaddr));
1064 if (ioctl(sk, SIOCSIFDSTADDR, &ifr_tun) < 0) {
1065 ERR("ioctl SIOCSIFDSTADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1067 return VPNSVC_ERROR_IO_ERROR;
1071 if (mtu > 0 && ifr_tun.ifr_mtu != (int)mtu) {
1072 ifr_tun.ifr_mtu = mtu;
1073 if (ioctl(sk, SIOCSIFMTU, &ifr_tun) < 0) {
1074 ERR("ioctl SIOCSIFMTU failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1076 return VPNSVC_ERROR_IO_ERROR;
1082 return VPNSVC_ERROR_NONE;
1085 int vpn_service_add_route(char *iface_name, const char *route, int prefix)
1088 struct sockaddr_in addr;
1090 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1092 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1094 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1095 return VPNSVC_ERROR_IO_ERROR;
1098 memset(&rt, 0, sizeof(rt));
1099 rt.rt_flags = RTF_UP;
1101 memset(&addr, 0, sizeof(addr));
1102 addr.sin_family = AF_INET;
1103 addr.sin_addr.s_addr = inet_addr(route);
1104 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1106 memset(&addr, 0, sizeof(addr));
1107 addr.sin_family = AF_INET;
1108 addr.sin_addr.s_addr = INADDR_ANY;
1109 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1111 /* set mask using by prefix length */
1112 memset(&addr, 0, sizeof(addr));
1113 addr.sin_family = AF_INET;
1114 addr.sin_addr.s_addr = INADDR_ANY;
1115 addr.sin_addr.s_addr = host2net(make_mask(prefix));
1116 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1118 rt.rt_dev = iface_name;
1120 if (ioctl(sk, SIOCADDRT, &rt) < 0) {
1121 ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1123 return VPNSVC_ERROR_IO_ERROR;
1128 return VPNSVC_ERROR_NONE;
1131 int vpn_service_remove_route(char *iface_name, const char *route, int prefix)
1134 struct sockaddr_in addr;
1136 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1138 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1140 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1141 return VPNSVC_ERROR_IO_ERROR;
1144 memset(&rt, 0, sizeof(rt));
1145 rt.rt_flags = RTF_UP;
1147 memset(&addr, 0, sizeof(addr));
1148 addr.sin_family = AF_INET;
1149 addr.sin_addr.s_addr = inet_addr(route);
1150 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1152 memset(&addr, 0, sizeof(addr));
1153 addr.sin_family = AF_INET;
1154 addr.sin_addr.s_addr = INADDR_ANY;
1155 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1157 /* set mask using by prefix length */
1158 memset(&addr, 0, sizeof(addr));
1159 addr.sin_family = AF_INET;
1160 addr.sin_addr.s_addr = INADDR_ANY;
1161 addr.sin_addr.s_addr = host2net(make_mask(prefix));
1162 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1164 rt.rt_dev = iface_name;
1166 if (ioctl(sk, SIOCDELRT, &rt) < 0) {
1167 ERR("ioctl SIOCDERLT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1169 return VPNSVC_ERROR_IO_ERROR;
1174 return VPNSVC_ERROR_NONE;
1178 int vpn_service_add_dns_server(char *iface_name, const char *dns_server)
1181 struct sockaddr_in addr;
1183 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1185 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1187 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1188 return VPNSVC_ERROR_IO_ERROR;
1191 memset(&rt, 0, sizeof(rt));
1192 rt.rt_flags = RTF_UP;
1194 memset(&addr, 0, sizeof(addr));
1195 addr.sin_family = AF_INET;
1196 addr.sin_addr.s_addr = inet_addr(dns_server);
1197 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1199 memset(&addr, 0, sizeof(addr));
1200 addr.sin_family = AF_INET;
1201 addr.sin_addr.s_addr = INADDR_ANY;
1202 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1204 /* set mask using by prefix length */
1205 memset(&addr, 0, sizeof(addr));
1206 addr.sin_family = AF_INET;
1207 addr.sin_addr.s_addr = INADDR_ANY;
1208 addr.sin_addr.s_addr = host2net(make_mask(32));
1209 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1211 rt.rt_dev = iface_name;
1213 if (ioctl(sk, SIOCADDRT, &rt) < 0) {
1214 ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1216 return VPNSVC_ERROR_IO_ERROR;
1221 return VPNSVC_ERROR_NONE;
1224 int vpn_service_remove_dns_server(char *iface_name, const char *dns_server)
1227 struct sockaddr_in addr;
1229 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1231 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1233 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1234 return VPNSVC_ERROR_IO_ERROR;
1237 memset(&rt, 0, sizeof(rt));
1238 rt.rt_flags = RTF_UP;
1240 memset(&addr, 0, sizeof(addr));
1241 addr.sin_family = AF_INET;
1242 addr.sin_addr.s_addr = inet_addr(dns_server);
1243 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1245 memset(&addr, 0, sizeof(addr));
1246 addr.sin_family = AF_INET;
1247 addr.sin_addr.s_addr = INADDR_ANY;
1248 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1250 /* set mask using by prefix length */
1251 memset(&addr, 0, sizeof(addr));
1252 addr.sin_family = AF_INET;
1253 addr.sin_addr.s_addr = INADDR_ANY;
1254 addr.sin_addr.s_addr = host2net(make_mask(32));
1255 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1257 rt.rt_dev = iface_name;
1259 if (ioctl(sk, SIOCDELRT, &rt) < 0) {
1260 ERR("ioctl SIOCDELRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1262 return VPNSVC_ERROR_IO_ERROR;
1267 return VPNSVC_ERROR_NONE;