Fixing P151224-03183, Redirect the DNS queries to VPN interface #2
[platform/core/api/vpn-service.git] / daemon / src / vpn_service_daemon.c
1 /*
2  * VPN Service Module
3  *
4  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20
21 #include <errno.h>
22 #include <net/route.h>
23 #include <glib.h>
24 #include <gio/gio.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/ioctl.h>
29 #include <sys/un.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32
33 #include "vpn_service_daemon.h"
34
35 #ifdef LOG_TAG
36 #undef LOG_TAG
37 #endif
38 #define LOG_TAG "VPNSVC_DAEMON"
39 #define BUF_SIZE_FOR_ERR 100
40
41 #define CONNMAN_SERVICE "net.connman"
42 #define CONNMAN_INTERFACE_MANAGER "net.connman.Manager"
43 #define CONNMAN_INTERFACE_SERVICE "net.connman.Service"
44
45
46 /* for iptables */
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";
60 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;";
61 static char iptables_nat_register_rule_fmt[] = "%s -t nat -A %s -p udp -d %s --dport 53 -j DNAT --to %s:53 -w;";
62 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;";
63
64 typedef unsigned long int ipv4; /* Declare variable type for ipv4 net address. */
65
66 static GDBusConnection *global_connection = NULL;
67
68 static ipv4 make_mask(int prefix)
69 {
70         ipv4 mask = 0;
71         int i = 0;
72
73         for (i = prefix; i > 0; i--)
74                 mask += (ipv4) (1 << (32 - i));
75         return mask;
76 }
77
78 static in_addr_t host2net(ipv4 host)
79 {
80         in_addr_t net;
81
82         net = 0;
83
84         net |= (host & 0x000000FF) << 24;
85         net |= (host & 0x0000FF00) <<  8;
86         net |= (host & 0x00FF0000) >>  8;
87         net |= (host & 0xFF000000) >> 24;
88
89         return net;
90 }
91
92 static int add_routes(char* iface_name, char* routes[], int prefix[], size_t nr_routes)
93 {
94         struct rtentry rt;
95         struct sockaddr_in addr;
96         int sk;
97         unsigned int i = 0;
98         char buf[BUF_SIZE_FOR_ERR] = { 0 };
99
100         LOGD("Enter add_routes");
101
102         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
103         if (sk < 0) {
104                 LOGE("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
105                 return VPNSVC_ERROR_IO_ERROR;
106         }
107
108         for (i = 0; i < nr_routes; i++) {
109                 memset(&rt, 0, sizeof(rt));
110                 rt.rt_flags = RTF_UP;
111
112                 memset(&addr, 0, sizeof(addr));
113                 addr.sin_family = AF_INET;
114                 addr.sin_addr.s_addr = inet_addr(routes[i]);
115                 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
116
117                 memset(&addr, 0, sizeof(addr));
118                 addr.sin_family = AF_INET;
119                 addr.sin_addr.s_addr = INADDR_ANY;
120                 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
121
122                 /* set mask using by prefix length */
123                 memset(&addr, 0, sizeof(addr));
124                 addr.sin_family = AF_INET;
125                 addr.sin_addr.s_addr = INADDR_ANY;
126                 addr.sin_addr.s_addr = host2net(make_mask(prefix[i]));
127                 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
128
129                 rt.rt_dev = iface_name;
130
131                 if (ioctl(sk, SIOCADDRT, &rt) < 0) {
132                         LOGE("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
133                         close(sk);
134                         return VPNSVC_ERROR_IO_ERROR;
135                 }
136         }
137
138         close(sk);
139
140         return VPNSVC_ERROR_NONE;
141 }
142
143 static int add_dns_routes(char* if_name, char** dns_servers, size_t nr_dns)
144 {
145         struct rtentry rt;
146         struct sockaddr_in addr;
147         int sk;
148         unsigned int i = 0;
149
150         LOGD("Enter add_routes");
151
152         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
153         if (sk < 0) {
154                 LOGE("socket failed : %s", strerror(errno));
155                 return VPNSVC_ERROR_IO_ERROR;
156         }
157
158         for (i = 0; i < nr_dns; i++) {
159                 memset(&rt, 0, sizeof(rt));
160                 rt.rt_flags = RTF_UP;
161
162                 memset(&addr, 0, sizeof(addr));
163                 addr.sin_family = AF_INET;
164                 addr.sin_addr.s_addr = inet_addr(dns_servers[i]);
165                 memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
166
167                 memset(&addr, 0, sizeof(addr));
168                 addr.sin_family = AF_INET;
169                 addr.sin_addr.s_addr = INADDR_ANY;
170                 memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
171
172                 /* set mask using by prefix length */
173                 memset(&addr, 0, sizeof(addr));
174                 addr.sin_family = AF_INET;
175                 addr.sin_addr.s_addr = INADDR_ANY;
176                 addr.sin_addr.s_addr = host2net(make_mask(32));
177                 memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
178
179                 rt.rt_dev = if_name;
180
181                 if (ioctl(sk, SIOCADDRT, &rt) < 0) {
182                         LOGE("ioctl SIOCADDRT failed : %s", strerror(errno));
183                         close(sk);
184                         return VPNSVC_ERROR_IO_ERROR;
185                 }
186         }
187
188         close(sk);
189
190         return VPNSVC_ERROR_NONE;
191 }
192
193 static void connman_connection_open(void)
194 {
195         if (global_connection == NULL) {
196                 GError *error = NULL;
197 #if !GLIB_CHECK_VERSION(2, 36, 0)
198                 g_type_init();
199 #endif
200
201                 global_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
202                 if (global_connection == NULL) {
203                         if (error != NULL) {
204                                 LOGE("Error connman connection open: %s", error->message);
205                                 g_error_free(error);
206                         }
207                 }
208         }
209 }
210
211 static void connman_connection_close(GDBusConnection *connection)
212 {
213         if (connection)
214                 g_object_unref(connection);
215 }
216
217 static GVariant *connman_method_call(
218         GDBusConnection *connection, char *service, char *path,
219         char *interface, char *method, GVariant *params)
220 {
221         GError *error = NULL;
222         GVariant *message = NULL;
223
224         message = g_dbus_connection_call_sync(
225                 connection, service, path, interface, method, params,
226                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
227
228         if (message == NULL) {
229                 if (error != NULL) {
230                         LOGE("error: g_dbus_connection_call_sync [%d: %s]", error->code, error->message);
231                         g_error_free(error);
232                 } else {
233                         LOGE("error: g_dbus_connection_call_sync\n");
234                 }
235         }
236
237         return message;
238 }
239
240 static char *connman_default_profile(GDBusConnection *connection)
241 {
242         gchar *key = NULL;
243         GVariantIter *value = NULL;
244         GVariant *message = NULL;
245         GVariantIter *iter = NULL;
246         char *profile = NULL;
247
248         message = connman_method_call(connection, CONNMAN_SERVICE, "/",
249                                                                   CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
250
251         if (message) {
252                 g_variant_get(message, "(a(oa{sv}))", &iter);
253                 while (g_variant_iter_loop(iter, "(oa{sv})", &key, &value)) {
254                         profile = strdup(key);
255                         break;
256                 }
257
258                 if (value)
259                         g_variant_iter_free(value);
260                 if (key)
261                         g_free(key);
262
263                 g_variant_iter_free(iter);
264                 g_variant_unref(message);
265         }
266
267         return profile;
268 }
269
270 static char *connman_get_items(GDBusConnection *connection, char *profile, const char *keystr)
271 {
272         GVariant *message = NULL;
273         GVariantIter *iter = NULL;
274         GVariantIter *next = NULL;
275         gchar *obj = NULL;
276         char *items = NULL;
277
278         message = connman_method_call(connection, CONNMAN_SERVICE, "/",
279                                                                   CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
280
281         if (message) {
282                 g_variant_get(message, "(a(oa{sv}))", &iter);
283                 while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
284                         if (strcmp(obj, profile) == 0) {
285                                 GVariant *var;
286                                 gchar *key;
287
288                                 while (g_variant_iter_loop(next, "{sv}", &key, &var)) {
289                                         if (g_strcmp0(key, keystr) == 0) {
290                                                 GVariantIter *iter_item;
291                                                 const gchar *value = NULL;
292
293                                                 g_variant_get(var, "as", &iter_item);
294                                                 while (g_variant_iter_loop(iter_item, "s", &value)) {
295                                                         if (items) {
296                                                                 char *tmp_items;
297
298                                                                 tmp_items = (char *) malloc(strlen(items) + 1 + strlen(value) + 1);
299                                                                 if (items) {
300                                                                         snprintf(tmp_items, strlen(tmp_items), "%s,%s", items, value);
301                                                                         free(items);
302                                                                         items = tmp_items;
303                                                                 }
304                                                         } else {
305                                                                 items = strdup(value);
306                                                         }
307                                                 }
308                                                 g_variant_iter_free(iter_item);
309                                                 break;
310                                         }
311                                 }
312                                 break;
313                         }
314                 }
315                 g_variant_iter_free(iter);
316                 g_variant_unref(message);
317         }
318
319         return items;
320 }
321
322 static void connman_set_items(GDBusConnection *connection, char *profile,
323                                                           const char *keystr, char *items)
324 {
325         GVariant *message = NULL;
326         GVariantBuilder *builder = NULL;
327         GVariant *params = NULL;
328         char *strings = strdup(items);
329         char *addr = NULL;
330         char *temp = NULL;
331
332         builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
333         if ((addr = strtok_r(strings, ", ", &temp)) != NULL) {
334                 do {
335                         g_variant_builder_add(builder, "s", addr);
336                 } while ((addr = strtok_r(NULL, ", ", &temp)) != NULL);
337         }
338         free(strings);
339         params = g_variant_new("(sv)", keystr,
340                                                    g_variant_builder_end(builder));
341         g_variant_builder_unref(builder);
342
343         message = connman_method_call(connection, CONNMAN_SERVICE, profile,
344                                                                   CONNMAN_INTERFACE_SERVICE, "SetProperty", params);
345         if (message)
346                 g_variant_unref(message);
347
348 }
349
350 static char *connman_get_nameservers(GDBusConnection *connection, char *profile)
351 {
352         return connman_get_items(connection, profile, "Nameservers");
353 }
354
355 static char *connman_get_nameservers_conf(GDBusConnection *connection, char *profile)
356 {
357         return connman_get_items(connection, profile, "Nameservers.Configuration");
358 }
359
360 static void connman_set_nameservers(GDBusConnection *connection, char *profile,
361                                                                         char *nameservers)
362 {
363         return connman_set_items(connection, profile,
364                                                          "Nameservers.Configuration", nameservers);
365 }
366
367 static char *connman_get_domains(GDBusConnection *connection, char *profile)
368 {
369         return connman_get_items(connection, profile, "Domains");
370 }
371
372 static char *connman_get_domains_conf(GDBusConnection *connection, char *profile)
373 {
374         return connman_get_items(connection, profile, "Domains.Configuration");
375 }
376
377 static void connman_set_domains(GDBusConnection *connection, char *profile,
378                                                                         char *domains)
379 {
380         return connman_set_items(connection, profile,
381                                                          "Domains.Configuration", domains);
382 }
383
384 static int add_dns_servers(char** dns_servers, size_t nr_dns, size_t total_dns_string_cnt)
385 {
386         char *profile = NULL;
387         char *items = NULL;
388         char *org_items = NULL;
389         char *new_items = NULL;
390         unsigned int i = 0;
391
392         connman_connection_open();
393
394         profile = connman_default_profile(global_connection);
395         if (profile == NULL) {
396                 LOGE("connman_default_profile failed");
397                 connman_connection_close(global_connection);
398                 return VPNSVC_ERROR_IPC_FAILED;
399         }
400
401         LOGD("profile : %s\n", profile);
402
403         /* add name servers */
404         org_items = connman_get_nameservers(global_connection, profile);
405
406         if (org_items) {
407                 LOGD("original DNS : %s\n", org_items);
408                 /* nr_dns = comma(,) count */
409                 items = (char *) calloc((total_dns_string_cnt + nr_dns + strlen(org_items) + 1), sizeof(char));
410                 if (items == NULL) {
411                         LOGE("OOM while malloc\n");
412                         return VPNSVC_ERROR_OUT_OF_MEMORY;
413                 }
414                 strncpy(items, org_items, strlen(org_items));
415                 for (i = 0 ; i < nr_dns ; i++) {
416                         strncat(items, ",", 1);
417                         strncat(items, dns_servers[i], strlen(dns_servers[i]));
418                 }
419                 free(org_items);
420                 org_items = NULL;
421         } else {
422                 /* nr_dns = comma(,) count + end null char */
423                 items = (char *) calloc(total_dns_string_cnt + nr_dns, sizeof(char));
424                 if (items == NULL) {
425                         LOGE("OOM while malloc\n");
426                         return VPNSVC_ERROR_OUT_OF_MEMORY;
427                 }
428                 for (i = 0 ; i < nr_dns ; i++) {
429                         strncat(items, dns_servers[i], strlen(dns_servers[i]));
430                         if (i != nr_dns - 1)
431                                 strncat(items, ",", 1);
432                 }
433         }
434
435         if (items) {
436                 LOGD("adding DNS : %s\n", items);
437                 connman_set_nameservers(global_connection, profile, items);
438                 free(items);
439                 items = NULL;
440         }
441
442         /* print new DNSs */
443         new_items = connman_get_nameservers_conf(global_connection, profile);
444         LOGD("new_dns : %s\n", new_items);
445
446         if (new_items)
447                 free(new_items);
448         free(profile);
449         return VPNSVC_ERROR_NONE;
450 }
451
452 static int del_dns_servers()
453 {
454         char *profile = NULL;
455
456         connman_connection_open();
457
458         profile = connman_default_profile(global_connection);
459         if (profile == NULL) {
460                 LOGE("connman_default_profile failed");
461                 connman_connection_close(global_connection);
462                 return VPNSVC_ERROR_IPC_FAILED;
463         }
464
465         LOGD("profile : %s", profile);
466
467         /* del name servers */
468         connman_set_nameservers(global_connection, profile, "");
469
470         if (profile)
471                 free(profile);
472
473         return VPNSVC_ERROR_NONE;
474 }
475
476 static int add_dns_suffix(const char* dns_suffix, size_t dns_suffix_len)
477 {
478         char *profile = NULL;
479         char *items = NULL;
480         char *org_items = NULL;
481         char *new_items = NULL;
482
483         connman_connection_open();
484
485         profile = connman_default_profile(global_connection);
486         if (profile == NULL) {
487                 LOGE("connman_default_profile failed");
488                 connman_connection_close(global_connection);
489                 return VPNSVC_ERROR_IPC_FAILED;
490         }
491
492         LOGD("profile : %s", profile);
493
494         /* add name servers */
495         org_items = connman_get_domains(global_connection, profile);
496
497         if (org_items) {
498                 LOGD("original DNS suffix : %s", org_items);
499                 /* comma(,) and end null character included */
500                 items = (char *) calloc((dns_suffix_len + strlen(org_items) + 2), sizeof(char));
501                 if (items == NULL) {
502                         LOGE("OOM while malloc");
503                         return VPNSVC_ERROR_OUT_OF_MEMORY;
504                 }
505                 strncpy(items, org_items, strlen(org_items));
506                 strncat(items, ",", 1);
507                 strncat(items, dns_suffix, dns_suffix_len);
508                 free(org_items);
509                 org_items = NULL;
510         } else {
511                 /* nr_dns = comma(,) count + end null char */
512                 items = (char *) calloc((dns_suffix_len + 1), sizeof(char));
513                 if (items == NULL) {
514                         LOGE("OOM while malloc");
515                         return VPNSVC_ERROR_OUT_OF_MEMORY;
516                 }
517                 strncat(items, dns_suffix, dns_suffix_len);
518         }
519
520         if (items) {
521                 LOGD("adding DNS suffix : %s\n", items);
522                 connman_set_domains(global_connection, profile, items);
523                 free(items);
524                 items = NULL;
525         }
526
527         /* print new domains */
528         new_items = connman_get_domains_conf(global_connection, profile);
529         LOGD("new DNS suffix : %s\n", new_items);
530
531         if (new_items)
532                 free(new_items);
533
534         if (profile)
535                 free(profile);
536
537         return VPNSVC_ERROR_NONE;
538 }
539
540 static int del_dns_suffix()
541 {
542         char *profile = NULL;
543
544         connman_connection_open();
545
546         profile = connman_default_profile(global_connection);
547         if (profile == NULL) {
548                 LOGE("connman_default_profile failed");
549                 connman_connection_close(global_connection);
550                 return VPNSVC_ERROR_IPC_FAILED;
551         }
552
553         LOGD("profile : %s", profile);
554
555         /* del DNS suffix */
556         connman_set_domains(global_connection, profile, "");
557
558         if (profile)
559                 free(profile);
560
561         return VPNSVC_ERROR_NONE;
562 }
563
564
565 static void iptables_exec(char *cmdline)
566 {
567         FILE *fp = NULL;
568
569         fp = popen(cmdline, "r");
570
571         if (fp != NULL)
572                 pclose(fp);
573 }
574
575 static void dns_nat_register(char **vpn_dns_address, size_t nr_dns, char *vpn_device_address)
576 {
577         int size = 0, i;
578         char buf[8192];
579
580         snprintf(buf + size, sizeof(buf) - size, iptables_nat_register_init_fmt,
581                         iptables_cmd, iptables_nat_chain_name,
582                         iptables_cmd, iptables_nat_chain_name,
583                         iptables_cmd, iptables_filter_out, iptables_nat_chain_name);
584         size = strlen(buf);
585
586         for (i = 0 ; i < nr_dns ; i++) {
587                 snprintf(buf + size, sizeof(buf) - size, iptables_nat_register_rule_fmt,
588                                 iptables_cmd, iptables_nat_chain_name, vpn_dns_address[i], vpn_device_address);
589                 size = strlen(buf);
590         }
591         LOGD("iptable dns nat reg cmd : %s", buf);
592         iptables_exec(buf);
593 }
594
595 static void dns_nat_unregister(void)
596 {
597         int size = 0;
598         char buf[8192];
599
600         snprintf(buf + size, sizeof(buf) - size, iptables_nat_unregister_fmt,
601                         iptables_cmd, iptables_filter_out, iptables_nat_chain_name,
602                         iptables_cmd, iptables_nat_chain_name,
603                         iptables_cmd, iptables_nat_chain_name);
604         size = strlen(buf);
605         LOGD("iptable dns nat unreg cmd : %s", buf);
606         iptables_exec(buf);
607 }
608
609 static void iptables_register(void)
610 {
611         int size = 0;
612         char buf[8192], *filter;
613
614         filter = iptables_filter_out;
615         snprintf(buf + size, sizeof(buf) - size, iptables_register_fmt,
616                          iptables_cmd, iptables_filter_prefix, filter,
617                          iptables_cmd, iptables_filter_prefix, filter,
618                          iptables_cmd, iptables_filter_prefix, filter,
619                          iptables_cmd, iptables_filter_prefix, filter,
620                          iptables_cmd, filter, iptables_filter_prefix, filter);
621         size = strlen(buf);
622         filter = iptables_filter_in;
623         snprintf(buf + size, sizeof(buf) - size, iptables_register_fmt,
624                          iptables_cmd, iptables_filter_prefix, filter,
625                          iptables_cmd, iptables_filter_prefix, filter,
626                          iptables_cmd, iptables_filter_prefix, filter,
627                          iptables_cmd, iptables_filter_prefix, filter,
628                          iptables_cmd, filter, iptables_filter_prefix, filter);
629         LOGD("iptable reg cmd : %s", buf);
630         iptables_exec(buf);
631 }
632
633 static void iptables_unregister(void)
634 {
635         int size = 0;
636         char buf[8192], *filter;
637
638         filter = iptables_filter_out;
639         snprintf(buf + size, sizeof(buf) - size, iptables_unregister_fmt,
640                          iptables_cmd, filter, iptables_filter_prefix, filter,
641                          iptables_cmd, iptables_filter_prefix, filter,
642                          iptables_cmd, iptables_filter_prefix, filter);
643         size = strlen(buf);
644         filter = iptables_filter_in;
645         snprintf(buf + size, sizeof(buf) - size, iptables_unregister_fmt,
646                          iptables_cmd, filter, iptables_filter_prefix, filter,
647                          iptables_cmd, iptables_filter_prefix, filter,
648                          iptables_cmd, iptables_filter_prefix, filter);
649         LOGD("iptable unreg cmd : %s", buf);
650         iptables_exec(buf);
651 }
652
653 static void iptables_rule(const char c, const char *addr, const int mask)
654 {
655         int size = 0;
656         char buf[4096];
657
658         snprintf(buf + size, sizeof(buf) - size, iptables_rule_fmt, iptables_cmd, c,
659                          iptables_filter_prefix, iptables_filter_out, 'd', addr, mask);
660         size = strlen(buf);
661         snprintf(buf + size, sizeof(buf) - size, iptables_rule_fmt, iptables_cmd, c,
662                          iptables_filter_prefix, iptables_filter_in, 's', addr, mask);
663         LOGD("iptable cmd : %s", buf);
664         iptables_exec(buf);
665 }
666
667 static void iptables_rule_interface(const char c, const char *addr, const int mask, const char *interface)
668 {
669         int size = 0;
670         char buf[4096];
671
672         snprintf(buf + size, sizeof(buf) - size,
673                         iptables_rule_with_interface_fmt, iptables_cmd,
674                         c, iptables_filter_prefix, iptables_filter_out,
675                         'o', interface, 'd', addr, mask);
676         size = strlen(buf);
677         snprintf(buf + size, sizeof(buf) - size,
678                         iptables_rule_with_interface_fmt, iptables_cmd,
679                         c, iptables_filter_prefix, iptables_filter_in,
680                         'i', interface, 's', addr, mask);
681         LOGD("iptable cmd : %s", buf);
682         iptables_exec(buf);
683 }
684
685 void iptables_add_orig(const char *addr, const int mask)
686 {
687         iptables_rule_interface('I', addr, mask, iptables_filter_interface_wlan);
688 }
689
690 void iptables_delete_orig(const char *addr, const int mask)
691 {
692         iptables_rule_interface('D', addr, mask, iptables_filter_interface_wlan);
693 }
694
695 void iptables_add(const char *addr, const int mask)
696 {
697         iptables_rule('I', addr, mask);
698 }
699
700 void iptables_delete(const char *addr, const int mask)
701 {
702         iptables_rule('D', addr, mask);
703 }
704
705 static int get_interface_index(const char *iface_name)
706 {
707         struct ifreq ifr;
708         int sk = 0;
709         char buf[BUF_SIZE_FOR_ERR] = { 0 };
710
711         LOGD("enter get_interface_index, iface_name : %s", iface_name);
712
713         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
714         if (sk < 0) {
715                 LOGE("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
716                 return VPNSVC_ERROR_IO_ERROR;
717         }
718
719         memset(&ifr, 0, sizeof(ifr));
720
721         if (*iface_name)
722         strncpy(ifr.ifr_name, iface_name, strlen(iface_name));
723
724         /* get an interface name by ifindex */
725         if (ioctl(sk, SIOCGIFINDEX, &ifr) < 0) {
726                 LOGE("ioctl SIOCGIFINDEX failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
727                 close(sk);
728                 return VPNSVC_ERROR_IO_ERROR;
729         }
730
731         close(sk);
732
733         return ifr.ifr_ifindex;
734 }
735
736
737 int vpn_daemon_init(const char* iface_name, size_t iface_name_len, int fd, vpnsvc_tun_s *handle_s)
738 {
739         struct ifreq ifr;
740         size_t len = 0;
741         char buf[BUF_SIZE_FOR_ERR] = { 0 };
742
743         LOGD("enter vpn_daemon_init, iface_name : %s, iface_name_len : %d, fd : %d\n", iface_name, iface_name_len, fd);
744
745         memset(&ifr, 0, sizeof(ifr));
746
747         /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
748         *               IFF_TAP   - TAP device
749         *
750         *               IFF_NO_PI - Do not provide packet information
751         */
752
753         ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
754
755         if (*iface_name)
756                 strncpy(ifr.ifr_name, iface_name, iface_name_len);
757
758         LOGD("before init, ifindex : %d", ifr.ifr_ifindex);
759
760         if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
761                 LOGE("TUNSETIFF Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
762                 close(fd);
763                 return VPNSVC_ERROR_IO_ERROR;
764         }
765
766         if (ioctl(fd, TUNSETOWNER, 5000) < 0) {
767                 LOGE("TUNSETOWNER Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
768                 close(fd);
769                 return VPNSVC_ERROR_IO_ERROR;
770         }
771
772         if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
773                 LOGE("TUNSETPERSIST Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
774                 close(fd);
775                 return VPNSVC_ERROR_IO_ERROR;
776         }
777
778         handle_s->fd = 0;   /* server fd does not meaning */
779         handle_s->index = get_interface_index(iface_name);
780         len = strlen(ifr.ifr_name);
781         strncpy(handle_s->name, ifr.ifr_name, len);
782         handle_s->name[len] = '\0';
783
784         return VPNSVC_ERROR_NONE;
785 }
786
787 int vpn_daemon_deinit(const char* dev_name)
788 {
789         char buf[100];
790         FILE *fp = NULL;
791
792         snprintf(buf, sizeof(buf), "/usr/sbin/ip link del %s", dev_name);
793         LOGD("link delete cmd : %s", buf);
794
795         fp = popen(buf, "r");
796         if (fp != NULL) {
797                 pclose(fp);
798                 return VPNSVC_ERROR_NONE;
799         } else {
800                 return VPNSVC_ERROR_IO_ERROR;
801         }
802 }
803
804 int vpn_daemon_protect(int socket_fd, const char* dev_name)
805 {
806         int ret = VPNSVC_ERROR_NONE;
807         char buf[BUF_SIZE_FOR_ERR] = { 0 };
808         LOGD("enter vpn_daemon_protect, socket : %d, dev_name : %s\n", socket_fd, dev_name);
809
810         ret = setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE,
811                                         dev_name, strlen(dev_name));
812
813         if (ret < 0) {
814                 LOGD("setsockopt failed : %d, %s", ret, strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
815                 ret = VPNSVC_ERROR_IO_ERROR;
816         } else {
817                 ret = VPNSVC_ERROR_NONE;
818         }
819
820         return ret;
821 }
822
823 int vpn_daemon_up(int iface_index, const char* local_ip, const char* remote_ip,
824                                                 char* routes[], int prefix[], size_t nr_routes,
825                                                 char** dns_servers, size_t nr_dns, size_t total_dns_string_cnt,
826                                                 const char* dns_suffix, const unsigned int mtu) {
827
828         struct sockaddr_in local_addr;
829         struct sockaddr_in remote_addr;
830         struct ifreq ifr_tun;
831         int sk;
832         int ret = VPNSVC_ERROR_NONE;
833         char buf[BUF_SIZE_FOR_ERR] = { 0 };
834
835         LOGD("enter vpn_daemon_up");
836
837         LOGD("iface_index : %d", iface_index);
838         LOGD("local ip : %s", local_ip);
839         LOGD("remote ip : %s", remote_ip);
840         LOGD("route pointer : %p, nr_routes : %d, dns_server pointer : %p, nr_dns : %d, dns_suffix : %s, mtu : %d", routes, nr_routes, dns_servers, nr_dns, dns_suffix, mtu);
841
842
843         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
844         if (sk < 0) {
845                 LOGE("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
846                 return VPNSVC_ERROR_IO_ERROR;
847         }
848
849         memset(&ifr_tun, 0, sizeof(ifr_tun));
850         ifr_tun.ifr_ifindex = iface_index;
851
852         /* get an interface name by ifindex */
853         if (ioctl(sk, SIOCGIFNAME, &ifr_tun) < 0) {
854                 LOGE("ioctl SIOCGIFNAME failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
855                 close(sk);
856                 return VPNSVC_ERROR_IO_ERROR;
857         }
858
859         /* local ip setting */
860         memset(&local_addr, 0, sizeof(local_addr));
861         local_addr.sin_addr.s_addr = inet_addr(local_ip); /* network byte order */
862         local_addr.sin_family = AF_INET;
863         memcpy(&ifr_tun.ifr_addr, &local_addr, sizeof(ifr_tun.ifr_addr));
864         if (ioctl(sk, SIOCSIFADDR, &ifr_tun) < 0) {
865                 LOGE("ioctl SIOCSIFADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
866                 close(sk);
867                 return VPNSVC_ERROR_IO_ERROR;
868         }
869
870         /* remote ip setting */
871         memset(&remote_addr, 0, sizeof(remote_addr));
872         remote_addr.sin_addr.s_addr = inet_addr(remote_ip); /*network byte order*/
873         remote_addr.sin_family = AF_INET;
874         memcpy(&ifr_tun.ifr_dstaddr, &remote_addr, sizeof(ifr_tun.ifr_dstaddr));
875         if (ioctl(sk, SIOCSIFDSTADDR, &ifr_tun) < 0) {
876                 LOGE("ioctl SIOCSIFDSTADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
877                 close(sk);
878                 return VPNSVC_ERROR_IO_ERROR;
879         }
880
881         /* set the flags for vpn up */
882         if (ioctl(sk, SIOCGIFFLAGS, &ifr_tun) < 0) {
883                 LOGE("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
884                 close(sk);
885                 return VPNSVC_ERROR_IO_ERROR;
886         }
887
888         ifr_tun.ifr_flags |= IFF_UP;
889         ifr_tun.ifr_flags |= IFF_RUNNING;
890
891         if (ioctl(sk, SIOCSIFFLAGS, &ifr_tun) < 0)  {
892                 LOGE("ioctl SIOCSIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
893                 close(sk);
894                 return VPNSVC_ERROR_IO_ERROR;
895         }
896
897         /* mtu setting */
898         if (ioctl(sk, SIOCGIFMTU, &ifr_tun) < 0) {
899                 LOGE("ioctl SIOCGIFMTU failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
900                 close(sk);
901                 return VPNSVC_ERROR_IO_ERROR;
902         }
903
904         if (mtu > 0 && ifr_tun.ifr_mtu != (int)mtu) {
905                 ifr_tun.ifr_mtu = mtu;
906                 if (ioctl(sk, SIOCSIFMTU, &ifr_tun) < 0) {
907                         LOGE("ioctl SIOCSIFMTU failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
908                         close(sk);
909                         return VPNSVC_ERROR_IO_ERROR;
910                 }
911         }
912
913         close(sk);
914
915         /* add routes */
916         if (nr_routes > 0) {
917                 ret = add_routes(ifr_tun.ifr_name, routes, prefix, nr_routes);
918                 if (ret != VPNSVC_ERROR_NONE) {
919                         LOGE("add_routes failed");
920                         return ret;
921                 }
922         }
923
924         /* add DNS routes */
925         if (nr_dns > 0) {
926                 ret = add_dns_routes(ifr_tun.ifr_name, dns_servers, nr_dns);
927                 if (ret != VPNSVC_ERROR_NONE) {
928                         LOGE("add_dns failed");
929                         return ret;
930                 }
931         }
932
933 #if 0
934         /* add DNS servers */
935         if (nr_dns > 0) {
936                 ret = add_dns_servers(dns_servers, nr_dns, total_dns_string_cnt);
937                 if (ret != VPNSVC_ERROR_NONE) {
938                         LOGE("add_dns failed");
939                         return ret;
940                 }
941         }
942
943         /* add_dns_suffix */
944         if (dns_suffix) {
945                 ret = add_dns_suffix(dns_suffix, strlen(dns_suffix));
946                 if (ret != VPNSVC_ERROR_NONE) {
947                         LOGE("add_dns_suffix failed");
948                         return ret;
949                 }
950         }
951
952         if (nr_dns > 0) {
953                 dns_nat_register(dns_servers, nr_dns, local_ip);
954         }
955 #endif
956
957         return ret;
958 }
959
960
961
962 int vpn_daemon_down(int iface_index)
963 {
964         struct ifreq ifr, addr_ifr;
965         struct sockaddr_in *addr = NULL;
966         int sk;
967         char buf[BUF_SIZE_FOR_ERR] = { 0 };
968
969         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
970         if (sk < 0) {
971                 LOGE("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
972                 return VPNSVC_ERROR_IO_ERROR;
973         }
974
975         memset(&ifr, 0, sizeof(ifr));
976         ifr.ifr_ifindex = iface_index;
977
978         if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
979                 LOGE("ioctl SIOCGIFNAME failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
980                 close(sk);
981                 return VPNSVC_ERROR_IO_ERROR;
982         }
983
984         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
985                 LOGE("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
986                 close(sk);
987                 return VPNSVC_ERROR_IO_ERROR;
988         }
989
990         memset(&addr_ifr, 0, sizeof(addr_ifr));
991         memcpy(&addr_ifr.ifr_name, &ifr.ifr_name, sizeof(ifr.ifr_name) - 1);
992         addr = (struct sockaddr_in *)&addr_ifr.ifr_addr;
993         addr->sin_family = AF_INET;
994         if (ioctl(sk, SIOCSIFADDR, &addr_ifr) < 0)
995                 LOGD("ioctl SIOCSIFADDR (could not clear IP address) failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
996
997         if (!(ifr.ifr_flags & IFF_UP)) {
998                 LOGD("Interface already down");
999                 close(sk);
1000                 return VPNSVC_ERROR_NONE;
1001         }
1002
1003         ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
1004         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
1005                 LOGE("ioctl SIOCSIFFLAGS (interface down) failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1006                 close(sk);
1007                 return VPNSVC_ERROR_IO_ERROR;
1008         }
1009
1010         close(sk);
1011
1012         /* routes are will be removed  automatically while down interfaces */
1013         /* remove dns servers */
1014         del_dns_servers();
1015
1016         /* remove dns suffix */
1017         del_dns_suffix();
1018
1019         /* remove dns filter */
1020         dns_nat_unregister();
1021
1022         return VPNSVC_ERROR_NONE;
1023 }
1024
1025 int vpn_daemon_block_networks(char* nets_vpn[], int prefix_vpn[], size_t nr_nets_vpn,
1026                 char* nets_orig[], int prefix_orig[], size_t nr_nets_orig) {
1027         unsigned int i;
1028
1029         /* iptable chain regist */
1030         iptables_register();
1031
1032         for (i = 0; i < nr_nets_vpn; i++) {
1033                 LOGD("block[%d] ip/mask : %s/%d", i, nets_vpn[i], prefix_vpn[i]);
1034                 iptables_add(nets_vpn[i], prefix_vpn[i]);
1035         }
1036
1037         for (i = 0; i < nr_nets_orig; i++) {
1038                 LOGD("allow[%d] ip/mask : %s/%d", i, nets_orig[i], prefix_orig[i]);
1039                 iptables_add_orig(nets_orig[i], prefix_orig[i]);
1040         }
1041
1042         return VPNSVC_ERROR_NONE;
1043 }
1044
1045 int vpn_daemon_unblock_networks(void)
1046 {
1047         iptables_unregister();
1048
1049         return VPNSVC_ERROR_NONE;
1050 }