Track IPv6 address changes through rtnl
[platform/upstream/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                 src = &ipv6_address;
572         }
573
574         if (inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN) == NULL)
575                 return;
576
577         __connman_ipconfig_newaddr(index, family, label,
578                                         prefixlen, ip_string);
579 }
580
581 static void process_deladdr(unsigned char family, unsigned char prefixlen,
582                                 int index, struct ifaddrmsg *msg, int bytes)
583 {
584         const char *label = NULL;
585         void *src;
586         char ip_string[INET6_ADDRSTRLEN];
587
588         if (family != AF_INET && family != AF_INET6)
589                 return;
590
591         if (family == AF_INET) {
592                 struct in_addr ipv4_addr = { INADDR_ANY };
593
594                 extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
595                 src = &ipv4_addr;
596         } else if (family == AF_INET6) {
597                 struct in6_addr ipv6_address, ipv6_local;
598
599                 extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
600                 src = &ipv6_address;
601         }
602
603         if (inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN) == NULL)
604                 return;
605
606         __connman_ipconfig_deladdr(index, family, label,
607                                         prefixlen, ip_string);
608 }
609
610 static void extract_route(struct rtmsg *msg, int bytes, int *index,
611                                                 struct in_addr *dst,
612                                                 struct in_addr *gateway)
613 {
614         struct rtattr *attr;
615
616         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
617                                         attr = RTA_NEXT(attr, bytes)) {
618                 switch (attr->rta_type) {
619                 case RTA_DST:
620                         if (dst != NULL)
621                                 *dst = *((struct in_addr *) RTA_DATA(attr));
622                         break;
623                 case RTA_GATEWAY:
624                         if (gateway != NULL)
625                                 *gateway = *((struct in_addr *) RTA_DATA(attr));
626                         break;
627                 case RTA_OIF:
628                         if (index != NULL)
629                                 *index = *((int *) RTA_DATA(attr));
630                         break;
631                 }
632         }
633 }
634
635 static void process_newroute(unsigned char family, unsigned char scope,
636                                                 struct rtmsg *msg, int bytes)
637 {
638         GSList *list;
639         struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
640         char dststr[16], gatewaystr[16];
641         int index = -1;
642
643         if (family != AF_INET)
644                 return;
645
646         extract_route(msg, bytes, &index, &dst, &gateway);
647
648         inet_ntop(family, &dst, dststr, sizeof(dststr));
649         inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
650
651         __connman_ipconfig_newroute(index, scope, dststr, gatewaystr);
652
653         /* skip host specific routes */
654         if (scope != RT_SCOPE_UNIVERSE &&
655                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
656                 return;
657
658         if (dst.s_addr != INADDR_ANY)
659                 return;
660
661         for (list = rtnl_list; list; list = list->next) {
662                 struct connman_rtnl *rtnl = list->data;
663
664                 if (rtnl->newgateway)
665                         rtnl->newgateway(index, gatewaystr);
666         }
667 }
668
669 static void process_delroute(unsigned char family, unsigned char scope,
670                                                 struct rtmsg *msg, int bytes)
671 {
672         GSList *list;
673         struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };
674         char dststr[16], gatewaystr[16];
675         int index = -1;
676
677         if (family != AF_INET)
678                 return;
679
680         extract_route(msg, bytes, &index, &dst, &gateway);
681
682         inet_ntop(family, &dst, dststr, sizeof(dststr));
683         inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
684
685         __connman_ipconfig_delroute(index, scope, dststr, gatewaystr);
686
687         /* skip host specific routes */
688         if (scope != RT_SCOPE_UNIVERSE &&
689                         !(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
690                 return;
691
692         if (dst.s_addr != INADDR_ANY)
693                 return;
694
695         for (list = rtnl_list; list; list = list->next) {
696                 struct connman_rtnl *rtnl = list->data;
697
698                 if (rtnl->delgateway)
699                         rtnl->delgateway(index, gatewaystr);
700         }
701 }
702
703 static inline void print_ether(struct rtattr *attr, const char *name)
704 {
705         int len = (int) RTA_PAYLOAD(attr);
706
707         if (len == ETH_ALEN) {
708                 struct ether_addr eth;
709                 memcpy(&eth, RTA_DATA(attr), ETH_ALEN);
710                 print("  attr %s (len %d) %s\n", name, len, ether_ntoa(&eth));
711         } else
712                 print("  attr %s (len %d)\n", name, len);
713 }
714
715 static inline void print_inet(struct rtattr *attr, const char *name,
716                                                         unsigned char family)
717 {
718         int len = (int) RTA_PAYLOAD(attr);
719
720         if (family == AF_INET && len == sizeof(struct in_addr)) {
721                 struct in_addr addr;
722                 addr = *((struct in_addr *) RTA_DATA(attr));
723                 print("  attr %s (len %d) %s\n", name, len, inet_ntoa(addr));
724         } else
725                 print("  attr %s (len %d)\n", name, len);
726 }
727
728 static inline void print_string(struct rtattr *attr, const char *name)
729 {
730         print("  attr %s (len %d) %s\n", name, (int) RTA_PAYLOAD(attr),
731                                                 (char *) RTA_DATA(attr));
732 }
733
734 static inline void print_byte(struct rtattr *attr, const char *name)
735 {
736         print("  attr %s (len %d) 0x%02x\n", name, (int) RTA_PAYLOAD(attr),
737                                         *((unsigned char *) RTA_DATA(attr)));
738 }
739
740 static inline void print_integer(struct rtattr *attr, const char *name)
741 {
742         print("  attr %s (len %d) %d\n", name, (int) RTA_PAYLOAD(attr),
743                                                 *((int *) RTA_DATA(attr)));
744 }
745
746 static inline void print_attr(struct rtattr *attr, const char *name)
747 {
748         int len = (int) RTA_PAYLOAD(attr);
749
750         if (name && len > 0)
751                 print("  attr %s (len %d)\n", name, len);
752         else
753                 print("  attr %d (len %d)\n", attr->rta_type, len);
754 }
755
756 static void rtnl_link(struct nlmsghdr *hdr)
757 {
758         struct ifinfomsg *msg;
759         struct rtattr *attr;
760         int bytes;
761
762         msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
763         bytes = IFLA_PAYLOAD(hdr);
764
765         print("ifi_index %d ifi_flags 0x%04x", msg->ifi_index, msg->ifi_flags);
766
767         for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
768                                         attr = RTA_NEXT(attr, bytes)) {
769                 switch (attr->rta_type) {
770                 case IFLA_ADDRESS:
771                         print_ether(attr, "address");
772                         break;
773                 case IFLA_BROADCAST:
774                         print_ether(attr, "broadcast");
775                         break;
776                 case IFLA_IFNAME:
777                         print_string(attr, "ifname");
778                         break;
779                 case IFLA_MTU:
780                         print_integer(attr, "mtu");
781                         break;
782                 case IFLA_LINK:
783                         print_attr(attr, "link");
784                         break;
785                 case IFLA_QDISC:
786                         print_attr(attr, "qdisc");
787                         break;
788                 case IFLA_STATS:
789                         print_attr(attr, "stats");
790                         break;
791                 case IFLA_COST:
792                         print_attr(attr, "cost");
793                         break;
794                 case IFLA_PRIORITY:
795                         print_attr(attr, "priority");
796                         break;
797                 case IFLA_MASTER:
798                         print_attr(attr, "master");
799                         break;
800                 case IFLA_WIRELESS:
801                         print_attr(attr, "wireless");
802                         break;
803                 case IFLA_PROTINFO:
804                         print_attr(attr, "protinfo");
805                         break;
806                 case IFLA_TXQLEN:
807                         print_integer(attr, "txqlen");
808                         break;
809                 case IFLA_MAP:
810                         print_attr(attr, "map");
811                         break;
812                 case IFLA_WEIGHT:
813                         print_attr(attr, "weight");
814                         break;
815                 case IFLA_OPERSTATE:
816                         print_byte(attr, "operstate");
817                         break;
818                 case IFLA_LINKMODE:
819                         print_byte(attr, "linkmode");
820                         break;
821                 default:
822                         print_attr(attr, NULL);
823                         break;
824                 }
825         }
826 }
827
828 static void rtnl_newlink(struct nlmsghdr *hdr)
829 {
830         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
831
832         rtnl_link(hdr);
833
834         process_newlink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
835                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
836 }
837
838 static void rtnl_dellink(struct nlmsghdr *hdr)
839 {
840         struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
841
842         rtnl_link(hdr);
843
844         process_dellink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
845                                 msg->ifi_change, msg, IFA_PAYLOAD(hdr));
846 }
847
848 static void rtnl_addr(struct nlmsghdr *hdr)
849 {
850         struct ifaddrmsg *msg;
851         struct rtattr *attr;
852         int bytes;
853
854         msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
855         bytes = IFA_PAYLOAD(hdr);
856
857         print("ifa_family %d ifa_index %d", msg->ifa_family, msg->ifa_index);
858
859         for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
860                                         attr = RTA_NEXT(attr, bytes)) {
861                 switch (attr->rta_type) {
862                 case IFA_ADDRESS:
863                         print_inet(attr, "address", msg->ifa_family);
864                         break;
865                 case IFA_LOCAL:
866                         print_inet(attr, "local", msg->ifa_family);
867                         break;
868                 case IFA_LABEL:
869                         print_string(attr, "label");
870                         break;
871                 case IFA_BROADCAST:
872                         print_inet(attr, "broadcast", msg->ifa_family);
873                         break;
874                 case IFA_ANYCAST:
875                         print_attr(attr, "anycast");
876                         break;
877                 case IFA_CACHEINFO:
878                         print_attr(attr, "cacheinfo");
879                         break;
880                 case IFA_MULTICAST:
881                         print_attr(attr, "multicast");
882                         break;
883                 default:
884                         print_attr(attr, NULL);
885                         break;
886                 }
887         }
888 }
889
890 static void rtnl_newaddr(struct nlmsghdr *hdr)
891 {
892         struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
893
894         rtnl_addr(hdr);
895
896         process_newaddr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
897                                                 msg, IFA_PAYLOAD(hdr));
898 }
899
900 static void rtnl_deladdr(struct nlmsghdr *hdr)
901 {
902         struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
903
904         rtnl_addr(hdr);
905
906         process_deladdr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
907                                                 msg, IFA_PAYLOAD(hdr));
908 }
909
910 static void rtnl_route(struct nlmsghdr *hdr)
911 {
912         struct rtmsg *msg;
913         struct rtattr *attr;
914         int bytes;
915
916         msg = (struct rtmsg *) NLMSG_DATA(hdr);
917         bytes = RTM_PAYLOAD(hdr);
918
919         print("rtm_family %d rtm_table %d rtm_protocol %d",
920                         msg->rtm_family, msg->rtm_table, msg->rtm_protocol);
921         print("rtm_scope %d rtm_type %d rtm_flags 0x%04x",
922                                 msg->rtm_scope, msg->rtm_type, msg->rtm_flags);
923
924         for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
925                                         attr = RTA_NEXT(attr, bytes)) {
926                 switch (attr->rta_type) {
927                 case RTA_DST:
928                         print_inet(attr, "dst", msg->rtm_family);
929                         break;
930                 case RTA_SRC:
931                         print_inet(attr, "src", msg->rtm_family);
932                         break;
933                 case RTA_IIF:
934                         print_string(attr, "iif");
935                         break;
936                 case RTA_OIF:
937                         print_integer(attr, "oif");
938                         break;
939                 case RTA_GATEWAY:
940                         print_inet(attr, "gateway", msg->rtm_family);
941                         break;
942                 case RTA_PRIORITY:
943                         print_attr(attr, "priority");
944                         break;
945                 case RTA_PREFSRC:
946                         print_inet(attr, "prefsrc", msg->rtm_family);
947                         break;
948                 case RTA_METRICS:
949                         print_attr(attr, "metrics");
950                         break;
951                 case RTA_TABLE:
952                         print_integer(attr, "table");
953                         break;
954                 default:
955                         print_attr(attr, NULL);
956                         break;
957                 }
958         }
959 }
960
961 static connman_bool_t is_route_rtmsg(struct rtmsg *msg)
962 {
963
964         if (msg->rtm_table != RT_TABLE_MAIN)
965                 return FALSE;
966
967         if (msg->rtm_protocol != RTPROT_BOOT &&
968                         msg->rtm_protocol != RTPROT_KERNEL)
969                 return FALSE;
970
971         if (msg->rtm_type != RTN_UNICAST)
972                 return FALSE;
973
974         return TRUE;
975 }
976
977 static void rtnl_newroute(struct nlmsghdr *hdr)
978 {
979         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
980
981         rtnl_route(hdr);
982
983         if (is_route_rtmsg(msg))
984                 process_newroute(msg->rtm_family, msg->rtm_scope,
985                                                 msg, RTM_PAYLOAD(hdr));
986 }
987
988 static void rtnl_delroute(struct nlmsghdr *hdr)
989 {
990         struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
991
992         rtnl_route(hdr);
993
994         if (is_route_rtmsg(msg))
995                 process_delroute(msg->rtm_family, msg->rtm_scope,
996                                                 msg, RTM_PAYLOAD(hdr));
997 }
998
999 static const char *type2string(uint16_t type)
1000 {
1001         switch (type) {
1002         case NLMSG_NOOP:
1003                 return "NOOP";
1004         case NLMSG_ERROR:
1005                 return "ERROR";
1006         case NLMSG_DONE:
1007                 return "DONE";
1008         case NLMSG_OVERRUN:
1009                 return "OVERRUN";
1010         case RTM_GETLINK:
1011                 return "GETLINK";
1012         case RTM_NEWLINK:
1013                 return "NEWLINK";
1014         case RTM_DELLINK:
1015                 return "DELLINK";
1016         case RTM_NEWADDR:
1017                 return "NEWADDR";
1018         case RTM_DELADDR:
1019                 return "DELADDR";
1020         case RTM_GETROUTE:
1021                 return "GETROUTE";
1022         case RTM_NEWROUTE:
1023                 return "NEWROUTE";
1024         case RTM_DELROUTE:
1025                 return "DELROUTE";
1026         default:
1027                 return "UNKNOWN";
1028         }
1029 }
1030
1031 static GIOChannel *channel = NULL;
1032
1033 struct rtnl_request {
1034         struct nlmsghdr hdr;
1035         struct rtgenmsg msg;
1036 };
1037 #define RTNL_REQUEST_SIZE  (sizeof(struct nlmsghdr) + sizeof(struct rtgenmsg))
1038
1039 static GSList *request_list = NULL;
1040 static guint32 request_seq = 0;
1041
1042 static struct rtnl_request *find_request(guint32 seq)
1043 {
1044         GSList *list;
1045
1046         for (list = request_list; list; list = list->next) {
1047                 struct rtnl_request *req = list->data;
1048
1049                 if (req->hdr.nlmsg_seq == seq)
1050                         return req;
1051         }
1052
1053         return NULL;
1054 }
1055
1056 static int send_request(struct rtnl_request *req)
1057 {
1058         struct sockaddr_nl addr;
1059         int sk;
1060
1061         DBG("%s len %d type %d flags 0x%04x seq %d",
1062                                 type2string(req->hdr.nlmsg_type),
1063                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1064                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1065
1066         sk = g_io_channel_unix_get_fd(channel);
1067
1068         memset(&addr, 0, sizeof(addr));
1069         addr.nl_family = AF_NETLINK;
1070
1071         return sendto(sk, req, req->hdr.nlmsg_len, 0,
1072                                 (struct sockaddr *) &addr, sizeof(addr));
1073 }
1074
1075 static int queue_request(struct rtnl_request *req)
1076 {
1077         request_list = g_slist_append(request_list, req);
1078
1079         if (g_slist_length(request_list) > 1)
1080                 return 0;
1081
1082         return send_request(req);
1083 }
1084
1085 static int process_response(guint32 seq)
1086 {
1087         struct rtnl_request *req;
1088
1089         DBG("seq %d", seq);
1090
1091         req = find_request(seq);
1092         if (req != NULL) {
1093                 request_list = g_slist_remove(request_list, req);
1094                 g_free(req);
1095         }
1096
1097         req = g_slist_nth_data(request_list, 0);
1098         if (req == NULL)
1099                 return 0;
1100
1101         return send_request(req);
1102 }
1103
1104 static void rtnl_message(void *buf, size_t len)
1105 {
1106         DBG("buf %p len %zd", buf, len);
1107
1108         while (len > 0) {
1109                 struct nlmsghdr *hdr = buf;
1110                 struct nlmsgerr *err;
1111
1112                 if (!NLMSG_OK(hdr, len))
1113                         break;
1114
1115                 DBG("%s len %d type %d flags 0x%04x seq %d",
1116                                         type2string(hdr->nlmsg_type),
1117                                         hdr->nlmsg_len, hdr->nlmsg_type,
1118                                         hdr->nlmsg_flags, hdr->nlmsg_seq);
1119
1120                 switch (hdr->nlmsg_type) {
1121                 case NLMSG_NOOP:
1122                 case NLMSG_OVERRUN:
1123                         return;
1124                 case NLMSG_DONE:
1125                         process_response(hdr->nlmsg_seq);
1126                         return;
1127                 case NLMSG_ERROR:
1128                         err = NLMSG_DATA(hdr);
1129                         DBG("error %d (%s)", -err->error,
1130                                                 strerror(-err->error));
1131                         return;
1132                 case RTM_NEWLINK:
1133                         rtnl_newlink(hdr);
1134                         break;
1135                 case RTM_DELLINK:
1136                         rtnl_dellink(hdr);
1137                         break;
1138                 case RTM_NEWADDR:
1139                         rtnl_newaddr(hdr);
1140                         break;
1141                 case RTM_DELADDR:
1142                         rtnl_deladdr(hdr);
1143                         break;
1144                 case RTM_NEWROUTE:
1145                         rtnl_newroute(hdr);
1146                         break;
1147                 case RTM_DELROUTE:
1148                         rtnl_delroute(hdr);
1149                         break;
1150                 }
1151
1152                 len -= hdr->nlmsg_len;
1153                 buf += hdr->nlmsg_len;
1154         }
1155 }
1156
1157 static gboolean netlink_event(GIOChannel *chan,
1158                                 GIOCondition cond, gpointer data)
1159 {
1160         unsigned char buf[4096];
1161         gsize len;
1162         GIOError err;
1163
1164         if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
1165                 return FALSE;
1166
1167         memset(buf, 0, sizeof(buf));
1168
1169         err = g_io_channel_read(chan, (gchar *) buf, sizeof(buf), &len);
1170         if (err) {
1171                 if (err == G_IO_ERROR_AGAIN)
1172                         return TRUE;
1173                 return FALSE;
1174         }
1175
1176         rtnl_message(buf, len);
1177
1178         return TRUE;
1179 }
1180
1181 static int send_getlink(void)
1182 {
1183         struct rtnl_request *req;
1184
1185         DBG("");
1186
1187         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1188         if (req == NULL)
1189                 return -ENOMEM;
1190
1191         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1192         req->hdr.nlmsg_type = RTM_GETLINK;
1193         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1194         req->hdr.nlmsg_pid = 0;
1195         req->hdr.nlmsg_seq = request_seq++;
1196         req->msg.rtgen_family = AF_INET;
1197
1198         return queue_request(req);
1199 }
1200
1201 static int send_getaddr(void)
1202 {
1203         struct rtnl_request *req;
1204
1205         DBG("");
1206
1207         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1208         if (req == NULL)
1209                 return -ENOMEM;
1210
1211         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1212         req->hdr.nlmsg_type = RTM_GETADDR;
1213         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1214         req->hdr.nlmsg_pid = 0;
1215         req->hdr.nlmsg_seq = request_seq++;
1216         req->msg.rtgen_family = AF_INET;
1217
1218         return queue_request(req);
1219 }
1220
1221 static int send_getroute(void)
1222 {
1223         struct rtnl_request *req;
1224
1225         DBG("");
1226
1227         req = g_try_malloc0(RTNL_REQUEST_SIZE);
1228         if (req == NULL)
1229                 return -ENOMEM;
1230
1231         req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
1232         req->hdr.nlmsg_type = RTM_GETROUTE;
1233         req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
1234         req->hdr.nlmsg_pid = 0;
1235         req->hdr.nlmsg_seq = request_seq++;
1236         req->msg.rtgen_family = AF_INET;
1237
1238         return queue_request(req);
1239 }
1240
1241 static gboolean update_timeout_cb(gpointer user_data)
1242 {
1243         __connman_rtnl_request_update();
1244
1245         return TRUE;
1246 }
1247
1248 static void update_interval_callback(guint min)
1249 {
1250         if (update_timeout > 0)
1251                 g_source_remove(update_timeout);
1252
1253         if (min < G_MAXUINT) {
1254                 update_interval = min;
1255                 update_timeout = g_timeout_add_seconds(update_interval,
1256                                                 update_timeout_cb, NULL);
1257         } else {
1258                 update_timeout = 0;
1259                 update_interval = G_MAXUINT;
1260         }
1261 }
1262
1263 static gint compare_interval(gconstpointer a, gconstpointer b)
1264 {
1265         guint val_a = GPOINTER_TO_UINT(a);
1266         guint val_b = GPOINTER_TO_UINT(b);
1267
1268         return val_a - val_b;
1269 }
1270
1271 unsigned int __connman_rtnl_update_interval_add(unsigned int interval)
1272 {
1273         guint min;
1274
1275         if (interval == 0)
1276                 return 0;
1277
1278         update_list = g_slist_insert_sorted(update_list,
1279                         GUINT_TO_POINTER(interval), compare_interval);
1280
1281         min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1282         if (min < update_interval) {
1283                 update_interval_callback(min);
1284                 __connman_rtnl_request_update();
1285         }
1286
1287         return update_interval;
1288 }
1289
1290 unsigned int __connman_rtnl_update_interval_remove(unsigned int interval)
1291 {
1292         guint min = G_MAXUINT;
1293
1294         if (interval == 0)
1295                 return 0;
1296
1297         update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval));
1298
1299         if (update_list != NULL)
1300                 min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
1301
1302         if (min > update_interval)
1303                 update_interval_callback(min);
1304
1305         return min;
1306 }
1307
1308 int __connman_rtnl_request_update(void)
1309 {
1310         return send_getlink();
1311 }
1312
1313 int __connman_rtnl_init(void)
1314 {
1315         struct sockaddr_nl addr;
1316         int sk;
1317
1318         DBG("");
1319
1320         interface_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
1321                                                         NULL, free_interface);
1322
1323         sk = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
1324         if (sk < 0)
1325                 return -1;
1326
1327         memset(&addr, 0, sizeof(addr));
1328         addr.nl_family = AF_NETLINK;
1329         addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
1330                                 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE;
1331
1332         if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1333                 close(sk);
1334                 return -1;
1335         }
1336
1337         channel = g_io_channel_unix_new(sk);
1338         g_io_channel_set_close_on_unref(channel, TRUE);
1339
1340         g_io_add_watch(channel, G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
1341                                                         netlink_event, NULL);
1342
1343         return 0;
1344 }
1345
1346 void __connman_rtnl_start(void)
1347 {
1348         DBG("");
1349
1350         send_getlink();
1351         send_getaddr();
1352         send_getroute();
1353 }
1354
1355 void __connman_rtnl_cleanup(void)
1356 {
1357         GSList *list;
1358
1359         DBG("");
1360
1361         for (list = watch_list; list; list = list->next) {
1362                 struct watch_data *watch = list->data;
1363
1364                 DBG("removing watch %d", watch->id);
1365
1366                 g_free(watch);
1367                 list->data = NULL;
1368         }
1369
1370         g_slist_free(watch_list);
1371         watch_list = NULL;
1372
1373         g_slist_free(update_list);
1374         update_list = NULL;
1375
1376         for (list = request_list; list; list = list->next) {
1377                 struct rtnl_request *req = list->data;
1378
1379                 DBG("%s len %d type %d flags 0x%04x seq %d",
1380                                 type2string(req->hdr.nlmsg_type),
1381                                 req->hdr.nlmsg_len, req->hdr.nlmsg_type,
1382                                 req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);
1383
1384                 g_free(req);
1385                 list->data = NULL;
1386         }
1387
1388         g_slist_free(request_list);
1389         request_list = NULL;
1390
1391         g_io_channel_shutdown(channel, TRUE, NULL);
1392         g_io_channel_unref(channel);
1393
1394         channel = NULL;
1395
1396         g_hash_table_destroy(interface_list);
1397 }