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"
39 #define BUF_SIZE_FOR_ERR 100
41 #define CONNMAN_SERVICE "net.connman"
42 #define CONNMAN_INTERFACE_MANAGER "net.connman.Manager"
43 #define CONNMAN_INTERFACE_SERVICE "net.connman.Service"
47 static char iptables_cmd[] = "/usr/sbin/iptables";
48 static char iptables_filter_prefix[] = "CAPI_VPN_SERVICE_";
49 static char iptables_filter_out[] = "OUTPUT";
50 static char iptables_filter_in[] = "INPUT";
51 static char iptables_filter_interface_wlan[] = "wlan0";
52 /* static char iptables_register_fmt[] = "%s -N %s%s -w;" "%s -F %s%s -w;" "%s -A %s%s -j RETURN -w;" "%s -I %s -j %s%s -w;"; */
53 static char iptables_register_fmt[] = "%s -N %s%s -w;" "%s -F %s%s -w;" "%s -A %s%s -j DROP -w;" "%s -A %s%s -j RETURN -w;" "%s -I %s -j %s%s -w;";
54 static char iptables_unregister_fmt[] = "%s -D %s -j %s%s -w;" "%s -F %s%s -w;" "%s -X %s%s -w;";
55 static char iptables_rule_fmt[] = "%s -%c %s%s -%c %s/%d -j ACCEPT -w;";
56 static char iptables_rule_with_interface_fmt[] = "%s -%c %s%s -%c %s -%c %s/%d -j ACCEPT -w;";
57 /*static char iptables_usage_fmt[] = "%s -L %s%s -n -v -w;";*/
58 /* iptables -t nat -A CAPI_VPN_SERVICE_OUTPUT -p udp -d <vpn dns address> --dport 53 -j DNAT --to <vpn defice address:53> */
59 static char iptables_nat_chain_name[] = "CAPI_VPN_SERVICE_NAT_OUTPUT";
61 static char iptables_nat_register_init_fmt[] = "%s -t nat -N %s -w;" "%s -t nat -F %s -w;" "%s -t nat -I %s -j %s -w;";
62 static char iptables_nat_register_rule_fmt[] = "%s -t nat -A %s -p udp -d %s --dport 53 -j DNAT --to %s:53 -w;";
64 static char iptables_nat_unregister_fmt[] = "%s -t nat -D %s -j %s -w;" "%s -t nat -F %s -w;" "%s -t nat -X %s -w;";
66 typedef unsigned long int ipv4; /* Declare variable type for ipv4 net address. */
68 static GDBusConnection *global_connection = NULL;
70 static ipv4 make_mask(int prefix)
75 for (i = prefix; i > 0; i--)
76 mask += (ipv4) (1 << (32 - i));
80 static in_addr_t host2net(ipv4 host)
86 net |= (host & 0x000000FF) << 24;
87 net |= (host & 0x0000FF00) << 8;
88 net |= (host & 0x00FF0000) >> 8;
89 net |= (host & 0xFF000000) >> 24;
94 static void connman_connection_open(void)
96 if (global_connection == NULL) {
98 #if !GLIB_CHECK_VERSION(2, 36, 0)
102 global_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
103 if (global_connection == NULL) {
105 ERR("Error connman connection open: %s", error->message);
112 static void connman_connection_close(GDBusConnection *connection)
115 g_object_unref(connection);
118 static GVariant *connman_method_call(
119 GDBusConnection *connection, char *service, char *path,
120 char *interface, char *method, GVariant *params)
122 GError *error = NULL;
123 GVariant *message = NULL;
125 message = g_dbus_connection_call_sync(
126 connection, service, path, interface, method, params,
127 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
129 if (message == NULL) {
131 ERR("error: g_dbus_connection_call_sync [%d: %s]", error->code, error->message);
134 ERR("error: g_dbus_connection_call_sync\n");
141 static char *connman_default_profile(GDBusConnection *connection)
144 GVariantIter *value = NULL;
145 GVariant *message = NULL;
146 GVariantIter *iter = NULL;
147 char *profile = NULL;
149 message = connman_method_call(connection, CONNMAN_SERVICE, "/",
150 CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
153 g_variant_get(message, "(a(oa{sv}))", &iter);
154 while (g_variant_iter_loop(iter, "(oa{sv})", &key, &value)) {
155 profile = strdup(key);
160 g_variant_iter_free(value);
164 g_variant_iter_free(iter);
165 g_variant_unref(message);
172 static char *connman_get_items(GDBusConnection *connection, char *profile, const char *keystr)
174 GVariant *message = NULL;
175 GVariantIter *iter = NULL;
176 GVariantIter *next = NULL;
180 message = connman_method_call(connection, CONNMAN_SERVICE, "/",
181 CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
184 g_variant_get(message, "(a(oa{sv}))", &iter);
185 while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
186 if (strcmp(obj, profile) == 0) {
190 while (g_variant_iter_loop(next, "{sv}", &key, &var)) {
191 if (g_strcmp0(key, keystr) == 0) {
192 GVariantIter *iter_item;
193 const gchar *value = NULL;
195 g_variant_get(var, "as", &iter_item);
196 while (g_variant_iter_loop(iter_item, "s", &value)) {
200 tmp_items = (char *) malloc(strlen(items) + 1 + strlen(value) + 1);
202 snprintf(tmp_items, strlen(tmp_items), "%s,%s", items, value);
207 items = strdup(value);
210 g_variant_iter_free(iter_item);
217 g_variant_iter_free(iter);
218 g_variant_unref(message);
225 static void connman_set_items(GDBusConnection *connection, char *profile,
226 const char *keystr, char *items)
228 GVariant *message = NULL;
229 GVariantBuilder *builder = NULL;
230 GVariant *params = NULL;
231 char *strings = strdup(items);
235 builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
236 if ((addr = strtok_r(strings, ", ", &temp)) != NULL) {
238 g_variant_builder_add(builder, "s", addr);
239 } while ((addr = strtok_r(NULL, ", ", &temp)) != NULL);
242 params = g_variant_new("(sv)", keystr,
243 g_variant_builder_end(builder));
244 g_variant_builder_unref(builder);
246 message = connman_method_call(connection, CONNMAN_SERVICE, profile,
247 CONNMAN_INTERFACE_SERVICE, "SetProperty", params);
249 g_variant_unref(message);
254 static char *connman_get_nameservers(GDBusConnection *connection, char *profile)
256 return connman_get_items(connection, profile, "Nameservers");
259 static char *connman_get_nameservers_conf(GDBusConnection *connection, char *profile)
261 return connman_get_items(connection, profile, "Nameservers.Configuration");
265 static void connman_set_nameservers(GDBusConnection *connection, char *profile,
268 return connman_set_items(connection, profile,
269 "Nameservers.Configuration", nameservers);
273 static char *connman_get_domains(GDBusConnection *connection, char *profile)
275 return connman_get_items(connection, profile, "Domains");
278 static char *connman_get_domains_conf(GDBusConnection *connection, char *profile)
280 return connman_get_items(connection, profile, "Domains.Configuration");
284 static void connman_set_domains(GDBusConnection *connection, char *profile,
287 return connman_set_items(connection, profile,
288 "Domains.Configuration", domains);
292 static int add_dns_servers(char** dns_servers, size_t nr_dns, size_t total_dns_string_cnt)
294 char *profile = NULL;
296 char *org_items = NULL;
297 char *new_items = NULL;
300 connman_connection_open();
302 profile = connman_default_profile(global_connection);
303 if (profile == NULL) {
304 ERR("connman_default_profile failed");
305 connman_connection_close(global_connection);
306 return VPNSVC_ERROR_IPC_FAILED;
309 DBG("profile : %s\n", profile);
311 /* add name servers */
312 org_items = connman_get_nameservers(global_connection, profile);
315 DBG("original DNS : %s\n", org_items);
316 /* nr_dns = comma(,) count */
317 items = (char *) calloc((total_dns_string_cnt + nr_dns + strlen(org_items) + 1), sizeof(char));
319 ERR("OOM while malloc\n");
320 return VPNSVC_ERROR_OUT_OF_MEMORY;
322 strncpy(items, org_items, strlen(org_items));
323 for (i = 0 ; i < nr_dns ; i++) {
324 strncat(items, ",", 1);
325 strncat(items, dns_servers[i], strlen(dns_servers[i]));
330 /* nr_dns = comma(,) count + end null char */
331 items = (char *) calloc(total_dns_string_cnt + nr_dns, sizeof(char));
333 ERR("OOM while malloc\n");
334 return VPNSVC_ERROR_OUT_OF_MEMORY;
336 for (i = 0 ; i < nr_dns ; i++) {
337 strncat(items, dns_servers[i], strlen(dns_servers[i]));
339 strncat(items, ",", 1);
344 DBG("adding DNS : %s\n", items);
345 connman_set_nameservers(global_connection, profile, items);
351 new_items = connman_get_nameservers_conf(global_connection, profile);
352 DBG("new_dns : %s\n", new_items);
357 return VPNSVC_ERROR_NONE;
361 static int del_dns_servers()
363 char *profile = NULL;
365 connman_connection_open();
367 profile = connman_default_profile(global_connection);
368 if (profile == NULL) {
369 ERR("connman_default_profile failed");
370 connman_connection_close(global_connection);
371 return VPNSVC_ERROR_IPC_FAILED;
374 DBG("profile : %s", profile);
376 /* del name servers */
377 connman_set_nameservers(global_connection, profile, "");
382 return VPNSVC_ERROR_NONE;
386 static int add_dns_suffix(const char* dns_suffix, size_t dns_suffix_len)
388 char *profile = NULL;
390 char *org_items = NULL;
391 char *new_items = NULL;
393 connman_connection_open();
395 profile = connman_default_profile(global_connection);
396 if (profile == NULL) {
397 ERR("connman_default_profile failed");
398 connman_connection_close(global_connection);
399 return VPNSVC_ERROR_IPC_FAILED;
402 DBG("profile : %s", profile);
404 /* add name servers */
405 org_items = connman_get_domains(global_connection, profile);
408 DBG("original DNS suffix : %s", org_items);
409 /* comma(,) and end null character included */
410 items = (char *) calloc((dns_suffix_len + strlen(org_items) + 2), sizeof(char));
412 ERR("OOM while malloc");
413 return VPNSVC_ERROR_OUT_OF_MEMORY;
415 strncpy(items, org_items, strlen(org_items));
416 strncat(items, ",", 1);
417 strncat(items, dns_suffix, dns_suffix_len);
421 /* nr_dns = comma(,) count + end null char */
422 items = (char *) calloc((dns_suffix_len + 1), sizeof(char));
424 ERR("OOM while malloc");
425 return VPNSVC_ERROR_OUT_OF_MEMORY;
427 strncat(items, dns_suffix, dns_suffix_len);
431 DBG("adding DNS suffix : %s\n", items);
432 connman_set_domains(global_connection, profile, items);
437 /* print new domains */
438 new_items = connman_get_domains_conf(global_connection, profile);
439 DBG("new DNS suffix : %s\n", new_items);
447 return VPNSVC_ERROR_NONE;
451 static int del_dns_suffix()
453 char *profile = NULL;
455 connman_connection_open();
457 profile = connman_default_profile(global_connection);
458 if (profile == NULL) {
459 ERR("connman_default_profile failed");
460 connman_connection_close(global_connection);
461 return VPNSVC_ERROR_IPC_FAILED;
464 DBG("profile : %s", profile);
467 connman_set_domains(global_connection, profile, "");
472 return VPNSVC_ERROR_NONE;
476 static void iptables_exec(char *cmdline)
480 fp = popen(cmdline, "r");
487 static void dns_nat_register(char **vpn_dns_address, size_t nr_dns, char *vpn_device_address)
492 snprintf(buf + size, sizeof(buf) - size, iptables_nat_register_init_fmt,
493 iptables_cmd, iptables_nat_chain_name,
494 iptables_cmd, iptables_nat_chain_name,
495 iptables_cmd, iptables_filter_out, iptables_nat_chain_name);
498 for (i = 0 ; i < nr_dns ; i++) {
499 snprintf(buf + size, sizeof(buf) - size, iptables_nat_register_rule_fmt,
500 iptables_cmd, iptables_nat_chain_name, vpn_dns_address[i], vpn_device_address);
503 DBG("iptable dns nat reg cmd : %s", buf);
508 static void dns_nat_unregister(void)
513 snprintf(buf + size, sizeof(buf) - size, iptables_nat_unregister_fmt,
514 iptables_cmd, iptables_filter_out, iptables_nat_chain_name,
515 iptables_cmd, iptables_nat_chain_name,
516 iptables_cmd, iptables_nat_chain_name);
518 DBG("iptable dns nat unreg cmd : %s", buf);
522 static void iptables_register(void)
525 char buf[8192], *filter;
527 filter = iptables_filter_out;
528 snprintf(buf + size, sizeof(buf) - size, iptables_register_fmt,
529 iptables_cmd, iptables_filter_prefix, filter,
530 iptables_cmd, iptables_filter_prefix, filter,
531 iptables_cmd, iptables_filter_prefix, filter,
532 iptables_cmd, iptables_filter_prefix, filter,
533 iptables_cmd, filter, iptables_filter_prefix, filter);
535 filter = iptables_filter_in;
536 snprintf(buf + size, sizeof(buf) - size, iptables_register_fmt,
537 iptables_cmd, iptables_filter_prefix, filter,
538 iptables_cmd, iptables_filter_prefix, filter,
539 iptables_cmd, iptables_filter_prefix, filter,
540 iptables_cmd, iptables_filter_prefix, filter,
541 iptables_cmd, filter, iptables_filter_prefix, filter);
542 DBG("iptable reg cmd : %s", buf);
546 static void iptables_unregister(void)
549 char buf[8192], *filter;
551 filter = iptables_filter_out;
552 snprintf(buf + size, sizeof(buf) - size, iptables_unregister_fmt,
553 iptables_cmd, filter, iptables_filter_prefix, filter,
554 iptables_cmd, iptables_filter_prefix, filter,
555 iptables_cmd, iptables_filter_prefix, filter);
557 filter = iptables_filter_in;
558 snprintf(buf + size, sizeof(buf) - size, iptables_unregister_fmt,
559 iptables_cmd, filter, iptables_filter_prefix, filter,
560 iptables_cmd, iptables_filter_prefix, filter,
561 iptables_cmd, iptables_filter_prefix, filter);
562 DBG("iptable unreg cmd : %s", buf);
566 static void iptables_rule(const char c, const char *addr, const int mask)
571 snprintf(buf + size, sizeof(buf) - size, iptables_rule_fmt, iptables_cmd, c,
572 iptables_filter_prefix, iptables_filter_out, 'd', addr, mask);
574 snprintf(buf + size, sizeof(buf) - size, iptables_rule_fmt, iptables_cmd, c,
575 iptables_filter_prefix, iptables_filter_in, 's', addr, mask);
576 DBG("iptable cmd : %s", buf);
580 static void iptables_rule_interface(const char c, const char *addr, const int mask, const char *interface)
585 snprintf(buf + size, sizeof(buf) - size,
586 iptables_rule_with_interface_fmt, iptables_cmd,
587 c, iptables_filter_prefix, iptables_filter_out,
588 'o', interface, 'd', addr, mask);
590 snprintf(buf + size, sizeof(buf) - size,
591 iptables_rule_with_interface_fmt, iptables_cmd,
592 c, iptables_filter_prefix, iptables_filter_in,
593 'i', interface, 's', addr, mask);
594 DBG("iptable cmd : %s", buf);
598 void iptables_add_orig(const char *addr, const int mask)
600 iptables_rule_interface('I', addr, mask, iptables_filter_interface_wlan);
603 void iptables_delete_orig(const char *addr, const int mask)
605 iptables_rule_interface('D', addr, mask, iptables_filter_interface_wlan);
608 void iptables_add(const char *addr, const int mask)
610 iptables_rule('I', addr, mask);
613 void iptables_delete(const char *addr, const int mask)
615 iptables_rule('D', addr, mask);
618 static int get_interface_index(const char *iface_name)
622 char buf[BUF_SIZE_FOR_ERR] = { 0 };
624 DBG("enter get_interface_index, iface_name : %s", iface_name);
626 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
628 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
629 return VPNSVC_ERROR_IO_ERROR;
632 memset(&ifr, 0, sizeof(ifr));
635 strncpy(ifr.ifr_name, iface_name, strlen(iface_name));
637 /* get an interface name by ifindex */
638 if (ioctl(sk, SIOCGIFINDEX, &ifr) < 0) {
639 ERR("ioctl SIOCGIFINDEX failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
641 return VPNSVC_ERROR_IO_ERROR;
646 return ifr.ifr_ifindex;
649 static int check_interface_precondition(const char *iface_name)
653 struct ifreq ifr_tun;
654 char buf[BUF_SIZE_FOR_ERR] = { 0 };
656 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
658 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
659 return VPNSVC_ERROR_IO_ERROR;
662 memset(&ifr_tun, 0, sizeof(ifr_tun));
663 g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name));
666 if (ioctl(sk, SIOCGIFADDR, &ifr_tun) < 0) {
667 ERR("Fail to get local IP address: %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
669 return VPNSVC_ERROR_INVALID_PARAMETER;
673 if (ioctl(sk, SIOCGIFDSTADDR, &ifr_tun) < 0) {
674 ERR("Fail to get remote IP address: %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
676 return VPNSVC_ERROR_INVALID_PARAMETER;
681 return VPNSVC_ERROR_NONE;
685 int vpn_service_init(const char* iface_name, size_t iface_name_len, int fd, vpnsvc_tun_s *handle_s)
689 char buf[BUF_SIZE_FOR_ERR] = { 0 };
691 DBG("enter vpn_daemon_init, iface_name : %s, iface_name_len : %d, fd : %d\n", iface_name, iface_name_len, fd);
693 memset(&ifr, 0, sizeof(ifr));
695 /* Flags: IFF_TUN - TUN device (no Ethernet headers)
696 * IFF_TAP - TAP device
698 * IFF_NO_PI - Do not provide packet information
701 ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
704 strncpy(ifr.ifr_name, iface_name, iface_name_len);
706 DBG("before init, ifindex : %d", ifr.ifr_ifindex);
708 if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
709 ERR("TUNSETIFF Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
711 return VPNSVC_ERROR_IO_ERROR;
714 if (ioctl(fd, TUNSETOWNER, 5000) < 0) {
715 ERR("TUNSETOWNER Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
717 return VPNSVC_ERROR_IO_ERROR;
720 if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
721 ERR("TUNSETPERSIST Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
723 return VPNSVC_ERROR_IO_ERROR;
726 handle_s->fd = 0; /* server fd does not meaning */
727 handle_s->index = get_interface_index(iface_name);
728 len = strlen(ifr.ifr_name);
729 strncpy(handle_s->name, ifr.ifr_name, len);
730 handle_s->name[len] = '\0';
732 return VPNSVC_ERROR_NONE;
735 int vpn_service_deinit(const char* dev_name)
740 snprintf(buf, sizeof(buf), "/usr/sbin/ip link del %s", dev_name);
741 DBG("link delete cmd : %s", buf);
743 fp = popen(buf, "r");
746 return VPNSVC_ERROR_NONE;
748 return VPNSVC_ERROR_IO_ERROR;
752 int vpn_service_protect(int socket_fd, const char* dev_name)
754 int ret = VPNSVC_ERROR_NONE;
755 char buf[BUF_SIZE_FOR_ERR] = { 0 };
756 DBG("enter vpn_daemon_protect, socket : %d, dev_name : %s\n", socket_fd, dev_name);
758 ret = setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE,
759 dev_name, strlen(dev_name));
762 DBG("setsockopt failed : %d, %s", ret, strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
763 ret = VPNSVC_ERROR_IO_ERROR;
765 ret = VPNSVC_ERROR_NONE;
771 int vpn_service_up(const char *iface_name)
773 struct ifreq ifr_tun;
775 int ret = VPNSVC_ERROR_NONE;
776 char buf[BUF_SIZE_FOR_ERR] = { 0 };
778 DBG("enter vpn_daemon_up");
779 DBG("iface_name : %s", iface_name);
782 ret = check_interface_precondition(iface_name);
783 if (ret != VPNSVC_ERROR_NONE)
786 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
788 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
789 return VPNSVC_ERROR_IO_ERROR;
792 memset(&ifr_tun, 0, sizeof(ifr_tun));
793 g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name));
795 /* set the flags for vpn up */
796 if (ioctl(sk, SIOCGIFFLAGS, &ifr_tun) < 0) {
797 ERR("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
799 return VPNSVC_ERROR_IO_ERROR;
802 ifr_tun.ifr_flags |= IFF_UP;
803 ifr_tun.ifr_flags |= IFF_RUNNING;
805 if (ioctl(sk, SIOCSIFFLAGS, &ifr_tun) < 0) {
806 ERR("ioctl SIOCSIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
808 return VPNSVC_ERROR_IO_ERROR;
814 /* add DNS servers */
816 ret = add_dns_servers(dns_servers, nr_dns, total_dns_string_cnt);
817 if (ret != VPNSVC_ERROR_NONE) {
818 ERR("add_dns failed");
825 ret = add_dns_suffix(dns_suffix, strlen(dns_suffix));
826 if (ret != VPNSVC_ERROR_NONE) {
827 ERR("add_dns_suffix failed");
833 dns_nat_register(dns_servers, nr_dns, local_ip);
841 int vpn_service_down(const char *iface_name)
845 char buf[BUF_SIZE_FOR_ERR] = { 0 };
847 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
849 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
850 return VPNSVC_ERROR_IO_ERROR;
853 memset(&ifr, 0, sizeof(ifr));
854 g_strlcpy((char *)ifr.ifr_name, iface_name, sizeof(ifr.ifr_name));
856 if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
857 ERR("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
859 return VPNSVC_ERROR_IO_ERROR;
862 if (!(ifr.ifr_flags & IFF_UP)) {
863 DBG("Interface already down");
865 return VPNSVC_ERROR_NONE;
868 ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
869 if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
870 ERR("ioctl SIOCSIFFLAGS (interface down) failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
872 return VPNSVC_ERROR_IO_ERROR;
877 /* routes are will be removed automatically while down interfaces */
878 /* remove dns servers */
881 /* remove dns suffix */
884 /* remove dns filter */
885 dns_nat_unregister();
887 return VPNSVC_ERROR_NONE;
890 int vpn_service_block_networks(char* nets_vpn[], int prefix_vpn[], size_t nr_nets_vpn,
891 char* nets_orig[], int prefix_orig[], size_t nr_nets_orig) {
894 /* iptable chain regist */
897 for (i = 0; i < nr_nets_vpn; i++) {
898 DBG("block[%d] ip/mask : %s/%d", i, nets_vpn[i], prefix_vpn[i]);
899 iptables_add(nets_vpn[i], prefix_vpn[i]);
902 for (i = 0; i < nr_nets_orig; i++) {
903 DBG("allow[%d] ip/mask : %s/%d", i, nets_orig[i], prefix_orig[i]);
904 iptables_add_orig(nets_orig[i], prefix_orig[i]);
907 return VPNSVC_ERROR_NONE;
910 int vpn_service_unblock_networks(void)
912 iptables_unregister();
914 return VPNSVC_ERROR_NONE;
917 int vpn_service_update_settings(int iface_index, const char *local_ip,
918 const char *remote_ip, const unsigned int mtu)
921 struct ifreq ifr_tun;
922 struct sockaddr_in local_addr;
923 struct sockaddr_in remote_addr;
924 char buf[BUF_SIZE_FOR_ERR] = { 0 };
926 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
928 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
929 return VPNSVC_ERROR_IO_ERROR;
932 memset(&ifr_tun, 0, sizeof(ifr_tun));
933 ifr_tun.ifr_ifindex = iface_index;
935 /* get an interface name by ifindex */
936 if (ioctl(sk, SIOCGIFNAME, &ifr_tun) < 0) {
937 ERR("ioctl SIOCGIFNAME failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
939 return VPNSVC_ERROR_IO_ERROR;
942 /* local ip setting */
943 memset(&local_addr, 0, sizeof(local_addr));
944 local_addr.sin_addr.s_addr = inet_addr(local_ip); /* network byte order */
945 local_addr.sin_family = AF_INET;
946 memcpy(&ifr_tun.ifr_addr, &local_addr, sizeof(ifr_tun.ifr_addr));
947 if (ioctl(sk, SIOCSIFADDR, &ifr_tun) < 0) {
948 ERR("ioctl SIOCSIFADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
950 return VPNSVC_ERROR_IO_ERROR;
953 /* remote ip setting */
954 memset(&remote_addr, 0, sizeof(remote_addr));
955 remote_addr.sin_addr.s_addr = inet_addr(remote_ip); /*network byte order*/
956 remote_addr.sin_family = AF_INET;
957 memcpy(&ifr_tun.ifr_dstaddr, &remote_addr, sizeof(ifr_tun.ifr_dstaddr));
958 if (ioctl(sk, SIOCSIFDSTADDR, &ifr_tun) < 0) {
959 ERR("ioctl SIOCSIFDSTADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
961 return VPNSVC_ERROR_IO_ERROR;
965 if (mtu > 0 && ifr_tun.ifr_mtu != (int)mtu) {
966 ifr_tun.ifr_mtu = mtu;
967 if (ioctl(sk, SIOCSIFMTU, &ifr_tun) < 0) {
968 ERR("ioctl SIOCSIFMTU failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
970 return VPNSVC_ERROR_IO_ERROR;
976 return VPNSVC_ERROR_NONE;
979 int vpn_service_add_route(char *iface_name, const char *route, int prefix)
982 struct sockaddr_in addr;
984 char buf[BUF_SIZE_FOR_ERR] = { 0 };
986 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
988 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
989 return VPNSVC_ERROR_IO_ERROR;
992 memset(&rt, 0, sizeof(rt));
993 rt.rt_flags = RTF_UP;
995 memset(&addr, 0, sizeof(addr));
996 addr.sin_family = AF_INET;
997 addr.sin_addr.s_addr = inet_addr(route);
998 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1000 memset(&addr, 0, sizeof(addr));
1001 addr.sin_family = AF_INET;
1002 addr.sin_addr.s_addr = INADDR_ANY;
1003 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1005 /* set mask using by prefix length */
1006 memset(&addr, 0, sizeof(addr));
1007 addr.sin_family = AF_INET;
1008 addr.sin_addr.s_addr = INADDR_ANY;
1009 addr.sin_addr.s_addr = host2net(make_mask(prefix));
1010 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1012 rt.rt_dev = iface_name;
1014 if (ioctl(sk, SIOCADDRT, &rt) < 0) {
1015 ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1017 return VPNSVC_ERROR_IO_ERROR;
1022 return VPNSVC_ERROR_NONE;
1025 int vpn_service_remove_route(char *iface_name, const char *route, int prefix)
1028 struct sockaddr_in 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(&rt, 0, sizeof(rt));
1039 rt.rt_flags = RTF_UP;
1041 memset(&addr, 0, sizeof(addr));
1042 addr.sin_family = AF_INET;
1043 addr.sin_addr.s_addr = inet_addr(route);
1044 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1046 memset(&addr, 0, sizeof(addr));
1047 addr.sin_family = AF_INET;
1048 addr.sin_addr.s_addr = INADDR_ANY;
1049 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1051 /* set mask using by prefix length */
1052 memset(&addr, 0, sizeof(addr));
1053 addr.sin_family = AF_INET;
1054 addr.sin_addr.s_addr = INADDR_ANY;
1055 addr.sin_addr.s_addr = host2net(make_mask(prefix));
1056 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1058 rt.rt_dev = iface_name;
1060 if (ioctl(sk, SIOCDELRT, &rt) < 0) {
1061 ERR("ioctl SIOCDERLT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1063 return VPNSVC_ERROR_IO_ERROR;
1068 return VPNSVC_ERROR_NONE;
1072 int vpn_service_add_dns_server(char *iface_name, const char *dns_server)
1075 struct sockaddr_in addr;
1077 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1079 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1081 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1082 return VPNSVC_ERROR_IO_ERROR;
1085 memset(&rt, 0, sizeof(rt));
1086 rt.rt_flags = RTF_UP;
1088 memset(&addr, 0, sizeof(addr));
1089 addr.sin_family = AF_INET;
1090 addr.sin_addr.s_addr = inet_addr(dns_server);
1091 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1093 memset(&addr, 0, sizeof(addr));
1094 addr.sin_family = AF_INET;
1095 addr.sin_addr.s_addr = INADDR_ANY;
1096 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1098 /* set mask using by prefix length */
1099 memset(&addr, 0, sizeof(addr));
1100 addr.sin_family = AF_INET;
1101 addr.sin_addr.s_addr = INADDR_ANY;
1102 addr.sin_addr.s_addr = host2net(make_mask(32));
1103 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1105 rt.rt_dev = iface_name;
1107 if (ioctl(sk, SIOCADDRT, &rt) < 0) {
1108 ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1110 return VPNSVC_ERROR_IO_ERROR;
1115 return VPNSVC_ERROR_NONE;
1118 int vpn_service_remove_dns_server(char *iface_name, const char *dns_server)
1121 struct sockaddr_in addr;
1123 char buf[BUF_SIZE_FOR_ERR] = { 0 };
1125 sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1127 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1128 return VPNSVC_ERROR_IO_ERROR;
1131 memset(&rt, 0, sizeof(rt));
1132 rt.rt_flags = RTF_UP;
1134 memset(&addr, 0, sizeof(addr));
1135 addr.sin_family = AF_INET;
1136 addr.sin_addr.s_addr = inet_addr(dns_server);
1137 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1139 memset(&addr, 0, sizeof(addr));
1140 addr.sin_family = AF_INET;
1141 addr.sin_addr.s_addr = INADDR_ANY;
1142 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1144 /* set mask using by prefix length */
1145 memset(&addr, 0, sizeof(addr));
1146 addr.sin_family = AF_INET;
1147 addr.sin_addr.s_addr = INADDR_ANY;
1148 addr.sin_addr.s_addr = host2net(make_mask(32));
1149 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1151 rt.rt_dev = iface_name;
1153 if (ioctl(sk, SIOCDELRT, &rt) < 0) {
1154 ERR("ioctl SIOCDELRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1156 return VPNSVC_ERROR_IO_ERROR;
1161 return VPNSVC_ERROR_NONE;