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