[WGID-200328, 200330, 200606] Fixed some codes for secure coding
[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 #include "util.h"
39
40 #define BUF_SIZE_FOR_CMD 1024
41 #define BUF_SIZE_FOR_ERR 100
42
43 #define CONNMAN_SERVICE "net.connman"
44 #define CONNMAN_INTERFACE_MANAGER "net.connman.Manager"
45 #define CONNMAN_INTERFACE_SERVICE "net.connman.Service"
46
47
48 /* for iptables */
49 static char iptables_cmd[] = "/usr/sbin/iptables";
50 static char iptables_filter_prefix[] = "CAPI_VPN_SERVICE_";
51 static char iptables_filter_out[] = "OUTPUT";
52 static char iptables_filter_in[] = "INPUT";
53 static char iptables_filter_interface_wlan[] = "wlan0";
54 static char iptables_nat_chain_name[] = "CAPI_VPN_SERVICE_NAT_OUTPUT";
55
56 #define IPTABLES_FMT_CREATE_CHAIN "%s -N %s%s -w"
57 #define IPTABLES_FMT_APPEND_DROP_RULE "%s -A %s%s -j DROP -w"
58 #define IPTABLES_FMT_APPEND_RETURN_RULE "%s -A %s%s -j RETURN -w"
59 #define IPTABLES_FMT_INSERT_RULE "%s -I %s -j %s%s -w"
60 #define IPTABLES_FMT_DEL_RULE "%s -D %s -j %s%s -w"
61 #define IPTABLES_FMT_FLUSH_CHAIN "%s -F %s%s -w"
62 #define IPTABLES_FMT_DEL_CHAIN "%s -X %s%s -w"
63 #define IPTABLES_FMT_APPEND_ACCEPT_RULE "%s -%c %s%s -%c %s/%d -j ACCEPT -w"
64 #define IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF "%s -%c %s%s -%c %s -%c %s/%d -j ACCEPT -w"
65 #define IPTABLES_FMT_DEL_RULE_FROM_NAT "%s -t nat -D %s -j %s -w"
66 #define IPTABLES_FMT_FLUSH_CHAIN_FROM_NAT "%s -t nat -F %s -w"
67 #define IPTABLES_FMT_DEL_CHAIN_FROM_NAT "%s -t nat -X %s -w"
68
69 /*static char iptables_usage_fmt[] = "%s -L %s%s -n -v -w;";*/
70 /* iptables -t nat -A CAPI_VPN_SERVICE_OUTPUT -p udp -d <vpn dns address> --dport 53 -j DNAT --to <vpn defice address:53> */
71
72 typedef unsigned long int ipv4; /* Declare variable type for ipv4 net address. */
73
74 static GDBusConnection *global_connection = NULL;
75
76 static ipv4 make_mask(int prefix)
77 {
78         ipv4 mask = 0;
79         int i = 0;
80
81         for (i = prefix; i > 0; i--)
82                 mask += (ipv4) (1 << (32 - i));
83         return mask;
84 }
85
86 static in_addr_t host2net(ipv4 host)
87 {
88         in_addr_t net;
89
90         net = 0;
91
92         net |= (host & 0x000000FF) << 24;
93         net |= (host & 0x0000FF00) <<  8;
94         net |= (host & 0x00FF0000) >>  8;
95         net |= (host & 0xFF000000) >> 24;
96
97         return net;
98 }
99
100 static void connman_connection_open(void)
101 {
102         if (global_connection == NULL) {
103                 GError *error = NULL;
104 #if !GLIB_CHECK_VERSION(2, 36, 0)
105                 g_type_init();
106 #endif
107
108                 global_connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
109                 if (global_connection == NULL) {
110                         if (error != NULL) {
111                                 ERR("Error connman connection open: %s", error->message);
112                                 g_error_free(error);
113                         }
114                 }
115         }
116 }
117
118 static void connman_connection_close(GDBusConnection *connection)
119 {
120         if (connection)
121                 g_object_unref(connection);
122 }
123
124 static GVariant *connman_method_call(
125         GDBusConnection *connection, char *service, char *path,
126         char *interface, char *method, GVariant *params)
127 {
128         GError *error = NULL;
129         GVariant *message = NULL;
130
131         message = g_dbus_connection_call_sync(
132                 connection, service, path, interface, method, params,
133                 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
134
135         if (message == NULL) {
136                 if (error != NULL) {
137                         ERR("error: g_dbus_connection_call_sync [%d: %s]", error->code, error->message);
138                         g_error_free(error);
139                 } else {
140                         ERR("error: g_dbus_connection_call_sync\n");
141                 }
142         }
143
144         return message;
145 }
146
147 static char *connman_default_profile(GDBusConnection *connection)
148 {
149         gchar *key = NULL;
150         GVariantIter *value = NULL;
151         GVariant *message = NULL;
152         GVariantIter *iter = NULL;
153         char *profile = NULL;
154
155         message = connman_method_call(connection, CONNMAN_SERVICE, "/",
156                                                                   CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
157
158         if (message) {
159                 g_variant_get(message, "(a(oa{sv}))", &iter);
160                 while (g_variant_iter_loop(iter, "(oa{sv})", &key, &value)) {
161                         profile = strdup(key);
162                         break;
163                 }
164
165                 if (value)
166                         g_variant_iter_free(value);
167                 if (key)
168                         g_free(key);
169
170                 g_variant_iter_free(iter);
171                 g_variant_unref(message);
172         }
173
174         return profile;
175 }
176
177 #if 0
178 static char *connman_get_items(GDBusConnection *connection, char *profile, const char *keystr)
179 {
180         GVariant *message = NULL;
181         GVariantIter *iter = NULL;
182         GVariantIter *next = NULL;
183         gchar *obj = NULL;
184         char *items = NULL;
185
186         message = connman_method_call(connection, CONNMAN_SERVICE, "/",
187                                                                   CONNMAN_INTERFACE_MANAGER, "GetServices", NULL);
188
189         if (message) {
190                 g_variant_get(message, "(a(oa{sv}))", &iter);
191                 while (g_variant_iter_loop(iter, "(oa{sv})", &obj, &next)) {
192                         if (strcmp(obj, profile) == 0) {
193                                 GVariant *var;
194                                 gchar *key;
195
196                                 while (g_variant_iter_loop(next, "{sv}", &key, &var)) {
197                                         if (g_strcmp0(key, keystr) == 0) {
198                                                 GVariantIter *iter_item;
199                                                 const gchar *value = NULL;
200
201                                                 g_variant_get(var, "as", &iter_item);
202                                                 while (g_variant_iter_loop(iter_item, "s", &value)) {
203                                                         if (items) {
204                                                                 char *tmp_items;
205
206                                                                 tmp_items = (char *) malloc(strlen(items) + 1 + strlen(value) + 1);
207                                                                 if (items) {
208                                                                         snprintf(tmp_items, strlen(tmp_items), "%s,%s", items, value);
209                                                                         free(items);
210                                                                         items = tmp_items;
211                                                                 }
212                                                         } else {
213                                                                 items = strdup(value);
214                                                         }
215                                                 }
216                                                 g_variant_iter_free(iter_item);
217                                                 break;
218                                         }
219                                 }
220                                 break;
221                         }
222                 }
223                 g_variant_iter_free(iter);
224                 g_variant_unref(message);
225         }
226
227         return items;
228 }
229 #endif
230
231 static void connman_set_items(GDBusConnection *connection, char *profile,
232                                                           const char *keystr, char *items)
233 {
234         GVariant *message = NULL;
235         GVariantBuilder *builder = NULL;
236         GVariant *params = NULL;
237         char *strings = strdup(items);
238         char *addr = NULL;
239         char *temp = NULL;
240
241         builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
242         if ((addr = strtok_r(strings, ", ", &temp)) != NULL) {
243                 do {
244                         g_variant_builder_add(builder, "s", addr);
245                 } while ((addr = strtok_r(NULL, ", ", &temp)) != NULL);
246         }
247         free(strings);
248         params = g_variant_new("(sv)", keystr,
249                                                    g_variant_builder_end(builder));
250         g_variant_builder_unref(builder);
251
252         message = connman_method_call(connection, CONNMAN_SERVICE, profile,
253                                                                   CONNMAN_INTERFACE_SERVICE, "SetProperty", params);
254         if (message)
255                 g_variant_unref(message);
256
257 }
258
259 #if 0
260 static char *connman_get_nameservers(GDBusConnection *connection, char *profile)
261 {
262         return connman_get_items(connection, profile, "Nameservers");
263 }
264
265 static char *connman_get_nameservers_conf(GDBusConnection *connection, char *profile)
266 {
267         return connman_get_items(connection, profile, "Nameservers.Configuration");
268 }
269 #endif
270
271 static void connman_set_nameservers(GDBusConnection *connection, char *profile,
272                                                                         char *nameservers)
273 {
274         return connman_set_items(connection, profile,
275                                                          "Nameservers.Configuration", nameservers);
276 }
277
278 #if 0
279 static char *connman_get_domains(GDBusConnection *connection, char *profile)
280 {
281         return connman_get_items(connection, profile, "Domains");
282 }
283
284 static char *connman_get_domains_conf(GDBusConnection *connection, char *profile)
285 {
286         return connman_get_items(connection, profile, "Domains.Configuration");
287 }
288 #endif
289
290 static void connman_set_domains(GDBusConnection *connection, char *profile,
291                                                                         char *domains)
292 {
293         return connman_set_items(connection, profile,
294                                                          "Domains.Configuration", domains);
295 }
296
297 #if 0
298 static int add_dns_servers(char** dns_servers, size_t nr_dns, size_t total_dns_string_cnt)
299 {
300         char *profile = NULL;
301         char *items = NULL;
302         char *org_items = NULL;
303         char *new_items = NULL;
304         unsigned int i = 0;
305
306         connman_connection_open();
307
308         profile = connman_default_profile(global_connection);
309         if (profile == NULL) {
310                 ERR("connman_default_profile failed");
311                 connman_connection_close(global_connection);
312                 return VPNSVC_ERROR_IPC_FAILED;
313         }
314
315         DBG("profile : %s\n", profile);
316
317         /* add name servers */
318         org_items = connman_get_nameservers(global_connection, profile);
319
320         if (org_items) {
321                 DBG("original DNS : %s\n", org_items);
322                 /* nr_dns = comma(,) count */
323                 items = (char *) calloc((total_dns_string_cnt + nr_dns + strlen(org_items) + 1), sizeof(char));
324                 if (items == NULL) {
325                         ERR("OOM while malloc\n");
326                         return VPNSVC_ERROR_OUT_OF_MEMORY;
327                 }
328                 strncpy(items, org_items, strlen(org_items));
329                 for (i = 0 ; i < nr_dns ; i++) {
330                         strncat(items, ",", 1);
331                         strncat(items, dns_servers[i], strlen(dns_servers[i]));
332                 }
333                 free(org_items);
334                 org_items = NULL;
335         } else {
336                 /* nr_dns = comma(,) count + end null char */
337                 items = (char *) calloc(total_dns_string_cnt + nr_dns, sizeof(char));
338                 if (items == NULL) {
339                         ERR("OOM while malloc\n");
340                         return VPNSVC_ERROR_OUT_OF_MEMORY;
341                 }
342                 for (i = 0 ; i < nr_dns ; i++) {
343                         strncat(items, dns_servers[i], strlen(dns_servers[i]));
344                         if (i != nr_dns - 1)
345                                 strncat(items, ",", 1);
346                 }
347         }
348
349         if (items) {
350                 DBG("adding DNS : %s\n", items);
351                 connman_set_nameservers(global_connection, profile, items);
352                 free(items);
353                 items = NULL;
354         }
355
356         /* print new DNSs */
357         new_items = connman_get_nameservers_conf(global_connection, profile);
358         DBG("new_dns : %s\n", new_items);
359
360         if (new_items)
361                 free(new_items);
362         free(profile);
363         return VPNSVC_ERROR_NONE;
364 }
365 #endif
366
367 static int del_dns_servers()
368 {
369         char *profile = NULL;
370
371         connman_connection_open();
372
373         profile = connman_default_profile(global_connection);
374         if (profile == NULL) {
375                 ERR("connman_default_profile failed");
376                 connman_connection_close(global_connection);
377                 return VPNSVC_ERROR_IPC_FAILED;
378         }
379
380         DBG("profile : %s", profile);
381
382         /* del name servers */
383         connman_set_nameservers(global_connection, profile, "");
384
385         if (profile)
386                 free(profile);
387
388         return VPNSVC_ERROR_NONE;
389 }
390
391 #if 0
392 static int add_dns_suffix(const char* dns_suffix, size_t dns_suffix_len)
393 {
394         char *profile = NULL;
395         char *items = NULL;
396         char *org_items = NULL;
397         char *new_items = NULL;
398
399         connman_connection_open();
400
401         profile = connman_default_profile(global_connection);
402         if (profile == NULL) {
403                 ERR("connman_default_profile failed");
404                 connman_connection_close(global_connection);
405                 return VPNSVC_ERROR_IPC_FAILED;
406         }
407
408         DBG("profile : %s", profile);
409
410         /* add name servers */
411         org_items = connman_get_domains(global_connection, profile);
412
413         if (org_items) {
414                 DBG("original DNS suffix : %s", org_items);
415                 /* comma(,) and end null character included */
416                 items = (char *) calloc((dns_suffix_len + strlen(org_items) + 2), sizeof(char));
417                 if (items == NULL) {
418                         ERR("OOM while malloc");
419                         return VPNSVC_ERROR_OUT_OF_MEMORY;
420                 }
421                 strncpy(items, org_items, strlen(org_items));
422                 strncat(items, ",", 1);
423                 strncat(items, dns_suffix, dns_suffix_len);
424                 free(org_items);
425                 org_items = NULL;
426         } else {
427                 /* nr_dns = comma(,) count + end null char */
428                 items = (char *) calloc((dns_suffix_len + 1), sizeof(char));
429                 if (items == NULL) {
430                         ERR("OOM while malloc");
431                         return VPNSVC_ERROR_OUT_OF_MEMORY;
432                 }
433                 strncat(items, dns_suffix, dns_suffix_len);
434         }
435
436         if (items) {
437                 DBG("adding DNS suffix : %s\n", items);
438                 connman_set_domains(global_connection, profile, items);
439                 free(items);
440                 items = NULL;
441         }
442
443         /* print new domains */
444         new_items = connman_get_domains_conf(global_connection, profile);
445         DBG("new DNS suffix : %s\n", new_items);
446
447         if (new_items)
448                 free(new_items);
449
450         if (profile)
451                 free(profile);
452
453         return VPNSVC_ERROR_NONE;
454 }
455 #endif
456
457 static int del_dns_suffix()
458 {
459         char *profile = NULL;
460
461         connman_connection_open();
462
463         profile = connman_default_profile(global_connection);
464         if (profile == NULL) {
465                 ERR("connman_default_profile failed");
466                 connman_connection_close(global_connection);
467                 return VPNSVC_ERROR_IPC_FAILED;
468         }
469
470         DBG("profile : %s", profile);
471
472         /* del DNS suffix */
473         connman_set_domains(global_connection, profile, "");
474
475         if (profile)
476                 free(profile);
477
478         return VPNSVC_ERROR_NONE;
479 }
480
481 static int _check_config_str(void)
482 {
483         char *buf = NULL;
484         size_t len;
485
486         len = confstr(_CS_PATH, NULL, 0);
487         if (len == 0)
488                 return -1;
489
490         if ((buf = malloc(len)) == NULL)
491                 return -1;
492
493         if (confstr(_CS_PATH, buf, len) == 0) {
494                 free(buf);
495                 return -1;
496         }
497
498         free(buf);
499
500         return 0;
501 }
502
503 #if 0
504 static void dns_nat_register(char **vpn_dns_address, size_t nr_dns, char *vpn_device_address)
505 {
506         int size = 0, i;
507         char buf[8192];
508
509         snprintf(buf + size, sizeof(buf) - size, iptables_nat_register_init_fmt,
510                         iptables_cmd, iptables_nat_chain_name,
511                         iptables_cmd, iptables_nat_chain_name,
512                         iptables_cmd, iptables_filter_out, iptables_nat_chain_name);
513         size = strlen(buf);
514
515         for (i = 0 ; i < nr_dns ; i++) {
516                 snprintf(buf + size, sizeof(buf) - size, iptables_nat_register_rule_fmt,
517                                 iptables_cmd, iptables_nat_chain_name, vpn_dns_address[i], vpn_device_address);
518                 size = strlen(buf);
519         }
520         DBG("iptable dns nat reg cmd : %s", buf);
521         iptables_exec(buf);
522 }
523 #endif
524
525 static void dns_nat_unregister(void)
526 {
527         char buf[BUF_SIZE_FOR_CMD];
528
529         snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE_FROM_NAT,
530                         iptables_cmd, iptables_filter_out, iptables_nat_chain_name);
531         if (netconfig_execute_cmd(buf))
532                 ERR("Failed to execute command: %s", buf);
533
534         memset(buf, '0', sizeof(buf));
535         snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN_FROM_NAT,
536                         iptables_cmd, iptables_nat_chain_name);
537         if (netconfig_execute_cmd(buf))
538                 ERR("Failed to execute command: %s", buf);
539
540         memset(buf, '0', sizeof(buf));
541         snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN_FROM_NAT,
542                         iptables_cmd, iptables_nat_chain_name);
543         if (netconfig_execute_cmd(buf))
544                 ERR("Failed to execute command: %s", buf);
545 }
546
547 static void iptables_register(void)
548 {
549         char buf[BUF_SIZE_FOR_CMD] = {0, };
550         char *filter;
551
552         filter = iptables_filter_out;
553
554         snprintf(buf, sizeof(buf), IPTABLES_FMT_CREATE_CHAIN,
555                         iptables_cmd, iptables_filter_prefix, filter);
556         if (netconfig_execute_cmd(buf))
557                 ERR("Failed to execute command: %s", buf);
558
559         memset(buf, '0', sizeof(buf));
560         snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
561                         iptables_cmd, iptables_filter_prefix, filter);
562         if (netconfig_execute_cmd(buf))
563                 ERR("Failed to execute command: %s", buf);
564
565         memset(buf, '0', sizeof(buf));
566         snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_DROP_RULE,
567                         iptables_cmd, iptables_filter_prefix, filter);
568         if (netconfig_execute_cmd(buf))
569                 ERR("Failed to execute command: %s", buf);
570
571         memset(buf, '0', sizeof(buf));
572         snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_RETURN_RULE,
573                         iptables_cmd, iptables_filter_prefix, filter);
574         if (netconfig_execute_cmd(buf))
575                 ERR("Failed to execute command: %s", buf);
576
577         memset(buf, '0', sizeof(buf));
578         snprintf(buf, sizeof(buf), IPTABLES_FMT_INSERT_RULE,
579                         iptables_cmd, filter, iptables_filter_prefix, filter);
580
581         filter = iptables_filter_in;
582
583         memset(buf, '0', sizeof(buf));
584         snprintf(buf, sizeof(buf), IPTABLES_FMT_CREATE_CHAIN,
585                         iptables_cmd, iptables_filter_prefix, filter);
586         if (netconfig_execute_cmd(buf))
587                 ERR("Failed to execute command: %s", buf);
588
589         memset(buf, '0', sizeof(buf));
590         snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
591                         iptables_cmd, iptables_filter_prefix, filter);
592         if (netconfig_execute_cmd(buf))
593                 ERR("Failed to execute command: %s", buf);
594
595         memset(buf, '0', sizeof(buf));
596         snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_DROP_RULE,
597                         iptables_cmd, iptables_filter_prefix, filter);
598         if (netconfig_execute_cmd(buf))
599                 ERR("Failed to execute command: %s", buf);
600
601         memset(buf, '0', sizeof(buf));
602         snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_RETURN_RULE,
603                         iptables_cmd, iptables_filter_prefix, filter);
604         if (netconfig_execute_cmd(buf))
605                 ERR("Failed to execute command: %s", buf);
606
607         memset(buf, '0', sizeof(buf));
608         snprintf(buf, sizeof(buf), IPTABLES_FMT_INSERT_RULE,
609                         iptables_cmd, filter, iptables_filter_prefix, filter);
610 }
611
612 static void iptables_unregister(void)
613 {
614         char buf[BUF_SIZE_FOR_CMD] = {0, };
615         char *filter;
616
617         filter = iptables_filter_out;
618
619         snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE,
620                         iptables_cmd, filter, iptables_filter_prefix, filter);
621         if (netconfig_execute_cmd(buf))
622                 ERR("Failed to execute command: %s", buf);
623
624         memset(buf, '0', sizeof(buf));
625         snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
626                         iptables_cmd, iptables_filter_prefix, filter);
627         if (netconfig_execute_cmd(buf))
628                 ERR("Failed to execute command: %s", buf);
629
630         memset(buf, '0', sizeof(buf));
631         snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN,
632                         iptables_cmd, iptables_filter_prefix, filter);
633         if (netconfig_execute_cmd(buf))
634                 ERR("Failed to execute command: %s", buf);
635
636         filter = iptables_filter_in;
637
638         memset(buf, '0', sizeof(buf));
639         snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_RULE,
640                         iptables_cmd, filter, iptables_filter_prefix, filter);
641         if (netconfig_execute_cmd(buf))
642                 ERR("Failed to execute command: %s", buf);
643
644         memset(buf, '0', sizeof(buf));
645         snprintf(buf, sizeof(buf), IPTABLES_FMT_FLUSH_CHAIN,
646                         iptables_cmd, iptables_filter_prefix, filter);
647         if (netconfig_execute_cmd(buf))
648                 ERR("Failed to execute command: %s", buf);
649
650         memset(buf, '0', sizeof(buf));
651         snprintf(buf, sizeof(buf), IPTABLES_FMT_DEL_CHAIN,
652                         iptables_cmd, iptables_filter_prefix, filter);
653         if (netconfig_execute_cmd(buf))
654                 ERR("Failed to execute command: %s", buf);
655 }
656
657 static void iptables_rule(const char c, const char *addr, const int mask)
658 {
659         char buf[BUF_SIZE_FOR_CMD];
660
661         snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE,
662                         iptables_cmd, c, iptables_filter_prefix,
663                         iptables_filter_out, 'd', addr, mask);
664         if (netconfig_execute_cmd(buf))
665                 ERR("Failed to execute command: %s", buf);
666
667         memset(buf, '0', sizeof(buf));
668         snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE,
669                         iptables_cmd, c,  iptables_filter_prefix,
670                         iptables_filter_in, 's', addr, mask);
671         if (netconfig_execute_cmd(buf))
672                 ERR("Failed to execute command: %s", buf);
673 }
674
675 static void iptables_rule_interface(const char c, const char *addr, const int mask, const char *interface)
676 {
677         char buf[BUF_SIZE_FOR_CMD];
678
679         snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF,
680                         iptables_cmd, c, iptables_filter_prefix, iptables_filter_out,
681                         'o', interface, 'd', addr, mask);
682         if (netconfig_execute_cmd(buf))
683                 ERR("Failed to execute command: %s", buf);
684
685         memset(buf, '0', sizeof(buf));
686         snprintf(buf, sizeof(buf), IPTABLES_FMT_APPEND_ACCEPT_RULE_WITH_INTF,
687                         iptables_cmd, c, iptables_filter_prefix, iptables_filter_in,
688                         'i', interface, 's', addr, mask);
689         if (netconfig_execute_cmd(buf))
690                 ERR("Failed to execute command: %s", buf);
691 }
692
693 void iptables_add_orig(const char *addr, const int mask)
694 {
695         iptables_rule_interface('I', addr, mask, iptables_filter_interface_wlan);
696 }
697
698 void iptables_delete_orig(const char *addr, const int mask)
699 {
700         iptables_rule_interface('D', addr, mask, iptables_filter_interface_wlan);
701 }
702
703 void iptables_add(const char *addr, const int mask)
704 {
705         iptables_rule('I', addr, mask);
706 }
707
708 void iptables_delete(const char *addr, const int mask)
709 {
710         iptables_rule('D', addr, mask);
711 }
712
713 static int get_interface_index(const char *iface_name)
714 {
715         struct ifreq ifr;
716         int sk = 0;
717         char buf[BUF_SIZE_FOR_ERR] = { 0 };
718
719         DBG("enter get_interface_index, iface_name : %s", iface_name);
720
721         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
722         if (sk < 0) {
723                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
724                 return VPNSVC_ERROR_IO_ERROR;
725         }
726
727         memset(&ifr, 0, sizeof(ifr));
728
729         if (*iface_name)
730         strncpy(ifr.ifr_name, iface_name, strlen(iface_name));
731
732         /* get an interface name by ifindex */
733         if (ioctl(sk, SIOCGIFINDEX, &ifr) < 0) {
734                 ERR("ioctl SIOCGIFINDEX failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
735                 close(sk);
736                 return VPNSVC_ERROR_IO_ERROR;
737         }
738
739         close(sk);
740
741         return ifr.ifr_ifindex;
742 }
743
744 static int check_interface_precondition(const char *iface_name)
745 {
746
747         int sk;
748         struct ifreq ifr_tun;
749         char buf[BUF_SIZE_FOR_ERR] = { 0 };
750
751         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
752         if (sk < 0) {
753                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
754                 return VPNSVC_ERROR_IO_ERROR;
755         }
756
757         memset(&ifr_tun, 0, sizeof(ifr_tun));
758         g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name));
759
760         /* local ip */
761         if (ioctl(sk, SIOCGIFADDR, &ifr_tun) < 0) {
762                 ERR("Fail to get local IP address: %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
763                 close(sk);
764                 return VPNSVC_ERROR_INVALID_PARAMETER;
765         }
766
767         /* remote ip */
768         if (ioctl(sk, SIOCGIFDSTADDR, &ifr_tun) < 0) {
769                 ERR("Fail to get remote IP address: %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
770                 close(sk);
771                 return VPNSVC_ERROR_INVALID_PARAMETER;
772         }
773
774         close(sk);
775
776         return VPNSVC_ERROR_NONE;
777 }
778
779
780 int vpn_service_init(const char* iface_name, size_t iface_name_len, int fd, vpnsvc_tun_s *handle_s)
781 {
782         struct ifreq ifr;
783         size_t len = 0;
784         char buf[BUF_SIZE_FOR_ERR] = { 0 };
785
786         DBG("enter vpn_daemon_init, iface_name : %s, iface_name_len : %d, fd : %d\n", iface_name, iface_name_len, fd);
787
788         memset(&ifr, 0, sizeof(ifr));
789
790         /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
791         *               IFF_TAP   - TAP device
792         *
793         *               IFF_NO_PI - Do not provide packet information
794         */
795
796         ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
797
798         if (*iface_name)
799                 strncpy(ifr.ifr_name, iface_name, iface_name_len);
800
801         DBG("before init, ifindex : %d", ifr.ifr_ifindex);
802
803         if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
804                 ERR("TUNSETIFF Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
805                 close(fd);
806                 return VPNSVC_ERROR_IO_ERROR;
807         }
808
809         if (ioctl(fd, TUNSETOWNER, 5000) < 0) {
810                 ERR("TUNSETOWNER Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
811                 close(fd);
812                 return VPNSVC_ERROR_IO_ERROR;
813         }
814
815         if (ioctl(fd, TUNSETPERSIST, 1) < 0) {
816                 ERR("TUNSETPERSIST Failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
817                 close(fd);
818                 return VPNSVC_ERROR_IO_ERROR;
819         }
820
821         handle_s->fd = 0;   /* server fd does not meaning */
822         handle_s->index = get_interface_index(iface_name);
823         len = strlen(ifr.ifr_name);
824         strncpy(handle_s->name, ifr.ifr_name, len);
825         handle_s->name[len] = '\0';
826
827         return VPNSVC_ERROR_NONE;
828 }
829
830 int vpn_service_deinit(const char* dev_name)
831 {
832         char buf[100], *cmd;
833         FILE *fp = NULL;
834
835         if (_check_config_str() != 0) {
836                 ERR("Failed to get configuration string");
837                 return VPNSVC_ERROR_IO_ERROR;
838         }
839
840         snprintf(buf, sizeof(buf), "/usr/sbin/ip link del %s", dev_name);
841
842         cmd = g_try_malloc0(strlen(buf) + 1);
843         strncpy(cmd, buf, strlen(buf));
844
845         DBG("link delete cmd : %s", cmd);
846
847         fp = popen(cmd, "r");
848         g_free(cmd);
849
850         if (fp != NULL) {
851                 pclose(fp);
852                 return VPNSVC_ERROR_NONE;
853         } else {
854                 return VPNSVC_ERROR_IO_ERROR;
855         }
856 }
857
858 int vpn_service_protect(int socket_fd, const char* dev_name)
859 {
860         int ret = VPNSVC_ERROR_NONE;
861         char buf[BUF_SIZE_FOR_ERR] = { 0 };
862         DBG("enter vpn_daemon_protect, socket : %d, dev_name : %s\n", socket_fd, dev_name);
863
864         ret = setsockopt(socket_fd, SOL_SOCKET, SO_BINDTODEVICE,
865                                         dev_name, strlen(dev_name));
866
867         if (ret < 0) {
868                 DBG("setsockopt failed : %d, %s", ret, strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
869                 ret = VPNSVC_ERROR_IO_ERROR;
870         } else {
871                 ret = VPNSVC_ERROR_NONE;
872         }
873
874         return ret;
875 }
876
877 int vpn_service_up(const char *iface_name)
878 {
879         struct ifreq ifr_tun;
880         int sk;
881         int ret = VPNSVC_ERROR_NONE;
882         char buf[BUF_SIZE_FOR_ERR] = { 0 };
883
884         DBG("enter vpn_daemon_up");
885         DBG("iface_name : %s", iface_name);
886
887
888         ret = check_interface_precondition(iface_name);
889         if (ret != VPNSVC_ERROR_NONE)
890                 return ret;
891
892         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
893         if (sk < 0) {
894                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
895                 return VPNSVC_ERROR_IO_ERROR;
896         }
897
898         memset(&ifr_tun, 0, sizeof(ifr_tun));
899         g_strlcpy((char *)ifr_tun.ifr_name, iface_name, sizeof(ifr_tun.ifr_name));
900
901         /* set the flags for vpn up */
902         if (ioctl(sk, SIOCGIFFLAGS, &ifr_tun) < 0) {
903                 ERR("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
904                 close(sk);
905                 return VPNSVC_ERROR_IO_ERROR;
906         }
907
908         ifr_tun.ifr_flags |= IFF_UP;
909         ifr_tun.ifr_flags |= IFF_RUNNING;
910
911         if (ioctl(sk, SIOCSIFFLAGS, &ifr_tun) < 0)  {
912                 ERR("ioctl SIOCSIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
913                 close(sk);
914                 return VPNSVC_ERROR_IO_ERROR;
915         }
916
917         close(sk);
918
919 #if 0
920         /* add DNS servers */
921         if (nr_dns > 0) {
922                 ret = add_dns_servers(dns_servers, nr_dns, total_dns_string_cnt);
923                 if (ret != VPNSVC_ERROR_NONE) {
924                         ERR("add_dns failed");
925                         return ret;
926                 }
927         }
928
929         /* add_dns_suffix */
930         if (dns_suffix) {
931                 ret = add_dns_suffix(dns_suffix, strlen(dns_suffix));
932                 if (ret != VPNSVC_ERROR_NONE) {
933                         ERR("add_dns_suffix failed");
934                         return ret;
935                 }
936         }
937
938         if (nr_dns > 0)
939                 dns_nat_register(dns_servers, nr_dns, local_ip);
940 #endif
941
942         return ret;
943 }
944
945
946
947 int vpn_service_down(const char *iface_name)
948 {
949         struct ifreq ifr;
950         int sk;
951         char buf[BUF_SIZE_FOR_ERR] = { 0 };
952
953         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
954         if (sk < 0) {
955                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
956                 return VPNSVC_ERROR_IO_ERROR;
957         }
958
959         memset(&ifr, 0, sizeof(ifr));
960         g_strlcpy((char *)ifr.ifr_name, iface_name, sizeof(ifr.ifr_name));
961
962         if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) {
963                 ERR("ioctl SIOCGIFFLAGS failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
964                 close(sk);
965                 return VPNSVC_ERROR_IO_ERROR;
966         }
967
968         if (!(ifr.ifr_flags & IFF_UP)) {
969                 DBG("Interface already down");
970                 close(sk);
971                 return VPNSVC_ERROR_NONE;
972         }
973
974         ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
975         if (ioctl(sk, SIOCSIFFLAGS, &ifr) < 0) {
976                 ERR("ioctl SIOCSIFFLAGS (interface down) failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
977                 close(sk);
978                 return VPNSVC_ERROR_IO_ERROR;
979         }
980
981         close(sk);
982
983         /* routes are will be removed  automatically while down interfaces */
984         /* remove dns servers */
985         del_dns_servers();
986
987         /* remove dns suffix */
988         del_dns_suffix();
989
990         /* remove dns filter */
991         dns_nat_unregister();
992
993         return VPNSVC_ERROR_NONE;
994 }
995
996 int vpn_service_block_networks(char* nets_vpn[], int prefix_vpn[], size_t nr_nets_vpn,
997                 char* nets_orig[], int prefix_orig[], size_t nr_nets_orig) {
998         unsigned int i;
999
1000         /* iptable chain regist */
1001         iptables_register();
1002
1003         for (i = 0; i < nr_nets_vpn; i++) {
1004                 DBG("block[%d] ip/mask : %s/%d", i, nets_vpn[i], prefix_vpn[i]);
1005                 iptables_add(nets_vpn[i], prefix_vpn[i]);
1006         }
1007
1008         for (i = 0; i < nr_nets_orig; i++) {
1009                 DBG("allow[%d] ip/mask : %s/%d", i, nets_orig[i], prefix_orig[i]);
1010                 iptables_add_orig(nets_orig[i], prefix_orig[i]);
1011         }
1012
1013         return VPNSVC_ERROR_NONE;
1014 }
1015
1016 int vpn_service_unblock_networks(void)
1017 {
1018         iptables_unregister();
1019
1020         return VPNSVC_ERROR_NONE;
1021 }
1022
1023 int vpn_service_update_settings(int iface_index, const char *local_ip,
1024                 const char *remote_ip, const unsigned int mtu)
1025 {
1026         int sk;
1027         struct ifreq ifr_tun;
1028         struct sockaddr_in local_addr;
1029         struct sockaddr_in remote_addr;
1030         char buf[BUF_SIZE_FOR_ERR] = { 0 };
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(&ifr_tun, 0, sizeof(ifr_tun));
1039         ifr_tun.ifr_ifindex = iface_index;
1040
1041         /* get an interface name by ifindex */
1042         if (ioctl(sk, SIOCGIFNAME, &ifr_tun) < 0) {
1043                 ERR("ioctl SIOCGIFNAME failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1044                 close(sk);
1045                 return VPNSVC_ERROR_IO_ERROR;
1046         }
1047
1048         /* local ip setting */
1049         memset(&local_addr, 0, sizeof(local_addr));
1050         local_addr.sin_addr.s_addr = inet_addr(local_ip); /* network byte order */
1051         local_addr.sin_family = AF_INET;
1052         memcpy(&ifr_tun.ifr_addr, &local_addr, sizeof(ifr_tun.ifr_addr));
1053         if (ioctl(sk, SIOCSIFADDR, &ifr_tun) < 0) {
1054                 ERR("ioctl SIOCSIFADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1055                 close(sk);
1056                 return VPNSVC_ERROR_IO_ERROR;
1057         }
1058
1059         /* remote ip setting */
1060         memset(&remote_addr, 0, sizeof(remote_addr));
1061         remote_addr.sin_addr.s_addr = inet_addr(remote_ip); /*network byte order*/
1062         remote_addr.sin_family = AF_INET;
1063         memcpy(&ifr_tun.ifr_dstaddr, &remote_addr, sizeof(ifr_tun.ifr_dstaddr));
1064         if (ioctl(sk, SIOCSIFDSTADDR, &ifr_tun) < 0) {
1065                 ERR("ioctl SIOCSIFDSTADDR failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1066                 close(sk);
1067                 return VPNSVC_ERROR_IO_ERROR;
1068         }
1069
1070         /* mtu setting */
1071         if (mtu > 0 && ifr_tun.ifr_mtu != (int)mtu) {
1072                 ifr_tun.ifr_mtu = mtu;
1073                 if (ioctl(sk, SIOCSIFMTU, &ifr_tun) < 0) {
1074                         ERR("ioctl SIOCSIFMTU failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1075                         close(sk);
1076                         return VPNSVC_ERROR_IO_ERROR;
1077                 }
1078         }
1079
1080         close(sk);
1081
1082         return VPNSVC_ERROR_NONE;
1083 }
1084
1085 int vpn_service_add_route(char *iface_name, const char *route, int prefix)
1086 {
1087         struct rtentry rt;
1088         struct sockaddr_in addr;
1089         int sk;
1090         char buf[BUF_SIZE_FOR_ERR] = { 0 };
1091
1092         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1093         if (sk < 0) {
1094                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1095                 return VPNSVC_ERROR_IO_ERROR;
1096         }
1097
1098         memset(&rt, 0, sizeof(rt));
1099         rt.rt_flags = RTF_UP;
1100
1101         memset(&addr, 0, sizeof(addr));
1102         addr.sin_family = AF_INET;
1103         addr.sin_addr.s_addr = inet_addr(route);
1104         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1105
1106         memset(&addr, 0, sizeof(addr));
1107         addr.sin_family = AF_INET;
1108         addr.sin_addr.s_addr = INADDR_ANY;
1109         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1110
1111         /* set mask using by prefix length */
1112         memset(&addr, 0, sizeof(addr));
1113         addr.sin_family = AF_INET;
1114         addr.sin_addr.s_addr = INADDR_ANY;
1115         addr.sin_addr.s_addr = host2net(make_mask(prefix));
1116         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1117
1118         rt.rt_dev = iface_name;
1119
1120         if (ioctl(sk, SIOCADDRT, &rt) < 0) {
1121                 ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1122                 close(sk);
1123                 return VPNSVC_ERROR_IO_ERROR;
1124         }
1125
1126         close(sk);
1127
1128         return VPNSVC_ERROR_NONE;
1129 }
1130
1131 int vpn_service_remove_route(char *iface_name, const char *route, int prefix)
1132 {
1133         struct rtentry rt;
1134         struct sockaddr_in addr;
1135         int sk;
1136         char buf[BUF_SIZE_FOR_ERR] = { 0 };
1137
1138         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1139         if (sk < 0) {
1140                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1141                 return VPNSVC_ERROR_IO_ERROR;
1142         }
1143
1144         memset(&rt, 0, sizeof(rt));
1145         rt.rt_flags = RTF_UP;
1146
1147         memset(&addr, 0, sizeof(addr));
1148         addr.sin_family = AF_INET;
1149         addr.sin_addr.s_addr = inet_addr(route);
1150         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1151
1152         memset(&addr, 0, sizeof(addr));
1153         addr.sin_family = AF_INET;
1154         addr.sin_addr.s_addr = INADDR_ANY;
1155         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1156
1157         /* set mask using by prefix length */
1158         memset(&addr, 0, sizeof(addr));
1159         addr.sin_family = AF_INET;
1160         addr.sin_addr.s_addr = INADDR_ANY;
1161         addr.sin_addr.s_addr = host2net(make_mask(prefix));
1162         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1163
1164         rt.rt_dev = iface_name;
1165
1166         if (ioctl(sk, SIOCDELRT, &rt) < 0) {
1167                 ERR("ioctl SIOCDERLT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1168                 close(sk);
1169                 return VPNSVC_ERROR_IO_ERROR;
1170         }
1171
1172         close(sk);
1173
1174         return VPNSVC_ERROR_NONE;
1175
1176 }
1177
1178 int vpn_service_add_dns_server(char *iface_name, const char *dns_server)
1179 {
1180         struct rtentry rt;
1181         struct sockaddr_in addr;
1182         int sk;
1183         char buf[BUF_SIZE_FOR_ERR] = { 0 };
1184
1185         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1186         if (sk < 0) {
1187                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1188                 return VPNSVC_ERROR_IO_ERROR;
1189         }
1190
1191         memset(&rt, 0, sizeof(rt));
1192         rt.rt_flags = RTF_UP;
1193
1194         memset(&addr, 0, sizeof(addr));
1195         addr.sin_family = AF_INET;
1196         addr.sin_addr.s_addr = inet_addr(dns_server);
1197         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1198
1199         memset(&addr, 0, sizeof(addr));
1200         addr.sin_family = AF_INET;
1201         addr.sin_addr.s_addr = INADDR_ANY;
1202         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1203
1204         /* set mask using by prefix length */
1205         memset(&addr, 0, sizeof(addr));
1206         addr.sin_family = AF_INET;
1207         addr.sin_addr.s_addr = INADDR_ANY;
1208         addr.sin_addr.s_addr = host2net(make_mask(32));
1209         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1210
1211         rt.rt_dev = iface_name;
1212
1213         if (ioctl(sk, SIOCADDRT, &rt) < 0) {
1214                 ERR("ioctl SIOCADDRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1215                 close(sk);
1216                 return VPNSVC_ERROR_IO_ERROR;
1217         }
1218
1219         close(sk);
1220
1221         return VPNSVC_ERROR_NONE;
1222 }
1223
1224 int vpn_service_remove_dns_server(char *iface_name, const char *dns_server)
1225 {
1226         struct rtentry rt;
1227         struct sockaddr_in addr;
1228         int sk;
1229         char buf[BUF_SIZE_FOR_ERR] = { 0 };
1230
1231         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1232         if (sk < 0) {
1233                 ERR("socket failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1234                 return VPNSVC_ERROR_IO_ERROR;
1235         }
1236
1237         memset(&rt, 0, sizeof(rt));
1238         rt.rt_flags = RTF_UP;
1239
1240         memset(&addr, 0, sizeof(addr));
1241         addr.sin_family = AF_INET;
1242         addr.sin_addr.s_addr = inet_addr(dns_server);
1243         memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
1244
1245         memset(&addr, 0, sizeof(addr));
1246         addr.sin_family = AF_INET;
1247         addr.sin_addr.s_addr = INADDR_ANY;
1248         memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
1249
1250         /* set mask using by prefix length */
1251         memset(&addr, 0, sizeof(addr));
1252         addr.sin_family = AF_INET;
1253         addr.sin_addr.s_addr = INADDR_ANY;
1254         addr.sin_addr.s_addr = host2net(make_mask(32));
1255         memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
1256
1257         rt.rt_dev = iface_name;
1258
1259         if (ioctl(sk, SIOCDELRT, &rt) < 0) {
1260                 ERR("ioctl SIOCDELRT failed : %s", strerror_r(errno, buf, BUF_SIZE_FOR_ERR));
1261                 close(sk);
1262                 return VPNSVC_ERROR_IO_ERROR;
1263         }
1264
1265         close(sk);
1266
1267         return VPNSVC_ERROR_NONE;
1268 }