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