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