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