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