5f7e3f19ce62ac43da6bb665bcf99c78c21ddbbd
[platform/core/connectivity/net-config.git] / src / vpnsvc-internal.c
1 /*
2  * Network Configuration - VPN Service Internal 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 <arpa/inet.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <linux/if.h>
34 #include <linux/if_tun.h>
35
36 #include "vpnsvc-internal.h"
37 #include "log.h"
38
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 #if 0
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;";
63 #endif
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;";
65
66 typedef unsigned long int ipv4; /* Declare variable type for ipv4 net address. */
67
68 static GDBusConnection *global_connection = NULL;
69
70 static ipv4 make_mask(int prefix)
71 {
72         ipv4 mask = 0;
73         int i = 0;
74
75         for (i = prefix; i > 0; i--)
76                 mask += (ipv4) (1 << (32 - i));
77         return mask;
78 }
79
80 static in_addr_t host2net(ipv4 host)
81 {
82         in_addr_t net;
83
84         net = 0;
85
86         net |= (host & 0x000000FF) << 24;
87         net |= (host & 0x0000FF00) <<  8;
88         net |= (host & 0x00FF0000) >>  8;
89         net |= (host & 0xFF000000) >> 24;
90
91         return net;
92 }
93
94 static void connman_connection_open(void)
95 {
96         if (global_connection == NULL) {
97                 GError *error = NULL;
98 #if !GLIB_CHECK_VERSION(2, 36, 0)
99                 g_type_init();
100 #endif
101
102                 global_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
103                 if (global_connection == NULL) {
104                         if (error != NULL) {
105                                 ERR("Error connman connection open: %s", error->message);
106                                 g_error_free(error);
107                         }
108                 }
109         }
110 }
111
112 static void connman_connection_close(GDBusConnection *connection)
113 {
114         if (connection)
115                 g_object_unref(connection);
116 }
117
118 static GVariant *connman_method_call(
119         GDBusConnection *connection, char *service, char *path,
120         char *interface, char *method, GVariant *params)
121 {
122         GError *error = NULL;
123         GVariant *message = NULL;
124
125         message = g_dbus_connection_call_sync(
126                 connection, service, path, interface, method, params,
127                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
128
129         if (message == NULL) {
130                 if (error != NULL) {
131                         ERR("error: g_dbus_connection_call_sync [%d: %s]", error->code, error->message);
132                         g_error_free(error);
133                 } else {
134                         ERR("error: g_dbus_connection_call_sync\n");
135                 }
136         }
137
138         return message;
139 }
140
141 static char *connman_default_profile(GDBusConnection *connection)
142 {
143         gchar *key = NULL;
144         GVariantIter *value = NULL;
145         GVariant *message = NULL;
146         GVariantIter *iter = NULL;
147         char *profile = NULL;
148
149         message = connman_method_call(connection, CONNMAN_SERVICE, "/",
150                                                                   CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
151
152         if (message) {
153                 g_variant_get(message, "(a(oa{sv}))", &iter);
154                 while (g_variant_iter_loop(iter, "(oa{sv})", &key, &value)) {
155                         profile = strdup(key);
156                         break;
157                 }
158
159                 if (value)
160                         g_variant_iter_free(value);
161                 if (key)
162                         g_free(key);
163
164                 g_variant_iter_free(iter);
165                 g_variant_unref(message);
166         }
167
168         return profile;
169 }
170
171 #if 0
172 static char *connman_get_items(GDBusConnection *connection, char *profile, const char *keystr)
173 {
174         GVariant *message = NULL;
175         GVariantIter *iter = NULL;
176         GVariantIter *next = NULL;
177         gchar *obj = NULL;
178         char *items = NULL;
179
180         message = connman_method_call(connection, CONNMAN_SERVICE, "/",
181                                                                   CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
182
183         if (message) {
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) {
187                                 GVariant *var;
188                                 gchar *key;
189
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;
194
195                                                 g_variant_get(var, "as", &iter_item);
196                                                 while (g_variant_iter_loop(iter_item, "s", &value)) {
197                                                         if (items) {
198                                                                 char *tmp_items;
199
200                                                                 tmp_items = (char *) malloc(strlen(items) + 1 + strlen(value) + 1);
201                                                                 if (items) {
202                                                                         snprintf(tmp_items, strlen(tmp_items), "%s,%s", items, value);
203                                                                         free(items);
204                                                                         items = tmp_items;
205                                                                 }
206                                                         } else {
207                                                                 items = strdup(value);
208                                                         }
209                                                 }
210                                                 g_variant_iter_free(iter_item);
211                                                 break;
212                                         }
213                                 }
214                                 break;
215                         }
216                 }
217                 g_variant_iter_free(iter);
218                 g_variant_unref(message);
219         }
220
221         return items;
222 }
223 #endif
224
225 static void connman_set_items(GDBusConnection *connection, char *profile,
226                                                           const char *keystr, char *items)
227 {
228         GVariant *message = NULL;
229         GVariantBuilder *builder = NULL;
230         GVariant *params = NULL;
231         char *strings = strdup(items);
232         char *addr = NULL;
233         char *temp = NULL;
234
235         builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
236         if ((addr = strtok_r(strings, ", ", &temp)) != NULL) {
237                 do {
238                         g_variant_builder_add(builder, "s", addr);
239                 } while ((addr = strtok_r(NULL, ", ", &temp)) != NULL);
240         }
241         free(strings);
242         params = g_variant_new("(sv)", keystr,
243                                                    g_variant_builder_end(builder));
244         g_variant_builder_unref(builder);
245
246         message = connman_method_call(connection, CONNMAN_SERVICE, profile,
247                                                                   CONNMAN_INTERFACE_SERVICE, "SetProperty", params);
248         if (message)
249                 g_variant_unref(message);
250
251 }
252
253 #if 0
254 static char *connman_get_nameservers(GDBusConnection *connection, char *profile)
255 {
256         return connman_get_items(connection, profile, "Nameservers");
257 }
258
259 static char *connman_get_nameservers_conf(GDBusConnection *connection, char *profile)
260 {
261         return connman_get_items(connection, profile, "Nameservers.Configuration");
262 }
263 #endif
264
265 static void connman_set_nameservers(GDBusConnection *connection, char *profile,
266                                                                         char *nameservers)
267 {
268         return connman_set_items(connection, profile,
269                                                          "Nameservers.Configuration", nameservers);
270 }
271
272 #if 0
273 static char *connman_get_domains(GDBusConnection *connection, char *profile)
274 {
275         return connman_get_items(connection, profile, "Domains");
276 }
277
278 static char *connman_get_domains_conf(GDBusConnection *connection, char *profile)
279 {
280         return connman_get_items(connection, profile, "Domains.Configuration");
281 }
282 #endif
283
284 static void connman_set_domains(GDBusConnection *connection, char *profile,
285                                                                         char *domains)
286 {
287         return connman_set_items(connection, profile,
288                                                          "Domains.Configuration", domains);
289 }
290
291 #if 0
292 static int add_dns_servers(char** dns_servers, size_t nr_dns, size_t total_dns_string_cnt)
293 {
294         char *profile = NULL;
295         char *items = NULL;
296         char *org_items = NULL;
297         char *new_items = NULL;
298         unsigned int i = 0;
299
300         connman_connection_open();
301
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;
307         }
308
309         DBG("profile : %s\n", profile);
310
311         /* add name servers */
312         org_items = connman_get_nameservers(global_connection, profile);
313
314         if (org_items) {
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));
318                 if (items == NULL) {
319                         ERR("OOM while malloc\n");
320                         return VPNSVC_ERROR_OUT_OF_MEMORY;
321                 }
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]));
326                 }
327                 free(org_items);
328                 org_items = NULL;
329         } else {
330                 /* nr_dns = comma(,) count + end null char */
331                 items = (char *) calloc(total_dns_string_cnt + nr_dns, sizeof(char));
332                 if (items == NULL) {
333                         ERR("OOM while malloc\n");
334                         return VPNSVC_ERROR_OUT_OF_MEMORY;
335                 }
336                 for (i = 0 ; i < nr_dns ; i++) {
337                         strncat(items, dns_servers[i], strlen(dns_servers[i]));
338                         if (i != nr_dns - 1)
339                                 strncat(items, ",", 1);
340                 }
341         }
342
343         if (items) {
344                 DBG("adding DNS : %s\n", items);
345                 connman_set_nameservers(global_connection, profile, items);
346                 free(items);
347                 items = NULL;
348         }
349
350         /* print new DNSs */
351         new_items = connman_get_nameservers_conf(global_connection, profile);
352         DBG("new_dns : %s\n", new_items);
353
354         if (new_items)
355                 free(new_items);
356         free(profile);
357         return VPNSVC_ERROR_NONE;
358 }
359 #endif
360
361 static int del_dns_servers()
362 {
363         char *profile = NULL;
364
365         connman_connection_open();
366
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;
372         }
373
374         DBG("profile : %s", profile);
375
376         /* del name servers */
377         connman_set_nameservers(global_connection, profile, "");
378
379         if (profile)
380                 free(profile);
381
382         return VPNSVC_ERROR_NONE;
383 }
384
385 #if 0
386 static int add_dns_suffix(const char* dns_suffix, size_t dns_suffix_len)
387 {
388         char *profile = NULL;
389         char *items = NULL;
390         char *org_items = NULL;
391         char *new_items = NULL;
392
393         connman_connection_open();
394
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;
400         }
401
402         DBG("profile : %s", profile);
403
404         /* add name servers */
405         org_items = connman_get_domains(global_connection, profile);
406
407         if (org_items) {
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));
411                 if (items == NULL) {
412                         ERR("OOM while malloc");
413                         return VPNSVC_ERROR_OUT_OF_MEMORY;
414                 }
415                 strncpy(items, org_items, strlen(org_items));
416                 strncat(items, ",", 1);
417                 strncat(items, dns_suffix, dns_suffix_len);
418                 free(org_items);
419                 org_items = NULL;
420         } else {
421                 /* nr_dns = comma(,) count + end null char */
422                 items = (char *) calloc((dns_suffix_len + 1), sizeof(char));
423                 if (items == NULL) {
424                         ERR("OOM while malloc");
425                         return VPNSVC_ERROR_OUT_OF_MEMORY;
426                 }
427                 strncat(items, dns_suffix, dns_suffix_len);
428         }
429
430         if (items) {
431                 DBG("adding DNS suffix : %s\n", items);
432                 connman_set_domains(global_connection, profile, items);
433                 free(items);
434                 items = NULL;
435         }
436
437         /* print new domains */
438         new_items = connman_get_domains_conf(global_connection, profile);
439         DBG("new DNS suffix : %s\n", new_items);
440
441         if (new_items)
442                 free(new_items);
443
444         if (profile)
445                 free(profile);
446
447         return VPNSVC_ERROR_NONE;
448 }
449 #endif
450
451 static int del_dns_suffix()
452 {
453         char *profile = NULL;
454
455         connman_connection_open();
456
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;
462         }
463
464         DBG("profile : %s", profile);
465
466         /* del DNS suffix */
467         connman_set_domains(global_connection, profile, "");
468
469         if (profile)
470                 free(profile);
471
472         return VPNSVC_ERROR_NONE;
473 }
474
475
476 static void iptables_exec(char *cmdline)
477 {
478         FILE *fp = NULL;
479
480         fp = popen(cmdline, "r");
481
482         if (fp != NULL)
483                 pclose(fp);
484 }
485
486 #if 0
487 static void dns_nat_register(char **vpn_dns_address, size_t nr_dns, char *vpn_device_address)
488 {
489         int size = 0, i;
490         char buf[8192];
491
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);
496         size = strlen(buf);
497
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);
501                 size = strlen(buf);
502         }
503         DBG("iptable dns nat reg cmd : %s", buf);
504         iptables_exec(buf);
505 }
506 #endif
507
508 static void dns_nat_unregister(void)
509 {
510         int size = 0;
511         char buf[8192];
512
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);
517         size = strlen(buf);
518         DBG("iptable dns nat unreg cmd : %s", buf);
519         iptables_exec(buf);
520 }
521
522 static void iptables_register(void)
523 {
524         int size = 0;
525         char buf[8192], *filter;
526
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);
534         size = strlen(buf);
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);
543         iptables_exec(buf);
544 }
545
546 static void iptables_unregister(void)
547 {
548         int size = 0;
549         char buf[8192], *filter;
550
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);
556         size = strlen(buf);
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);
563         iptables_exec(buf);
564 }
565
566 static void iptables_rule(const char c, const char *addr, const int mask)
567 {
568         int size = 0;
569         char buf[4096];
570
571         snprintf(buf + size, sizeof(buf) - size, iptables_rule_fmt, iptables_cmd, c,
572                          iptables_filter_prefix, iptables_filter_out, 'd', addr, mask);
573         size = strlen(buf);
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);
577         iptables_exec(buf);
578 }
579
580 static void iptables_rule_interface(const char c, const char *addr, const int mask, const char *interface)
581 {
582         int size = 0;
583         char buf[4096];
584
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);
589         size = strlen(buf);
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);
595         iptables_exec(buf);
596 }
597
598 void iptables_add_orig(const char *addr, const int mask)
599 {
600         iptables_rule_interface('I', addr, mask, iptables_filter_interface_wlan);
601 }
602
603 void iptables_delete_orig(const char *addr, const int mask)
604 {
605         iptables_rule_interface('D', addr, mask, iptables_filter_interface_wlan);
606 }
607
608 void iptables_add(const char *addr, const int mask)
609 {
610         iptables_rule('I', addr, mask);
611 }
612
613 void iptables_delete(const char *addr, const int mask)
614 {
615         iptables_rule('D', addr, mask);
616 }
617
618 static int get_interface_index(const char *iface_name)
619 {
620         struct ifreq ifr;
621         int sk = 0;
622         char buf[BUF_SIZE_FOR_ERR] = { 0 };
623
624         DBG("enter get_interface_index, iface_name : %s", iface_name);
625
626         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
627         if (sk < 0) {
628                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
629                 return VPNSVC_ERROR_IO_ERROR;
630         }
631
632         memset(&ifr, 0, sizeof(ifr));
633
634         if (*iface_name)
635         strncpy(ifr.ifr_name, iface_name, strlen(iface_name));
636
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));
640                 close(sk);
641                 return VPNSVC_ERROR_IO_ERROR;
642         }
643
644         close(sk);
645
646         return ifr.ifr_ifindex;
647 }
648
649 static int check_interface_precondition(const char *iface_name)
650 {
651
652         int sk;
653         struct ifreq ifr_tun;
654         char buf[BUF_SIZE_FOR_ERR] = { 0 };
655
656         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
657         if (sk < 0) {
658                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
659                 return VPNSVC_ERROR_IO_ERROR;
660         }
661
662         memset(&ifr_tun, 0, sizeof(ifr_tun));
663         g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name));
664
665         /* local ip */
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));
668                 close(sk);
669                 return VPNSVC_ERROR_INVALID_PARAMETER;
670         }
671
672         /* remote ip */
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));
675                 close(sk);
676                 return VPNSVC_ERROR_INVALID_PARAMETER;
677         }
678
679         close(sk);
680
681         return VPNSVC_ERROR_NONE;
682 }
683
684
685 int vpn_service_init(const char* iface_name, size_t iface_name_len, int fd, vpnsvc_tun_s *handle_s)
686 {
687         struct ifreq ifr;
688         size_t len = 0;
689         char buf[BUF_SIZE_FOR_ERR] = { 0 };
690
691         DBG("enter vpn_daemon_init, iface_name : %s, iface_name_len : %d, fd : %d\n", iface_name, iface_name_len, fd);
692
693         memset(&ifr, 0, sizeof(ifr));
694
695         /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
696         *               IFF_TAP   - TAP device
697         *
698         *               IFF_NO_PI - Do not provide packet information
699         */
700
701         ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
702
703         if (*iface_name)
704                 strncpy(ifr.ifr_name, iface_name, iface_name_len);
705
706         DBG("before init, ifindex : %d", ifr.ifr_ifindex);
707
708         if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
709                 ERR("TUNSETIFF Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
710                 close(fd);
711                 return VPNSVC_ERROR_IO_ERROR;
712         }
713
714         if (ioctl(fd, TUNSETOWNER, 5000) < 0) {
715                 ERR("TUNSETOWNER Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
716                 close(fd);
717                 return VPNSVC_ERROR_IO_ERROR;
718         }
719
720         if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
721                 ERR("TUNSETPERSIST Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
722                 close(fd);
723                 return VPNSVC_ERROR_IO_ERROR;
724         }
725
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';
731
732         return VPNSVC_ERROR_NONE;
733 }
734
735 int vpn_service_deinit(const char* dev_name)
736 {
737         char buf[100];
738         FILE *fp = NULL;
739
740         snprintf(buf, sizeof(buf), "/usr/sbin/ip link del %s", dev_name);
741         DBG("link delete cmd : %s", buf);
742
743         fp = popen(buf, "r");
744         if (fp != NULL) {
745                 pclose(fp);
746                 return VPNSVC_ERROR_NONE;
747         } else {
748                 return VPNSVC_ERROR_IO_ERROR;
749         }
750 }
751
752 int vpn_service_protect(int socket_fd, const char* dev_name)
753 {
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);
757
758         ret = setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE,
759                                         dev_name, strlen(dev_name));
760
761         if (ret < 0) {
762                 DBG("setsockopt failed : %d, %s", ret, strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
763                 ret = VPNSVC_ERROR_IO_ERROR;
764         } else {
765                 ret = VPNSVC_ERROR_NONE;
766         }
767
768         return ret;
769 }
770
771 int vpn_service_up(const char *iface_name)
772 {
773         struct ifreq ifr_tun;
774         int sk;
775         int ret = VPNSVC_ERROR_NONE;
776         char buf[BUF_SIZE_FOR_ERR] = { 0 };
777
778         DBG("enter vpn_daemon_up");
779         DBG("iface_name : %s", iface_name);
780
781
782         ret = check_interface_precondition(iface_name);
783         if (ret != VPNSVC_ERROR_NONE)
784                 return ret;
785
786         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
787         if (sk < 0) {
788                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
789                 return VPNSVC_ERROR_IO_ERROR;
790         }
791
792         memset(&ifr_tun, 0, sizeof(ifr_tun));
793         g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name));
794
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));
798                 close(sk);
799                 return VPNSVC_ERROR_IO_ERROR;
800         }
801
802         ifr_tun.ifr_flags |= IFF_UP;
803         ifr_tun.ifr_flags |= IFF_RUNNING;
804
805         if (ioctl(sk, SIOCSIFFLAGS, &ifr_tun) < 0)  {
806                 ERR("ioctl SIOCSIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
807                 close(sk);
808                 return VPNSVC_ERROR_IO_ERROR;
809         }
810
811         close(sk);
812
813 #if 0
814         /* add DNS servers */
815         if (nr_dns > 0) {
816                 ret = add_dns_servers(dns_servers, nr_dns, total_dns_string_cnt);
817                 if (ret != VPNSVC_ERROR_NONE) {
818                         ERR("add_dns failed");
819                         return ret;
820                 }
821         }
822
823         /* add_dns_suffix */
824         if (dns_suffix) {
825                 ret = add_dns_suffix(dns_suffix, strlen(dns_suffix));
826                 if (ret != VPNSVC_ERROR_NONE) {
827                         ERR("add_dns_suffix failed");
828                         return ret;
829                 }
830         }
831
832         if (nr_dns > 0)
833                 dns_nat_register(dns_servers, nr_dns, local_ip);
834 #endif
835
836         return ret;
837 }
838
839
840
841 int vpn_service_down(const char *iface_name)
842 {
843         struct ifreq ifr;
844         int sk;
845         char buf[BUF_SIZE_FOR_ERR] = { 0 };
846
847         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
848         if (sk < 0) {
849                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
850                 return VPNSVC_ERROR_IO_ERROR;
851         }
852
853         memset(&ifr, 0, sizeof(ifr));
854         g_strlcpy((char *)ifr.ifr_name, iface_name, sizeof(ifr.ifr_name));
855
856         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
857                 ERR("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
858                 close(sk);
859                 return VPNSVC_ERROR_IO_ERROR;
860         }
861
862         if (!(ifr.ifr_flags & IFF_UP)) {
863                 DBG("Interface already down");
864                 close(sk);
865                 return VPNSVC_ERROR_NONE;
866         }
867
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));
871                 close(sk);
872                 return VPNSVC_ERROR_IO_ERROR;
873         }
874
875         close(sk);
876
877         /* routes are will be removed  automatically while down interfaces */
878         /* remove dns servers */
879         del_dns_servers();
880
881         /* remove dns suffix */
882         del_dns_suffix();
883
884         /* remove dns filter */
885         dns_nat_unregister();
886
887         return VPNSVC_ERROR_NONE;
888 }
889
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) {
892         unsigned int i;
893
894         /* iptable chain regist */
895         iptables_register();
896
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]);
900         }
901
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]);
905         }
906
907         return VPNSVC_ERROR_NONE;
908 }
909
910 int vpn_service_unblock_networks(void)
911 {
912         iptables_unregister();
913
914         return VPNSVC_ERROR_NONE;
915 }
916
917 int vpn_service_update_settings(int iface_index, const char *local_ip,
918                 const char *remote_ip, const unsigned int mtu)
919 {
920         int sk;
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 };
925
926         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
927         if (sk < 0) {
928                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
929                 return VPNSVC_ERROR_IO_ERROR;
930         }
931
932         memset(&ifr_tun, 0, sizeof(ifr_tun));
933         ifr_tun.ifr_ifindex = iface_index;
934
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));
938                 close(sk);
939                 return VPNSVC_ERROR_IO_ERROR;
940         }
941
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));
949                 close(sk);
950                 return VPNSVC_ERROR_IO_ERROR;
951         }
952
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));
960                 close(sk);
961                 return VPNSVC_ERROR_IO_ERROR;
962         }
963
964         /* mtu setting */
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));
969                         close(sk);
970                         return VPNSVC_ERROR_IO_ERROR;
971                 }
972         }
973
974         close(sk);
975
976         return VPNSVC_ERROR_NONE;
977 }
978
979 int vpn_service_add_route(char *iface_name, const char *route, int prefix)
980 {
981         struct rtentry rt;
982         struct sockaddr_in addr;
983         int sk;
984         char buf[BUF_SIZE_FOR_ERR] = { 0 };
985
986         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
987         if (sk < 0) {
988                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
989                 return VPNSVC_ERROR_IO_ERROR;
990         }
991
992         memset(&rt, 0, sizeof(rt));
993         rt.rt_flags = RTF_UP;
994
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));
999
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));
1004
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));
1011
1012         rt.rt_dev = iface_name;
1013
1014         if (ioctl(sk, SIOCADDRT, &rt) < 0) {
1015                 ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1016                 close(sk);
1017                 return VPNSVC_ERROR_IO_ERROR;
1018         }
1019
1020         close(sk);
1021
1022         return VPNSVC_ERROR_NONE;
1023 }
1024
1025 int vpn_service_remove_route(char *iface_name, const char *route, int prefix)
1026 {
1027         struct rtentry rt;
1028         struct sockaddr_in addr;
1029         int sk;
1030         char buf[BUF_SIZE_FOR_ERR] = { 0 };
1031
1032         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1033         if (sk < 0) {
1034                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1035                 return VPNSVC_ERROR_IO_ERROR;
1036         }
1037
1038         memset(&rt, 0, sizeof(rt));
1039         rt.rt_flags = RTF_UP;
1040
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));
1045
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));
1050
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));
1057
1058         rt.rt_dev = iface_name;
1059
1060         if (ioctl(sk, SIOCDELRT, &rt) < 0) {
1061                 ERR("ioctl SIOCDERLT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1062                 close(sk);
1063                 return VPNSVC_ERROR_IO_ERROR;
1064         }
1065
1066         close(sk);
1067
1068         return VPNSVC_ERROR_NONE;
1069
1070 }
1071
1072 int vpn_service_add_dns_server(char *iface_name, const char *dns_server)
1073 {
1074         struct rtentry rt;
1075         struct sockaddr_in addr;
1076         int sk;
1077         char buf[BUF_SIZE_FOR_ERR] = { 0 };
1078
1079         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1080         if (sk < 0) {
1081                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1082                 return VPNSVC_ERROR_IO_ERROR;
1083         }
1084
1085         memset(&rt, 0, sizeof(rt));
1086         rt.rt_flags = RTF_UP;
1087
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));
1092
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));
1097
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));
1104
1105         rt.rt_dev = iface_name;
1106
1107         if (ioctl(sk, SIOCADDRT, &rt) < 0) {
1108                 ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1109                 close(sk);
1110                 return VPNSVC_ERROR_IO_ERROR;
1111         }
1112
1113         close(sk);
1114
1115         return VPNSVC_ERROR_NONE;
1116 }
1117
1118 int vpn_service_remove_dns_server(char *iface_name, const char *dns_server)
1119 {
1120         struct rtentry rt;
1121         struct sockaddr_in addr;
1122         int sk;
1123         char buf[BUF_SIZE_FOR_ERR] = { 0 };
1124
1125         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1126         if (sk < 0) {
1127                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1128                 return VPNSVC_ERROR_IO_ERROR;
1129         }
1130
1131         memset(&rt, 0, sizeof(rt));
1132         rt.rt_flags = RTF_UP;
1133
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));
1138
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));
1143
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));
1150
1151         rt.rt_dev = iface_name;
1152
1153         if (ioctl(sk, SIOCDELRT, &rt) < 0) {
1154                 ERR("ioctl SIOCDELRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1155                 close(sk);
1156                 return VPNSVC_ERROR_IO_ERROR;
1157         }
1158
1159         close(sk);
1160
1161         return VPNSVC_ERROR_NONE;
1162 }