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