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 if (g_variant_iter_loop(iter, "(oa{sv})", &key, &value))
161 profile = strdup(key);
164 g_variant_iter_free(value);
168 g_variant_iter_free(iter);
169 g_variant_unref(message);
176 static char *connman_get_items(GDBusConnection *connection, char *profile, const char *keystr)
178 GVariant *message = NULL;
179 GVariantIter *iter = NULL;
180 GVariantIter *next = NULL;
184 message = connman_method_call(connection, CONNMAN_SERVICE, "/",
185 CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
188 g_variant_get(message, "(a(oa{sv}))", &iter);
189 while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
190 if (strcmp(obj, profile) == 0) {
194 while (g_variant_iter_loop(next, "{sv}", &key, &var)) {
195 if (g_strcmp0(key, keystr) == 0) {
196 GVariantIter *iter_item;
197 const gchar *value = NULL;
199 g_variant_get(var, "as", &iter_item);
200 while (g_variant_iter_loop(iter_item, "s", &value)) {
204 tmp_items = (char *) malloc(strlen(items) + 1 + strlen(value) + 1);
206 snprintf(tmp_items, strlen(tmp_items), "%s,%s", items, value);
211 items = strdup(value);
214 g_variant_iter_free(iter_item);
221 g_variant_iter_free(iter);
222 g_variant_unref(message);
229 static void connman_set_items(GDBusConnection *connection, char *profile,
230 const char *keystr, char *items)
232 GVariant *message = NULL;
233 GVariantBuilder *builder = NULL;
234 GVariant *params = NULL;
235 char *strings = strdup(items);
239 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
240 if ((addr = strtok_r(strings, ", ", &temp)) != NULL) {
242 g_variant_builder_add(builder, "s", addr);
243 } while ((addr = strtok_r(NULL, ", ", &temp)) != NULL);
246 params = g_variant_new("(sv)", keystr,
247 g_variant_builder_end(builder));
248 g_variant_builder_unref(builder);
250 message = connman_method_call(connection, CONNMAN_SERVICE, profile,
251 CONNMAN_INTERFACE_SERVICE, "SetProperty", params);
253 g_variant_unref(message);
258 static char *connman_get_nameservers(GDBusConnection *connection, char *profile)
260 return connman_get_items(connection, profile, "Nameservers");
263 static char *connman_get_nameservers_conf(GDBusConnection *connection, char *profile)
265 return connman_get_items(connection, profile, "Nameservers.Configuration");
269 static void connman_set_nameservers(GDBusConnection *connection, char *profile,
272 return connman_set_items(connection, profile,
273 "Nameservers.Configuration", nameservers);
277 static char *connman_get_domains(GDBusConnection *connection, char *profile)
279 return connman_get_items(connection, profile, "Domains");
282 static char *connman_get_domains_conf(GDBusConnection *connection, char *profile)
284 return connman_get_items(connection, profile, "Domains.Configuration");
288 static void connman_set_domains(GDBusConnection *connection, char *profile,
291 return connman_set_items(connection, profile,
292 "Domains.Configuration", domains);
296 static int add_dns_servers(char** dns_servers, size_t nr_dns, size_t total_dns_string_cnt)
298 char *profile = NULL;
300 char *org_items = NULL;
301 char *new_items = NULL;
304 connman_connection_open();
306 profile = connman_default_profile(global_connection);
307 if (profile == NULL) {
308 ERR("connman_default_profile failed");
309 connman_connection_close(global_connection);
310 return VPNSVC_ERROR_IPC_FAILED;
313 DBG("profile : %s\n", profile);
315 /* add name servers */
316 org_items = connman_get_nameservers(global_connection, profile);
319 DBG("original DNS : %s\n", org_items);
320 /* nr_dns = comma(,) count */
321 items = (char *) calloc((total_dns_string_cnt + nr_dns + strlen(org_items) + 1), sizeof(char));
323 ERR("OOM while malloc\n");
324 return VPNSVC_ERROR_OUT_OF_MEMORY;
326 strncpy(items, org_items, strlen(org_items));
327 for (i = 0 ; i < nr_dns ; i++) {
328 strncat(items, ",", 1);
329 strncat(items, dns_servers[i], strlen(dns_servers[i]));
334 /* nr_dns = comma(,) count + end null char */
335 items = (char *) calloc(total_dns_string_cnt + nr_dns, sizeof(char));
337 ERR("OOM while malloc\n");
338 return VPNSVC_ERROR_OUT_OF_MEMORY;
340 for (i = 0 ; i < nr_dns ; i++) {
341 strncat(items, dns_servers[i], strlen(dns_servers[i]));
343 strncat(items, ",", 1);
348 DBG("adding DNS : %s\n", items);
349 connman_set_nameservers(global_connection, profile, items);
355 new_items = connman_get_nameservers_conf(global_connection, profile);
356 DBG("new_dns : %s\n", new_items);
361 return VPNSVC_ERROR_NONE;
365 static int del_dns_servers()
367 char *profile = NULL;
369 connman_connection_open();
371 profile = connman_default_profile(global_connection);
372 if (profile == NULL) {
373 ERR("connman_default_profile failed");
374 connman_connection_close(global_connection);
375 return VPNSVC_ERROR_IPC_FAILED;
378 DBG("profile : %s", profile);
380 /* del name servers */
381 connman_set_nameservers(global_connection, profile, "");
386 return VPNSVC_ERROR_NONE;
390 static int add_dns_suffix(const char* dns_suffix, size_t dns_suffix_len)
392 char *profile = NULL;
394 char *org_items = NULL;
395 char *new_items = NULL;
397 connman_connection_open();
399 profile = connman_default_profile(global_connection);
400 if (profile == NULL) {
401 ERR("connman_default_profile failed");
402 connman_connection_close(global_connection);
403 return VPNSVC_ERROR_IPC_FAILED;
406 DBG("profile : %s", profile);
408 /* add name servers */
409 org_items = connman_get_domains(global_connection, profile);
412 DBG("original DNS suffix : %s", org_items);
413 /* comma(,) and end null character included */
414 items = (char *) calloc((dns_suffix_len + strlen(org_items) + 2), sizeof(char));
416 ERR("OOM while malloc");
417 return VPNSVC_ERROR_OUT_OF_MEMORY;
419 strncpy(items, org_items, strlen(org_items));
420 strncat(items, ",", 1);
421 strncat(items, dns_suffix, dns_suffix_len);
425 /* nr_dns = comma(,) count + end null char */
426 items = (char *) calloc((dns_suffix_len + 1), sizeof(char));
428 ERR("OOM while malloc");
429 return VPNSVC_ERROR_OUT_OF_MEMORY;
431 strncat(items, dns_suffix, dns_suffix_len);
435 DBG("adding DNS suffix : %s\n", items);
436 connman_set_domains(global_connection, profile, items);
441 /* print new domains */
442 new_items = connman_get_domains_conf(global_connection, profile);
443 DBG("new DNS suffix : %s\n", new_items);
451 return VPNSVC_ERROR_NONE;
455 static int del_dns_suffix()
457 char *profile = NULL;
459 connman_connection_open();
461 profile = connman_default_profile(global_connection);
462 if (profile == NULL) {
463 ERR("connman_default_profile failed");
464 connman_connection_close(global_connection);
465 return VPNSVC_ERROR_IPC_FAILED;
468 DBG("profile : %s", profile);
471 connman_set_domains(global_connection, profile, "");
476 return VPNSVC_ERROR_NONE;
480 static void dns_nat_register(char **vpn_dns_address, size_t nr_dns, char *vpn_device_address)
485 snprintf(buf + size, sizeof(buf) - size, iptables_nat_register_init_fmt,
486 iptables_cmd, iptables_nat_chain_name,
487 iptables_cmd, iptables_nat_chain_name,
488 iptables_cmd, iptables_filter_out, iptables_nat_chain_name);
491 for (i = 0 ; i < nr_dns ; i++) {
492 snprintf(buf + size, sizeof(buf) - size, iptables_nat_register_rule_fmt,
493 iptables_cmd, iptables_nat_chain_name, vpn_dns_address[i], vpn_device_address);
496 DBG("iptable dns nat reg cmd : %s", buf);
501 static void dns_nat_unregister(void)
503 char buf[BUF_SIZE_FOR_CMD];
505 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE_FROM_NAT,
506 iptables_cmd, iptables_filter_out, iptables_nat_chain_name);
507 if (netconfig_execute_cmd(buf))
508 ERR("Failed to execute command: %s", buf);
510 memset(buf, 0, sizeof(buf));
511 snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN_FROM_NAT,
512 iptables_cmd, iptables_nat_chain_name);
513 if (netconfig_execute_cmd(buf))
514 ERR("Failed to execute command: %s", buf);
516 memset(buf, 0, sizeof(buf));
517 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN_FROM_NAT,
518 iptables_cmd, iptables_nat_chain_name);
519 if (netconfig_execute_cmd(buf))
520 ERR("Failed to execute command: %s", buf);
523 static void iptables_register(void)
525 char buf[BUF_SIZE_FOR_CMD] = {0, };
528 filter = iptables_filter_out;
530 snprintf(buf, sizeof(buf), IPTABLES_FMT_CREATE_CHAIN,
531 iptables_cmd, iptables_filter_prefix, filter);
532 if (netconfig_execute_cmd(buf))
533 ERR("Failed to execute command: %s", buf);
535 memset(buf, 0, sizeof(buf));
536 snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
537 iptables_cmd, iptables_filter_prefix, filter);
538 if (netconfig_execute_cmd(buf))
539 ERR("Failed to execute command: %s", buf);
541 memset(buf, 0, sizeof(buf));
542 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_DROP_RULE,
543 iptables_cmd, iptables_filter_prefix, filter);
544 if (netconfig_execute_cmd(buf))
545 ERR("Failed to execute command: %s", buf);
547 memset(buf, 0, sizeof(buf));
548 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_RETURN_RULE,
549 iptables_cmd, iptables_filter_prefix, filter);
550 if (netconfig_execute_cmd(buf))
551 ERR("Failed to execute command: %s", buf);
553 memset(buf, 0, sizeof(buf));
554 snprintf(buf, sizeof(buf), IPTABLES_FMT_INSERT_RULE,
555 iptables_cmd, filter, iptables_filter_prefix, filter);
557 filter = iptables_filter_in;
559 memset(buf, 0, sizeof(buf));
560 snprintf(buf, sizeof(buf), IPTABLES_FMT_CREATE_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_FLUSH_CHAIN,
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_DROP_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_APPEND_RETURN_RULE,
579 iptables_cmd, iptables_filter_prefix, filter);
580 if (netconfig_execute_cmd(buf))
581 ERR("Failed to execute command: %s", buf);
583 memset(buf, 0, sizeof(buf));
584 snprintf(buf, sizeof(buf), IPTABLES_FMT_INSERT_RULE,
585 iptables_cmd, filter, iptables_filter_prefix, filter);
588 static void iptables_unregister(void)
590 char buf[BUF_SIZE_FOR_CMD] = {0, };
593 filter = iptables_filter_out;
595 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE,
596 iptables_cmd, filter, iptables_filter_prefix, filter);
597 if (netconfig_execute_cmd(buf))
598 ERR("Failed to execute command: %s", buf);
600 memset(buf, 0, sizeof(buf));
601 snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
602 iptables_cmd, iptables_filter_prefix, filter);
603 if (netconfig_execute_cmd(buf))
604 ERR("Failed to execute command: %s", buf);
606 memset(buf, 0, sizeof(buf));
607 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN,
608 iptables_cmd, iptables_filter_prefix, filter);
609 if (netconfig_execute_cmd(buf))
610 ERR("Failed to execute command: %s", buf);
612 filter = iptables_filter_in;
614 memset(buf, 0, sizeof(buf));
615 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE,
616 iptables_cmd, filter, iptables_filter_prefix, filter);
617 if (netconfig_execute_cmd(buf))
618 ERR("Failed to execute command: %s", buf);
620 memset(buf, 0, sizeof(buf));
621 snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
622 iptables_cmd, iptables_filter_prefix, filter);
623 if (netconfig_execute_cmd(buf))
624 ERR("Failed to execute command: %s", buf);
626 memset(buf, 0, sizeof(buf));
627 snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN,
628 iptables_cmd, iptables_filter_prefix, filter);
629 if (netconfig_execute_cmd(buf))
630 ERR("Failed to execute command: %s", buf);
633 static void iptables_rule(const char c, const char *addr, const int mask)
635 char buf[BUF_SIZE_FOR_CMD];
637 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE,
638 iptables_cmd, c, iptables_filter_prefix,
639 iptables_filter_out, 'd', addr, mask);
640 if (netconfig_execute_cmd(buf))
641 ERR("Failed to execute command: %s", buf);
643 memset(buf, 0, sizeof(buf));
644 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE,
645 iptables_cmd, c, iptables_filter_prefix,
646 iptables_filter_in, 's', addr, mask);
647 if (netconfig_execute_cmd(buf))
648 ERR("Failed to execute command: %s", buf);
651 static void iptables_rule_interface(const char c, const char *addr, const int mask, const char *interface)
653 char buf[BUF_SIZE_FOR_CMD];
655 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF,
656 iptables_cmd, c, iptables_filter_prefix, iptables_filter_out,
657 'o', interface, 'd', addr, mask);
658 if (netconfig_execute_cmd(buf))
659 ERR("Failed to execute command: %s", buf);
661 memset(buf, 0, sizeof(buf));
662 snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF,
663 iptables_cmd, c, iptables_filter_prefix, iptables_filter_in,
664 'i', interface, 's', addr, mask);
665 if (netconfig_execute_cmd(buf))
666 ERR("Failed to execute command: %s", buf);
669 void iptables_add_orig(const char *addr, const int mask)
671 iptables_rule_interface('I', addr, mask, iptables_filter_interface_wlan);
674 void iptables_delete_orig(const char *addr, const int mask)
676 iptables_rule_interface('D', addr, mask, iptables_filter_interface_wlan);
679 void iptables_add(const char *addr, const int mask)
681 iptables_rule('I', addr, mask);
684 void iptables_delete(const char *addr, const int mask)
686 iptables_rule('D', addr, mask);
689 static int get_interface_index(const char *iface_name)
693 char buf[BUF_SIZE_FOR_ERR] = { 0 };
695 DBG("enter get_interface_index, iface_name : %s", iface_name);
697 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
699 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
700 return VPNSVC_ERROR_IO_ERROR;
703 memset(&ifr, 0, sizeof(ifr));
706 strncpy(ifr.ifr_name, iface_name, IFNAMSIZ - 1);
708 /* get an interface name by ifindex */
709 if (ioctl(sk, SIOCGIFINDEX, &ifr) < 0) {
710 ERR("ioctl SIOCGIFINDEX failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
712 return VPNSVC_ERROR_IO_ERROR;
717 return ifr.ifr_ifindex;
720 static int check_interface_precondition(const char *iface_name)
724 struct ifreq ifr_tun;
725 char buf[BUF_SIZE_FOR_ERR] = { 0 };
727 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
729 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
730 return VPNSVC_ERROR_IO_ERROR;
733 memset(&ifr_tun, 0, sizeof(ifr_tun));
734 g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name));
737 if (ioctl(sk, SIOCGIFADDR, &ifr_tun) < 0) {
738 ERR("Fail to get local IP address: %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
740 return VPNSVC_ERROR_INVALID_PARAMETER;
744 if (ioctl(sk, SIOCGIFDSTADDR, &ifr_tun) < 0) {
745 ERR("Fail to get remote IP address: %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
747 return VPNSVC_ERROR_INVALID_PARAMETER;
752 return VPNSVC_ERROR_NONE;
756 int vpn_service_init(const char* iface_name, size_t iface_name_len, int fd, vpnsvc_tun_s *handle_s)
759 char buf[BUF_SIZE_FOR_ERR] = { 0 };
761 DBG("enter vpn_daemon_init, iface_name : %s, iface_name_len : %d, fd : %d\n", iface_name, iface_name_len, fd);
763 memset(&ifr, 0, sizeof(ifr));
765 /* Flags: IFF_TUN - TUN device (no Ethernet headers)
766 * IFF_TAP - TAP device
768 * IFF_NO_PI - Do not provide packet information
771 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
774 strncpy(ifr.ifr_name, iface_name, iface_name_len);
775 ifr.ifr_name[iface_name_len] = '\0';
777 DBG("before init, ifindex : %d", ifr.ifr_ifindex);
779 if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
780 ERR("TUNSETIFF Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
782 return VPNSVC_ERROR_IO_ERROR;
785 if (ioctl(fd, TUNSETOWNER, 5000) < 0) {
786 ERR("TUNSETOWNER Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
788 return VPNSVC_ERROR_IO_ERROR;
791 if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
792 ERR("TUNSETPERSIST Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
794 return VPNSVC_ERROR_IO_ERROR;
797 handle_s->fd = 0; /* server fd does not meaning */
798 handle_s->index = get_interface_index(iface_name);
799 g_strlcpy(handle_s->name, ifr.ifr_name, VPNSVC_VPN_IFACE_NAME_LEN);
801 return VPNSVC_ERROR_NONE;
804 int vpn_service_deinit(const char* dev_name)
808 snprintf(buf, sizeof(buf), "/usr/sbin/ip link del %s", dev_name);
810 if (netconfig_execute_cmd(buf)) {
811 ERR("Failed to execute command: %s", buf);
812 return VPNSVC_ERROR_IO_ERROR;
815 return VPNSVC_ERROR_NONE;
818 int vpn_service_protect(int socket_fd, const char* dev_name)
820 int ret = VPNSVC_ERROR_NONE;
821 char buf[BUF_SIZE_FOR_ERR] = { 0 };
822 DBG("enter vpn_daemon_protect, socket : %d, dev_name : %s\n", socket_fd, dev_name);
824 ret = setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE,
825 dev_name, strlen(dev_name));
828 DBG("setsockopt failed : %d, %s", ret, strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
829 ret = VPNSVC_ERROR_IO_ERROR;
831 ret = VPNSVC_ERROR_NONE;
837 int vpn_service_up(const char *iface_name)
839 struct ifreq ifr_tun;
841 int ret = VPNSVC_ERROR_NONE;
842 char buf[BUF_SIZE_FOR_ERR] = { 0 };
844 DBG("enter vpn_daemon_up");
845 DBG("iface_name : %s", iface_name);
848 ret = check_interface_precondition(iface_name);
849 if (ret != VPNSVC_ERROR_NONE)
852 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
854 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
855 return VPNSVC_ERROR_IO_ERROR;
858 memset(&ifr_tun, 0, sizeof(ifr_tun));
859 g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name));
861 /* set the flags for vpn up */
862 if (ioctl(sk, SIOCGIFFLAGS, &ifr_tun) < 0) {
863 ERR("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
865 return VPNSVC_ERROR_IO_ERROR;
868 ifr_tun.ifr_flags |= IFF_UP;
869 ifr_tun.ifr_flags |= IFF_RUNNING;
871 if (ioctl(sk, SIOCSIFFLAGS, &ifr_tun) < 0) {
872 ERR("ioctl SIOCSIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
874 return VPNSVC_ERROR_IO_ERROR;
880 /* add DNS servers */
882 ret = add_dns_servers(dns_servers, nr_dns, total_dns_string_cnt);
883 if (ret != VPNSVC_ERROR_NONE) {
884 ERR("add_dns failed");
891 ret = add_dns_suffix(dns_suffix, strlen(dns_suffix));
892 if (ret != VPNSVC_ERROR_NONE) {
893 ERR("add_dns_suffix failed");
899 dns_nat_register(dns_servers, nr_dns, local_ip);
907 int vpn_service_down(const char *iface_name)
911 char buf[BUF_SIZE_FOR_ERR] = { 0 };
913 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
915 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
916 return VPNSVC_ERROR_IO_ERROR;
919 memset(&ifr, 0, sizeof(ifr));
920 g_strlcpy((char *)ifr.ifr_name, iface_name, sizeof(ifr.ifr_name));
922 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
923 ERR("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
925 return VPNSVC_ERROR_IO_ERROR;
928 if (!(ifr.ifr_flags & IFF_UP)) {
929 DBG("Interface already down");
931 return VPNSVC_ERROR_NONE;
934 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
935 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
936 ERR("ioctl SIOCSIFFLAGS (interface down) failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
938 return VPNSVC_ERROR_IO_ERROR;
943 /* routes are will be removed automatically while down interfaces */
944 /* remove dns servers */
947 /* remove dns suffix */
950 /* remove dns filter */
951 dns_nat_unregister();
953 return VPNSVC_ERROR_NONE;
956 int vpn_service_block_networks(char* nets_vpn[], int prefix_vpn[], size_t nr_nets_vpn,
957 char* nets_orig[], int prefix_orig[], size_t nr_nets_orig) {
960 /* iptable chain regist */
963 for (i = 0; i < nr_nets_vpn; i++) {
964 DBG("block[%d] ip/mask : %s/%d", i, nets_vpn[i], prefix_vpn[i]);
965 iptables_add(nets_vpn[i], prefix_vpn[i]);
968 for (i = 0; i < nr_nets_orig; i++) {
969 DBG("allow[%d] ip/mask : %s/%d", i, nets_orig[i], prefix_orig[i]);
970 iptables_add_orig(nets_orig[i], prefix_orig[i]);
973 return VPNSVC_ERROR_NONE;
976 int vpn_service_unblock_networks(void)
978 iptables_unregister();
980 return VPNSVC_ERROR_NONE;
983 int vpn_service_update_settings(int iface_index, const char *local_ip,
984 const char *remote_ip, const unsigned int mtu)
987 struct ifreq ifr_tun;
988 struct sockaddr_in local_addr;
989 struct sockaddr_in remote_addr;
990 char buf[BUF_SIZE_FOR_ERR] = { 0 };
992 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
994 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
995 return VPNSVC_ERROR_IO_ERROR;
998 memset(&ifr_tun, 0, sizeof(ifr_tun));
999 ifr_tun.ifr_ifindex = iface_index;
1001 /* get an interface name by ifindex */
1002 if (ioctl(sk, SIOCGIFNAME, &ifr_tun) < 0) {
1003 ERR("ioctl SIOCGIFNAME failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1005 return VPNSVC_ERROR_IO_ERROR;
1008 /* local ip setting */
1009 memset(&local_addr, 0, sizeof(local_addr));
1010 local_addr.sin_addr.s_addr = inet_addr(local_ip); /* network byte order */
1011 local_addr.sin_family = AF_INET;
1012 memcpy(&ifr_tun.ifr_addr, &local_addr, sizeof(ifr_tun.ifr_addr));
1013 if (ioctl(sk, SIOCSIFADDR, &ifr_tun) < 0) {
1014 ERR("ioctl SIOCSIFADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1016 return VPNSVC_ERROR_IO_ERROR;
1019 /* remote ip setting */
1020 memset(&remote_addr, 0, sizeof(remote_addr));
1021 remote_addr.sin_addr.s_addr = inet_addr(remote_ip); /*network byte order*/
1022 remote_addr.sin_family = AF_INET;
1023 memcpy(&ifr_tun.ifr_dstaddr, &remote_addr, sizeof(ifr_tun.ifr_dstaddr));
1024 if (ioctl(sk, SIOCSIFDSTADDR, &ifr_tun) < 0) {
1025 ERR("ioctl SIOCSIFDSTADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1027 return VPNSVC_ERROR_IO_ERROR;
1031 if (mtu > 0 && ifr_tun.ifr_mtu != (int)mtu) {
1032 ifr_tun.ifr_mtu = mtu;
1033 if (ioctl(sk, SIOCSIFMTU, &ifr_tun) < 0) {
1034 ERR("ioctl SIOCSIFMTU failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1036 return VPNSVC_ERROR_IO_ERROR;
1042 return VPNSVC_ERROR_NONE;
1045 int vpn_service_add_route(char *iface_name, const char *route, int prefix)
1048 struct sockaddr_in addr;
1050 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1052 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1054 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1055 return VPNSVC_ERROR_IO_ERROR;
1058 memset(&rt, 0, sizeof(rt));
1059 rt.rt_flags = RTF_UP;
1061 memset(&addr, 0, sizeof(addr));
1062 addr.sin_family = AF_INET;
1063 addr.sin_addr.s_addr = inet_addr(route);
1064 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1066 memset(&addr, 0, sizeof(addr));
1067 addr.sin_family = AF_INET;
1068 addr.sin_addr.s_addr = INADDR_ANY;
1069 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1071 /* set mask using by prefix length */
1072 memset(&addr, 0, sizeof(addr));
1073 addr.sin_family = AF_INET;
1074 addr.sin_addr.s_addr = INADDR_ANY;
1075 addr.sin_addr.s_addr = host2net(make_mask(prefix));
1076 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1078 rt.rt_dev = iface_name;
1080 if (ioctl(sk, SIOCADDRT, &rt) < 0) {
1081 ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1083 return VPNSVC_ERROR_IO_ERROR;
1088 return VPNSVC_ERROR_NONE;
1091 int vpn_service_remove_route(char *iface_name, const char *route, int prefix)
1094 struct sockaddr_in addr;
1096 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1098 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1100 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1101 return VPNSVC_ERROR_IO_ERROR;
1104 memset(&rt, 0, sizeof(rt));
1105 rt.rt_flags = RTF_UP;
1107 memset(&addr, 0, sizeof(addr));
1108 addr.sin_family = AF_INET;
1109 addr.sin_addr.s_addr = inet_addr(route);
1110 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1112 memset(&addr, 0, sizeof(addr));
1113 addr.sin_family = AF_INET;
1114 addr.sin_addr.s_addr = INADDR_ANY;
1115 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1117 /* set mask using by prefix length */
1118 memset(&addr, 0, sizeof(addr));
1119 addr.sin_family = AF_INET;
1120 addr.sin_addr.s_addr = INADDR_ANY;
1121 addr.sin_addr.s_addr = host2net(make_mask(prefix));
1122 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1124 rt.rt_dev = iface_name;
1126 if (ioctl(sk, SIOCDELRT, &rt) < 0) {
1127 ERR("ioctl SIOCDERLT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1129 return VPNSVC_ERROR_IO_ERROR;
1134 return VPNSVC_ERROR_NONE;
1138 int vpn_service_add_dns_server(char *iface_name, const char *dns_server)
1141 struct sockaddr_in addr;
1143 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1145 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1147 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1148 return VPNSVC_ERROR_IO_ERROR;
1151 memset(&rt, 0, sizeof(rt));
1152 rt.rt_flags = RTF_UP;
1154 memset(&addr, 0, sizeof(addr));
1155 addr.sin_family = AF_INET;
1156 addr.sin_addr.s_addr = inet_addr(dns_server);
1157 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1159 memset(&addr, 0, sizeof(addr));
1160 addr.sin_family = AF_INET;
1161 addr.sin_addr.s_addr = INADDR_ANY;
1162 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1164 /* set mask using by prefix length */
1165 memset(&addr, 0, sizeof(addr));
1166 addr.sin_family = AF_INET;
1167 addr.sin_addr.s_addr = INADDR_ANY;
1168 addr.sin_addr.s_addr = host2net(make_mask(32));
1169 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1171 rt.rt_dev = iface_name;
1173 if (ioctl(sk, SIOCADDRT, &rt) < 0) {
1174 ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1176 return VPNSVC_ERROR_IO_ERROR;
1181 return VPNSVC_ERROR_NONE;
1184 int vpn_service_remove_dns_server(char *iface_name, const char *dns_server)
1187 struct sockaddr_in addr;
1189 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1191 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1193 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1194 return VPNSVC_ERROR_IO_ERROR;
1197 memset(&rt, 0, sizeof(rt));
1198 rt.rt_flags = RTF_UP;
1200 memset(&addr, 0, sizeof(addr));
1201 addr.sin_family = AF_INET;
1202 addr.sin_addr.s_addr = inet_addr(dns_server);
1203 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1205 memset(&addr, 0, sizeof(addr));
1206 addr.sin_family = AF_INET;
1207 addr.sin_addr.s_addr = INADDR_ANY;
1208 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1210 /* set mask using by prefix length */
1211 memset(&addr, 0, sizeof(addr));
1212 addr.sin_family = AF_INET;
1213 addr.sin_addr.s_addr = INADDR_ANY;
1214 addr.sin_addr.s_addr = host2net(make_mask(32));
1215 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1217 rt.rt_dev = iface_name;
1219 if (ioctl(sk, SIOCDELRT, &rt) < 0) {
1220 ERR("ioctl SIOCDELRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1222 return VPNSVC_ERROR_IO_ERROR;
1227 return VPNSVC_ERROR_NONE;