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