rtnl: Remove dead assignment
[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         /* 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 =
295                         __connman_ipconfig_get_gateway_from_index(index,
296                                         CONNMAN_IPCONFIG_TYPE_ALL);
297
298                 if (gateway != NULL)
299                         rtnl->newgateway(index, gateway);
300         }
301 }
302
303 static GSList *rtnl_list = NULL;
304
305 static gint compare_priority(gconstpointer a, gconstpointer b)
306 {
307         const struct connman_rtnl *rtnl1 = a;
308         const struct connman_rtnl *rtnl2 = b;
309
310         return rtnl2->priority - rtnl1->priority;
311 }
312
313 /**
314  * connman_rtnl_register:
315  * @rtnl: RTNL module
316  *
317  * Register a new RTNL module
318  *
319  * Returns: %0 on success
320  */
321 int connman_rtnl_register(struct connman_rtnl *rtnl)
322 {
323         DBG("rtnl %p name %s", rtnl, rtnl->name);
324
325         rtnl_list = g_slist_insert_sorted(rtnl_list, rtnl,
326                                                         compare_priority);
327
328         __connman_ipconfig_foreach(trigger_rtnl, rtnl);
329
330         return 0;
331 }
332
333 /**
334  * connman_rtnl_unregister:
335  * @rtnl: RTNL module
336  *
337  * Remove a previously registered RTNL module
338  */
339 void connman_rtnl_unregister(struct connman_rtnl *rtnl)
340 {
341         DBG("rtnl %p name %s", rtnl, rtnl->name);
342
343         rtnl_list = g_slist_remove(rtnl_list, rtnl);
344 }
345
346 static const char *operstate2str(unsigned char operstate)
347 {
348         switch (operstate) {
349         case IF_OPER_UNKNOWN:
350                 return "UNKNOWN";
351         case IF_OPER_NOTPRESENT:
352                 return "NOT-PRESENT";
353         case IF_OPER_DOWN:
354                 return "DOWN";
355         case IF_OPER_LOWERLAYERDOWN:
356                 return "LOWER-LAYER-DOWN";
357         case IF_OPER_TESTING:
358                 return "TESTING";
359         case IF_OPER_DORMANT:
360                 return "DORMANT";
361         case IF_OPER_UP:
362                 return "UP";
363         }
364
365         return "";
366 }
367
368 static void extract_link(struct ifinfomsg *msg, int bytes,
369                                 struct ether_addr *address, const char **ifname,
370                                 unsigned int *mtu, unsigned char *operstate,
371                                                 struct rtnl_link_stats *stats)
372 {
373         struct rtattr *attr;
374
375         for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
376                                         attr = RTA_NEXT(attr, bytes)) {
377                 switch (attr->rta_type) {
378                 case IFLA_ADDRESS:
379                         if (address != NULL)
380                                 memcpy(address, RTA_DATA(attr), ETH_ALEN);
381                         break;
382                 case IFLA_IFNAME:
383                         if (ifname != NULL)
384                                 *ifname = RTA_DATA(attr);
385                         break;
386                 case IFLA_MTU:
387                         if (mtu != NULL)
388                                 *mtu = *((unsigned int *) RTA_DATA(attr));
389                         break;
390                 case IFLA_STATS:
391                         if (stats != NULL)
392                                 memcpy(stats, RTA_DATA(attr),
393                                         sizeof(struct rtnl_link_stats));
394                         break;
395                 case IFLA_OPERSTATE:
396                         if (operstate != NULL)
397                                 *operstate = *((unsigned char *) RTA_DATA(attr));
398                         break;
399                 case IFLA_LINKMODE:
400                         break;
401                 }
402         }
403 }
404
405 static void process_newlink(unsigned short type, int index, unsigned flags,
406                         unsigned change, struct ifinfomsg *msg, int bytes)
407 {
408         struct ether_addr address = {{ 0, 0, 0, 0, 0, 0 }};
409         struct ether_addr compare = {{ 0, 0, 0, 0, 0, 0 }};
410         struct rtnl_link_stats stats;
411         unsigned char operstate = 0xff;
412         struct interface_data *interface;
413         const char *ifname = NULL;
414         unsigned int mtu = 0;
415         char ident[13], str[18];
416         GSList *list;
417
418         memset(&stats, 0, sizeof(stats));
419         extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats);
420
421         snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
422                                                 address.ether_addr_octet[0],
423                                                 address.ether_addr_octet[1],
424                                                 address.ether_addr_octet[2],
425                                                 address.ether_addr_octet[3],
426                                                 address.ether_addr_octet[4],
427                                                 address.ether_addr_octet[5]);
428
429         snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
430                                                 address.ether_addr_octet[0],
431                                                 address.ether_addr_octet[1],
432                                                 address.ether_addr_octet[2],
433                                                 address.ether_addr_octet[3],
434                                                 address.ether_addr_octet[4],
435                                                 address.ether_addr_octet[5]);
436
437         switch (type) {
438         case ARPHRD_ETHER:
439         case ARPHRD_LOOPBACK:
440         case ARPHDR_PHONET_PIPE:
441         case ARPHRD_NONE:
442                 __connman_ipconfig_newlink(index, type, flags,
443                                                         str, mtu, &stats);
444                 break;
445         }
446
447         if (memcmp(&address, &compare, ETH_ALEN) != 0)
448                 connman_info("%s {newlink} index %d address %s mtu %u",
449                                                 ifname, index, str, mtu);
450
451         if (operstate != 0xff)
452                 connman_info("%s {newlink} index %d operstate %u <%s>",
453                                                 ifname, index, operstate,
454                                                 operstate2str(operstate));
455
456         interface = g_hash_table_lookup(interface_list, GINT_TO_POINTER(index));
457         if (interface == NULL) {
458                 interface = g_new0(struct interface_data, 1);
459                 interface->index = index;
460                 interface->name = g_strdup(ifname);
461                 interface->ident = g_strdup(ident);
462
463                 g_hash_table_insert(interface_list,
464                                         GINT_TO_POINTER(index), interface);
465
466                 if (type == ARPHRD_ETHER)
467                         read_uevent(interface);
468
469                 __connman_technology_add_interface(interface->service_type,
470                         interface->index, interface->name, interface->ident);
471         }
472
473         for (list = rtnl_list; list; list = list->next) {
474                 struct connman_rtnl *rtnl = list->data;
475
476                 if (rtnl->newlink)
477                         rtnl->newlink(type, index, flags, change);
478         }
479
480         for (list = watch_list; list; list = list->next) {
481                 struct watch_data *watch = list->data;
482
483                 if (watch->index != index)
484                         continue;
485
486                 if (watch->newlink)
487                         watch->newlink(flags, change, watch->user_data);
488         }
489 }
490
491 static void process_dellink(unsigned short type, int index, unsigned flags,
492                         unsigned change, struct ifinfomsg *msg, int bytes)
493 {
494         struct rtnl_link_stats stats;
495         unsigned char operstate = 0xff;
496         const char *ifname = NULL;
497         GSList *list;
498
499         memset(&stats, 0, sizeof(stats));
500         extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, &stats);
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                 char *interface = connman_inet_ifname(index);
615
616                 __connman_resolver_redo_servers(interface);
617
618                 g_free(interface);
619         }
620 }
621
622 static void process_deladdr(unsigned char family, unsigned char prefixlen,
623                                 int index, struct ifaddrmsg *msg, int bytes)
624 {
625         const char *label = NULL;
626         void *src;
627         char ip_string[INET6_ADDRSTRLEN];
628
629         if (family == AF_INET) {
630                 struct in_addr ipv4_addr = { INADDR_ANY };
631
632                 extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
633                 src = &ipv4_addr;
634         } else if (family == AF_INET6) {
635                 struct in6_addr ipv6_address, ipv6_local;
636
637                 extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
638                 if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
639                         return;
640
641                 src = &ipv6_address;
642         } else {
643                 return;
644         }
645
646         if (inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN) == NULL)
647                 return;
648
649         __connman_ipconfig_deladdr(index, family, label,
650                                         prefixlen, ip_string);
651 }
652
653 static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index,
654                                                 struct in_addr *dst,
655                                                 struct in_addr *gateway)
656 {
657         struct rtattr *attr;
658
659         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
660                                         attr = RTA_NEXT(attr, bytes)) {
661                 switch (attr->rta_type) {
662                 case RTA_DST:
663                         if (dst != NULL)
664                                 *dst = *((struct in_addr *) RTA_DATA(attr));
665                         break;
666                 case RTA_GATEWAY:
667                         if (gateway != NULL)
668                                 *gateway = *((struct in_addr *) RTA_DATA(attr));
669                         break;
670                 case RTA_OIF:
671                         if (index != NULL)
672                                 *index = *((int *) RTA_DATA(attr));
673                         break;
674                 }
675         }
676 }
677
678 static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index,
679                                                 struct in6_addr *dst,
680                                                 struct in6_addr *gateway)
681 {
682         struct rtattr *attr;
683
684         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
685                                         attr = RTA_NEXT(attr, bytes)) {
686                 switch (attr->rta_type) {
687                 case RTA_DST:
688                         if (dst != NULL)
689                                 *dst = *((struct in6_addr *) RTA_DATA(attr));
690                         break;
691                 case RTA_GATEWAY:
692                         if (gateway != NULL)
693                                 *gateway =
694                                         *((struct in6_addr *) RTA_DATA(attr));
695                         break;
696                 case RTA_OIF:
697                         if (index != NULL)
698                                 *index = *((int *) RTA_DATA(attr));
699                         break;
700                 }
701         }
702 }
703
704 static void process_newroute(unsigned char family, unsigned char scope,
705                                                 struct rtmsg *msg, int bytes)
706 {
707         GSList *list;
708         char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
709         int index = -1;
710
711         if (family == AF_INET) {
712                 struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
713
714                 extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
715
716                 inet_ntop(family, &dst, dststr, sizeof(dststr));
717                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
718
719                 __connman_ipconfig_newroute(index, family, scope, dststr,
720                                                                 gatewaystr);
721
722                 /* skip host specific routes */
723                 if (scope != RT_SCOPE_UNIVERSE &&
724                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
725                         return;
726
727                 if (dst.s_addr != INADDR_ANY)
728                         return;
729
730         } else if (family == AF_INET6) {
731                 struct in6_addr dst = IN6ADDR_ANY_INIT,
732                                 gateway = IN6ADDR_ANY_INIT;
733
734                 extract_ipv6_route(msg, bytes, &index, &dst, &gateway);
735
736                 inet_ntop(family, &dst, dststr, sizeof(dststr));
737                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
738
739                 __connman_ipconfig_newroute(index, family, scope, dststr,
740                                                                 gatewaystr);
741
742                 /* skip host specific routes */
743                 if (scope != RT_SCOPE_UNIVERSE &&
744                         !(scope == RT_SCOPE_LINK &&
745                                 IN6_IS_ADDR_UNSPECIFIED(&dst)))
746                         return;
747
748                 if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
749                         return;
750         } else
751                 return;
752
753         for (list = rtnl_list; list; list = list->next) {
754                 struct connman_rtnl *rtnl = list->data;
755
756                 if (rtnl->newgateway)
757                         rtnl->newgateway(index, gatewaystr);
758         }
759 }
760
761 static void process_delroute(unsigned char family, unsigned char scope,
762                                                 struct rtmsg *msg, int bytes)
763 {
764         GSList *list;
765         char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
766         int index = -1;
767
768         if (family == AF_INET) {
769                 struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
770
771                 extract_ipv4_route(msg, bytes, &index, &dst, &gateway);
772
773                 inet_ntop(family, &dst, dststr, sizeof(dststr));
774                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
775
776                 __connman_ipconfig_delroute(index, family, scope, dststr,
777                                                                 gatewaystr);
778
779                 /* skip host specific routes */
780                 if (scope != RT_SCOPE_UNIVERSE &&
781                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
782                         return;
783
784                 if (dst.s_addr != INADDR_ANY)
785                         return;
786
787         }  else if (family == AF_INET6) {
788                 struct in6_addr dst = IN6ADDR_ANY_INIT,
789                                 gateway = IN6ADDR_ANY_INIT;
790
791                 extract_ipv6_route(msg, bytes, &index, &dst, &gateway);
792
793                 inet_ntop(family, &dst, dststr, sizeof(dststr));
794                 inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
795
796                 __connman_ipconfig_delroute(index, family, scope, dststr,
797                                                 gatewaystr);
798
799                 /* skip host specific routes */
800                 if (scope != RT_SCOPE_UNIVERSE &&
801                         !(scope == RT_SCOPE_LINK &&
802                                 IN6_IS_ADDR_UNSPECIFIED(&dst)))
803                         return;
804
805                 if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
806                         return;
807         } else
808                 return;
809
810         for (list = rtnl_list; list; list = list->next) {
811                 struct connman_rtnl *rtnl = list->data;
812
813                 if (rtnl->delgateway)
814                         rtnl->delgateway(index, gatewaystr);
815         }
816 }
817
818 static inline void print_ether(struct rtattr *attr, const char *name)
819 {
820         int len = (int) RTA_PAYLOAD(attr);
821
822         if (len == ETH_ALEN) {
823                 struct ether_addr eth;
824                 memcpy(&eth, RTA_DATA(attr), ETH_ALEN);
825                 print("  attr %s (len %d) %s\n", name, len, ether_ntoa(&eth));
826         } else
827                 print("  attr %s (len %d)\n", name, len);
828 }
829
830 static inline void print_inet(struct rtattr *attr, const char *name,
831                                                         unsigned char family)
832 {
833         int len = (int) RTA_PAYLOAD(attr);
834
835         if (family == AF_INET && len == sizeof(struct in_addr)) {
836                 struct in_addr addr;
837                 addr = *((struct in_addr *) RTA_DATA(attr));
838                 print("  attr %s (len %d) %s\n", name, len, inet_ntoa(addr));
839         } else
840                 print("  attr %s (len %d)\n", name, len);
841 }
842
843 static inline void print_string(struct rtattr *attr, const char *name)
844 {
845         print("  attr %s (len %d) %s\n", name, (int) RTA_PAYLOAD(attr),
846                                                 (char *) RTA_DATA(attr));
847 }
848
849 static inline void print_byte(struct rtattr *attr, const char *name)
850 {
851         print("  attr %s (len %d) 0x%02x\n", name, (int) RTA_PAYLOAD(attr),
852                                         *((unsigned char *) RTA_DATA(attr)));
853 }
854
855 static inline void print_integer(struct rtattr *attr, const char *name)
856 {
857         print("  attr %s (len %d) %d\n", name, (int) RTA_PAYLOAD(attr),
858                                                 *((int *) RTA_DATA(attr)));
859 }
860
861 static inline void print_attr(struct rtattr *attr, const char *name)
862 {
863         int len = (int) RTA_PAYLOAD(attr);
864
865         if (name && len > 0)
866                 print("  attr %s (len %d)\n", name, len);
867         else
868                 print("  attr %d (len %d)\n", attr->rta_type, len);
869 }
870
871 static void rtnl_link(struct nlmsghdr *hdr)
872 {
873         struct ifinfomsg *msg;
874         struct rtattr *attr;
875         int bytes;
876
877         msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
878         bytes = IFLA_PAYLOAD(hdr);
879
880         print("ifi_index %d ifi_flags 0x%04x", msg->ifi_index, msg->ifi_flags);
881
882         for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
883                                         attr = RTA_NEXT(attr, bytes)) {
884                 switch (attr->rta_type) {
885                 case IFLA_ADDRESS:
886                         print_ether(attr, "address");
887                         break;
888                 case IFLA_BROADCAST:
889                         print_ether(attr, "broadcast");
890                         break;
891                 case IFLA_IFNAME:
892                         print_string(attr, "ifname");
893                         break;
894                 case IFLA_MTU:
895                         print_integer(attr, "mtu");
896                         break;
897                 case IFLA_LINK:
898                         print_attr(attr, "link");
899                         break;
900                 case IFLA_QDISC:
901                         print_attr(attr, "qdisc");
902                         break;
903                 case IFLA_STATS:
904                         print_attr(attr, "stats");
905                         break;
906                 case IFLA_COST:
907                         print_attr(attr, "cost");
908                         break;
909                 case IFLA_PRIORITY:
910                         print_attr(attr, "priority");
911                         break;
912                 case IFLA_MASTER:
913                         print_attr(attr, "master");
914                         break;
915                 case IFLA_WIRELESS:
916                         print_attr(attr, "wireless");
917                         break;
918                 case IFLA_PROTINFO:
919                         print_attr(attr, "protinfo");
920                         break;
921                 case IFLA_TXQLEN:
922                         print_integer(attr, "txqlen");
923                         break;
924                 case IFLA_MAP:
925                         print_attr(attr, "map");
926                         break;
927                 case IFLA_WEIGHT:
928                         print_attr(attr, "weight");
929                         break;
930                 case IFLA_OPERSTATE:
931                         print_byte(attr, "operstate");
932                         break;
933                 case IFLA_LINKMODE:
934                         print_byte(attr, "linkmode");
935                         break;
936                 default:
937                         print_attr(attr, NULL);
938                         break;
939                 }
940         }
941 }
942
943 static void rtnl_newlink(struct nlmsghdr *hdr)
944 {
945         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
946
947         rtnl_link(hdr);
948
949         process_newlink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
950                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
951 }
952
953 static void rtnl_dellink(struct nlmsghdr *hdr)
954 {
955         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
956
957         rtnl_link(hdr);
958
959         process_dellink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
960                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
961 }
962
963 static void rtnl_addr(struct nlmsghdr *hdr)
964 {
965         struct ifaddrmsg *msg;
966         struct rtattr *attr;
967         int bytes;
968
969         msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
970         bytes = IFA_PAYLOAD(hdr);
971
972         print("ifa_family %d ifa_index %d", msg->ifa_family, msg->ifa_index);
973
974         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
975                                         attr = RTA_NEXT(attr, bytes)) {
976                 switch (attr->rta_type) {
977                 case IFA_ADDRESS:
978                         print_inet(attr, "address", msg->ifa_family);
979                         break;
980                 case IFA_LOCAL:
981                         print_inet(attr, "local", msg->ifa_family);
982                         break;
983                 case IFA_LABEL:
984                         print_string(attr, "label");
985                         break;
986                 case IFA_BROADCAST:
987                         print_inet(attr, "broadcast", msg->ifa_family);
988                         break;
989                 case IFA_ANYCAST:
990                         print_attr(attr, "anycast");
991                         break;
992                 case IFA_CACHEINFO:
993                         print_attr(attr, "cacheinfo");
994                         break;
995                 case IFA_MULTICAST:
996                         print_attr(attr, "multicast");
997                         break;
998                 default:
999                         print_attr(attr, NULL);
1000                         break;
1001                 }
1002         }
1003 }
1004
1005 static void rtnl_newaddr(struct nlmsghdr *hdr)
1006 {
1007         struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
1008
1009         rtnl_addr(hdr);
1010
1011         process_newaddr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
1012                                                 msg, IFA_PAYLOAD(hdr));
1013 }
1014
1015 static void rtnl_deladdr(struct nlmsghdr *hdr)
1016 {
1017         struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
1018
1019         rtnl_addr(hdr);
1020
1021         process_deladdr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
1022                                                 msg, IFA_PAYLOAD(hdr));
1023 }
1024
1025 static void rtnl_route(struct nlmsghdr *hdr)
1026 {
1027         struct rtmsg *msg;
1028         struct rtattr *attr;
1029         int bytes;
1030
1031         msg = (struct rtmsg *) NLMSG_DATA(hdr);
1032         bytes = RTM_PAYLOAD(hdr);
1033
1034         print("rtm_family %d rtm_table %d rtm_protocol %d",
1035                         msg->rtm_family, msg->rtm_table, msg->rtm_protocol);
1036         print("rtm_scope %d rtm_type %d rtm_flags 0x%04x",
1037                                 msg->rtm_scope, msg->rtm_type, msg->rtm_flags);
1038
1039         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
1040                                         attr = RTA_NEXT(attr, bytes)) {
1041                 switch (attr->rta_type) {
1042                 case RTA_DST:
1043                         print_inet(attr, "dst", msg->rtm_family);
1044                         break;
1045                 case RTA_SRC:
1046                         print_inet(attr, "src", msg->rtm_family);
1047                         break;
1048                 case RTA_IIF:
1049                         print_string(attr, "iif");
1050                         break;
1051                 case RTA_OIF:
1052                         print_integer(attr, "oif");
1053                         break;
1054                 case RTA_GATEWAY:
1055                         print_inet(attr, "gateway", msg->rtm_family);
1056                         break;
1057                 case RTA_PRIORITY:
1058                         print_attr(attr, "priority");
1059                         break;
1060                 case RTA_PREFSRC:
1061                         print_inet(attr, "prefsrc", msg->rtm_family);
1062                         break;
1063                 case RTA_METRICS:
1064                         print_attr(attr, "metrics");
1065                         break;
1066                 case RTA_TABLE:
1067                         print_integer(attr, "table");
1068                         break;
1069                 default:
1070                         print_attr(attr, NULL);
1071                         break;
1072                 }
1073         }
1074 }
1075
1076 static connman_bool_t is_route_rtmsg(struct rtmsg *msg)
1077 {
1078
1079         if (msg->rtm_table != RT_TABLE_MAIN)
1080                 return FALSE;
1081
1082         if (msg->rtm_protocol != RTPROT_BOOT &&
1083                         msg->rtm_protocol != RTPROT_KERNEL)
1084                 return FALSE;
1085
1086         if (msg->rtm_type != RTN_UNICAST)
1087                 return FALSE;
1088
1089         return TRUE;
1090 }
1091
1092 static void rtnl_newroute(struct nlmsghdr *hdr)
1093 {
1094         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
1095
1096         rtnl_route(hdr);
1097
1098         if (is_route_rtmsg(msg))
1099                 process_newroute(msg->rtm_family, msg->rtm_scope,
1100                                                 msg, RTM_PAYLOAD(hdr));
1101 }
1102
1103 static void rtnl_delroute(struct nlmsghdr *hdr)
1104 {
1105         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
1106
1107         rtnl_route(hdr);
1108
1109         if (is_route_rtmsg(msg))
1110                 process_delroute(msg->rtm_family, msg->rtm_scope,
1111                                                 msg, RTM_PAYLOAD(hdr));
1112 }
1113
1114 static void *rtnl_nd_opt_rdnss(struct nd_opt_hdr *opt, guint32 *lifetime,
1115                                int *nr_servers)
1116 {
1117         guint32 *optint = (void *)opt;
1118
1119         if (opt->nd_opt_len < 3)
1120                 return NULL;
1121
1122         if (*lifetime > ntohl(optint[1]))
1123                 *lifetime = ntohl(optint[1]);
1124
1125         /* nd_opt_len is in units of 8 bytes. The header is 1 unit (8 bytes)
1126            and each address is another 2 units (16 bytes).
1127            So the number of addresses (given rounding) is nd_opt_len/2 */
1128         *nr_servers = opt->nd_opt_len / 2;
1129
1130         /* And they start 8 bytes into the packet, or two guint32s in. */
1131         return optint + 2;
1132 }
1133
1134 static const char **rtnl_nd_opt_dnssl(struct nd_opt_hdr *opt, guint32 *lifetime)
1135 {
1136         const char **domains = NULL;
1137         guint32 *optint = (void *)opt;
1138         unsigned char *optc = (void *)&optint[2];
1139         int data_len = (opt->nd_opt_len * 8) - 8;
1140         int nr_domains = 0;
1141         int i, tmp;
1142
1143         if (*lifetime > ntohl(optint[1]))
1144                 *lifetime = ntohl(optint[1]);
1145
1146         /* Turn it into normal strings by converting the length bytes into '.',
1147            and count how many search domains there are while we're at it. */
1148         i = 0;
1149         while (i < data_len) {
1150                 if (optc[i] > 0x3f) {
1151                         DBG("DNSSL contains compressed elements in violation of RFC6106");
1152                         return NULL;
1153                 }
1154
1155                 if (optc[i] == 0) {
1156                         nr_domains++;
1157                         i++;
1158                         /* Check for double zero */
1159                         if (i < data_len && optc[i] == 0)
1160                                 break;
1161                         continue;
1162                 }
1163
1164                 tmp = i;
1165                 i += optc[i] + 1;
1166
1167                 if (i >= data_len) {
1168                         DBG("DNSSL data overflows option length");
1169                         return NULL;
1170                 }
1171
1172                 optc[tmp] = '.';
1173         }
1174
1175         domains = g_try_new0(const char *, nr_domains + 1);
1176         if (!domains)
1177                 return NULL;
1178
1179         /* Now point to the normal strings, missing out the leading '.' that
1180            each of them will have now. */
1181         for (i = 0; i < nr_domains; i++) {
1182                 domains[i] = (char *)optc + 1;
1183                 optc += strlen((char *)optc) + 1;
1184         }
1185
1186         return domains;
1187 }
1188
1189 static void rtnl_newnduseropt(struct nlmsghdr *hdr)
1190 {
1191         struct nduseroptmsg *msg = (struct nduseroptmsg *) NLMSG_DATA(hdr);
1192         struct nd_opt_hdr *opt;
1193         guint32 lifetime = -1;
1194         const char **domains = NULL;
1195         struct in6_addr *servers = NULL;
1196         int nr_servers = 0;
1197         int msglen = msg->nduseropt_opts_len;
1198         char *interface;
1199
1200         DBG("family %02x index %x len %04x type %02x code %02x",
1201             msg->nduseropt_family, msg->nduseropt_ifindex,
1202             msg->nduseropt_opts_len, msg->nduseropt_icmp_type,
1203             msg->nduseropt_icmp_code);
1204
1205         if (msg->nduseropt_family != AF_INET6 ||
1206             msg->nduseropt_icmp_type != ND_ROUTER_ADVERT ||
1207             msg->nduseropt_icmp_code != 0)
1208                 return;
1209
1210         interface = connman_inet_ifname(msg->nduseropt_ifindex);
1211         if (!interface)
1212                 return;
1213
1214         for (opt = (void *)&msg[1];
1215              msglen >= 2 && msglen >= opt->nd_opt_len && opt->nd_opt_len;
1216              msglen -= opt->nd_opt_len,
1217                      opt = ((void *)opt) + opt->nd_opt_len*8) {
1218
1219                 DBG("nd opt type %d len %d\n",
1220                     opt->nd_opt_type, opt->nd_opt_len);
1221
1222                 if (opt->nd_opt_type == 25)
1223                         servers = rtnl_nd_opt_rdnss(opt, &lifetime,
1224                                                     &nr_servers);
1225                 else if (opt->nd_opt_type == 31)
1226                         domains = rtnl_nd_opt_dnssl(opt, &lifetime);
1227         }
1228
1229         if (nr_servers) {
1230                 int i, j;
1231                 char buf[40];
1232
1233                 for (i = 0; i < nr_servers; i++) {
1234                         if (!inet_ntop(AF_INET6, servers + i, buf, sizeof(buf)))
1235                                 continue;
1236
1237                         if (domains == NULL || domains[0] == NULL) {
1238                                 connman_resolver_append_lifetime(interface,
1239                                                         NULL, buf, lifetime);
1240                                 continue;
1241                         }
1242
1243                         for (j = 0; domains[j]; j++)
1244                                 connman_resolver_append_lifetime(interface,
1245                                                                 domains[j],
1246                                                                 buf, lifetime);
1247                 }
1248         }
1249         g_free(domains);
1250         g_free(interface);
1251 }
1252
1253 static const char *type2string(uint16_t type)
1254 {
1255         switch (type) {
1256         case NLMSG_NOOP:
1257                 return "NOOP";
1258         case NLMSG_ERROR:
1259                 return "ERROR";
1260         case NLMSG_DONE:
1261                 return "DONE";
1262         case NLMSG_OVERRUN:
1263                 return "OVERRUN";
1264         case RTM_GETLINK:
1265                 return "GETLINK";
1266         case RTM_NEWLINK:
1267                 return "NEWLINK";
1268         case RTM_DELLINK:
1269                 return "DELLINK";
1270         case RTM_NEWADDR:
1271                 return "NEWADDR";
1272         case RTM_DELADDR:
1273                 return "DELADDR";
1274         case RTM_GETROUTE:
1275                 return "GETROUTE";
1276         case RTM_NEWROUTE:
1277                 return "NEWROUTE";
1278         case RTM_DELROUTE:
1279                 return "DELROUTE";
1280         case RTM_NEWNDUSEROPT:
1281                 return "NEWNDUSEROPT";
1282         default:
1283                 return "UNKNOWN";
1284         }
1285 }
1286
1287 static GIOChannel *channel = NULL;
1288
1289 struct rtnl_request {
1290         struct nlmsghdr hdr;
1291         struct rtgenmsg msg;
1292 };
1293 #define RTNL_REQUEST_SIZE  (sizeof(struct nlmsghdr) + sizeof(struct rtgenmsg))
1294
1295 static GSList *request_list = NULL;
1296 static guint32 request_seq = 0;
1297
1298 static struct rtnl_request *find_request(guint32 seq)
1299 {
1300         GSList *list;
1301
1302         for (list = request_list; list; list = list->next) {
1303                 struct rtnl_request *req = list->data;
1304
1305                 if (req->hdr.nlmsg_seq == seq)
1306                         return req;
1307         }
1308
1309         return NULL;
1310 }
1311
1312 static int send_request(struct rtnl_request *req)
1313 {
1314         struct sockaddr_nl addr;
1315         int sk;
1316
1317         DBG("%s len %d type %d flags 0x%04x seq %d",
1318                                 type2string(req->hdr.nlmsg_type),
1319                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1320                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1321
1322         sk = g_io_channel_unix_get_fd(channel);
1323
1324         memset(&addr, 0, sizeof(addr));
1325         addr.nl_family = AF_NETLINK;
1326
1327         return sendto(sk, req, req->hdr.nlmsg_len, 0,
1328                                 (struct sockaddr *) &addr, sizeof(addr));
1329 }
1330
1331 static int queue_request(struct rtnl_request *req)
1332 {
1333         request_list = g_slist_append(request_list, req);
1334
1335         if (g_slist_length(request_list) > 1)
1336                 return 0;
1337
1338         return send_request(req);
1339 }
1340
1341 static int process_response(guint32 seq)
1342 {
1343         struct rtnl_request *req;
1344
1345         DBG("seq %d", seq);
1346
1347         req = find_request(seq);
1348         if (req != NULL) {
1349                 request_list = g_slist_remove(request_list, req);
1350                 g_free(req);
1351         }
1352
1353         req = g_slist_nth_data(request_list, 0);
1354         if (req == NULL)
1355                 return 0;
1356
1357         return send_request(req);
1358 }
1359
1360 static void rtnl_message(void *buf, size_t len)
1361 {
1362         DBG("buf %p len %zd", buf, len);
1363
1364         while (len > 0) {
1365                 struct nlmsghdr *hdr = buf;
1366                 struct nlmsgerr *err;
1367
1368                 if (!NLMSG_OK(hdr, len))
1369                         break;
1370
1371                 DBG("%s len %d type %d flags 0x%04x seq %d pid %d",
1372                                         type2string(hdr->nlmsg_type),
1373                                         hdr->nlmsg_len, hdr->nlmsg_type,
1374                                         hdr->nlmsg_flags, hdr->nlmsg_seq,
1375                                         hdr->nlmsg_pid);
1376
1377                 switch (hdr->nlmsg_type) {
1378                 case NLMSG_NOOP:
1379                 case NLMSG_OVERRUN:
1380                         return;
1381                 case NLMSG_DONE:
1382                         process_response(hdr->nlmsg_seq);
1383                         return;
1384                 case NLMSG_ERROR:
1385                         err = NLMSG_DATA(hdr);
1386                         DBG("error %d (%s)", -err->error,
1387                                                 strerror(-err->error));
1388                         return;
1389                 case RTM_NEWLINK:
1390                         rtnl_newlink(hdr);
1391                         break;
1392                 case RTM_DELLINK:
1393                         rtnl_dellink(hdr);
1394                         break;
1395                 case RTM_NEWADDR:
1396                         rtnl_newaddr(hdr);
1397                         break;
1398                 case RTM_DELADDR:
1399                         rtnl_deladdr(hdr);
1400                         break;
1401                 case RTM_NEWROUTE:
1402                         rtnl_newroute(hdr);
1403                         break;
1404                 case RTM_DELROUTE:
1405                         rtnl_delroute(hdr);
1406                         break;
1407                 case RTM_NEWNDUSEROPT:
1408                         rtnl_newnduseropt(hdr);
1409                         break;
1410                 }
1411
1412                 len -= hdr->nlmsg_len;
1413                 buf += hdr->nlmsg_len;
1414         }
1415 }
1416
1417 static gboolean netlink_event(GIOChannel *chan,
1418                                 GIOCondition cond, gpointer data)
1419 {
1420         unsigned char buf[4096];
1421         struct sockaddr_nl nladdr;
1422         socklen_t addr_len = sizeof(nladdr);
1423         ssize_t status;
1424         int fd;
1425
1426         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1427                 return FALSE;
1428
1429         memset(buf, 0, sizeof(buf));
1430         memset(&nladdr, 0, sizeof(nladdr));
1431
1432         fd = g_io_channel_unix_get_fd(chan);
1433
1434         status = recvfrom(fd, buf, sizeof(buf), 0,
1435                        (struct sockaddr *) &nladdr, &addr_len);
1436         if (status < 0) {
1437                 if (errno == EINTR || errno == EAGAIN)
1438                         return TRUE;
1439
1440                 return FALSE;
1441         }
1442
1443         if (status == 0)
1444                 return FALSE;
1445
1446         if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
1447                 DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
1448                 return TRUE;
1449         }
1450
1451         rtnl_message(buf, status);
1452
1453         return TRUE;
1454 }
1455
1456 static int send_getlink(void)
1457 {
1458         struct rtnl_request *req;
1459
1460         DBG("");
1461
1462         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1463         if (req == NULL)
1464                 return -ENOMEM;
1465
1466         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1467         req->hdr.nlmsg_type = RTM_GETLINK;
1468         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1469         req->hdr.nlmsg_pid = 0;
1470         req->hdr.nlmsg_seq = request_seq++;
1471         req->msg.rtgen_family = AF_INET;
1472
1473         return queue_request(req);
1474 }
1475
1476 static int send_getaddr(void)
1477 {
1478         struct rtnl_request *req;
1479
1480         DBG("");
1481
1482         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1483         if (req == NULL)
1484                 return -ENOMEM;
1485
1486         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1487         req->hdr.nlmsg_type = RTM_GETADDR;
1488         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1489         req->hdr.nlmsg_pid = 0;
1490         req->hdr.nlmsg_seq = request_seq++;
1491         req->msg.rtgen_family = AF_INET;
1492
1493         return queue_request(req);
1494 }
1495
1496 static int send_getroute(void)
1497 {
1498         struct rtnl_request *req;
1499
1500         DBG("");
1501
1502         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1503         if (req == NULL)
1504                 return -ENOMEM;
1505
1506         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1507         req->hdr.nlmsg_type = RTM_GETROUTE;
1508         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1509         req->hdr.nlmsg_pid = 0;
1510         req->hdr.nlmsg_seq = request_seq++;
1511         req->msg.rtgen_family = AF_INET;
1512
1513         return queue_request(req);
1514 }
1515
1516 static gboolean update_timeout_cb(gpointer user_data)
1517 {
1518         __connman_rtnl_request_update();
1519
1520         return TRUE;
1521 }
1522
1523 static void update_interval_callback(guint min)
1524 {
1525         if (update_timeout > 0)
1526                 g_source_remove(update_timeout);
1527
1528         if (min < G_MAXUINT) {
1529                 update_interval = min;
1530                 update_timeout = g_timeout_add_seconds(update_interval,
1531                                                 update_timeout_cb, NULL);
1532         } else {
1533                 update_timeout = 0;
1534                 update_interval = G_MAXUINT;
1535         }
1536 }
1537
1538 static gint compare_interval(gconstpointer a, gconstpointer b)
1539 {
1540         guint val_a = GPOINTER_TO_UINT(a);
1541         guint val_b = GPOINTER_TO_UINT(b);
1542
1543         return val_a - val_b;
1544 }
1545
1546 unsigned int __connman_rtnl_update_interval_add(unsigned int interval)
1547 {
1548         guint min;
1549
1550         if (interval == 0)
1551                 return 0;
1552
1553         update_list = g_slist_insert_sorted(update_list,
1554                         GUINT_TO_POINTER(interval), compare_interval);
1555
1556         min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1557         if (min < update_interval) {
1558                 update_interval_callback(min);
1559                 __connman_rtnl_request_update();
1560         }
1561
1562         return update_interval;
1563 }
1564
1565 unsigned int __connman_rtnl_update_interval_remove(unsigned int interval)
1566 {
1567         guint min = G_MAXUINT;
1568
1569         if (interval == 0)
1570                 return 0;
1571
1572         update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval));
1573
1574         if (update_list != NULL)
1575                 min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1576
1577         if (min > update_interval)
1578                 update_interval_callback(min);
1579
1580         return min;
1581 }
1582
1583 int __connman_rtnl_request_update(void)
1584 {
1585         return send_getlink();
1586 }
1587
1588 int __connman_rtnl_init(void)
1589 {
1590         struct sockaddr_nl addr;
1591         int sk;
1592
1593         DBG("");
1594
1595         interface_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
1596                                                         NULL, free_interface);
1597
1598         sk = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
1599         if (sk < 0)
1600                 return -1;
1601
1602         memset(&addr, 0, sizeof(addr));
1603         addr.nl_family = AF_NETLINK;
1604         addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
1605                                 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE |
1606                                 (1<<(RTNLGRP_ND_USEROPT-1));
1607
1608         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1609                 close(sk);
1610                 return -1;
1611         }
1612
1613         channel = g_io_channel_unix_new(sk);
1614         g_io_channel_set_close_on_unref(channel, TRUE);
1615
1616         g_io_channel_set_encoding(channel, NULL, NULL);
1617         g_io_channel_set_buffered(channel, FALSE);
1618
1619         g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1620                                                         netlink_event, NULL);
1621
1622         return 0;
1623 }
1624
1625 void __connman_rtnl_start(void)
1626 {
1627         DBG("");
1628
1629         send_getlink();
1630         send_getaddr();
1631         send_getroute();
1632 }
1633
1634 void __connman_rtnl_cleanup(void)
1635 {
1636         GSList *list;
1637
1638         DBG("");
1639
1640         for (list = watch_list; list; list = list->next) {
1641                 struct watch_data *watch = list->data;
1642
1643                 DBG("removing watch %d", watch->id);
1644
1645                 g_free(watch);
1646                 list->data = NULL;
1647         }
1648
1649         g_slist_free(watch_list);
1650         watch_list = NULL;
1651
1652         g_slist_free(update_list);
1653         update_list = NULL;
1654
1655         for (list = request_list; list; list = list->next) {
1656                 struct rtnl_request *req = list->data;
1657
1658                 DBG("%s len %d type %d flags 0x%04x seq %d",
1659                                 type2string(req->hdr.nlmsg_type),
1660                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1661                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1662
1663                 g_free(req);
1664                 list->data = NULL;
1665         }
1666
1667         g_slist_free(request_list);
1668         request_list = NULL;
1669
1670         g_io_channel_shutdown(channel, TRUE, NULL);
1671         g_io_channel_unref(channel);
1672
1673         channel = NULL;
1674
1675         g_hash_table_destroy(interface_list);
1676 }