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