Removed unused netconfig_wifi_on/off function
[platform/core/connectivity/net-config.git] / src / utils / util.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2000 - 2012 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 #include <app.h>
21 #include <errno.h>
22 #include <vconf.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <net/if.h>
28 #include <net/route.h>
29 #include <arpa/inet.h>
30 #include <sys/wait.h>
31 #include <sys/stat.h>
32 #include <sys/ioctl.h>
33 #include <vconf-keys.h>
34 #include <syspopup_caller.h>
35 #include <bundle.h>
36 #include <bundle_internal.h>
37 #include <eventsystem.h>
38 #include <tzplatform_config.h>
39
40 #include "log.h"
41 #include "util.h"
42 #include "neterror.h"
43 #include "wifi-state.h"
44 #include "netdbus.h"
45
46 #define DBUS_SERVICE_DBUS               "org.freedesktop.DBus"
47 #define DBUS_INTERFACE_DBUS             "org.freedesktop.DBus"
48 #define MAC_INFO_FILEPATH               tzplatform_mkpath(TZ_SYS_ETC, "/.mac.info")
49 #define MAC_ADDRESS_FILEPATH    "/sys/class/net/wlan0/address"
50 #define MAC_ADDRESS_MAX_LEN             18
51
52 static gboolean netconfig_device_picker_test = FALSE;
53 static int mdnsd_ref_count = 0;
54 typedef struct {
55         char *conn_name;
56         int conn_id;
57 } dnssd_conn_destroy_data;
58
59 GKeyFile *netconfig_keyfile_load(const char *pathname)
60 {
61         GKeyFile *keyfile = NULL;
62         GError *error = NULL;
63
64         keyfile = g_key_file_new();
65         if (g_key_file_load_from_file(keyfile, pathname, 0, &error) != TRUE) {
66                 DBG("Unable to open %s, error %s", pathname, error->message);
67                 g_error_free(error);
68
69                 g_key_file_free(keyfile);
70                 keyfile = NULL;
71         }
72
73         DBG("loaded keyfile %s", pathname);
74         return keyfile;
75 }
76
77 void netconfig_keyfile_save(GKeyFile *keyfile, const char *pathname)
78 {
79         gsize size = 0;
80         GError *error = NULL;
81         gchar *keydata = NULL;
82         gchar *needle = NULL, *directory = NULL;
83
84         directory = g_strdup(pathname);
85         needle = g_strrstr(directory, "/");
86
87         if (needle != NULL)
88                 *needle = '\0';
89
90         if (directory == NULL || (*directory) == '\0') {
91                 g_free(directory);
92                 ERR("directory is NULL");
93                 return;
94         }
95
96         if (g_file_test(directory, G_FILE_TEST_IS_DIR) != TRUE) {
97                 if (g_mkdir_with_parents(directory,
98                                 S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
99                         g_free(directory);
100                         ERR("failed to make directory");
101                         return;
102                 }
103         }
104         g_free(directory);
105
106         keydata = g_key_file_to_data(keyfile, &size, &error);
107         if (g_file_set_contents(pathname, keydata, size, &error) != TRUE) {
108                 ERR("Unable to save %s, error %s", pathname, error->message);
109                 g_error_free(error);
110         }
111
112         chmod(pathname, S_IRUSR | S_IWUSR);
113         DBG("Successfully saved keyfile %s", pathname);
114
115         g_free(keydata);
116 }
117
118 void netconfig_start_timer_seconds(guint secs,
119                 gboolean(*callback) (gpointer), void *user_data, guint *timer_id)
120 {
121         guint t_id = 0;
122
123         if (callback == NULL) {
124                 ERR("callback function is NULL");
125                 return;
126         }
127
128         if ((timer_id != NULL && *timer_id != 0)) {
129                 ERR("timer already is registered");
130                 return;
131         }
132
133         t_id = g_timeout_add_seconds(secs, callback, user_data);
134
135         if (t_id == 0) {
136                 ERR("Can't add timer");
137                 return;
138         }
139
140         if (timer_id != NULL)
141                 *timer_id = t_id;
142 }
143
144 void netconfig_start_timer(guint msecs,
145                 gboolean(*callback) (gpointer), void *user_data, guint *timer_id)
146 {
147         guint t_id = 0;
148
149         INFO("Register timer with callback pointer (%p)", callback);
150
151         if (callback == NULL) {
152                 ERR("callback function is NULL");
153                 return;
154         }
155
156         if ((timer_id != NULL && *timer_id != 0)) {
157                 ERR("timer already is registered");
158                 return;
159         }
160
161         t_id = g_timeout_add(msecs, callback, user_data);
162
163         if (t_id == 0) {
164                 ERR("Can't add timer");
165                 return;
166         }
167
168         if (timer_id != NULL)
169                 *timer_id = t_id;
170 }
171
172 void netconfig_stop_timer(guint *timer_id)
173 {
174         if (timer_id == NULL) {
175                 ERR("timer is NULL");
176                 return;
177         }
178
179         if (*timer_id != 0) {
180                 g_source_remove(*timer_id);
181                 *timer_id = 0;
182         }
183 }
184
185 static gboolean __netconfig_test_device_picker()
186 {
187         char *favorite_wifi_service = NULL;
188
189         favorite_wifi_service = wifi_get_favorite_service();
190         if (favorite_wifi_service != NULL) {
191                 ERR("favorite_wifi_service is existed[%s] : Donot launch device picker", favorite_wifi_service);
192                 g_free(favorite_wifi_service);
193                 return FALSE;
194         }
195
196         return TRUE;
197 }
198
199 static void __netconfig_pop_device_picker(void)
200 {
201 #if defined TIZEN_WEARABLE
202         int ret = 0;
203         app_control_h   control = NULL;
204
205         ret = app_control_create(&control);
206         if (APP_CONTROL_ERROR_NONE != ret) {
207                 DBG("failed to create app control");
208                 return ;
209         }
210
211         app_control_add_extra_data(control, "viewtype", "scanlist");
212
213         app_control_set_app_id(control, "org.tizen.wifi");
214         ret = app_control_send_launch_request(control, NULL, NULL);
215         if (APP_CONTROL_ERROR_NONE == ret)
216                 DBG("Launch request sent successfully");
217
218         app_control_destroy(control);
219 #else
220         bundle *b = NULL;
221         int wifi_ug_state = 0;
222
223         netconfig_vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state);
224         if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND)
225                 return;
226
227         b = bundle_create();
228
229         DBG("Launch Wi-Fi device picker");
230         syspopup_launch("wifi-qs", b);
231
232         bundle_free(b);
233 #endif
234 }
235
236 static gboolean __netconfig_wifi_try_device_picker(gpointer data)
237 {
238         if (__netconfig_test_device_picker() == TRUE)
239                 __netconfig_pop_device_picker();
240
241         return FALSE;
242 }
243
244 static guint __netconfig_wifi_device_picker_timer_id(gboolean is_set_method, guint timer_id)
245 {
246         static guint netconfig_wifi_device_picker_service_timer = 0;
247
248         if (is_set_method != TRUE)
249                 return netconfig_wifi_device_picker_service_timer;
250
251         if (netconfig_wifi_device_picker_service_timer != timer_id)
252                 netconfig_wifi_device_picker_service_timer = timer_id;
253
254         return netconfig_wifi_device_picker_service_timer;
255 }
256
257 static void __netconfig_wifi_device_picker_set_timer_id(guint timer_id)
258 {
259         __netconfig_wifi_device_picker_timer_id(TRUE, timer_id);
260 }
261
262 static guint __netconfig_wifi_device_picker_get_timer_id(void)
263 {
264         return __netconfig_wifi_device_picker_timer_id(FALSE, -1);
265 }
266
267 void netconfig_wifi_enable_device_picker_test(void)
268 {
269         netconfig_device_picker_test = TRUE;
270 }
271
272 void netconfig_wifi_device_picker_service_start(void)
273 {
274         const int NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL = 700;
275         guint timer_id = 0;
276
277         if (netconfig_device_picker_test == TRUE)
278                 netconfig_device_picker_test = FALSE;
279         else
280                 return;
281
282         int wifi_ug_state;
283
284         netconfig_vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state);
285         if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND)
286                 return;
287
288         DBG("Register device picker timer with %d milliseconds", NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL);
289         netconfig_start_timer(NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL, __netconfig_wifi_try_device_picker, NULL, &timer_id);
290
291         __netconfig_wifi_device_picker_set_timer_id(timer_id);
292 }
293
294 void netconfig_wifi_device_picker_service_stop(void)
295 {
296         guint timer_id = 0;
297
298         timer_id = __netconfig_wifi_device_picker_get_timer_id();
299         if (timer_id == 0)
300                 return;
301
302         DBG("Clear device picker timer with timer_id %d", timer_id);
303
304         netconfig_stop_timer(&timer_id);
305
306         __netconfig_wifi_device_picker_set_timer_id(timer_id);
307 }
308
309 gboolean netconfig_is_wifi_direct_on(void)
310 {
311 #if defined TIZEN_P2P_ENABLE
312         int wifi_direct_state = 0;
313
314         netconfig_vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state);
315
316         DBG("Wi-Fi direct mode %d", wifi_direct_state);
317         return (wifi_direct_state != 0) ? TRUE : FALSE;
318 #else
319         return FALSE;
320 #endif
321 }
322
323 gboolean netconfig_is_wifi_tethering_on(void)
324 {
325 #if defined TIZEN_TETHERING_ENABLE
326         int wifi_tethering_state = 0;
327
328         netconfig_vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &wifi_tethering_state);
329         DBG("Wi-Ti tethering mode %d", wifi_tethering_state);
330         if ((wifi_tethering_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI)
331                 || (wifi_tethering_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI_AP)) {
332                 DBG("Mobile AP is on");
333                 return TRUE;
334         }
335 #endif
336         DBG("Mobile AP is off");
337         return FALSE;
338 }
339
340 gboolean netconfig_interface_up(const char *ifname)
341 {
342         int fd;
343         struct ifreq ifr;
344
345         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
346         if (fd < 0)
347                 return FALSE;
348
349         memset(&ifr, 0, sizeof(ifr));
350         g_strlcpy((char *)ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
351
352         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
353                 close(fd);
354                 return FALSE;
355         }
356
357         ifr.ifr_flags |= (IFF_UP | IFF_DYNAMIC);
358         if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
359                 close(fd);
360                 return FALSE;
361         }
362
363         close(fd);
364
365         DBG("Successfully activated wireless interface %s", ifname);
366         return TRUE;
367 }
368
369 gboolean netconfig_interface_down(const char *ifname)
370 {
371         int fd;
372         struct ifreq ifr;
373
374         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
375         if (fd < 0)
376                 return FALSE;
377
378         memset(&ifr, 0, sizeof(ifr));
379         g_strlcpy((char *)ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
380
381         if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
382                 close(fd);
383                 return FALSE;
384         }
385
386         ifr.ifr_flags = (ifr.ifr_flags & ~IFF_UP) | IFF_DYNAMIC;
387         if (ioctl(fd, SIOCSIFFLAGS, &ifr) < 0) {
388                 close(fd);
389                 return FALSE;
390         }
391
392         close(fd);
393
394         DBG("Successfully de-activated wireless interface %s", ifname);
395         return TRUE;
396 }
397
398 int netconfig_execute_file(const char *file_path,
399                 char *const args[], char *const envs[])
400 {
401         pid_t pid = 0;
402         int status = 0;
403         int rv = 0;
404         errno = 0;
405         register unsigned int index = 0;
406         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
407
408         while (args[index] != NULL) {
409                 DBG("%s", args[index]);
410                 index++;
411         }
412
413         if (!(pid = fork())) {
414                 DBG("pid(%d), ppid (%d)", getpid(), getppid());
415                 DBG("Inside child, exec (%s) command", file_path);
416
417                 errno = 0;
418                 if (execve(file_path, args, envs) == -1) {
419                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
420                         DBG("Fail to execute command (%s)", error_buf);
421                         exit(1);
422                 }
423         } else if (pid > 0) {
424                 if (waitpid(pid, &status, 0) == -1)
425                         DBG("wait pid (%u) status (%d)", pid, status);
426
427                 if (WIFEXITED(status)) {
428                         rv = WEXITSTATUS(status);
429                         DBG("exited, status=%d", rv);
430                 } else if (WIFSIGNALED(status)) {
431                         DBG("killed by signal %d", WTERMSIG(status));
432                 } else if (WIFSTOPPED(status)) {
433                         DBG("stopped by signal %d", WSTOPSIG(status));
434                 } else if (WIFCONTINUED(status)) {
435                         DBG("continued");
436                 }
437
438                 return rv;
439         }
440
441         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
442         DBG("failed to fork(%s)", error_buf);
443         return -EIO;
444 }
445
446 static void on_clat_handler()
447 {
448         pid_t clat_pid = 0;
449         int state = 0;
450
451         clat_pid = waitpid(-1, &state, WNOHANG);
452
453         DBG("clat(%d) state(%d)", clat_pid, WEXITSTATUS(state));
454 }
455
456 int netconfig_execute_clatd(const char *file_path, char *const args[])
457 {
458         pid_t pid = 0;
459         int rv = 0;
460         errno = 0;
461         register unsigned int index = 0;
462         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
463
464         struct sigaction act;
465         int state = 0;
466
467         act.sa_handler = on_clat_handler;
468         sigemptyset(&act.sa_mask);
469         act.sa_flags = 0;
470
471         state = sigaction(SIGCHLD, &act, 0);
472         if (state != 0) {
473                 DBG("sigaction() : %d");
474                 return -1;
475         }
476
477         while (args[index] != NULL) {
478                 DBG("%s", args[index]);
479                 index++;
480         }
481
482         if (!(pid = fork())) {
483                 DBG("pid(%d), ppid (%d)", getpid(), getppid());
484                 DBG("Inside child, exec (%s) command", file_path);
485
486                 errno = 0;
487                 if (execvp(file_path, args) == -1) {
488                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
489                         ERR("Fail to execute command (%s)", error_buf);
490                         return -1;
491                 }
492         } else if (pid > 0) {
493                 ERR("Success to launch clatd");
494                 return rv;
495         }
496
497         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
498         DBG("failed to fork(%s)", error_buf);
499         return -EIO;
500 }
501
502 int __netconfig_get_interface_index(const char *interface_name)
503 {
504         struct ifreq ifr;
505         int sock = 0;
506         int result = 0;
507         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
508
509         if (interface_name == NULL) {
510                 DBG("Inteface name is NULL");
511                 return -1;
512         }
513
514         errno = 0;
515         sock = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
516         if (sock < 0) {
517                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
518                 DBG("Failed to create socket : %s", error_buf);
519                 return -1;
520         }
521
522         memset(&ifr, 0, sizeof(ifr));
523         strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name) - 1);
524         result = ioctl(sock, SIOCGIFINDEX, &ifr);
525         close(sock);
526
527         if (result < 0) {
528                 DBG("Failed to get ifr index: %s", error_buf);
529                 return -1;
530         }
531
532         return ifr.ifr_ifindex;
533 }
534
535 int netconfig_add_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gint address_family)
536 {
537         struct ifreq ifr;
538         struct rtentry rt;
539         struct sockaddr_in addr_in;
540         int sock;
541         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
542
543         memset(&ifr, 0, sizeof(ifr));
544
545         ifr.ifr_ifindex = __netconfig_get_interface_index(interface);
546
547         if (ifr.ifr_ifindex < 0)
548                 return -1;
549
550         strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);
551
552         memset(&rt, 0, sizeof(rt));
553
554         rt.rt_flags = RTF_UP | RTF_HOST;
555         memset(&addr_in, 0, sizeof(struct sockaddr_in));
556         addr_in.sin_family = address_family;
557         addr_in.sin_addr.s_addr = inet_addr(ip_addr);
558         memcpy(&rt.rt_dst, &addr_in, sizeof(rt.rt_dst));
559
560         memset(&addr_in, 0, sizeof(struct sockaddr_in));
561         addr_in.sin_family = address_family;
562         addr_in.sin_addr.s_addr = INADDR_ANY;
563         memcpy(&rt.rt_gateway, &addr_in, sizeof(rt.rt_gateway));
564
565         memset(&addr_in, 0, sizeof(struct sockaddr_in));
566         addr_in.sin_family = AF_INET;
567         addr_in.sin_addr.s_addr = inet_addr(subnet);
568         memcpy(&rt.rt_genmask, &addr_in, sizeof(rt.rt_genmask));
569
570         rt.rt_dev = ifr.ifr_name;
571
572         errno = 0;
573         sock = socket(PF_INET, SOCK_DGRAM, 0);
574
575         if (sock < 0) {
576                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
577                 DBG("Failed to create socket : %s", error_buf);
578                 return -1;
579         }
580
581         if (ioctl(sock, SIOCADDRT, &rt) < 0) {
582                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
583                 DBG("Failed to set route address : %s", error_buf);
584                 close(sock);
585                 return -1;
586         }
587
588         close(sock);
589
590         return 1;
591 }
592
593 int netconfig_del_route_ipv4(gchar *ip_addr, gchar *subnet, gchar *interface, gint address_family)
594 {
595         struct ifreq ifr;
596         struct rtentry rt;
597         struct sockaddr_in addr_in;
598         int sock;
599         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
600
601         memset(&ifr, 0, sizeof(ifr));
602         ifr.ifr_ifindex = __netconfig_get_interface_index(interface);
603
604         if (ifr.ifr_ifindex < 0)
605                 return -1;
606
607         strncpy(ifr.ifr_name, interface, IFNAMSIZ-1);
608
609         memset(&rt, 0, sizeof(rt));
610
611         rt.rt_flags = RTF_UP;
612         memset(&addr_in, 0, sizeof(struct sockaddr_in));
613         addr_in.sin_family = address_family;
614         addr_in.sin_addr.s_addr = inet_addr(ip_addr);
615         memcpy(&rt.rt_dst, &addr_in, sizeof(rt.rt_dst));
616
617         memset(&addr_in, 0, sizeof(struct sockaddr_in));
618         addr_in.sin_family = address_family;
619         addr_in.sin_addr.s_addr = inet_addr(subnet);
620         memcpy(&rt.rt_genmask, &addr_in, sizeof(rt.rt_genmask));
621         rt.rt_dev = ifr.ifr_name;
622
623         errno = 0;
624         sock = socket(PF_INET, SOCK_DGRAM, 0);
625
626         if (sock < 0) {
627                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
628                 DBG("Failed to create socket : %s", error_buf);
629                 return -1;
630         }
631
632         if (ioctl(sock, SIOCDELRT, &rt) < 0) {
633                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
634                 DBG("Failed to set route address : %s", error_buf);
635                 close(sock);
636                 return -1;
637         }
638
639         close(sock);
640
641         return 1;
642 }
643
644 int netconfig_add_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len)
645 {
646         struct in6_rtmsg rt;
647         int fd = 0;
648         int err = 0;
649         char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
650
651         memset(&rt, 0, sizeof(rt));
652
653         rt.rtmsg_dst_len = prefix_len;
654
655         rt.rtmsg_flags = RTF_UP | RTF_HOST;
656
657         errno = 0;
658         if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) {
659                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
660                 DBG("inet_pton failed : %s", error_buf);
661                 return -1;
662         }
663
664         if (gateway != NULL) {
665                 rt.rtmsg_flags |= RTF_GATEWAY;
666                 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
667                         strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
668                         DBG("inet_pton failed : %s", error_buf);
669                         return -1;
670                 }
671         }
672
673         rt.rtmsg_metric = 1;
674
675         fd = socket(AF_INET6, SOCK_DGRAM, 0);
676         if (fd < 0) {
677                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
678                 DBG("Failed to create socket : %s", error_buf);
679                 return -1;
680         }
681
682         rt.rtmsg_ifindex = 0;
683
684         if (interface) {
685                 struct ifreq ifr;
686                 memset(&ifr, 0, sizeof(ifr));
687                 strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1);
688                 ioctl(fd, SIOCGIFINDEX, &ifr);
689                 rt.rtmsg_ifindex = ifr.ifr_ifindex;
690         }
691
692         if ((err = ioctl(fd, SIOCADDRT, &rt)) < 0) {
693                 strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
694                 DBG("Failed to add route: %s", error_buf);
695                 close(fd);
696                 return -1;
697         }
698
699         close(fd);
700
701         return 1;
702 }
703
704 int netconfig_del_route_ipv6(gchar *ip_addr, gchar *interface, gchar *gateway, unsigned char prefix_len)
705 {
706         struct in6_rtmsg rt;
707         int fd = 0;
708         int err = 0;
709
710         memset(&rt, 0, sizeof(rt));
711
712         rt.rtmsg_dst_len = prefix_len;
713
714         rt.rtmsg_flags = RTF_UP | RTF_HOST;
715
716         if (inet_pton(AF_INET6, ip_addr, &rt.rtmsg_dst) < 0) {
717                 err = -errno;
718                 return err;
719         }
720
721         if (gateway != NULL) {
722                 rt.rtmsg_flags |= RTF_GATEWAY;
723                 if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
724                         err = -errno;
725                         return err;
726                 }
727         }
728
729         rt.rtmsg_metric = 1;
730
731         fd = socket(AF_INET6, SOCK_DGRAM, 0);
732         if (fd < 0)
733                 return -1;
734
735         rt.rtmsg_ifindex = 0;
736
737         if (interface) {
738                 struct ifreq ifr;
739                 memset(&ifr, 0, sizeof(ifr));
740                 strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1);
741                 ioctl(fd, SIOCGIFINDEX, &ifr);
742                 rt.rtmsg_ifindex = ifr.ifr_ifindex;
743         }
744
745         if ((err = ioctl(fd, SIOCDELRT, &rt)) < 0) {
746                 DBG("Failed to del route: %d\n", err);
747                 close(fd);
748                 return -1;
749         }
750
751         close(fd);
752
753         return 1;
754 }
755
756 gboolean handle_launch_direct(Wifi *wifi, GDBusMethodInvocation *context)
757 {
758 #if defined TIZEN_P2P_ENABLE
759         int ret = 0;
760         DBG("Launch Wi-Fi direct daemon");
761
762         const char *path = "/usr/bin/wifi-direct-server.sh";
763         char *const args[] = { "wifi-direct-server.sh", "start", NULL };
764         char *const envs[] = { NULL };
765
766         ret = netconfig_execute_file(path, args, envs);
767         if (ret < 0) {
768                 ERR("Failed to launch Wi-Fi direct daemon");
769                 netconfig_error_wifi_direct_failed(context);
770                 return FALSE;
771         }
772
773         wifi_complete_launch_direct(wifi, context);
774         return TRUE;
775 #else
776         wifi_complete_launch_direct(wifi, context);
777         return FALSE;
778 #endif
779 }
780
781 int execute_mdnsd_script(char* op)
782 {
783         const char *path = "/usr/bin/mdnsresponder-server.sh";
784         char *const args[] = { "mdnsresponder-server.sh", op, NULL };
785         char *const envs[] = { NULL };
786
787         return netconfig_execute_file(path, args, envs);
788 }
789
790 static void __dnssd_conn_destroyed_cb(GDBusConnection *conn,
791                 const gchar *Name, const gchar *path, const gchar *interface,
792                 const gchar *sig, GVariant *param, gpointer user_data)
793 {
794         gchar *name = NULL;
795         gchar *old = NULL;
796         gchar *new = NULL;
797         dnssd_conn_destroy_data *data = user_data;
798         GDBusConnection *connection = NULL;
799         connection = netdbus_get_connection();
800
801         if (param == NULL)
802                 return;
803
804         g_variant_get(param, "(sss)", &name, &old, &new);
805
806         if (g_strcmp0(name, data->conn_name) == 0 && *new == '\0') {
807                 DBG("Connection %s Destroyed: name %s id %d", data->conn_name, name,
808                         data->conn_id);
809                 mdnsd_ref_count--;
810                 g_dbus_connection_signal_unsubscribe(connection, data->conn_id);
811                 if (mdnsd_ref_count == 0) {
812                         if (execute_mdnsd_script("stop") < 0)
813                                 ERR("Failed to stop mdnsresponder daemon");
814                 }
815         }
816         g_free(name);
817         g_free(old);
818         g_free(new);
819         g_free(data->conn_name);
820         g_free(data);
821         return;
822 }
823
824 static void register_dnssd_conn_destroy_signal(gchar *name)
825 {
826         dnssd_conn_destroy_data *data;
827         GDBusConnection *connection = NULL;
828         connection = netdbus_get_connection();
829
830         if (connection == NULL) {
831                 ERR("Failed to get GDbus Connection");
832                 return;
833         }
834
835         data = g_try_malloc0(sizeof(dnssd_conn_destroy_data));
836         data->conn_name = g_strdup(name);
837
838         data->conn_id = g_dbus_connection_signal_subscribe(connection,
839                                                         DBUS_SERVICE_DBUS, DBUS_INTERFACE_DBUS,
840                                                         "NameOwnerChanged", NULL, name,
841                                                         G_DBUS_SIGNAL_FLAGS_NONE, __dnssd_conn_destroyed_cb,
842                                                         data, NULL);
843         return;
844 }
845
846 gboolean handle_launch_mdns(Network *object, GDBusMethodInvocation *context,
847                                                         gchar *name)
848 {
849         DBG("Launch mdnsresponder daemon");
850
851         if (execute_mdnsd_script("start") < 0) {
852                 ERR("Failed to launch mdnsresponder daemon");
853                 netconfig_error_invalid_parameter(context);
854                 return FALSE;
855         }
856
857         mdnsd_ref_count++;
858         register_dnssd_conn_destroy_signal(name);
859         DBG("Ref mdnsresponder daemon. ref count: %d", mdnsd_ref_count);
860
861         network_complete_launch_mdns(object, context);
862         return TRUE;
863 }
864
865 gboolean netconfig_send_notification_to_net_popup(const char * noti, const char * ssid)
866 {
867         int ret = 0;
868         bundle *b;
869         static gboolean is_found_noti_exists = FALSE;
870         static gboolean is_portal_noti_exists = FALSE;
871
872         if (noti == NULL) {
873                 ERR("Invalid notification");
874                 return FALSE;
875         }
876
877         if (g_strcmp0(noti, NETCONFIG_DEL_FOUND_AP_NOTI) == 0) {
878                 if (is_found_noti_exists == FALSE)
879                         return TRUE;
880
881                 is_found_noti_exists = FALSE;
882         } else if (g_strcmp0(noti, NETCONFIG_ADD_FOUND_AP_NOTI) == 0) {
883                 if (is_found_noti_exists == TRUE)
884                         return TRUE;
885
886                 is_found_noti_exists = TRUE;
887         } else if (g_strcmp0(noti, NETCONFIG_ADD_PORTAL_NOTI) == 0) {
888                 if (is_portal_noti_exists == TRUE)
889                         return TRUE;
890
891                 is_portal_noti_exists = TRUE;
892         } else if (g_strcmp0(noti, NETCONFIG_DEL_PORTAL_NOTI) == 0) {
893                 if (is_portal_noti_exists == FALSE)
894                         return TRUE;
895
896                 is_portal_noti_exists = FALSE;
897         }
898
899         b = bundle_create();
900         bundle_add(b, "_SYSPOPUP_TYPE_", noti);
901
902         if (ssid != NULL) {
903                 DBG("ssid (%s)", ssid);
904                 bundle_add(b, "_AP_NAME_", ssid);
905         }
906
907         ret = syspopup_launch("net-popup", b);
908
909         bundle_free(b);
910
911         if (ret < 0) {
912                 ERR("Unable to launch noti-popup. Err = %d", ret);
913                 return FALSE;
914         }
915
916         DBG("Successfully sent notification (%s)", noti);
917         return TRUE;
918 }
919
920 int netconfig_send_message_to_net_popup(const char *title,
921                 const char *content, const char *type, const char *ssid)
922 {
923         int ret = 0;
924         bundle *b = bundle_create();
925
926         bundle_add(b, "_SYSPOPUP_TITLE_", title);
927         bundle_add(b, "_SYSPOPUP_CONTENT_", content);
928         bundle_add(b, "_SYSPOPUP_TYPE_", type);
929         bundle_add(b, "_AP_NAME_", ssid);
930
931         ret = syspopup_launch("net-popup", b);
932
933         bundle_free(b);
934
935         return ret;
936 }
937
938 int netconfig_send_restriction_to_net_popup(const char *title,
939                 const char *type, const char *restriction)
940 {
941         int ret = 0;
942         bundle *b = bundle_create();
943
944         bundle_add(b, "_SYSPOPUP_TITLE_", title);
945         bundle_add(b, "_SYSPOPUP_CONTENT_", "security restriction");
946         bundle_add(b, "_SYSPOPUP_TYPE_", type);
947         bundle_add(b, "_RESTRICTED_TYPE_", restriction);
948
949         ret = syspopup_launch("net-popup", b);
950
951         bundle_free(b);
952
953         return ret;
954 }
955
956 void netconfig_set_system_event(const char * sys_evt, const char * evt_key, const char * evt_val)
957 {
958         bundle *b = NULL;
959
960         DBG("System event set [%s : %s : %s]", sys_evt, evt_key, evt_val);
961
962         b = bundle_create();
963         bundle_add_str(b, evt_key, evt_val);
964         eventsystem_send_system_event(sys_evt, b);
965         bundle_free(b);
966 }
967
968 void netconfig_set_vconf_int(const char * key, int value)
969 {
970         int ret = 0;
971
972         DBG("[%s: %d]", key, value);
973
974         ret = vconf_set_int(key, value);
975         if (ret != VCONF_OK)
976                 ERR("Failed to set");
977 }
978
979 void netconfig_set_vconf_str(const char * key, const char * value)
980 {
981         int ret = 0;
982
983         DBG("[%s: %s]", key, value);
984
985         ret = vconf_set_str(key, value);
986         if (ret != VCONF_OK)
987                 ERR("Failed to set");
988 }
989
990 int netconfig_vconf_get_int(const char * key, int *value)
991 {
992         int ret = 0;
993
994         ret = vconf_get_int(key, value);
995         if (ret != VCONF_OK) {
996                 ERR("Failed to get vconfkey [%s] value", key);
997                 return -1;
998         }
999
1000         return 0;
1001 }
1002
1003 int netconfig_vconf_get_bool(const char * key, int *value)
1004 {
1005         int ret = 0;
1006
1007         ret = vconf_get_bool(key, value);
1008         if (ret != VCONF_OK) {
1009                 ERR("Failed to get vconfkey [%s] value", key);
1010                 return -1;
1011         }
1012
1013         return 0;
1014 }
1015
1016 char* netconfig_get_env(const char *key)
1017 {
1018         FILE *fp;
1019         char buf[256], *entry = NULL, *value = NULL, *last;
1020         int len = 0;
1021
1022         if (!key)
1023                 return NULL;
1024
1025         fp = fopen(NETCONFIG_TIZEN_SYSTEM_ENV, "r");
1026         if (!fp)
1027                 return NULL;
1028
1029         while (fgets(buf, sizeof(buf), fp)) {
1030                 entry = buf;
1031                 entry = strtok_r(entry, "=", &last);
1032                 if (entry) {
1033                         if (strstr(entry, key)) {
1034                                 entry = strtok_r(NULL, "\n", &last);
1035                                 if (entry) {
1036                                         len = strlen(entry);
1037                                         value = (char*)malloc(len+1);
1038                                         g_strlcpy(value, entry, len+1);
1039                                 } else {
1040                                         value = (char*)malloc(sizeof(char));
1041                                         g_strlcpy(value, "\n", sizeof(char));
1042                                 }
1043                                 break;
1044                         }
1045                 }
1046         }
1047
1048         fclose(fp);
1049         return value;
1050 }
1051
1052 void netconfig_set_mac_address_from_file(void)
1053 {
1054         FILE *file = NULL;
1055         char mac_str[MAC_ADDRESS_MAX_LEN];
1056         gchar *mac_lower_str = NULL;
1057         int mac_len = 0;
1058
1059         file = fopen(MAC_INFO_FILEPATH, "r");
1060         if (file == NULL) {
1061                 ERR("Fail to open %s", MAC_INFO_FILEPATH);
1062                 file = fopen(MAC_ADDRESS_FILEPATH, "r");
1063                 if (file == NULL) {
1064                         ERR("Fail to open %s", MAC_ADDRESS_FILEPATH);
1065                         return;
1066                 }
1067         }
1068         if (fgets(mac_str, sizeof(mac_str), file) == NULL) {
1069                 ERR("Fail to read mac address");
1070                 fclose(file);
1071                 return;
1072         }
1073
1074         mac_len = strlen(mac_str);
1075         if (mac_len < 17) {
1076                 ERR("mac.info is empty");
1077                 fclose(file);
1078                 return;
1079         }
1080
1081         mac_lower_str = g_ascii_strup(mac_str, (gssize)mac_len);
1082         netconfig_set_vconf_str(VCONFKEY_WIFI_BSSID_ADDRESS, mac_lower_str);
1083
1084         g_free(mac_lower_str);
1085         fclose(file);
1086 }