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