d7332880377983266d1e020d9a1d878b384785a0
[platform/upstream/connman.git] / src / rtnl.c
1 /*
2  *
3  *  Connection Manager
4  *
5  *  Copyright (C) 2007-2013  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <errno.h>
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <sys/socket.h>
31 #include <sys/ioctl.h>
32 #include <arpa/inet.h>
33 #include <netinet/ether.h>
34 #include <netinet/icmp6.h>
35 #include <net/if_arp.h>
36 #include <linux/if.h>
37 #include <linux/netlink.h>
38 #include <linux/rtnetlink.h>
39 #include <linux/wireless.h>
40
41 #include <glib.h>
42
43 #include "connman.h"
44
45 #ifndef ARPHDR_PHONET_PIPE
46 #define ARPHDR_PHONET_PIPE (821)
47 #endif
48
49 #if defined TIZEN_EXT
50 #ifndef ARPHDR_RMNET
51 #define ARPHDR_RMNET (530)
52 #endif
53 #endif
54
55 #define print(arg...) do { if (0) connman_info(arg); } while (0)
56 //#define print(arg...) connman_info(arg)
57
58 struct watch_data {
59         unsigned int id;
60         int index;
61         connman_rtnl_link_cb_t newlink;
62         void *user_data;
63 };
64
65 static GSList *watch_list = NULL;
66 static unsigned int watch_id = 0;
67
68 static GSList *update_list = NULL;
69 static guint update_interval = G_MAXUINT;
70 static guint update_timeout = 0;
71
72 struct interface_data {
73         int index;
74         char *ident;
75         enum connman_service_type service_type;
76         enum connman_device_type device_type;
77 };
78
79 static GHashTable *interface_list = NULL;
80
81 static void free_interface(gpointer data)
82 {
83         struct interface_data *interface = data;
84
85         __connman_technology_remove_interface(interface->service_type,
86                         interface->index, interface->ident);
87
88         g_free(interface->ident);
89         g_free(interface);
90 }
91
92 static bool ether_blacklisted(const char *name)
93 {
94         if (!name)
95                 return true;
96
97         if (__connman_device_isfiltered(name))
98                 return true;
99
100         return false;
101 }
102
103 #if !defined TIZEN_EXT
104 static bool wext_interface(char *ifname)
105 {
106         struct iwreq wrq;
107         int fd, err;
108
109         fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
110         if (fd < 0)
111                 return false;
112
113         memset(&wrq, 0, sizeof(wrq));
114         strncpy(wrq.ifr_name, ifname, sizeof(wrq.ifr_name) - 1);
115
116         err = ioctl(fd, SIOCGIWNAME, &wrq);
117
118         close(fd);
119
120         if (err < 0)
121                 return false;
122
123         return true;
124 }
125 #endif
126
127 #if defined TIZEN_EXT
128 static bool __connman_rtnl_is_cellular_device(const char *name)
129 {
130         char **pattern;
131         char **cellular_interfaces;
132
133         cellular_interfaces =
134                         connman_setting_get_string_list(
135                                         "NetworkCellularInterfaceList");
136         if (!cellular_interfaces)
137                 return false;
138
139         for (pattern = cellular_interfaces; *pattern; pattern++) {
140                 if (g_str_has_prefix(name, *pattern)) {
141                         DBG("Cellular interface: %s", name);
142                         return true;
143                 }
144         }
145
146         return false;
147 }
148 #endif
149
150 static void read_uevent(struct interface_data *interface)
151 {
152         char *filename, *name, line[128];
153         bool found_devtype;
154         FILE *f;
155
156         name = connman_inet_ifname(interface->index);
157
158 #if defined TIZEN_EXT
159         if (__connman_rtnl_is_cellular_device(name)) {
160                 interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR;
161                 interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR;
162                 g_free(name);
163                 return;
164         }
165 #endif
166
167         if (ether_blacklisted(name)) {
168                 interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
169                 interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
170         } else {
171                 interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
172                 interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
173         }
174
175         filename = g_strdup_printf("/sys/class/net/%s/uevent", name);
176
177         f = fopen(filename, "re");
178
179         g_free(filename);
180
181         if (!f) {
182                 interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
183                 interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
184                 goto out;
185         }
186
187         found_devtype = false;
188         while (fgets(line, sizeof(line), f)) {
189                 char *pos;
190
191                 pos = strchr(line, '\n');
192                 if (!pos)
193                         continue;
194                 pos[0] = '\0';
195
196                 if (strncmp(line, "DEVTYPE=", 8) != 0)
197                         continue;
198
199                 found_devtype = true;
200
201                 if (strcmp(line + 8, "wlan") == 0) {
202                         interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
203                         interface->device_type = CONNMAN_DEVICE_TYPE_WIFI;
204                 } else if (strcmp(line + 8, "wwan") == 0) {
205                         interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR;
206                         interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR;
207                 } else if (strcmp(line + 8, "bluetooth") == 0) {
208                         interface->service_type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
209                         interface->device_type = CONNMAN_DEVICE_TYPE_BLUETOOTH;
210                 } else if (strcmp(line + 8, "gadget") == 0) {
211                         interface->service_type = CONNMAN_SERVICE_TYPE_GADGET;
212                         interface->device_type = CONNMAN_DEVICE_TYPE_GADGET;
213                 } else if (strcmp(line + 8, "vlan") == 0) {
214                         interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
215                         interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
216                 } else if (strcmp(line + 8, "bond") == 0) {
217                         interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
218                         interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
219                 } else {
220                         interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
221                         interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
222                 }
223         }
224
225         fclose(f);
226
227         if (found_devtype)
228                 goto out;
229
230 #if !defined TIZEN_EXT
231         /* TIZEN does not use old wext interface */
232         /* We haven't got a DEVTYPE, let's check if it's a wireless device */
233         if (wext_interface(name)) {
234                 interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
235                 interface->device_type = CONNMAN_DEVICE_TYPE_WIFI;
236
237                 connman_error("%s runs an unsupported 802.11 driver", name);
238         }
239 #endif
240
241 out:
242         g_free(name);
243 }
244
245 enum connman_device_type __connman_rtnl_get_device_type(int index)
246 {
247         struct interface_data *interface;
248
249         interface = g_hash_table_lookup(interface_list,
250                                         GINT_TO_POINTER(index));
251         if (!interface)
252                 return CONNMAN_DEVICE_TYPE_UNKNOWN;
253
254         return interface->device_type;
255 }
256
257 /**
258  * connman_rtnl_add_newlink_watch:
259  * @index: network device index
260  * @callback: callback function
261  * @user_data: callback data;
262  *
263  * Add a new RTNL watch for newlink events
264  *
265  * Returns: %0 on failure and a unique id on success
266  */
267 unsigned int connman_rtnl_add_newlink_watch(int index,
268                         connman_rtnl_link_cb_t callback, void *user_data)
269 {
270         struct watch_data *watch;
271
272         watch = g_try_new0(struct watch_data, 1);
273         if (!watch)
274                 return 0;
275
276         watch->id = ++watch_id;
277         watch->index = index;
278
279         watch->newlink = callback;
280         watch->user_data = user_data;
281
282         watch_list = g_slist_prepend(watch_list, watch);
283
284         DBG("id %d", watch->id);
285
286         if (callback) {
287                 unsigned int flags = __connman_ipconfig_get_flags_from_index(index);
288
289                 if (flags > 0)
290                         callback(flags, 0, user_data);
291         }
292
293         return watch->id;
294 }
295
296 /**
297  * connman_rtnl_remove_watch:
298  * @id: watch identifier
299  *
300  * Remove the RTNL watch for the identifier
301  */
302 void connman_rtnl_remove_watch(unsigned int id)
303 {
304         GSList *list;
305
306         DBG("id %d", id);
307
308         if (id == 0)
309                 return;
310
311         for (list = watch_list; list; list = list->next) {
312                 struct watch_data *watch = list->data;
313
314                 if (watch->id  == id) {
315                         watch_list = g_slist_remove(watch_list, watch);
316                         g_free(watch);
317                         break;
318                 }
319         }
320 }
321
322 static void trigger_rtnl(int index, void *user_data)
323 {
324         struct connman_rtnl *rtnl = user_data;
325
326         if (rtnl->newlink) {
327                 unsigned short type = __connman_ipconfig_get_type_from_index(index);
328                 unsigned int flags = __connman_ipconfig_get_flags_from_index(index);
329
330                 rtnl->newlink(type, index, flags, 0);
331         }
332
333         if (rtnl->newgateway) {
334                 const char *gateway =
335                         __connman_ipconfig_get_gateway_from_index(index,
336                                         CONNMAN_IPCONFIG_TYPE_ALL);
337
338                 if (gateway)
339                         rtnl->newgateway(index, gateway);
340         }
341 }
342
343 static GSList *rtnl_list = NULL;
344
345 static gint compare_priority(gconstpointer a, gconstpointer b)
346 {
347         const struct connman_rtnl *rtnl1 = a;
348         const struct connman_rtnl *rtnl2 = b;
349
350         return rtnl2->priority - rtnl1->priority;
351 }
352
353 /**
354  * connman_rtnl_register:
355  * @rtnl: RTNL module
356  *
357  * Register a new RTNL module
358  *
359  * Returns: %0 on success
360  */
361 int connman_rtnl_register(struct connman_rtnl *rtnl)
362 {
363         DBG("rtnl %p name %s", rtnl, rtnl->name);
364
365         rtnl_list = g_slist_insert_sorted(rtnl_list, rtnl,
366                                                         compare_priority);
367
368         __connman_ipconfig_foreach(trigger_rtnl, rtnl);
369
370         return 0;
371 }
372
373 /**
374  * connman_rtnl_unregister:
375  * @rtnl: RTNL module
376  *
377  * Remove a previously registered RTNL module
378  */
379 void connman_rtnl_unregister(struct connman_rtnl *rtnl)
380 {
381         DBG("rtnl %p name %s", rtnl, rtnl->name);
382
383         rtnl_list = g_slist_remove(rtnl_list, rtnl);
384 }
385
386 static const char *operstate2str(unsigned char operstate)
387 {
388         switch (operstate) {
389         case IF_OPER_UNKNOWN:
390                 return "UNKNOWN";
391         case IF_OPER_NOTPRESENT:
392                 return "NOT-PRESENT";
393         case IF_OPER_DOWN:
394                 return "DOWN";
395         case IF_OPER_LOWERLAYERDOWN:
396                 return "LOWER-LAYER-DOWN";
397         case IF_OPER_TESTING:
398                 return "TESTING";
399         case IF_OPER_DORMANT:
400                 return "DORMANT";
401         case IF_OPER_UP:
402                 return "UP";
403         }
404
405         return "";
406 }
407
408 static bool extract_link(struct ifinfomsg *msg, int bytes,
409                                 struct ether_addr *address, const char **ifname,
410                                 unsigned int *mtu, unsigned char *operstate,
411                                 struct rtnl_link_stats *stats)
412 {
413         struct rtattr *attr;
414
415         for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
416                                         attr = RTA_NEXT(attr, bytes)) {
417                 switch (attr->rta_type) {
418                 case IFLA_ADDRESS:
419                         if (address)
420                                 memcpy(address, RTA_DATA(attr), ETH_ALEN);
421                         break;
422                 case IFLA_IFNAME:
423                         if (ifname)
424                                 *ifname = RTA_DATA(attr);
425                         break;
426                 case IFLA_MTU:
427                         if (mtu)
428                                 *mtu = *((unsigned int *) RTA_DATA(attr));
429                         break;
430                 case IFLA_STATS:
431                         if (stats)
432                                 memcpy(stats, RTA_DATA(attr),
433                                         sizeof(struct rtnl_link_stats));
434                         break;
435                 case IFLA_OPERSTATE:
436                         if (operstate)
437                                 *operstate = *((unsigned char *) RTA_DATA(attr));
438                         break;
439                 case IFLA_LINKMODE:
440                         break;
441                 case IFLA_WIRELESS:
442                         return false;
443                 }
444         }
445
446         return true;
447 }
448
449 static void process_newlink(unsigned short type, int index, unsigned flags,
450                         unsigned change, struct ifinfomsg *msg, int bytes)
451 {
452         struct ether_addr address = {{ 0, 0, 0, 0, 0, 0 }};
453         struct rtnl_link_stats stats;
454         unsigned char operstate = 0xff;
455         struct interface_data *interface;
456         const char *ifname = NULL;
457         unsigned int mtu = 0;
458         char ident[13], str[18];
459         GSList *list;
460
461         memset(&stats, 0, sizeof(stats));
462         if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats))
463                 return;
464
465 #if defined TIZEN_EXT_WIFI_MESH
466         /* Do not accept Wi-Fi Mesh interface */
467         if (g_strrstr(ifname, "mesh") != NULL) {
468                 DBG("Newlink event for Wi-Fi Mesh interface ignored");
469                 return;
470         }
471
472         /* Do not accept Wi-Fi WLAN1 interface "dedicated for softAP */
473         if (!g_strcmp0(ifname, "wlan1")) {
474                 DBG("Newlink event for Wi-Fi WLAN1 interface ignored");
475                 return;
476         }
477 #endif
478
479 #if defined TIZEN_EXT
480         /* Do not accept Wi-Fi P2P interface */
481         if (g_strrstr(ifname, "p2p") != NULL) {
482                 DBG("Newlink event for Wi-Fi P2P interface ignored");
483                 return;
484         }
485 #endif
486
487         snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
488                                                 address.ether_addr_octet[0],
489                                                 address.ether_addr_octet[1],
490                                                 address.ether_addr_octet[2],
491                                                 address.ether_addr_octet[3],
492                                                 address.ether_addr_octet[4],
493                                                 address.ether_addr_octet[5]);
494
495         snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
496                                                 address.ether_addr_octet[0],
497                                                 address.ether_addr_octet[1],
498                                                 address.ether_addr_octet[2],
499                                                 address.ether_addr_octet[3],
500                                                 address.ether_addr_octet[4],
501                                                 address.ether_addr_octet[5]);
502
503         if (flags & IFF_SLAVE) {
504                 connman_info("%s {newlink} ignoring slave, index %d address %s",
505                                                 ifname, index, str);
506                 return;
507         }
508
509 #ifdef TIZEN_EXT
510         if (TIZEN_TV_EXT && g_strcmp0(ident, "eeeeeeeeeeee") == 0) {
511                 DBG("Newlink event with Dummy MAC. Ignored!");
512                 return;
513         }
514 #endif
515
516         switch (type) {
517         case ARPHRD_ETHER:
518         case ARPHRD_LOOPBACK:
519         case ARPHDR_PHONET_PIPE:
520         case ARPHRD_PPP:
521         case ARPHRD_NONE:
522 #if defined TIZEN_EXT
523 /*
524  * Description: ARPHDR_RMNET for QC modem using QMI
525  */
526         case ARPHDR_RMNET:
527 #endif
528                 __connman_ipconfig_newlink(index, type, flags,
529                                                         str, mtu, &stats);
530                 break;
531         }
532
533         connman_info("%s {newlink} index %d address %s mtu %u",
534                                         ifname, index, str, mtu);
535
536         if (operstate != 0xff)
537                 connman_info("%s {newlink} index %d operstate %u <%s>",
538                                                 ifname, index, operstate,
539                                                 operstate2str(operstate));
540
541         interface = g_hash_table_lookup(interface_list, GINT_TO_POINTER(index));
542         if (!interface) {
543                 interface = g_new0(struct interface_data, 1);
544                 interface->index = index;
545                 interface->ident = g_strdup(ident);
546
547                 g_hash_table_insert(interface_list,
548                                         GINT_TO_POINTER(index), interface);
549
550                 if (type == ARPHRD_ETHER)
551                         read_uevent(interface);
552 #if defined TIZEN_EXT
553                 if (type == ARPHRD_PPP || type == ARPHDR_RMNET)
554                         read_uevent(interface);
555
556         } else if (g_strcmp0(interface->ident, ident) != 0) {
557                 /* If an original address is built-in physical device,
558                  * it's hardly get an address at a initial creation
559                  */
560                 __connman_technology_remove_interface(interface->service_type,
561                                 interface->index, interface->ident);
562
563                 g_free(interface->ident);
564                 interface->ident = g_strdup(ident);
565
566                 __connman_technology_add_interface(interface->service_type,
567                                 interface->index, interface->ident);
568
569                 interface = NULL;
570 #endif
571         } else if (type == ARPHRD_ETHER && interface->device_type == CONNMAN_DEVICE_TYPE_UNKNOWN)
572                 read_uevent(interface);
573         else
574                 interface = NULL;
575
576         for (list = rtnl_list; list; list = list->next) {
577                 struct connman_rtnl *rtnl = list->data;
578
579                 if (rtnl->newlink)
580                         rtnl->newlink(type, index, flags, change);
581         }
582
583         /*
584          * The interface needs to be added after the newlink call.
585          * The newlink will create the technology when needed and
586          * __connman_technology_add_interface() expects the
587          * technology to be there already.
588          */
589         if (interface)
590                 __connman_technology_add_interface(interface->service_type,
591                         interface->index, interface->ident);
592
593         for (list = watch_list; list; list = list->next) {
594                 struct watch_data *watch = list->data;
595
596                 if (watch->index != index)
597                         continue;
598
599                 if (watch->newlink)
600                         watch->newlink(flags, change, watch->user_data);
601         }
602 }
603
604 static void process_dellink(unsigned short type, int index, unsigned flags,
605                         unsigned change, struct ifinfomsg *msg, int bytes)
606 {
607         struct rtnl_link_stats stats;
608         unsigned char operstate = 0xff;
609         const char *ifname = NULL;
610         GSList *list;
611
612         memset(&stats, 0, sizeof(stats));
613         if (!extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, &stats))
614                 return;
615
616         if (operstate != 0xff)
617                 connman_info("%s {dellink} index %d operstate %u <%s>",
618                                                 ifname, index, operstate,
619                                                 operstate2str(operstate));
620
621         for (list = rtnl_list; list; list = list->next) {
622                 struct connman_rtnl *rtnl = list->data;
623
624                 if (rtnl->dellink)
625                         rtnl->dellink(type, index, flags, change);
626         }
627
628         switch (type) {
629         case ARPHRD_ETHER:
630         case ARPHRD_LOOPBACK:
631         case ARPHDR_PHONET_PIPE:
632         case ARPHRD_PPP:
633         case ARPHRD_NONE:
634 #if defined TIZEN_EXT
635         /*
636          * Description: SLP requires ARPHRD_PPP for PPP type device
637          *              ARPHDR_RMNET for QC modem using QMI
638          */
639         case ARPHDR_RMNET:
640 #endif
641                 __connman_ipconfig_dellink(index, &stats);
642                 break;
643         }
644
645         g_hash_table_remove(interface_list, GINT_TO_POINTER(index));
646 }
647
648 static void extract_ipv4_addr(struct ifaddrmsg *msg, int bytes,
649                                                 const char **label,
650                                                 struct in_addr *local,
651                                                 struct in_addr *address,
652                                                 struct in_addr *broadcast)
653 {
654         struct rtattr *attr;
655
656         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
657                                         attr = RTA_NEXT(attr, bytes)) {
658                 switch (attr->rta_type) {
659                 case IFA_ADDRESS:
660                         if (address)
661                                 *address = *((struct in_addr *) RTA_DATA(attr));
662                         break;
663                 case IFA_LOCAL:
664                         if (local)
665                                 *local = *((struct in_addr *) RTA_DATA(attr));
666                         break;
667                 case IFA_BROADCAST:
668                         if (broadcast)
669                                 *broadcast = *((struct in_addr *) RTA_DATA(attr));
670                         break;
671                 case IFA_LABEL:
672                         if (label)
673                                 *label = RTA_DATA(attr);
674                         break;
675                 }
676         }
677 }
678
679 static void extract_ipv6_addr(struct ifaddrmsg *msg, int bytes,
680                                                 struct in6_addr *addr,
681                                                 struct in6_addr *local)
682 {
683         struct rtattr *attr;
684
685         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
686                                         attr = RTA_NEXT(attr, bytes)) {
687                 switch (attr->rta_type) {
688                 case IFA_ADDRESS:
689                         if (addr)
690                                 *addr = *((struct in6_addr *) RTA_DATA(attr));
691                         break;
692                 case IFA_LOCAL:
693                         if (local)
694                                 *local = *((struct in6_addr *) RTA_DATA(attr));
695                         break;
696                 }
697         }
698 }
699
700 static void process_newaddr(unsigned char family, unsigned char prefixlen,
701                                 int index, struct ifaddrmsg *msg, int bytes)
702 {
703         struct in_addr ipv4_addr = { INADDR_ANY };
704         struct in6_addr ipv6_address, ipv6_local;
705         const char *label = NULL;
706         void *src;
707         char ip_string[INET6_ADDRSTRLEN];
708
709         if (family == AF_INET) {
710
711                 extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
712                 src = &ipv4_addr;
713         } else if (family == AF_INET6) {
714                 extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
715                 if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
716                         return;
717
718                 src = &ipv6_address;
719         } else {
720                 return;
721         }
722
723         if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN))
724                 return;
725
726         if (__connman_ipconfig_newaddr(index, family, label,
727                                         prefixlen, ip_string) >= 0) {
728                 if (family == AF_INET6) {
729                         /*
730                          * Re-create RDNSS configured servers if there
731                          * are any for this interface. This is done
732                          * because we might have now properly
733                          * configured interface with proper
734                          * autoconfigured address.
735                          */
736                         __connman_resolver_redo_servers(index);
737                 }
738         }
739 }
740
741 static void process_deladdr(unsigned char family, unsigned char prefixlen,
742                                 int index, struct ifaddrmsg *msg, int bytes)
743 {
744         struct in_addr ipv4_addr = { INADDR_ANY };
745         struct in6_addr ipv6_address, ipv6_local;
746         const char *label = NULL;
747         void *src;
748         char ip_string[INET6_ADDRSTRLEN];
749
750         if (family == AF_INET) {
751                 extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
752                 src = &ipv4_addr;
753         } else if (family == AF_INET6) {
754                 extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
755                 if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
756                         return;
757
758                 src = &ipv6_address;
759         } else {
760                 return;
761         }
762
763         if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN))
764                 return;
765
766         __connman_ipconfig_deladdr(index, family, label,
767                                         prefixlen, ip_string);
768 }
769
770 static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index,
771                                                 struct in_addr *dst,
772                                                 struct in_addr *gateway)
773 {
774         struct rtattr *attr;
775
776         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
777                                         attr = RTA_NEXT(attr, bytes)) {
778                 switch (attr->rta_type) {
779                 case RTA_DST:
780                         if (dst)
781                                 *dst = *((struct in_addr *) RTA_DATA(attr));
782                         break;
783                 case RTA_GATEWAY:
784                         if (gateway)
785                                 *gateway = *((struct in_addr *) RTA_DATA(attr));
786                         break;
787                 case RTA_OIF:
788                         if (index)
789                                 *index = *((int *) RTA_DATA(attr));
790                         break;
791                 }
792         }
793 }
794
795 static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index,
796                                                 struct in6_addr *dst,
797                                                 struct in6_addr *gateway)
798 {
799         struct rtattr *attr;
800
801         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
802                                         attr = RTA_NEXT(attr, bytes)) {
803                 switch (attr->rta_type) {
804                 case RTA_DST:
805                         if (dst)
806                                 *dst = *((struct in6_addr *) RTA_DATA(attr));
807                         break;
808                 case RTA_GATEWAY:
809                         if (gateway)
810                                 *gateway =
811                                         *((struct in6_addr *) RTA_DATA(attr));
812                         break;
813                 case RTA_OIF:
814                         if (index)
815                                 *index = *((int *) RTA_DATA(attr));
816                         break;
817                 }
818         }
819 }
820
821 static void process_newroute(unsigned char family, unsigned char scope,
822                                                 struct rtmsg *msg, int bytes)
823 {
824         GSList *list;
825         char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
826         int index = -1;
827
828         if (family == AF_INET) {
829                 struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
830
831                 extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
832
833                 inet_ntop(family, &dst, dststr, sizeof(dststr));
834                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
835
836                 __connman_ipconfig_newroute(index, family, scope, dststr,
837                                                                 gatewaystr);
838
839                 /* skip host specific routes */
840                 if (scope != RT_SCOPE_UNIVERSE &&
841                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
842                         return;
843
844                 if (dst.s_addr != INADDR_ANY)
845                         return;
846
847         } else if (family == AF_INET6) {
848                 struct in6_addr dst = IN6ADDR_ANY_INIT,
849                                 gateway = IN6ADDR_ANY_INIT;
850
851                 extract_ipv6_route(msg, bytes, &index, &dst, &gateway);
852
853                 inet_ntop(family, &dst, dststr, sizeof(dststr));
854                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
855
856                 __connman_ipconfig_newroute(index, family, scope, dststr,
857                                                                 gatewaystr);
858
859                 /* skip host specific routes */
860                 if (scope != RT_SCOPE_UNIVERSE &&
861                         !(scope == RT_SCOPE_LINK &&
862                                 IN6_IS_ADDR_UNSPECIFIED(&dst)))
863                         return;
864
865                 if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
866                         return;
867         } else
868                 return;
869
870         for (list = rtnl_list; list; list = list->next) {
871                 struct connman_rtnl *rtnl = list->data;
872
873                 if (rtnl->newgateway)
874                         rtnl->newgateway(index, gatewaystr);
875         }
876 }
877
878 static void process_delroute(unsigned char family, unsigned char scope,
879                                                 struct rtmsg *msg, int bytes)
880 {
881         GSList *list;
882         char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
883         int index = -1;
884
885         if (family == AF_INET) {
886                 struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
887
888                 extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
889
890                 inet_ntop(family, &dst, dststr, sizeof(dststr));
891                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
892
893                 __connman_ipconfig_delroute(index, family, scope, dststr,
894                                                                 gatewaystr);
895
896                 /* skip host specific routes */
897                 if (scope != RT_SCOPE_UNIVERSE &&
898                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
899                         return;
900
901                 if (dst.s_addr != INADDR_ANY)
902                         return;
903
904         }  else if (family == AF_INET6) {
905                 struct in6_addr dst = IN6ADDR_ANY_INIT,
906                                 gateway = IN6ADDR_ANY_INIT;
907
908                 extract_ipv6_route(msg, bytes, &index, &dst, &gateway);
909
910                 inet_ntop(family, &dst, dststr, sizeof(dststr));
911                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
912
913                 __connman_ipconfig_delroute(index, family, scope, dststr,
914                                                 gatewaystr);
915
916                 /* skip host specific routes */
917                 if (scope != RT_SCOPE_UNIVERSE &&
918                         !(scope == RT_SCOPE_LINK &&
919                                 IN6_IS_ADDR_UNSPECIFIED(&dst)))
920                         return;
921
922                 if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
923                         return;
924         } else
925                 return;
926
927         for (list = rtnl_list; list; list = list->next) {
928                 struct connman_rtnl *rtnl = list->data;
929
930                 if (rtnl->delgateway)
931                         rtnl->delgateway(index, gatewaystr);
932         }
933 }
934
935 static inline void print_ether(struct rtattr *attr, const char *name)
936 {
937         int len = (int) RTA_PAYLOAD(attr);
938
939         if (len == ETH_ALEN) {
940                 struct ether_addr eth;
941                 memcpy(&eth, RTA_DATA(attr), ETH_ALEN);
942                 print("  attr %s (len %d) %s\n", name, len, ether_ntoa(&eth));
943         } else
944                 print("  attr %s (len %d)\n", name, len);
945 }
946
947 static inline void print_inet(struct rtattr *attr, const char *name,
948                                                         unsigned char family)
949 {
950         int len = (int) RTA_PAYLOAD(attr);
951
952         if (family == AF_INET && len == sizeof(struct in_addr)) {
953                 struct in_addr addr;
954                 addr = *((struct in_addr *) RTA_DATA(attr));
955                 print("  attr %s (len %d) %s\n", name, len, inet_ntoa(addr));
956         } else
957                 print("  attr %s (len %d)\n", name, len);
958 }
959
960 static inline void print_string(struct rtattr *attr, const char *name)
961 {
962         print("  attr %s (len %d) %s\n", name, (int) RTA_PAYLOAD(attr),
963                                                 (char *) RTA_DATA(attr));
964 }
965
966 static inline void print_byte(struct rtattr *attr, const char *name)
967 {
968         print("  attr %s (len %d) 0x%02x\n", name, (int) RTA_PAYLOAD(attr),
969                                         *((unsigned char *) RTA_DATA(attr)));
970 }
971
972 static inline void print_integer(struct rtattr *attr, const char *name)
973 {
974         print("  attr %s (len %d) %d\n", name, (int) RTA_PAYLOAD(attr),
975                                                 *((int *) RTA_DATA(attr)));
976 }
977
978 static inline void print_attr(struct rtattr *attr, const char *name)
979 {
980         int len = (int) RTA_PAYLOAD(attr);
981
982         if (name && len > 0)
983                 print("  attr %s (len %d)\n", name, len);
984         else
985                 print("  attr %d (len %d)\n", attr->rta_type, len);
986 }
987
988 static void rtnl_link(struct nlmsghdr *hdr)
989 {
990         struct ifinfomsg *msg;
991         struct rtattr *attr;
992         int bytes;
993
994         msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
995         bytes = IFLA_PAYLOAD(hdr);
996
997         print("ifi_index %d ifi_flags 0x%04x", msg->ifi_index, msg->ifi_flags);
998
999         for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
1000                                         attr = RTA_NEXT(attr, bytes)) {
1001                 switch (attr->rta_type) {
1002                 case IFLA_ADDRESS:
1003                         print_ether(attr, "address");
1004                         break;
1005                 case IFLA_BROADCAST:
1006                         print_ether(attr, "broadcast");
1007                         break;
1008                 case IFLA_IFNAME:
1009                         print_string(attr, "ifname");
1010                         break;
1011                 case IFLA_MTU:
1012                         print_integer(attr, "mtu");
1013                         break;
1014                 case IFLA_LINK:
1015                         print_attr(attr, "link");
1016                         break;
1017                 case IFLA_QDISC:
1018                         print_attr(attr, "qdisc");
1019                         break;
1020                 case IFLA_STATS:
1021                         print_attr(attr, "stats");
1022                         break;
1023                 case IFLA_COST:
1024                         print_attr(attr, "cost");
1025                         break;
1026                 case IFLA_PRIORITY:
1027                         print_attr(attr, "priority");
1028                         break;
1029                 case IFLA_MASTER:
1030                         print_attr(attr, "master");
1031                         break;
1032                 case IFLA_WIRELESS:
1033                         print_attr(attr, "wireless");
1034                         break;
1035                 case IFLA_PROTINFO:
1036                         print_attr(attr, "protinfo");
1037                         break;
1038                 case IFLA_TXQLEN:
1039                         print_integer(attr, "txqlen");
1040                         break;
1041                 case IFLA_MAP:
1042                         print_attr(attr, "map");
1043                         break;
1044                 case IFLA_WEIGHT:
1045                         print_attr(attr, "weight");
1046                         break;
1047                 case IFLA_OPERSTATE:
1048                         print_byte(attr, "operstate");
1049                         break;
1050                 case IFLA_LINKMODE:
1051                         print_byte(attr, "linkmode");
1052                         break;
1053                 default:
1054                         print_attr(attr, NULL);
1055                         break;
1056                 }
1057         }
1058 }
1059
1060 static void rtnl_newlink(struct nlmsghdr *hdr)
1061 {
1062         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
1063
1064         rtnl_link(hdr);
1065
1066         if (hdr->nlmsg_type == IFLA_WIRELESS)
1067                 connman_warn_once("Obsolete WEXT WiFi driver detected");
1068
1069         process_newlink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
1070                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
1071 }
1072
1073 static void rtnl_dellink(struct nlmsghdr *hdr)
1074 {
1075         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
1076
1077         rtnl_link(hdr);
1078
1079         process_dellink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
1080                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
1081 }
1082
1083 static void rtnl_addr(struct nlmsghdr *hdr)
1084 {
1085         struct ifaddrmsg *msg;
1086         struct rtattr *attr;
1087         int bytes;
1088
1089         msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
1090         bytes = IFA_PAYLOAD(hdr);
1091
1092         print("ifa_family %d ifa_index %d", msg->ifa_family, msg->ifa_index);
1093
1094         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
1095                                         attr = RTA_NEXT(attr, bytes)) {
1096                 switch (attr->rta_type) {
1097                 case IFA_ADDRESS:
1098                         print_inet(attr, "address", msg->ifa_family);
1099                         break;
1100                 case IFA_LOCAL:
1101                         print_inet(attr, "local", msg->ifa_family);
1102                         break;
1103                 case IFA_LABEL:
1104                         print_string(attr, "label");
1105                         break;
1106                 case IFA_BROADCAST:
1107                         print_inet(attr, "broadcast", msg->ifa_family);
1108                         break;
1109                 case IFA_ANYCAST:
1110                         print_attr(attr, "anycast");
1111                         break;
1112                 case IFA_CACHEINFO:
1113                         print_attr(attr, "cacheinfo");
1114                         break;
1115                 case IFA_MULTICAST:
1116                         print_attr(attr, "multicast");
1117                         break;
1118                 default:
1119                         print_attr(attr, NULL);
1120                         break;
1121                 }
1122         }
1123 }
1124
1125 static void rtnl_newaddr(struct nlmsghdr *hdr)
1126 {
1127         struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
1128
1129         rtnl_addr(hdr);
1130
1131         process_newaddr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
1132                                                 msg, IFA_PAYLOAD(hdr));
1133 }
1134
1135 static void rtnl_deladdr(struct nlmsghdr *hdr)
1136 {
1137         struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
1138
1139         rtnl_addr(hdr);
1140
1141         process_deladdr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
1142                                                 msg, IFA_PAYLOAD(hdr));
1143 }
1144
1145 static void rtnl_route(struct nlmsghdr *hdr)
1146 {
1147         struct rtmsg *msg;
1148         struct rtattr *attr;
1149         int bytes;
1150
1151         msg = (struct rtmsg *) NLMSG_DATA(hdr);
1152         bytes = RTM_PAYLOAD(hdr);
1153
1154         print("rtm_family %d rtm_table %d rtm_protocol %d",
1155                         msg->rtm_family, msg->rtm_table, msg->rtm_protocol);
1156         print("rtm_scope %d rtm_type %d rtm_flags 0x%04x",
1157                                 msg->rtm_scope, msg->rtm_type, msg->rtm_flags);
1158
1159         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
1160                                         attr = RTA_NEXT(attr, bytes)) {
1161                 switch (attr->rta_type) {
1162                 case RTA_DST:
1163                         print_inet(attr, "dst", msg->rtm_family);
1164                         break;
1165                 case RTA_SRC:
1166                         print_inet(attr, "src", msg->rtm_family);
1167                         break;
1168                 case RTA_IIF:
1169                         print_string(attr, "iif");
1170                         break;
1171                 case RTA_OIF:
1172                         print_integer(attr, "oif");
1173                         break;
1174                 case RTA_GATEWAY:
1175                         print_inet(attr, "gateway", msg->rtm_family);
1176                         break;
1177                 case RTA_PRIORITY:
1178                         print_attr(attr, "priority");
1179                         break;
1180                 case RTA_PREFSRC:
1181                         print_inet(attr, "prefsrc", msg->rtm_family);
1182                         break;
1183                 case RTA_METRICS:
1184                         print_attr(attr, "metrics");
1185                         break;
1186                 case RTA_TABLE:
1187                         print_integer(attr, "table");
1188                         break;
1189                 default:
1190                         print_attr(attr, NULL);
1191                         break;
1192                 }
1193         }
1194 }
1195
1196 static bool is_route_rtmsg(struct rtmsg *msg)
1197 {
1198         if (msg->rtm_flags & RTM_F_CLONED)
1199                 return false;
1200
1201         if (msg->rtm_table != RT_TABLE_MAIN)
1202                 return false;
1203
1204         if (msg->rtm_protocol != RTPROT_BOOT &&
1205                         msg->rtm_protocol != RTPROT_KERNEL)
1206                 return false;
1207
1208         if (msg->rtm_type != RTN_UNICAST)
1209                 return false;
1210
1211         return true;
1212 }
1213
1214 static void rtnl_newroute(struct nlmsghdr *hdr)
1215 {
1216         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
1217
1218         rtnl_route(hdr);
1219
1220         if (is_route_rtmsg(msg))
1221                 process_newroute(msg->rtm_family, msg->rtm_scope,
1222                                                 msg, RTM_PAYLOAD(hdr));
1223 }
1224
1225 static void rtnl_delroute(struct nlmsghdr *hdr)
1226 {
1227         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
1228
1229         rtnl_route(hdr);
1230
1231         if (is_route_rtmsg(msg))
1232                 process_delroute(msg->rtm_family, msg->rtm_scope,
1233                                                 msg, RTM_PAYLOAD(hdr));
1234 }
1235
1236 static void *rtnl_nd_opt_rdnss(struct nd_opt_hdr *opt, guint32 *lifetime,
1237                                int *nr_servers)
1238 {
1239         guint32 *optint = (void *)opt;
1240
1241         if (opt->nd_opt_len < 3)
1242                 return NULL;
1243
1244         if (*lifetime > ntohl(optint[1]))
1245                 *lifetime = ntohl(optint[1]);
1246
1247         /* nd_opt_len is in units of 8 bytes. The header is 1 unit (8 bytes)
1248            and each address is another 2 units (16 bytes).
1249            So the number of addresses (given rounding) is nd_opt_len/2 */
1250         *nr_servers = opt->nd_opt_len / 2;
1251
1252         /* And they start 8 bytes into the packet, or two guint32s in. */
1253         return optint + 2;
1254 }
1255
1256 static const char **rtnl_nd_opt_dnssl(struct nd_opt_hdr *opt, guint32 *lifetime)
1257 {
1258         const char **domains = NULL;
1259         guint32 *optint = (void *)opt;
1260         unsigned char *optc = (void *)&optint[2];
1261         int data_len = (opt->nd_opt_len * 8) - 8;
1262         int nr_domains = 0;
1263         int i, tmp;
1264
1265         if (*lifetime > ntohl(optint[1]))
1266                 *lifetime = ntohl(optint[1]);
1267
1268         /* Turn it into normal strings by converting the length bytes into '.',
1269            and count how many search domains there are while we're at it. */
1270         i = 0;
1271         while (i < data_len) {
1272                 if (optc[i] > 0x3f) {
1273                         DBG("DNSSL contains compressed elements in violation of RFC6106");
1274                         return NULL;
1275                 }
1276
1277                 if (optc[i] == 0) {
1278                         nr_domains++;
1279                         i++;
1280                         /* Check for double zero */
1281                         if (i < data_len && optc[i] == 0)
1282                                 break;
1283                         continue;
1284                 }
1285
1286                 tmp = i;
1287                 i += optc[i] + 1;
1288
1289                 if (i >= data_len) {
1290                         DBG("DNSSL data overflows option length");
1291                         return NULL;
1292                 }
1293
1294                 optc[tmp] = '.';
1295         }
1296
1297         domains = g_try_new0(const char *, nr_domains + 1);
1298         if (!domains)
1299                 return NULL;
1300
1301         /* Now point to the normal strings, missing out the leading '.' that
1302            each of them will have now. */
1303         for (i = 0; i < nr_domains; i++) {
1304                 domains[i] = (char *)optc + 1;
1305                 optc += strlen((char *)optc) + 1;
1306         }
1307
1308         return domains;
1309 }
1310
1311 static void rtnl_newnduseropt(struct nlmsghdr *hdr)
1312 {
1313         struct nduseroptmsg *msg = (struct nduseroptmsg *) NLMSG_DATA(hdr);
1314         struct nd_opt_hdr *opt;
1315         guint32 lifetime = -1;
1316         const char **domains = NULL;
1317         struct in6_addr *servers = NULL;
1318         int i, nr_servers = 0;
1319         int msglen = msg->nduseropt_opts_len;
1320         int index;
1321
1322         DBG("family %d index %d len %d type %d code %d",
1323                 msg->nduseropt_family, msg->nduseropt_ifindex,
1324                 msg->nduseropt_opts_len, msg->nduseropt_icmp_type,
1325                 msg->nduseropt_icmp_code);
1326
1327         if (msg->nduseropt_family != AF_INET6 ||
1328                         msg->nduseropt_icmp_type != ND_ROUTER_ADVERT ||
1329                         msg->nduseropt_icmp_code != 0)
1330                 return;
1331
1332         index = msg->nduseropt_ifindex;
1333         if (index < 0)
1334                 return;
1335
1336 #if defined TIZEN_EXT
1337         struct connman_service *service;
1338         enum connman_service_state state;
1339         enum connman_dnsconfig_method ipv6_dns_method;
1340
1341         service = __connman_service_lookup_from_index(index);
1342         if (!service) {
1343                 DBG("Invalid service");
1344                 return;
1345         }
1346
1347         DBG("service: %p index: %d\n", service, index);
1348
1349         if (connman_setting_get_bool("SingleConnectedTechnology") == TRUE) {
1350                 state = __connman_service_ipconfig_get_state(service, CONNMAN_IPCONFIG_TYPE_IPV6);
1351                 if (state != CONNMAN_SERVICE_STATE_ASSOCIATION &&
1352                                 state != CONNMAN_SERVICE_STATE_CONFIGURATION &&
1353                                 state != CONNMAN_SERVICE_STATE_READY &&
1354                                 state != CONNMAN_SERVICE_STATE_ONLINE) {
1355                         DBG("Service state[%d] is not connecting/connected", state);
1356                         return;
1357                 }
1358         }
1359
1360         ipv6_dns_method = connman_service_get_ipv6_dns_method(service);
1361         if (ipv6_dns_method != CONNMAN_DNSCONFIG_METHOD_DHCP) {
1362                 DBG("IPv6 DNS method is not Auto ignore RA!!! [DNS method: %d]", ipv6_dns_method);
1363                 return;
1364         }
1365 #endif
1366
1367         for (opt = (void *)&msg[1];
1368                         msglen > 0;
1369                         msglen -= opt->nd_opt_len * 8,
1370                         opt = ((void *)opt) + opt->nd_opt_len*8) {
1371
1372                 DBG("remaining %d nd opt type %d len %d\n",
1373                         msglen, opt->nd_opt_type, opt->nd_opt_len);
1374
1375                 if (opt->nd_opt_type == 25) { /* ND_OPT_RDNSS */
1376                         char buf[40];
1377 #if defined TIZEN_EXT
1378                         struct connman_service *service;
1379
1380                         service = __connman_service_lookup_from_index(index);
1381                         DBG("service: %p\n",service);
1382 #endif
1383                         servers = rtnl_nd_opt_rdnss(opt, &lifetime,
1384                                         &nr_servers);
1385                         for (i = 0; i < nr_servers; i++) {
1386                                 if (!inet_ntop(AF_INET6, servers + i, buf,
1387                                                         sizeof(buf)))
1388                                         continue;
1389
1390 #if defined TIZEN_EXT
1391                                 __connman_service_nameserver_remove(service,
1392                                                 buf, false,
1393                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1394                                 __connman_service_nameserver_append(service,
1395                                                 buf, false,
1396                                                 CONNMAN_IPCONFIG_TYPE_IPV6);
1397 #endif
1398                                 connman_resolver_append_lifetime(index,
1399                                                 NULL, buf, lifetime);
1400                         }
1401
1402                 } else if (opt->nd_opt_type == 31) { /* ND_OPT_DNSSL */
1403                         g_free(domains);
1404
1405                         domains = rtnl_nd_opt_dnssl(opt, &lifetime);
1406                         for (i = 0; domains && domains[i]; i++)
1407                                 connman_resolver_append_lifetime(index,
1408                                                 domains[i], NULL, lifetime);
1409                 }
1410         }
1411
1412         g_free(domains);
1413 }
1414
1415 static const char *type2string(uint16_t type)
1416 {
1417         switch (type) {
1418         case NLMSG_NOOP:
1419                 return "NOOP";
1420         case NLMSG_ERROR:
1421                 return "ERROR";
1422         case NLMSG_DONE:
1423                 return "DONE";
1424         case NLMSG_OVERRUN:
1425                 return "OVERRUN";
1426         case RTM_GETLINK:
1427                 return "GETLINK";
1428         case RTM_NEWLINK:
1429                 return "NEWLINK";
1430         case RTM_DELLINK:
1431                 return "DELLINK";
1432         case RTM_GETADDR:
1433                 return "GETADDR";
1434         case RTM_NEWADDR:
1435                 return "NEWADDR";
1436         case RTM_DELADDR:
1437                 return "DELADDR";
1438         case RTM_GETROUTE:
1439                 return "GETROUTE";
1440         case RTM_NEWROUTE:
1441                 return "NEWROUTE";
1442         case RTM_DELROUTE:
1443                 return "DELROUTE";
1444         case RTM_NEWNDUSEROPT:
1445                 return "NEWNDUSEROPT";
1446         default:
1447                 return "UNKNOWN";
1448         }
1449 }
1450
1451 static GIOChannel *channel = NULL;
1452 static guint channel_watch = 0;
1453
1454 struct rtnl_request {
1455         struct nlmsghdr hdr;
1456         struct rtgenmsg msg;
1457 };
1458 #define RTNL_REQUEST_SIZE  (sizeof(struct nlmsghdr) + sizeof(struct rtgenmsg))
1459
1460 static GSList *request_list = NULL;
1461 static guint32 request_seq = 0;
1462
1463 static struct rtnl_request *find_request(guint32 seq)
1464 {
1465         GSList *list;
1466
1467         for (list = request_list; list; list = list->next) {
1468                 struct rtnl_request *req = list->data;
1469
1470                 if (req->hdr.nlmsg_seq == seq)
1471                         return req;
1472         }
1473
1474         return NULL;
1475 }
1476
1477 static int send_request(struct rtnl_request *req)
1478 {
1479         struct sockaddr_nl addr;
1480         int sk;
1481
1482         DBG("%s len %d type %d flags 0x%04x seq %d",
1483                                 type2string(req->hdr.nlmsg_type),
1484                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1485                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1486
1487         sk = g_io_channel_unix_get_fd(channel);
1488
1489         memset(&addr, 0, sizeof(addr));
1490         addr.nl_family = AF_NETLINK;
1491
1492         return sendto(sk, req, req->hdr.nlmsg_len, 0,
1493                                 (struct sockaddr *) &addr, sizeof(addr));
1494 }
1495
1496 static int queue_request(struct rtnl_request *req)
1497 {
1498         request_list = g_slist_append(request_list, req);
1499
1500         if (g_slist_length(request_list) > 1)
1501                 return 0;
1502
1503         return send_request(req);
1504 }
1505
1506 static int process_response(guint32 seq)
1507 {
1508         struct rtnl_request *req;
1509
1510         DBG("seq %d", seq);
1511
1512         req = find_request(seq);
1513         if (req) {
1514                 request_list = g_slist_remove(request_list, req);
1515                 g_free(req);
1516         }
1517
1518         req = g_slist_nth_data(request_list, 0);
1519         if (!req)
1520                 return 0;
1521
1522         return send_request(req);
1523 }
1524
1525 static void rtnl_message(void *buf, size_t len)
1526 {
1527         while (len > 0) {
1528                 struct nlmsghdr *hdr = buf;
1529                 struct nlmsgerr *err;
1530
1531                 if (!NLMSG_OK(hdr, len))
1532                         break;
1533
1534                 DBG("%s len %d type %d flags 0x%04x seq %d pid %d",
1535                                         type2string(hdr->nlmsg_type),
1536                                         hdr->nlmsg_len, hdr->nlmsg_type,
1537                                         hdr->nlmsg_flags, hdr->nlmsg_seq,
1538                                         hdr->nlmsg_pid);
1539
1540                 switch (hdr->nlmsg_type) {
1541                 case NLMSG_NOOP:
1542                 case NLMSG_OVERRUN:
1543                         return;
1544                 case NLMSG_DONE:
1545                         process_response(hdr->nlmsg_seq);
1546                         return;
1547                 case NLMSG_ERROR:
1548                         err = NLMSG_DATA(hdr);
1549                         DBG("error %d (%s)", -err->error,
1550                                                 strerror(-err->error));
1551                         return;
1552                 case RTM_NEWLINK:
1553                         rtnl_newlink(hdr);
1554                         break;
1555                 case RTM_DELLINK:
1556                         rtnl_dellink(hdr);
1557                         break;
1558                 case RTM_NEWADDR:
1559                         rtnl_newaddr(hdr);
1560                         break;
1561                 case RTM_DELADDR:
1562                         rtnl_deladdr(hdr);
1563                         break;
1564                 case RTM_NEWROUTE:
1565                         rtnl_newroute(hdr);
1566                         break;
1567                 case RTM_DELROUTE:
1568                         rtnl_delroute(hdr);
1569                         break;
1570                 case RTM_NEWNDUSEROPT:
1571                         rtnl_newnduseropt(hdr);
1572                         break;
1573                 }
1574
1575                 len -= hdr->nlmsg_len;
1576                 buf += hdr->nlmsg_len;
1577         }
1578 }
1579
1580 static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data)
1581 {
1582         unsigned char buf[4096];
1583         struct sockaddr_nl nladdr;
1584         socklen_t addr_len = sizeof(nladdr);
1585         ssize_t status;
1586         int fd;
1587
1588         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1589                 return FALSE;
1590
1591         memset(buf, 0, sizeof(buf));
1592         memset(&nladdr, 0, sizeof(nladdr));
1593
1594         fd = g_io_channel_unix_get_fd(chan);
1595
1596         status = recvfrom(fd, buf, sizeof(buf), 0,
1597                        (struct sockaddr *) &nladdr, &addr_len);
1598         if (status < 0) {
1599                 if (errno == EINTR || errno == EAGAIN)
1600                         return TRUE;
1601
1602                 return FALSE;
1603         }
1604
1605         if (status == 0)
1606                 return FALSE;
1607
1608         if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
1609                 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
1610                 return TRUE;
1611         }
1612
1613         rtnl_message(buf, status);
1614
1615         return TRUE;
1616 }
1617
1618 static int send_getlink(void)
1619 {
1620         struct rtnl_request *req;
1621
1622         DBG("");
1623
1624         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1625         if (!req)
1626                 return -ENOMEM;
1627
1628         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1629         req->hdr.nlmsg_type = RTM_GETLINK;
1630         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1631         req->hdr.nlmsg_pid = 0;
1632         req->hdr.nlmsg_seq = request_seq++;
1633         req->msg.rtgen_family = AF_INET;
1634
1635         return queue_request(req);
1636 }
1637
1638 static int send_getaddr(void)
1639 {
1640         struct rtnl_request *req;
1641
1642         DBG("");
1643
1644         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1645         if (!req)
1646                 return -ENOMEM;
1647
1648         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1649         req->hdr.nlmsg_type = RTM_GETADDR;
1650         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1651         req->hdr.nlmsg_pid = 0;
1652         req->hdr.nlmsg_seq = request_seq++;
1653         req->msg.rtgen_family = AF_INET;
1654
1655         return queue_request(req);
1656 }
1657
1658 static int send_getroute(void)
1659 {
1660         struct rtnl_request *req;
1661
1662         DBG("");
1663
1664         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1665         if (!req)
1666                 return -ENOMEM;
1667
1668         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1669         req->hdr.nlmsg_type = RTM_GETROUTE;
1670         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1671         req->hdr.nlmsg_pid = 0;
1672         req->hdr.nlmsg_seq = request_seq++;
1673         req->msg.rtgen_family = AF_INET;
1674
1675         return queue_request(req);
1676 }
1677
1678 static gboolean update_timeout_cb(gpointer user_data)
1679 {
1680         __connman_rtnl_request_update();
1681
1682         return TRUE;
1683 }
1684
1685 static void update_interval_callback(guint min)
1686 {
1687         if (update_timeout > 0)
1688                 g_source_remove(update_timeout);
1689
1690         if (min < G_MAXUINT) {
1691                 update_interval = min;
1692                 update_timeout = g_timeout_add_seconds(update_interval,
1693                                                 update_timeout_cb, NULL);
1694         } else {
1695                 update_timeout = 0;
1696                 update_interval = G_MAXUINT;
1697         }
1698 }
1699
1700 static gint compare_interval(gconstpointer a, gconstpointer b)
1701 {
1702         guint val_a = GPOINTER_TO_UINT(a);
1703         guint val_b = GPOINTER_TO_UINT(b);
1704
1705         return val_a - val_b;
1706 }
1707
1708 unsigned int __connman_rtnl_update_interval_add(unsigned int interval)
1709 {
1710         guint min;
1711
1712         if (interval == 0)
1713                 return 0;
1714
1715         update_list = g_slist_insert_sorted(update_list,
1716                         GUINT_TO_POINTER(interval), compare_interval);
1717
1718         min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1719         if (min < update_interval) {
1720                 update_interval_callback(min);
1721                 __connman_rtnl_request_update();
1722         }
1723
1724         return update_interval;
1725 }
1726
1727 unsigned int __connman_rtnl_update_interval_remove(unsigned int interval)
1728 {
1729         guint min = G_MAXUINT;
1730
1731         if (interval == 0)
1732                 return 0;
1733
1734         update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval));
1735
1736         if (update_list)
1737                 min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1738
1739         if (min > update_interval)
1740                 update_interval_callback(min);
1741
1742         return min;
1743 }
1744
1745 int __connman_rtnl_request_update(void)
1746 {
1747         return send_getlink();
1748 }
1749
1750 int __connman_rtnl_init(void)
1751 {
1752         struct sockaddr_nl addr;
1753         int sk;
1754
1755         DBG("");
1756
1757         interface_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
1758                                                         NULL, free_interface);
1759
1760         sk = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
1761         if (sk < 0)
1762                 return -1;
1763
1764         memset(&addr, 0, sizeof(addr));
1765         addr.nl_family = AF_NETLINK;
1766         addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
1767                                 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE |
1768                                 (1<<(RTNLGRP_ND_USEROPT-1));
1769
1770         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1771                 close(sk);
1772                 return -1;
1773         }
1774
1775         channel = g_io_channel_unix_new(sk);
1776         g_io_channel_set_close_on_unref(channel, TRUE);
1777
1778         g_io_channel_set_encoding(channel, NULL, NULL);
1779         g_io_channel_set_buffered(channel, FALSE);
1780
1781         channel_watch = g_io_add_watch(channel,
1782                                 G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1783                                 netlink_event, NULL);
1784
1785         return 0;
1786 }
1787
1788 void __connman_rtnl_start(void)
1789 {
1790         DBG("");
1791
1792         send_getlink();
1793         send_getaddr();
1794         send_getroute();
1795 }
1796
1797 void __connman_rtnl_cleanup(void)
1798 {
1799         GSList *list;
1800
1801         DBG("");
1802
1803         for (list = watch_list; list; list = list->next) {
1804                 struct watch_data *watch = list->data;
1805
1806                 DBG("removing watch %d", watch->id);
1807
1808                 g_free(watch);
1809                 list->data = NULL;
1810         }
1811
1812         g_slist_free(watch_list);
1813         watch_list = NULL;
1814
1815         g_slist_free(update_list);
1816         update_list = NULL;
1817
1818         for (list = request_list; list; list = list->next) {
1819                 struct rtnl_request *req = list->data;
1820
1821                 DBG("%s len %d type %d flags 0x%04x seq %d",
1822                                 type2string(req->hdr.nlmsg_type),
1823                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1824                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1825
1826                 g_free(req);
1827                 list->data = NULL;
1828         }
1829
1830         g_slist_free(request_list);
1831         request_list = NULL;
1832
1833         if (channel_watch) {
1834                 g_source_remove(channel_watch);
1835                 channel_watch = 0;
1836         }
1837
1838         g_io_channel_shutdown(channel, TRUE, NULL);
1839         g_io_channel_unref(channel);
1840
1841         channel = NULL;
1842
1843         g_hash_table_destroy(interface_list);
1844 }