39afb12b6f5aa4e77ae8f638eef20448840a5468
[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                 __connman_ipconfig_newlink(index, type, flags,
441                                                         str, mtu, &stats);
442                 break;
443         }
444
445         if (memcmp(&address, &compare, ETH_ALEN) != 0)
446                 connman_info("%s {newlink} index %d address %s mtu %u",
447                                                 ifname, index, str, mtu);
448
449         if (operstate != 0xff)
450                 connman_info("%s {newlink} index %d operstate %u <%s>",
451                                                 ifname, index, operstate,
452                                                 operstate2str(operstate));
453
454         interface = g_hash_table_lookup(interface_list, GINT_TO_POINTER(index));
455         if (interface == NULL) {
456                 interface = g_new0(struct interface_data, 1);
457                 interface->index = index;
458                 interface->name = g_strdup(ifname);
459                 interface->ident = g_strdup(ident);
460
461                 g_hash_table_insert(interface_list,
462                                         GINT_TO_POINTER(index), interface);
463
464                 if (type == ARPHRD_ETHER)
465                         read_uevent(interface);
466
467                 __connman_technology_add_interface(interface->service_type,
468                         interface->index, interface->name, interface->ident);
469         }
470
471         for (list = rtnl_list; list; list = list->next) {
472                 struct connman_rtnl *rtnl = list->data;
473
474                 if (rtnl->newlink)
475                         rtnl->newlink(type, index, flags, change);
476         }
477
478         for (list = watch_list; list; list = list->next) {
479                 struct watch_data *watch = list->data;
480
481                 if (watch->index != index)
482                         continue;
483
484                 if (watch->newlink)
485                         watch->newlink(flags, change, watch->user_data);
486         }
487 }
488
489 static void process_dellink(unsigned short type, int index, unsigned flags,
490                         unsigned change, struct ifinfomsg *msg, int bytes)
491 {
492         struct rtnl_link_stats stats;
493         unsigned char operstate = 0xff;
494         const char *ifname = NULL;
495         GSList *list;
496
497         memset(&stats, 0, sizeof(stats));
498         extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, &stats);
499
500         if (operstate != 0xff)
501                 connman_info("%s {dellink} index %d operstate %u <%s>",
502                                                 ifname, index, operstate,
503                                                 operstate2str(operstate));
504
505         for (list = rtnl_list; list; list = list->next) {
506                 struct connman_rtnl *rtnl = list->data;
507
508                 if (rtnl->dellink)
509                         rtnl->dellink(type, index, flags, change);
510         }
511
512         switch (type) {
513         case ARPHRD_ETHER:
514         case ARPHRD_LOOPBACK:
515         case ARPHRD_NONE:
516                 __connman_ipconfig_dellink(index, &stats);
517                 break;
518         }
519
520         g_hash_table_remove(interface_list, GINT_TO_POINTER(index));
521 }
522
523 static void extract_ipv4_addr(struct ifaddrmsg *msg, int bytes,
524                                                 const char **label,
525                                                 struct in_addr *local,
526                                                 struct in_addr *address,
527                                                 struct in_addr *broadcast)
528 {
529         struct rtattr *attr;
530
531         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
532                                         attr = RTA_NEXT(attr, bytes)) {
533                 switch (attr->rta_type) {
534                 case IFA_ADDRESS:
535                         if (address != NULL)
536                                 *address = *((struct in_addr *) RTA_DATA(attr));
537                         break;
538                 case IFA_LOCAL:
539                         if (local != NULL)
540                                 *local = *((struct in_addr *) RTA_DATA(attr));
541                         break;
542                 case IFA_BROADCAST:
543                         if (broadcast != NULL)
544                                 *broadcast = *((struct in_addr *) RTA_DATA(attr));
545                         break;
546                 case IFA_LABEL:
547                         if (label != NULL)
548                                 *label = RTA_DATA(attr);
549                         break;
550                 }
551         }
552 }
553
554 static void extract_ipv6_addr(struct ifaddrmsg *msg, int bytes,
555                                                 struct in6_addr *addr,
556                                                 struct in6_addr *local)
557 {
558         struct rtattr *attr;
559
560         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
561                                         attr = RTA_NEXT(attr, bytes)) {
562                 switch (attr->rta_type) {
563                 case IFA_ADDRESS:
564                         if (addr != NULL)
565                                 *addr = *((struct in6_addr *) RTA_DATA(attr));
566                         break;
567                 case IFA_LOCAL:
568                         if (local != NULL)
569                                 *local = *((struct in6_addr *) RTA_DATA(attr));
570                         break;
571                 }
572         }
573 }
574
575 static void process_newaddr(unsigned char family, unsigned char prefixlen,
576                                 int index, struct ifaddrmsg *msg, int bytes)
577 {
578         const char *label = NULL;
579         void *src;
580         char ip_string[INET6_ADDRSTRLEN];
581
582         if (family == AF_INET) {
583                 struct in_addr ipv4_addr = { INADDR_ANY };
584
585                 extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
586                 src = &ipv4_addr;
587         } else if (family == AF_INET6) {
588                 struct in6_addr ipv6_address, ipv6_local;
589
590                 extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
591                 if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
592                         return;
593
594                 src = &ipv6_address;
595         } else {
596                 return;
597         }
598
599         if (inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN) == NULL)
600                 return;
601
602         __connman_ipconfig_newaddr(index, family, label,
603                                         prefixlen, ip_string);
604 }
605
606 static void process_deladdr(unsigned char family, unsigned char prefixlen,
607                                 int index, struct ifaddrmsg *msg, int bytes)
608 {
609         const char *label = NULL;
610         void *src;
611         char ip_string[INET6_ADDRSTRLEN];
612
613         if (family == AF_INET) {
614                 struct in_addr ipv4_addr = { INADDR_ANY };
615
616                 extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
617                 src = &ipv4_addr;
618         } else if (family == AF_INET6) {
619                 struct in6_addr ipv6_address, ipv6_local;
620
621                 extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
622                 if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
623                         return;
624
625                 src = &ipv6_address;
626         } else {
627                 return;
628         }
629
630         if (inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN) == NULL)
631                 return;
632
633         __connman_ipconfig_deladdr(index, family, label,
634                                         prefixlen, ip_string);
635 }
636
637 static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index,
638                                                 struct in_addr *dst,
639                                                 struct in_addr *gateway)
640 {
641         struct rtattr *attr;
642
643         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
644                                         attr = RTA_NEXT(attr, bytes)) {
645                 switch (attr->rta_type) {
646                 case RTA_DST:
647                         if (dst != NULL)
648                                 *dst = *((struct in_addr *) RTA_DATA(attr));
649                         break;
650                 case RTA_GATEWAY:
651                         if (gateway != NULL)
652                                 *gateway = *((struct in_addr *) RTA_DATA(attr));
653                         break;
654                 case RTA_OIF:
655                         if (index != NULL)
656                                 *index = *((int *) RTA_DATA(attr));
657                         break;
658                 }
659         }
660 }
661
662 static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index,
663                                                 struct in6_addr *dst,
664                                                 struct in6_addr *gateway)
665 {
666         struct rtattr *attr;
667
668         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
669                                         attr = RTA_NEXT(attr, bytes)) {
670                 switch (attr->rta_type) {
671                 case RTA_DST:
672                         if (dst != NULL)
673                                 *dst = *((struct in6_addr *) RTA_DATA(attr));
674                         break;
675                 case RTA_GATEWAY:
676                         if (gateway != NULL)
677                                 *gateway =
678                                         *((struct in6_addr *) RTA_DATA(attr));
679                         break;
680                 case RTA_OIF:
681                         if (index != NULL)
682                                 *index = *((int *) RTA_DATA(attr));
683                         break;
684                 }
685         }
686 }
687
688 static void process_newroute(unsigned char family, unsigned char scope,
689                                                 struct rtmsg *msg, int bytes)
690 {
691         GSList *list;
692         char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
693         int index = -1;
694
695         if (family == AF_INET) {
696                 struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
697
698                 extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
699
700                 inet_ntop(family, &dst, dststr, sizeof(dststr));
701                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
702
703                 __connman_ipconfig_newroute(index, family, scope, dststr,
704                                                                 gatewaystr);
705
706                 /* skip host specific routes */
707                 if (scope != RT_SCOPE_UNIVERSE &&
708                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
709                         return;
710
711                 if (dst.s_addr != INADDR_ANY)
712                         return;
713
714         } else if (family == AF_INET6) {
715                 struct in6_addr dst = IN6ADDR_ANY_INIT,
716                                 gateway = IN6ADDR_ANY_INIT;
717
718                 extract_ipv6_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 &&
729                                 IN6_IS_ADDR_UNSPECIFIED(&dst)))
730                         return;
731
732                 if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
733                         return;
734         } else
735                 return;
736
737         for (list = rtnl_list; list; list = list->next) {
738                 struct connman_rtnl *rtnl = list->data;
739
740                 if (rtnl->newgateway)
741                         rtnl->newgateway(index, gatewaystr);
742         }
743 }
744
745 static void process_delroute(unsigned char family, unsigned char scope,
746                                                 struct rtmsg *msg, int bytes)
747 {
748         GSList *list;
749         char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
750         int index = -1;
751
752         if (family == AF_INET) {
753                 struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
754
755                 extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
756
757                 inet_ntop(family, &dst, dststr, sizeof(dststr));
758                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
759
760                 __connman_ipconfig_delroute(index, family, scope, dststr,
761                                                                 gatewaystr);
762
763                 /* skip host specific routes */
764                 if (scope != RT_SCOPE_UNIVERSE &&
765                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
766                         return;
767
768                 if (dst.s_addr != INADDR_ANY)
769                         return;
770
771         }  else if (family == AF_INET6) {
772                 struct in6_addr dst = IN6ADDR_ANY_INIT,
773                                 gateway = IN6ADDR_ANY_INIT;
774
775                 extract_ipv6_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 &&
786                                 IN6_IS_ADDR_UNSPECIFIED(&dst)))
787                         return;
788
789                 if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
790                         return;
791         } else
792                 return;
793
794         for (list = rtnl_list; list; list = list->next) {
795                 struct connman_rtnl *rtnl = list->data;
796
797                 if (rtnl->delgateway)
798                         rtnl->delgateway(index, gatewaystr);
799         }
800 }
801
802 static inline void print_ether(struct rtattr *attr, const char *name)
803 {
804         int len = (int) RTA_PAYLOAD(attr);
805
806         if (len == ETH_ALEN) {
807                 struct ether_addr eth;
808                 memcpy(&eth, RTA_DATA(attr), ETH_ALEN);
809                 print("  attr %s (len %d) %s\n", name, len, ether_ntoa(&eth));
810         } else
811                 print("  attr %s (len %d)\n", name, len);
812 }
813
814 static inline void print_inet(struct rtattr *attr, const char *name,
815                                                         unsigned char family)
816 {
817         int len = (int) RTA_PAYLOAD(attr);
818
819         if (family == AF_INET && len == sizeof(struct in_addr)) {
820                 struct in_addr addr;
821                 addr = *((struct in_addr *) RTA_DATA(attr));
822                 print("  attr %s (len %d) %s\n", name, len, inet_ntoa(addr));
823         } else
824                 print("  attr %s (len %d)\n", name, len);
825 }
826
827 static inline void print_string(struct rtattr *attr, const char *name)
828 {
829         print("  attr %s (len %d) %s\n", name, (int) RTA_PAYLOAD(attr),
830                                                 (char *) RTA_DATA(attr));
831 }
832
833 static inline void print_byte(struct rtattr *attr, const char *name)
834 {
835         print("  attr %s (len %d) 0x%02x\n", name, (int) RTA_PAYLOAD(attr),
836                                         *((unsigned char *) RTA_DATA(attr)));
837 }
838
839 static inline void print_integer(struct rtattr *attr, const char *name)
840 {
841         print("  attr %s (len %d) %d\n", name, (int) RTA_PAYLOAD(attr),
842                                                 *((int *) RTA_DATA(attr)));
843 }
844
845 static inline void print_attr(struct rtattr *attr, const char *name)
846 {
847         int len = (int) RTA_PAYLOAD(attr);
848
849         if (name && len > 0)
850                 print("  attr %s (len %d)\n", name, len);
851         else
852                 print("  attr %d (len %d)\n", attr->rta_type, len);
853 }
854
855 static void rtnl_link(struct nlmsghdr *hdr)
856 {
857         struct ifinfomsg *msg;
858         struct rtattr *attr;
859         int bytes;
860
861         msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
862         bytes = IFLA_PAYLOAD(hdr);
863
864         print("ifi_index %d ifi_flags 0x%04x", msg->ifi_index, msg->ifi_flags);
865
866         for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
867                                         attr = RTA_NEXT(attr, bytes)) {
868                 switch (attr->rta_type) {
869                 case IFLA_ADDRESS:
870                         print_ether(attr, "address");
871                         break;
872                 case IFLA_BROADCAST:
873                         print_ether(attr, "broadcast");
874                         break;
875                 case IFLA_IFNAME:
876                         print_string(attr, "ifname");
877                         break;
878                 case IFLA_MTU:
879                         print_integer(attr, "mtu");
880                         break;
881                 case IFLA_LINK:
882                         print_attr(attr, "link");
883                         break;
884                 case IFLA_QDISC:
885                         print_attr(attr, "qdisc");
886                         break;
887                 case IFLA_STATS:
888                         print_attr(attr, "stats");
889                         break;
890                 case IFLA_COST:
891                         print_attr(attr, "cost");
892                         break;
893                 case IFLA_PRIORITY:
894                         print_attr(attr, "priority");
895                         break;
896                 case IFLA_MASTER:
897                         print_attr(attr, "master");
898                         break;
899                 case IFLA_WIRELESS:
900                         print_attr(attr, "wireless");
901                         break;
902                 case IFLA_PROTINFO:
903                         print_attr(attr, "protinfo");
904                         break;
905                 case IFLA_TXQLEN:
906                         print_integer(attr, "txqlen");
907                         break;
908                 case IFLA_MAP:
909                         print_attr(attr, "map");
910                         break;
911                 case IFLA_WEIGHT:
912                         print_attr(attr, "weight");
913                         break;
914                 case IFLA_OPERSTATE:
915                         print_byte(attr, "operstate");
916                         break;
917                 case IFLA_LINKMODE:
918                         print_byte(attr, "linkmode");
919                         break;
920                 default:
921                         print_attr(attr, NULL);
922                         break;
923                 }
924         }
925 }
926
927 static void rtnl_newlink(struct nlmsghdr *hdr)
928 {
929         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
930
931         rtnl_link(hdr);
932
933         process_newlink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
934                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
935 }
936
937 static void rtnl_dellink(struct nlmsghdr *hdr)
938 {
939         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
940
941         rtnl_link(hdr);
942
943         process_dellink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
944                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
945 }
946
947 static void rtnl_addr(struct nlmsghdr *hdr)
948 {
949         struct ifaddrmsg *msg;
950         struct rtattr *attr;
951         int bytes;
952
953         msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
954         bytes = IFA_PAYLOAD(hdr);
955
956         print("ifa_family %d ifa_index %d", msg->ifa_family, msg->ifa_index);
957
958         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
959                                         attr = RTA_NEXT(attr, bytes)) {
960                 switch (attr->rta_type) {
961                 case IFA_ADDRESS:
962                         print_inet(attr, "address", msg->ifa_family);
963                         break;
964                 case IFA_LOCAL:
965                         print_inet(attr, "local", msg->ifa_family);
966                         break;
967                 case IFA_LABEL:
968                         print_string(attr, "label");
969                         break;
970                 case IFA_BROADCAST:
971                         print_inet(attr, "broadcast", msg->ifa_family);
972                         break;
973                 case IFA_ANYCAST:
974                         print_attr(attr, "anycast");
975                         break;
976                 case IFA_CACHEINFO:
977                         print_attr(attr, "cacheinfo");
978                         break;
979                 case IFA_MULTICAST:
980                         print_attr(attr, "multicast");
981                         break;
982                 default:
983                         print_attr(attr, NULL);
984                         break;
985                 }
986         }
987 }
988
989 static void rtnl_newaddr(struct nlmsghdr *hdr)
990 {
991         struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
992
993         rtnl_addr(hdr);
994
995         process_newaddr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
996                                                 msg, IFA_PAYLOAD(hdr));
997 }
998
999 static void rtnl_deladdr(struct nlmsghdr *hdr)
1000 {
1001         struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
1002
1003         rtnl_addr(hdr);
1004
1005         process_deladdr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
1006                                                 msg, IFA_PAYLOAD(hdr));
1007 }
1008
1009 static void rtnl_route(struct nlmsghdr *hdr)
1010 {
1011         struct rtmsg *msg;
1012         struct rtattr *attr;
1013         int bytes;
1014
1015         msg = (struct rtmsg *) NLMSG_DATA(hdr);
1016         bytes = RTM_PAYLOAD(hdr);
1017
1018         print("rtm_family %d rtm_table %d rtm_protocol %d",
1019                         msg->rtm_family, msg->rtm_table, msg->rtm_protocol);
1020         print("rtm_scope %d rtm_type %d rtm_flags 0x%04x",
1021                                 msg->rtm_scope, msg->rtm_type, msg->rtm_flags);
1022
1023         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
1024                                         attr = RTA_NEXT(attr, bytes)) {
1025                 switch (attr->rta_type) {
1026                 case RTA_DST:
1027                         print_inet(attr, "dst", msg->rtm_family);
1028                         break;
1029                 case RTA_SRC:
1030                         print_inet(attr, "src", msg->rtm_family);
1031                         break;
1032                 case RTA_IIF:
1033                         print_string(attr, "iif");
1034                         break;
1035                 case RTA_OIF:
1036                         print_integer(attr, "oif");
1037                         break;
1038                 case RTA_GATEWAY:
1039                         print_inet(attr, "gateway", msg->rtm_family);
1040                         break;
1041                 case RTA_PRIORITY:
1042                         print_attr(attr, "priority");
1043                         break;
1044                 case RTA_PREFSRC:
1045                         print_inet(attr, "prefsrc", msg->rtm_family);
1046                         break;
1047                 case RTA_METRICS:
1048                         print_attr(attr, "metrics");
1049                         break;
1050                 case RTA_TABLE:
1051                         print_integer(attr, "table");
1052                         break;
1053                 default:
1054                         print_attr(attr, NULL);
1055                         break;
1056                 }
1057         }
1058 }
1059
1060 static connman_bool_t is_route_rtmsg(struct rtmsg *msg)
1061 {
1062
1063         if (msg->rtm_table != RT_TABLE_MAIN)
1064                 return FALSE;
1065
1066         if (msg->rtm_protocol != RTPROT_BOOT &&
1067                         msg->rtm_protocol != RTPROT_KERNEL)
1068                 return FALSE;
1069
1070         if (msg->rtm_type != RTN_UNICAST)
1071                 return FALSE;
1072
1073         return TRUE;
1074 }
1075
1076 static void rtnl_newroute(struct nlmsghdr *hdr)
1077 {
1078         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
1079
1080         rtnl_route(hdr);
1081
1082         if (is_route_rtmsg(msg))
1083                 process_newroute(msg->rtm_family, msg->rtm_scope,
1084                                                 msg, RTM_PAYLOAD(hdr));
1085 }
1086
1087 static void rtnl_delroute(struct nlmsghdr *hdr)
1088 {
1089         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
1090
1091         rtnl_route(hdr);
1092
1093         if (is_route_rtmsg(msg))
1094                 process_delroute(msg->rtm_family, msg->rtm_scope,
1095                                                 msg, RTM_PAYLOAD(hdr));
1096 }
1097
1098 static void *rtnl_nd_opt_rdnss(struct nd_opt_hdr *opt, guint32 *lifetime,
1099                                int *nr_servers)
1100 {
1101         guint32 *optint = (void *)opt;
1102
1103         if (opt->nd_opt_len < 3)
1104                 return NULL;
1105
1106         if (*lifetime > ntohl(optint[1]))
1107                 *lifetime = ntohl(optint[1]);
1108
1109         /* nd_opt_len is in units of 8 bytes. The header is 1 unit (8 bytes)
1110            and each address is another 2 units (16 bytes).
1111            So the number of addresses (given rounding) is nd_opt_len/2 */
1112         *nr_servers = opt->nd_opt_len / 2;
1113
1114         /* And they start 8 bytes into the packet, or two guint32s in. */
1115         return optint + 2;
1116 }
1117
1118 static const char **rtnl_nd_opt_dnssl(struct nd_opt_hdr *opt, guint32 *lifetime)
1119 {
1120         const char **domains = NULL;
1121         guint32 *optint = (void *)opt;
1122         unsigned char *optc = (void *)&optint[2];
1123         int data_len = (opt->nd_opt_len * 8) - 8;
1124         int nr_domains = 0;
1125         int i, tmp;
1126
1127         if (*lifetime > ntohl(optint[1]))
1128                 *lifetime = ntohl(optint[1]);
1129
1130         /* Turn it into normal strings by converting the length bytes into '.',
1131            and count how many search domains there are while we're at it. */
1132         i = 0;
1133         while (i < data_len) {
1134                 if (optc[i] > 0x3f) {
1135                         DBG("DNSSL contains compressed elements in violation of RFC6106");
1136                         return NULL;
1137                 }
1138
1139                 if (optc[i] == 0) {
1140                         nr_domains++;
1141                         i++;
1142                         /* Check for double zero */
1143                         if (i < data_len && optc[i] == 0)
1144                                 break;
1145                         continue;
1146                 }
1147
1148                 tmp = i;
1149                 i += optc[i] + 1;
1150
1151                 if (i >= data_len) {
1152                         DBG("DNSSL data overflows option length");
1153                         return NULL;
1154                 }
1155
1156                 optc[tmp] = '.';
1157         }
1158
1159         domains = g_try_new0(const char *, nr_domains + 1);
1160         if (!domains)
1161                 return NULL;
1162
1163         /* Now point to the normal strings, missing out the leading '.' that
1164            each of them will have now. */
1165         for (i = 0; i < nr_domains; i++) {
1166                 domains[i] = (char *)optc + 1;
1167                 optc += strlen((char *)optc) + 1;
1168         }
1169
1170         return domains;
1171 }
1172
1173 static void rtnl_newnduseropt(struct nlmsghdr *hdr)
1174 {
1175         struct nduseroptmsg *msg = (struct nduseroptmsg *) NLMSG_DATA(hdr);
1176         struct nd_opt_hdr *opt = (void *)&msg[1];
1177         guint32 lifetime = -1;
1178         const char **domains = NULL;
1179         struct in6_addr *servers = NULL;
1180         int nr_servers = 0;
1181         int msglen = msg->nduseropt_opts_len;
1182         char *interface;
1183
1184         DBG("family %02x index %x len %04x type %02x code %02x",
1185             msg->nduseropt_family, msg->nduseropt_ifindex,
1186             msg->nduseropt_opts_len, msg->nduseropt_icmp_type,
1187             msg->nduseropt_icmp_code);
1188
1189         if (msg->nduseropt_family != AF_INET6 ||
1190             msg->nduseropt_icmp_type != ND_ROUTER_ADVERT ||
1191             msg->nduseropt_icmp_code != 0)
1192                 return;
1193
1194         interface = connman_inet_ifname(msg->nduseropt_ifindex);
1195         if (!interface)
1196                 return;
1197
1198         for (opt = (void *)&msg[1];
1199              msglen >= 2 && msglen >= opt->nd_opt_len && opt->nd_opt_len;
1200              msglen -= opt->nd_opt_len,
1201                      opt = ((void *)opt) + opt->nd_opt_len*8) {
1202
1203                 DBG("nd opt type %d len %d\n",
1204                     opt->nd_opt_type, opt->nd_opt_len);
1205
1206                 if (opt->nd_opt_type == 25)
1207                         servers = rtnl_nd_opt_rdnss(opt, &lifetime,
1208                                                     &nr_servers);
1209                 else if (opt->nd_opt_type == 31)
1210                         domains = rtnl_nd_opt_dnssl(opt, &lifetime);
1211         }
1212
1213         if (nr_servers) {
1214                 int i, j;
1215                 char buf[40];
1216
1217                 for (i = 0; i < nr_servers; i++) {
1218                         if (!inet_ntop(AF_INET6, servers + i, buf, sizeof(buf)))
1219                                 continue;
1220
1221                         if (domains == NULL || domains[0] == NULL) {
1222                                 connman_resolver_append_lifetime(interface,
1223                                                         NULL, buf, lifetime);
1224                                 continue;
1225                         }
1226
1227                         for (j = 0; domains[j]; j++)
1228                                 connman_resolver_append_lifetime(interface,
1229                                                                 domains[j],
1230                                                                 buf, lifetime);
1231                 }
1232         }
1233         g_free(domains);
1234         g_free(interface);
1235 }
1236
1237 static const char *type2string(uint16_t type)
1238 {
1239         switch (type) {
1240         case NLMSG_NOOP:
1241                 return "NOOP";
1242         case NLMSG_ERROR:
1243                 return "ERROR";
1244         case NLMSG_DONE:
1245                 return "DONE";
1246         case NLMSG_OVERRUN:
1247                 return "OVERRUN";
1248         case RTM_GETLINK:
1249                 return "GETLINK";
1250         case RTM_NEWLINK:
1251                 return "NEWLINK";
1252         case RTM_DELLINK:
1253                 return "DELLINK";
1254         case RTM_NEWADDR:
1255                 return "NEWADDR";
1256         case RTM_DELADDR:
1257                 return "DELADDR";
1258         case RTM_GETROUTE:
1259                 return "GETROUTE";
1260         case RTM_NEWROUTE:
1261                 return "NEWROUTE";
1262         case RTM_DELROUTE:
1263                 return "DELROUTE";
1264         case RTM_NEWNDUSEROPT:
1265                 return "NEWNDUSEROPT";
1266         default:
1267                 return "UNKNOWN";
1268         }
1269 }
1270
1271 static GIOChannel *channel = NULL;
1272
1273 struct rtnl_request {
1274         struct nlmsghdr hdr;
1275         struct rtgenmsg msg;
1276 };
1277 #define RTNL_REQUEST_SIZE  (sizeof(struct nlmsghdr) + sizeof(struct rtgenmsg))
1278
1279 static GSList *request_list = NULL;
1280 static guint32 request_seq = 0;
1281
1282 static struct rtnl_request *find_request(guint32 seq)
1283 {
1284         GSList *list;
1285
1286         for (list = request_list; list; list = list->next) {
1287                 struct rtnl_request *req = list->data;
1288
1289                 if (req->hdr.nlmsg_seq == seq)
1290                         return req;
1291         }
1292
1293         return NULL;
1294 }
1295
1296 static int send_request(struct rtnl_request *req)
1297 {
1298         struct sockaddr_nl addr;
1299         int sk;
1300
1301         DBG("%s len %d type %d flags 0x%04x seq %d",
1302                                 type2string(req->hdr.nlmsg_type),
1303                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1304                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1305
1306         sk = g_io_channel_unix_get_fd(channel);
1307
1308         memset(&addr, 0, sizeof(addr));
1309         addr.nl_family = AF_NETLINK;
1310
1311         return sendto(sk, req, req->hdr.nlmsg_len, 0,
1312                                 (struct sockaddr *) &addr, sizeof(addr));
1313 }
1314
1315 static int queue_request(struct rtnl_request *req)
1316 {
1317         request_list = g_slist_append(request_list, req);
1318
1319         if (g_slist_length(request_list) > 1)
1320                 return 0;
1321
1322         return send_request(req);
1323 }
1324
1325 static int process_response(guint32 seq)
1326 {
1327         struct rtnl_request *req;
1328
1329         DBG("seq %d", seq);
1330
1331         req = find_request(seq);
1332         if (req != NULL) {
1333                 request_list = g_slist_remove(request_list, req);
1334                 g_free(req);
1335         }
1336
1337         req = g_slist_nth_data(request_list, 0);
1338         if (req == NULL)
1339                 return 0;
1340
1341         return send_request(req);
1342 }
1343
1344 static void rtnl_message(void *buf, size_t len)
1345 {
1346         DBG("buf %p len %zd", buf, len);
1347
1348         while (len > 0) {
1349                 struct nlmsghdr *hdr = buf;
1350                 struct nlmsgerr *err;
1351
1352                 if (!NLMSG_OK(hdr, len))
1353                         break;
1354
1355                 DBG("%s len %d type %d flags 0x%04x seq %d",
1356                                         type2string(hdr->nlmsg_type),
1357                                         hdr->nlmsg_len, hdr->nlmsg_type,
1358                                         hdr->nlmsg_flags, hdr->nlmsg_seq);
1359
1360                 switch (hdr->nlmsg_type) {
1361                 case NLMSG_NOOP:
1362                 case NLMSG_OVERRUN:
1363                         return;
1364                 case NLMSG_DONE:
1365                         process_response(hdr->nlmsg_seq);
1366                         return;
1367                 case NLMSG_ERROR:
1368                         err = NLMSG_DATA(hdr);
1369                         DBG("error %d (%s)", -err->error,
1370                                                 strerror(-err->error));
1371                         return;
1372                 case RTM_NEWLINK:
1373                         rtnl_newlink(hdr);
1374                         break;
1375                 case RTM_DELLINK:
1376                         rtnl_dellink(hdr);
1377                         break;
1378                 case RTM_NEWADDR:
1379                         rtnl_newaddr(hdr);
1380                         break;
1381                 case RTM_DELADDR:
1382                         rtnl_deladdr(hdr);
1383                         break;
1384                 case RTM_NEWROUTE:
1385                         rtnl_newroute(hdr);
1386                         break;
1387                 case RTM_DELROUTE:
1388                         rtnl_delroute(hdr);
1389                         break;
1390                 case RTM_NEWNDUSEROPT:
1391                         rtnl_newnduseropt(hdr);
1392                         break;
1393                 }
1394
1395                 len -= hdr->nlmsg_len;
1396                 buf += hdr->nlmsg_len;
1397         }
1398 }
1399
1400 static gboolean netlink_event(GIOChannel *chan,
1401                                 GIOCondition cond, gpointer data)
1402 {
1403         unsigned char buf[4096];
1404         gsize len;
1405         GIOStatus status;
1406
1407         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1408                 return FALSE;
1409
1410         memset(buf, 0, sizeof(buf));
1411
1412         status = g_io_channel_read_chars(chan, (gchar *) buf,
1413                                                 sizeof(buf), &len, NULL);
1414
1415         switch (status) {
1416         case G_IO_STATUS_NORMAL:
1417                 break;
1418         case G_IO_STATUS_AGAIN:
1419                 return TRUE;
1420         default:
1421                 return FALSE;
1422         }
1423
1424         rtnl_message(buf, len);
1425
1426         return TRUE;
1427 }
1428
1429 static int send_getlink(void)
1430 {
1431         struct rtnl_request *req;
1432
1433         DBG("");
1434
1435         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1436         if (req == NULL)
1437                 return -ENOMEM;
1438
1439         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1440         req->hdr.nlmsg_type = RTM_GETLINK;
1441         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1442         req->hdr.nlmsg_pid = 0;
1443         req->hdr.nlmsg_seq = request_seq++;
1444         req->msg.rtgen_family = AF_INET;
1445
1446         return queue_request(req);
1447 }
1448
1449 static int send_getaddr(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_GETADDR;
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_getroute(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_GETROUTE;
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 gboolean update_timeout_cb(gpointer user_data)
1490 {
1491         __connman_rtnl_request_update();
1492
1493         return TRUE;
1494 }
1495
1496 static void update_interval_callback(guint min)
1497 {
1498         if (update_timeout > 0)
1499                 g_source_remove(update_timeout);
1500
1501         if (min < G_MAXUINT) {
1502                 update_interval = min;
1503                 update_timeout = g_timeout_add_seconds(update_interval,
1504                                                 update_timeout_cb, NULL);
1505         } else {
1506                 update_timeout = 0;
1507                 update_interval = G_MAXUINT;
1508         }
1509 }
1510
1511 static gint compare_interval(gconstpointer a, gconstpointer b)
1512 {
1513         guint val_a = GPOINTER_TO_UINT(a);
1514         guint val_b = GPOINTER_TO_UINT(b);
1515
1516         return val_a - val_b;
1517 }
1518
1519 unsigned int __connman_rtnl_update_interval_add(unsigned int interval)
1520 {
1521         guint min;
1522
1523         if (interval == 0)
1524                 return 0;
1525
1526         update_list = g_slist_insert_sorted(update_list,
1527                         GUINT_TO_POINTER(interval), compare_interval);
1528
1529         min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1530         if (min < update_interval) {
1531                 update_interval_callback(min);
1532                 __connman_rtnl_request_update();
1533         }
1534
1535         return update_interval;
1536 }
1537
1538 unsigned int __connman_rtnl_update_interval_remove(unsigned int interval)
1539 {
1540         guint min = G_MAXUINT;
1541
1542         if (interval == 0)
1543                 return 0;
1544
1545         update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval));
1546
1547         if (update_list != NULL)
1548                 min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1549
1550         if (min > update_interval)
1551                 update_interval_callback(min);
1552
1553         return min;
1554 }
1555
1556 int __connman_rtnl_request_update(void)
1557 {
1558         return send_getlink();
1559 }
1560
1561 int __connman_rtnl_init(void)
1562 {
1563         struct sockaddr_nl addr;
1564         int sk;
1565
1566         DBG("");
1567
1568         interface_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
1569                                                         NULL, free_interface);
1570
1571         sk = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
1572         if (sk < 0)
1573                 return -1;
1574
1575         memset(&addr, 0, sizeof(addr));
1576         addr.nl_family = AF_NETLINK;
1577         addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
1578                                 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE |
1579                                 (1<<(RTNLGRP_ND_USEROPT-1));
1580
1581         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1582                 close(sk);
1583                 return -1;
1584         }
1585
1586         channel = g_io_channel_unix_new(sk);
1587         g_io_channel_set_close_on_unref(channel, TRUE);
1588
1589         g_io_channel_set_encoding(channel, NULL, NULL);
1590         g_io_channel_set_buffered(channel, FALSE);
1591
1592         g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1593                                                         netlink_event, NULL);
1594
1595         return 0;
1596 }
1597
1598 void __connman_rtnl_start(void)
1599 {
1600         DBG("");
1601
1602         send_getlink();
1603         send_getaddr();
1604         send_getroute();
1605 }
1606
1607 void __connman_rtnl_cleanup(void)
1608 {
1609         GSList *list;
1610
1611         DBG("");
1612
1613         for (list = watch_list; list; list = list->next) {
1614                 struct watch_data *watch = list->data;
1615
1616                 DBG("removing watch %d", watch->id);
1617
1618                 g_free(watch);
1619                 list->data = NULL;
1620         }
1621
1622         g_slist_free(watch_list);
1623         watch_list = NULL;
1624
1625         g_slist_free(update_list);
1626         update_list = NULL;
1627
1628         for (list = request_list; list; list = list->next) {
1629                 struct rtnl_request *req = list->data;
1630
1631                 DBG("%s len %d type %d flags 0x%04x seq %d",
1632                                 type2string(req->hdr.nlmsg_type),
1633                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1634                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1635
1636                 g_free(req);
1637                 list->data = NULL;
1638         }
1639
1640         g_slist_free(request_list);
1641         request_list = NULL;
1642
1643         g_io_channel_shutdown(channel, TRUE, NULL);
1644         g_io_channel_unref(channel);
1645
1646         channel = NULL;
1647
1648         g_hash_table_destroy(interface_list);
1649 }