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