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