/*
 *
 *  Connection Manager
 *
 *  Copyright (C) 2007-2013  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netinet/ether.h>
#include <netinet/icmp6.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <linux/if.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/wireless.h>

#include <glib.h>

#include "connman.h"

#ifndef ARPHDR_PHONET_PIPE
#define ARPHDR_PHONET_PIPE (821)
#endif

#define print(arg...) do { if (0) connman_info(arg); } while (0)
//#define print(arg...) connman_info(arg)

struct watch_data {
	unsigned int id;
	int index;
	connman_rtnl_link_cb_t newlink;
	void *user_data;
};

static GSList *watch_list = NULL;
static unsigned int watch_id = 0;

static GSList *update_list = NULL;
static guint update_interval = G_MAXUINT;
static guint update_timeout = 0;

struct interface_data {
	int index;
	char *ident;
	enum connman_service_type service_type;
	enum connman_device_type device_type;
};

static GHashTable *interface_list = NULL;

static void free_interface(gpointer data)
{
	struct interface_data *interface = data;

	__connman_technology_remove_interface(interface->service_type,
			interface->index, interface->ident);

	g_free(interface->ident);
	g_free(interface);
}

static bool ether_blacklisted(const char *name)
{
	if (!name)
		return true;

	if (__connman_device_isfiltered(name))
		return true;

	return false;
}

static bool wext_interface(char *ifname)
{
	struct iwreq wrq;
	int fd, err;

	fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
	if (fd < 0)
		return false;

	memset(&wrq, 0, sizeof(wrq));
	strncpy(wrq.ifr_name, ifname, sizeof(wrq.ifr_name) - 1);

	err = ioctl(fd, SIOCGIWNAME, &wrq);

	close(fd);

	if (err < 0)
		return false;

	return true;
}

static void read_uevent(struct interface_data *interface)
{
	char *filename, *name, line[128];
	bool found_devtype;
	FILE *f;

	name = connman_inet_ifname(interface->index);

	if (ether_blacklisted(name)) {
		interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
		interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
	} else {
		interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
		interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
	}

	filename = g_strdup_printf("/sys/class/net/%s/uevent", name);

	f = fopen(filename, "re");

	g_free(filename);

	if (!f) {
		interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
		interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
		goto out;
	}

	found_devtype = false;
	while (fgets(line, sizeof(line), f)) {
		char *pos;

		pos = strchr(line, '\n');
		if (!pos)
			continue;
		pos[0] = '\0';

		if (strncmp(line, "DEVTYPE=", 8) != 0)
			continue;

		found_devtype = true;

		if (strcmp(line + 8, "wlan") == 0) {
			interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
			interface->device_type = CONNMAN_DEVICE_TYPE_WIFI;
		} else if (strcmp(line + 8, "wwan") == 0) {
			interface->service_type = CONNMAN_SERVICE_TYPE_CELLULAR;
			interface->device_type = CONNMAN_DEVICE_TYPE_CELLULAR;
		} else if (strcmp(line + 8, "bluetooth") == 0) {
			interface->service_type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
			interface->device_type = CONNMAN_DEVICE_TYPE_BLUETOOTH;
		} else if (strcmp(line + 8, "gadget") == 0) {
			interface->service_type = CONNMAN_SERVICE_TYPE_GADGET;
			interface->device_type = CONNMAN_DEVICE_TYPE_GADGET;
		} else if (strcmp(line + 8, "vlan") == 0) {
			interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
			interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
		} else if (strcmp(line + 8, "lowpan") == 0) {
			interface->service_type = CONNMAN_SERVICE_TYPE_LOWPAN;
			interface->device_type = CONNMAN_DEVICE_TYPE_LOWPAN;
		} else if (strcmp(line + 8, "lowpan") == 0) {
			interface->service_type = CONNMAN_SERVICE_TYPE_LOWPAN;
			interface->device_type = CONNMAN_DEVICE_TYPE_LOWPAN;
		} else {
			interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
			interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
		}
	}

	fclose(f);

	if (found_devtype)
		goto out;

	/* We haven't got a DEVTYPE, let's check if it's a wireless device */
	if (wext_interface(name)) {
		interface->service_type = CONNMAN_SERVICE_TYPE_WIFI;
		interface->device_type = CONNMAN_DEVICE_TYPE_WIFI;

		connman_error("%s runs an unsupported 802.11 driver", name);
	}

out:
	g_free(name);
}

enum connman_device_type __connman_rtnl_get_device_type(int index)
{
	struct interface_data *interface;

	interface = g_hash_table_lookup(interface_list,
					GINT_TO_POINTER(index));
	if (!interface)
		return CONNMAN_DEVICE_TYPE_UNKNOWN;

	return interface->device_type;
}

/**
 * connman_rtnl_add_newlink_watch:
 * @index: network device index
 * @callback: callback function
 * @user_data: callback data;
 *
 * Add a new RTNL watch for newlink events
 *
 * Returns: %0 on failure and a unique id on success
 */
unsigned int connman_rtnl_add_newlink_watch(int index,
			connman_rtnl_link_cb_t callback, void *user_data)
{
	struct watch_data *watch;

	watch = g_try_new0(struct watch_data, 1);
	if (!watch)
		return 0;

	watch->id = ++watch_id;
	watch->index = index;

	watch->newlink = callback;
	watch->user_data = user_data;

	watch_list = g_slist_prepend(watch_list, watch);

	DBG("id %d", watch->id);

	if (callback) {
		unsigned int flags = __connman_ipconfig_get_flags_from_index(index);

		if (flags > 0)
			callback(flags, 0, user_data);
	}

	return watch->id;
}

/**
 * connman_rtnl_remove_watch:
 * @id: watch identifier
 *
 * Remove the RTNL watch for the identifier
 */
void connman_rtnl_remove_watch(unsigned int id)
{
	GSList *list;

	DBG("id %d", id);

	if (id == 0)
		return;

	for (list = watch_list; list; list = list->next) {
		struct watch_data *watch = list->data;

		if (watch->id  == id) {
			watch_list = g_slist_remove(watch_list, watch);
			g_free(watch);
			break;
		}
	}
}

static void trigger_rtnl(int index, void *user_data)
{
	struct connman_rtnl *rtnl = user_data;

	if (rtnl->newlink) {
		unsigned short type = __connman_ipconfig_get_type_from_index(index);
		unsigned int flags = __connman_ipconfig_get_flags_from_index(index);

		rtnl->newlink(type, index, flags, 0);
	}

	if (rtnl->newgateway) {
		const char *gateway =
			__connman_ipconfig_get_gateway_from_index(index,
					CONNMAN_IPCONFIG_TYPE_ALL);

		if (gateway)
			rtnl->newgateway(index, gateway);
	}
}

static GSList *rtnl_list = NULL;

static gint compare_priority(gconstpointer a, gconstpointer b)
{
	const struct connman_rtnl *rtnl1 = a;
	const struct connman_rtnl *rtnl2 = b;

	return rtnl2->priority - rtnl1->priority;
}

/**
 * connman_rtnl_register:
 * @rtnl: RTNL module
 *
 * Register a new RTNL module
 *
 * Returns: %0 on success
 */
int connman_rtnl_register(struct connman_rtnl *rtnl)
{
	DBG("rtnl %p name %s", rtnl, rtnl->name);

	rtnl_list = g_slist_insert_sorted(rtnl_list, rtnl,
							compare_priority);

	__connman_ipconfig_foreach(trigger_rtnl, rtnl);

	return 0;
}

/**
 * connman_rtnl_unregister:
 * @rtnl: RTNL module
 *
 * Remove a previously registered RTNL module
 */
void connman_rtnl_unregister(struct connman_rtnl *rtnl)
{
	DBG("rtnl %p name %s", rtnl, rtnl->name);

	rtnl_list = g_slist_remove(rtnl_list, rtnl);
}

static const char *operstate2str(unsigned char operstate)
{
	switch (operstate) {
	case IF_OPER_UNKNOWN:
		return "UNKNOWN";
	case IF_OPER_NOTPRESENT:
		return "NOT-PRESENT";
	case IF_OPER_DOWN:
		return "DOWN";
	case IF_OPER_LOWERLAYERDOWN:
		return "LOWER-LAYER-DOWN";
	case IF_OPER_TESTING:
		return "TESTING";
	case IF_OPER_DORMANT:
		return "DORMANT";
	case IF_OPER_UP:
		return "UP";
	}

	return "";
}

static bool extract_link(struct ifinfomsg *msg, int bytes,
				struct ether_addr *address, const char **ifname,
				unsigned int *mtu, unsigned char *operstate,
				struct rtnl_link_stats *stats)
{
	struct rtattr *attr;

	for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
					attr = RTA_NEXT(attr, bytes)) {
		switch (attr->rta_type) {
		case IFLA_ADDRESS:
			if (address)
				memcpy(address, RTA_DATA(attr), ETH_ALEN);
			break;
		case IFLA_IFNAME:
			if (ifname)
				*ifname = RTA_DATA(attr);
			break;
		case IFLA_MTU:
			if (mtu)
				*mtu = *((unsigned int *) RTA_DATA(attr));
			break;
		case IFLA_STATS:
			if (stats)
				memcpy(stats, RTA_DATA(attr),
					sizeof(struct rtnl_link_stats));
			break;
		case IFLA_OPERSTATE:
			if (operstate)
				*operstate = *((unsigned char *) RTA_DATA(attr));
			break;
		case IFLA_LINKMODE:
			break;
		case IFLA_WIRELESS:
			return false;
		}
	}

	return true;
}

static void process_newlink(unsigned short type, int index, unsigned flags,
			unsigned change, struct ifinfomsg *msg, int bytes)
{
	struct ether_addr address = {{ 0, 0, 0, 0, 0, 0 }};
	struct rtnl_link_stats stats;
	unsigned char operstate = 0xff;
	struct interface_data *interface;
	const char *ifname = NULL;
	unsigned int mtu = 0;
	char ident[13], str[18];
	GSList *list;

	memset(&stats, 0, sizeof(stats));
	if (!extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats))
		return;

	snprintf(ident, 13, "%02x%02x%02x%02x%02x%02x",
						address.ether_addr_octet[0],
						address.ether_addr_octet[1],
						address.ether_addr_octet[2],
						address.ether_addr_octet[3],
						address.ether_addr_octet[4],
						address.ether_addr_octet[5]);

	snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
						address.ether_addr_octet[0],
						address.ether_addr_octet[1],
						address.ether_addr_octet[2],
						address.ether_addr_octet[3],
						address.ether_addr_octet[4],
						address.ether_addr_octet[5]);

	if (flags & IFF_SLAVE) {
		connman_info("%s {newlink} ignoring slave, index %d address %s",
						ifname, index, str);
		return;
	}

	switch (type) {
	case ARPHRD_ETHER:
	case ARPHRD_LOOPBACK:
	case ARPHDR_PHONET_PIPE:
	case ARPHRD_PPP:
	case ARPHRD_NONE:
		__connman_ipconfig_newlink(index, type, flags,
							str, mtu, &stats);
		break;
	}

	connman_info("%s {newlink} index %d address %s mtu %u",
					ifname, index, str, mtu);

	if (operstate != 0xff)
		connman_info("%s {newlink} index %d operstate %u <%s>",
						ifname, index, operstate,
						operstate2str(operstate));

	interface = g_hash_table_lookup(interface_list, GINT_TO_POINTER(index));
	if (!interface) {
		interface = g_new0(struct interface_data, 1);
		interface->index = index;
		interface->ident = g_strdup(ident);

		g_hash_table_insert(interface_list,
					GINT_TO_POINTER(index), interface);

		if (type == ARPHRD_ETHER)
			read_uevent(interface);
	} else
		interface = NULL;

	for (list = rtnl_list; list; list = list->next) {
		struct connman_rtnl *rtnl = list->data;

		if (rtnl->newlink)
			rtnl->newlink(type, index, flags, change);
	}

	/*
	 * The interface needs to be added after the newlink call.
	 * The newlink will create the technology when needed and
	 * __connman_technology_add_interface() expects the
	 * technology to be there already.
	 */
	if (interface)
		__connman_technology_add_interface(interface->service_type,
			interface->index, interface->ident);

	for (list = watch_list; list; list = list->next) {
		struct watch_data *watch = list->data;

		if (watch->index != index)
			continue;

		if (watch->newlink)
			watch->newlink(flags, change, watch->user_data);
	}
}

static void process_dellink(unsigned short type, int index, unsigned flags,
			unsigned change, struct ifinfomsg *msg, int bytes)
{
	struct rtnl_link_stats stats;
	unsigned char operstate = 0xff;
	const char *ifname = NULL;
	GSList *list;

	memset(&stats, 0, sizeof(stats));
	if (!extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, &stats))
		return;

	if (operstate != 0xff)
		connman_info("%s {dellink} index %d operstate %u <%s>",
						ifname, index, operstate,
						operstate2str(operstate));

	for (list = rtnl_list; list; list = list->next) {
		struct connman_rtnl *rtnl = list->data;

		if (rtnl->dellink)
			rtnl->dellink(type, index, flags, change);
	}

	switch (type) {
	case ARPHRD_ETHER:
	case ARPHRD_LOOPBACK:
	case ARPHDR_PHONET_PIPE:
	case ARPHRD_PPP:
	case ARPHRD_NONE:
		__connman_ipconfig_dellink(index, &stats);
		break;
	}

	g_hash_table_remove(interface_list, GINT_TO_POINTER(index));
}

static void extract_ipv4_addr(struct ifaddrmsg *msg, int bytes,
						const char **label,
						struct in_addr *local,
						struct in_addr *address,
						struct in_addr *broadcast)
{
	struct rtattr *attr;

	for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
					attr = RTA_NEXT(attr, bytes)) {
		switch (attr->rta_type) {
		case IFA_ADDRESS:
			if (address)
				*address = *((struct in_addr *) RTA_DATA(attr));
			break;
		case IFA_LOCAL:
			if (local)
				*local = *((struct in_addr *) RTA_DATA(attr));
			break;
		case IFA_BROADCAST:
			if (broadcast)
				*broadcast = *((struct in_addr *) RTA_DATA(attr));
			break;
		case IFA_LABEL:
			if (label)
				*label = RTA_DATA(attr);
			break;
		}
	}
}

static void extract_ipv6_addr(struct ifaddrmsg *msg, int bytes,
						struct in6_addr *addr,
						struct in6_addr *local)
{
	struct rtattr *attr;

	for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
					attr = RTA_NEXT(attr, bytes)) {
		switch (attr->rta_type) {
		case IFA_ADDRESS:
			if (addr)
				*addr = *((struct in6_addr *) RTA_DATA(attr));
			break;
		case IFA_LOCAL:
			if (local)
				*local = *((struct in6_addr *) RTA_DATA(attr));
			break;
		}
	}
}

static void process_newaddr(unsigned char family, unsigned char prefixlen,
				int index, struct ifaddrmsg *msg, int bytes)
{
	struct in_addr ipv4_addr = { INADDR_ANY };
	struct in6_addr ipv6_address, ipv6_local;
	const char *label = NULL;
	void *src;
	char ip_string[INET6_ADDRSTRLEN];

	if (family == AF_INET) {

		extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
		src = &ipv4_addr;
	} else if (family == AF_INET6) {
		extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
		if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
			return;

		src = &ipv6_address;
	} else {
		return;
	}

	if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN))
		return;

	if (__connman_ipconfig_newaddr(index, family, label,
					prefixlen, ip_string) >= 0) {
		if (family == AF_INET6) {
			/*
			 * Re-create RDNSS configured servers if there
			 * are any for this interface. This is done
			 * because we might have now properly
			 * configured interface with proper
			 * autoconfigured address.
			 */
			__connman_resolver_redo_servers(index);
		}
	}
}

static void process_deladdr(unsigned char family, unsigned char prefixlen,
				int index, struct ifaddrmsg *msg, int bytes)
{
	struct in_addr ipv4_addr = { INADDR_ANY };
	struct in6_addr ipv6_address, ipv6_local;
	const char *label = NULL;
	void *src;
	char ip_string[INET6_ADDRSTRLEN];

	if (family == AF_INET) {
		extract_ipv4_addr(msg, bytes, &label, &ipv4_addr, NULL, NULL);
		src = &ipv4_addr;
	} else if (family == AF_INET6) {
		extract_ipv6_addr(msg, bytes, &ipv6_address, &ipv6_local);
		if (IN6_IS_ADDR_LINKLOCAL(&ipv6_address))
			return;

		src = &ipv6_address;
	} else {
		return;
	}

	if (!inet_ntop(family, src, ip_string, INET6_ADDRSTRLEN))
		return;

	__connman_ipconfig_deladdr(index, family, label,
					prefixlen, ip_string);
}

static void extract_ipv4_route(struct rtmsg *msg, int bytes, int *index,
						struct in_addr *dst,
						struct in_addr *gateway)
{
	struct rtattr *attr;

	for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
					attr = RTA_NEXT(attr, bytes)) {
		switch (attr->rta_type) {
		case RTA_DST:
			if (dst)
				*dst = *((struct in_addr *) RTA_DATA(attr));
			break;
		case RTA_GATEWAY:
			if (gateway)
				*gateway = *((struct in_addr *) RTA_DATA(attr));
			break;
		case RTA_OIF:
			if (index)
				*index = *((int *) RTA_DATA(attr));
			break;
		}
	}
}

static void extract_ipv6_route(struct rtmsg *msg, int bytes, int *index,
						struct in6_addr *dst,
						struct in6_addr *gateway)
{
	struct rtattr *attr;

	for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
					attr = RTA_NEXT(attr, bytes)) {
		switch (attr->rta_type) {
		case RTA_DST:
			if (dst)
				*dst = *((struct in6_addr *) RTA_DATA(attr));
			break;
		case RTA_GATEWAY:
			if (gateway)
				*gateway =
					*((struct in6_addr *) RTA_DATA(attr));
			break;
		case RTA_OIF:
			if (index)
				*index = *((int *) RTA_DATA(attr));
			break;
		}
	}
}

static void process_newroute(unsigned char family, unsigned char scope,
						struct rtmsg *msg, int bytes)
{
	GSList *list;
	char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
	int index = -1;

	if (family == AF_INET) {
		struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };

		extract_ipv4_route(msg, bytes, &index, &dst, &gateway);

		inet_ntop(family, &dst, dststr, sizeof(dststr));
		inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));

		__connman_ipconfig_newroute(index, family, scope, dststr,
								gatewaystr);

		/* skip host specific routes */
		if (scope != RT_SCOPE_UNIVERSE &&
			!(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
			return;

		if (dst.s_addr != INADDR_ANY)
			return;

	} else if (family == AF_INET6) {
		struct in6_addr dst = IN6ADDR_ANY_INIT,
				gateway = IN6ADDR_ANY_INIT;

		extract_ipv6_route(msg, bytes, &index, &dst, &gateway);

		inet_ntop(family, &dst, dststr, sizeof(dststr));
		inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));

		__connman_ipconfig_newroute(index, family, scope, dststr,
								gatewaystr);

		/* skip host specific routes */
		if (scope != RT_SCOPE_UNIVERSE &&
			!(scope == RT_SCOPE_LINK &&
				IN6_IS_ADDR_UNSPECIFIED(&dst)))
			return;

		if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
			return;
	} else
		return;

	for (list = rtnl_list; list; list = list->next) {
		struct connman_rtnl *rtnl = list->data;

		if (rtnl->newgateway)
			rtnl->newgateway(index, gatewaystr);
	}
}

static void process_delroute(unsigned char family, unsigned char scope,
						struct rtmsg *msg, int bytes)
{
	GSList *list;
	char dststr[INET6_ADDRSTRLEN], gatewaystr[INET6_ADDRSTRLEN];
	int index = -1;

	if (family == AF_INET) {
		struct in_addr dst = { INADDR_ANY }, gateway = { INADDR_ANY };

		extract_ipv4_route(msg, bytes, &index, &dst, &gateway);

		inet_ntop(family, &dst, dststr, sizeof(dststr));
		inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));

		__connman_ipconfig_delroute(index, family, scope, dststr,
								gatewaystr);

		/* skip host specific routes */
		if (scope != RT_SCOPE_UNIVERSE &&
			!(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
			return;

		if (dst.s_addr != INADDR_ANY)
			return;

	}  else if (family == AF_INET6) {
		struct in6_addr dst = IN6ADDR_ANY_INIT,
				gateway = IN6ADDR_ANY_INIT;

		extract_ipv6_route(msg, bytes, &index, &dst, &gateway);

		inet_ntop(family, &dst, dststr, sizeof(dststr));
		inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));

		__connman_ipconfig_delroute(index, family, scope, dststr,
						gatewaystr);

		/* skip host specific routes */
		if (scope != RT_SCOPE_UNIVERSE &&
			!(scope == RT_SCOPE_LINK &&
				IN6_IS_ADDR_UNSPECIFIED(&dst)))
			return;

		if (!IN6_IS_ADDR_UNSPECIFIED(&dst))
			return;
	} else
		return;

	for (list = rtnl_list; list; list = list->next) {
		struct connman_rtnl *rtnl = list->data;

		if (rtnl->delgateway)
			rtnl->delgateway(index, gatewaystr);
	}
}

static inline void print_ether(struct rtattr *attr, const char *name)
{
	int len = (int) RTA_PAYLOAD(attr);

	if (len == ETH_ALEN) {
		struct ether_addr eth;
		memcpy(&eth, RTA_DATA(attr), ETH_ALEN);
		print("  attr %s (len %d) %s\n", name, len, ether_ntoa(&eth));
	} else
		print("  attr %s (len %d)\n", name, len);
}

static inline void print_inet(struct rtattr *attr, const char *name,
							unsigned char family)
{
	int len = (int) RTA_PAYLOAD(attr);

	if (family == AF_INET && len == sizeof(struct in_addr)) {
		struct in_addr addr;
		addr = *((struct in_addr *) RTA_DATA(attr));
		print("  attr %s (len %d) %s\n", name, len, inet_ntoa(addr));
	} else
		print("  attr %s (len %d)\n", name, len);
}

static inline void print_string(struct rtattr *attr, const char *name)
{
	print("  attr %s (len %d) %s\n", name, (int) RTA_PAYLOAD(attr),
						(char *) RTA_DATA(attr));
}

static inline void print_byte(struct rtattr *attr, const char *name)
{
	print("  attr %s (len %d) 0x%02x\n", name, (int) RTA_PAYLOAD(attr),
					*((unsigned char *) RTA_DATA(attr)));
}

static inline void print_integer(struct rtattr *attr, const char *name)
{
	print("  attr %s (len %d) %d\n", name, (int) RTA_PAYLOAD(attr),
						*((int *) RTA_DATA(attr)));
}

static inline void print_attr(struct rtattr *attr, const char *name)
{
	int len = (int) RTA_PAYLOAD(attr);

	if (name && len > 0)
		print("  attr %s (len %d)\n", name, len);
	else
		print("  attr %d (len %d)\n", attr->rta_type, len);
}

static void rtnl_link(struct nlmsghdr *hdr)
{
	struct ifinfomsg *msg;
	struct rtattr *attr;
	int bytes;

	msg = (struct ifinfomsg *) NLMSG_DATA(hdr);
	bytes = IFLA_PAYLOAD(hdr);

	print("ifi_index %d ifi_flags 0x%04x", msg->ifi_index, msg->ifi_flags);

	for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes);
					attr = RTA_NEXT(attr, bytes)) {
		switch (attr->rta_type) {
		case IFLA_ADDRESS:
			print_ether(attr, "address");
			break;
		case IFLA_BROADCAST:
			print_ether(attr, "broadcast");
			break;
		case IFLA_IFNAME:
			print_string(attr, "ifname");
			break;
		case IFLA_MTU:
			print_integer(attr, "mtu");
			break;
		case IFLA_LINK:
			print_attr(attr, "link");
			break;
		case IFLA_QDISC:
			print_attr(attr, "qdisc");
			break;
		case IFLA_STATS:
			print_attr(attr, "stats");
			break;
		case IFLA_COST:
			print_attr(attr, "cost");
			break;
		case IFLA_PRIORITY:
			print_attr(attr, "priority");
			break;
		case IFLA_MASTER:
			print_attr(attr, "master");
			break;
		case IFLA_WIRELESS:
			print_attr(attr, "wireless");
			break;
		case IFLA_PROTINFO:
			print_attr(attr, "protinfo");
			break;
		case IFLA_TXQLEN:
			print_integer(attr, "txqlen");
			break;
		case IFLA_MAP:
			print_attr(attr, "map");
			break;
		case IFLA_WEIGHT:
			print_attr(attr, "weight");
			break;
		case IFLA_OPERSTATE:
			print_byte(attr, "operstate");
			break;
		case IFLA_LINKMODE:
			print_byte(attr, "linkmode");
			break;
		default:
			print_attr(attr, NULL);
			break;
		}
	}
}

static void rtnl_newlink(struct nlmsghdr *hdr)
{
	struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);

	rtnl_link(hdr);

	if (hdr->nlmsg_type == IFLA_WIRELESS)
		connman_warn_once("Obsolete WEXT WiFi driver detected");

	process_newlink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
				msg->ifi_change, msg, IFA_PAYLOAD(hdr));
}

static void rtnl_dellink(struct nlmsghdr *hdr)
{
	struct ifinfomsg *msg = (struct ifinfomsg *) NLMSG_DATA(hdr);

	rtnl_link(hdr);

	process_dellink(msg->ifi_type, msg->ifi_index, msg->ifi_flags,
				msg->ifi_change, msg, IFA_PAYLOAD(hdr));
}

static void rtnl_addr(struct nlmsghdr *hdr)
{
	struct ifaddrmsg *msg;
	struct rtattr *attr;
	int bytes;

	msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);
	bytes = IFA_PAYLOAD(hdr);

	print("ifa_family %d ifa_index %d", msg->ifa_family, msg->ifa_index);

	for (attr = IFA_RTA(msg); RTA_OK(attr, bytes);
					attr = RTA_NEXT(attr, bytes)) {
		switch (attr->rta_type) {
		case IFA_ADDRESS:
			print_inet(attr, "address", msg->ifa_family);
			break;
		case IFA_LOCAL:
			print_inet(attr, "local", msg->ifa_family);
			break;
		case IFA_LABEL:
			print_string(attr, "label");
			break;
		case IFA_BROADCAST:
			print_inet(attr, "broadcast", msg->ifa_family);
			break;
		case IFA_ANYCAST:
			print_attr(attr, "anycast");
			break;
		case IFA_CACHEINFO:
			print_attr(attr, "cacheinfo");
			break;
		case IFA_MULTICAST:
			print_attr(attr, "multicast");
			break;
		default:
			print_attr(attr, NULL);
			break;
		}
	}
}

static void rtnl_newaddr(struct nlmsghdr *hdr)
{
	struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);

	rtnl_addr(hdr);

	process_newaddr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
						msg, IFA_PAYLOAD(hdr));
}

static void rtnl_deladdr(struct nlmsghdr *hdr)
{
	struct ifaddrmsg *msg = (struct ifaddrmsg *) NLMSG_DATA(hdr);

	rtnl_addr(hdr);

	process_deladdr(msg->ifa_family, msg->ifa_prefixlen, msg->ifa_index,
						msg, IFA_PAYLOAD(hdr));
}

static void rtnl_route(struct nlmsghdr *hdr)
{
	struct rtmsg *msg;
	struct rtattr *attr;
	int bytes;

	msg = (struct rtmsg *) NLMSG_DATA(hdr);
	bytes = RTM_PAYLOAD(hdr);

	print("rtm_family %d rtm_table %d rtm_protocol %d",
			msg->rtm_family, msg->rtm_table, msg->rtm_protocol);
	print("rtm_scope %d rtm_type %d rtm_flags 0x%04x",
				msg->rtm_scope, msg->rtm_type, msg->rtm_flags);

	for (attr = RTM_RTA(msg); RTA_OK(attr, bytes);
					attr = RTA_NEXT(attr, bytes)) {
		switch (attr->rta_type) {
		case RTA_DST:
			print_inet(attr, "dst", msg->rtm_family);
			break;
		case RTA_SRC:
			print_inet(attr, "src", msg->rtm_family);
			break;
		case RTA_IIF:
			print_string(attr, "iif");
			break;
		case RTA_OIF:
			print_integer(attr, "oif");
			break;
		case RTA_GATEWAY:
			print_inet(attr, "gateway", msg->rtm_family);
			break;
		case RTA_PRIORITY:
			print_attr(attr, "priority");
			break;
		case RTA_PREFSRC:
			print_inet(attr, "prefsrc", msg->rtm_family);
			break;
		case RTA_METRICS:
			print_attr(attr, "metrics");
			break;
		case RTA_TABLE:
			print_integer(attr, "table");
			break;
		default:
			print_attr(attr, NULL);
			break;
		}
	}
}

static bool is_route_rtmsg(struct rtmsg *msg)
{
	if (msg->rtm_flags & RTM_F_CLONED)
		return false;

	if (msg->rtm_table != RT_TABLE_MAIN)
		return false;

	if (msg->rtm_protocol != RTPROT_BOOT &&
			msg->rtm_protocol != RTPROT_KERNEL)
		return false;

	if (msg->rtm_type != RTN_UNICAST)
		return false;

	return true;
}

static void rtnl_newroute(struct nlmsghdr *hdr)
{
	struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);

	rtnl_route(hdr);

	if (is_route_rtmsg(msg))
		process_newroute(msg->rtm_family, msg->rtm_scope,
						msg, RTM_PAYLOAD(hdr));
}

static void rtnl_delroute(struct nlmsghdr *hdr)
{
	struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);

	rtnl_route(hdr);

	if (is_route_rtmsg(msg))
		process_delroute(msg->rtm_family, msg->rtm_scope,
						msg, RTM_PAYLOAD(hdr));
}

static void *rtnl_nd_opt_rdnss(struct nd_opt_hdr *opt, guint32 *lifetime,
			       int *nr_servers)
{
	guint32 *optint = (void *)opt;

	if (opt->nd_opt_len < 3)
		return NULL;

	if (*lifetime > ntohl(optint[1]))
		*lifetime = ntohl(optint[1]);

	/* nd_opt_len is in units of 8 bytes. The header is 1 unit (8 bytes)
	   and each address is another 2 units (16 bytes).
	   So the number of addresses (given rounding) is nd_opt_len/2 */
	*nr_servers = opt->nd_opt_len / 2;

	/* And they start 8 bytes into the packet, or two guint32s in. */
	return optint + 2;
}

static const char **rtnl_nd_opt_dnssl(struct nd_opt_hdr *opt, guint32 *lifetime)
{
	const char **domains = NULL;
	guint32 *optint = (void *)opt;
	unsigned char *optc = (void *)&optint[2];
	int data_len = (opt->nd_opt_len * 8) - 8;
	int nr_domains = 0;
	int i, tmp;

	if (*lifetime > ntohl(optint[1]))
		*lifetime = ntohl(optint[1]);

	/* Turn it into normal strings by converting the length bytes into '.',
	   and count how many search domains there are while we're at it. */
	i = 0;
	while (i < data_len) {
		if (optc[i] > 0x3f) {
			DBG("DNSSL contains compressed elements in violation of RFC6106");
			return NULL;
		}

		if (optc[i] == 0) {
			nr_domains++;
			i++;
			/* Check for double zero */
			if (i < data_len && optc[i] == 0)
				break;
			continue;
		}

		tmp = i;
		i += optc[i] + 1;

		if (i >= data_len) {
			DBG("DNSSL data overflows option length");
			return NULL;
		}

		optc[tmp] = '.';
	}

	domains = g_try_new0(const char *, nr_domains + 1);
	if (!domains)
		return NULL;

	/* Now point to the normal strings, missing out the leading '.' that
	   each of them will have now. */
	for (i = 0; i < nr_domains; i++) {
		domains[i] = (char *)optc + 1;
		optc += strlen((char *)optc) + 1;
	}

	return domains;
}

static void rtnl_newnduseropt(struct nlmsghdr *hdr)
{
	struct nduseroptmsg *msg = (struct nduseroptmsg *) NLMSG_DATA(hdr);
	struct nd_opt_hdr *opt;
	guint32 lifetime = -1;
	const char **domains = NULL;
	struct in6_addr *servers = NULL;
	int i, nr_servers = 0;
	int msglen = msg->nduseropt_opts_len;
	int index;

	DBG("family %d index %d len %d type %d code %d",
		msg->nduseropt_family, msg->nduseropt_ifindex,
		msg->nduseropt_opts_len, msg->nduseropt_icmp_type,
		msg->nduseropt_icmp_code);

	if (msg->nduseropt_family != AF_INET6 ||
			msg->nduseropt_icmp_type != ND_ROUTER_ADVERT ||
			msg->nduseropt_icmp_code != 0)
		return;

	index = msg->nduseropt_ifindex;
	if (index < 0)
		return;

	for (opt = (void *)&msg[1];
			msglen > 0;
			msglen -= opt->nd_opt_len * 8,
			opt = ((void *)opt) + opt->nd_opt_len*8) {

		DBG("remaining %d nd opt type %d len %d\n",
			msglen, opt->nd_opt_type, opt->nd_opt_len);

		if (opt->nd_opt_type == 25) { /* ND_OPT_RDNSS */
			char buf[40];

			servers = rtnl_nd_opt_rdnss(opt, &lifetime,
								&nr_servers);
			for (i = 0; i < nr_servers; i++) {
				if (!inet_ntop(AF_INET6, servers + i, buf,
								sizeof(buf)))
					continue;

				connman_resolver_append_lifetime(index,
							NULL, buf, lifetime);
			}

		} else if (opt->nd_opt_type == 31) { /* ND_OPT_DNSSL */
			g_free(domains);

			domains = rtnl_nd_opt_dnssl(opt, &lifetime);
			for (i = 0; domains && domains[i]; i++)
				connman_resolver_append_lifetime(index,
						domains[i], NULL, lifetime);
		}
	}

	g_free(domains);
}

static const char *type2string(uint16_t type)
{
	switch (type) {
	case NLMSG_NOOP:
		return "NOOP";
	case NLMSG_ERROR:
		return "ERROR";
	case NLMSG_DONE:
		return "DONE";
	case NLMSG_OVERRUN:
		return "OVERRUN";
	case RTM_GETLINK:
		return "GETLINK";
	case RTM_NEWLINK:
		return "NEWLINK";
	case RTM_DELLINK:
		return "DELLINK";
	case RTM_GETADDR:
		return "GETADDR";
	case RTM_NEWADDR:
		return "NEWADDR";
	case RTM_DELADDR:
		return "DELADDR";
	case RTM_GETROUTE:
		return "GETROUTE";
	case RTM_NEWROUTE:
		return "NEWROUTE";
	case RTM_DELROUTE:
		return "DELROUTE";
	case RTM_NEWNDUSEROPT:
		return "NEWNDUSEROPT";
	default:
		return "UNKNOWN";
	}
}

static GIOChannel *channel = NULL;
static guint channel_watch = 0;

struct rtnl_request {
	struct nlmsghdr hdr;
	struct rtgenmsg msg;
};
#define RTNL_REQUEST_SIZE  (sizeof(struct nlmsghdr) + sizeof(struct rtgenmsg))

static GSList *request_list = NULL;
static guint32 request_seq = 0;

static struct rtnl_request *find_request(guint32 seq)
{
	GSList *list;

	for (list = request_list; list; list = list->next) {
		struct rtnl_request *req = list->data;

		if (req->hdr.nlmsg_seq == seq)
			return req;
	}

	return NULL;
}

static int send_request(struct rtnl_request *req)
{
	struct sockaddr_nl addr;
	int sk;

	DBG("%s len %d type %d flags 0x%04x seq %d",
				type2string(req->hdr.nlmsg_type),
				req->hdr.nlmsg_len, req->hdr.nlmsg_type,
				req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);

	sk = g_io_channel_unix_get_fd(channel);

	memset(&addr, 0, sizeof(addr));
	addr.nl_family = AF_NETLINK;

	return sendto(sk, req, req->hdr.nlmsg_len, 0,
				(struct sockaddr *) &addr, sizeof(addr));
}

static int queue_request(struct rtnl_request *req)
{
	request_list = g_slist_append(request_list, req);

	if (g_slist_length(request_list) > 1)
		return 0;

	return send_request(req);
}

static int process_response(guint32 seq)
{
	struct rtnl_request *req;

	DBG("seq %d", seq);

	req = find_request(seq);
	if (req) {
		request_list = g_slist_remove(request_list, req);
		g_free(req);
	}

	req = g_slist_nth_data(request_list, 0);
	if (!req)
		return 0;

	return send_request(req);
}

static void rtnl_message(void *buf, size_t len)
{
	DBG("buf %p len %zd", buf, len);

	while (len > 0) {
		struct nlmsghdr *hdr = buf;
		struct nlmsgerr *err;

		if (!NLMSG_OK(hdr, len))
			break;

		DBG("%s len %d type %d flags 0x%04x seq %d pid %d",
					type2string(hdr->nlmsg_type),
					hdr->nlmsg_len, hdr->nlmsg_type,
					hdr->nlmsg_flags, hdr->nlmsg_seq,
					hdr->nlmsg_pid);

		switch (hdr->nlmsg_type) {
		case NLMSG_NOOP:
		case NLMSG_OVERRUN:
			return;
		case NLMSG_DONE:
			process_response(hdr->nlmsg_seq);
			return;
		case NLMSG_ERROR:
			err = NLMSG_DATA(hdr);
			DBG("error %d (%s)", -err->error,
						strerror(-err->error));
			return;
		case RTM_NEWLINK:
			rtnl_newlink(hdr);
			break;
		case RTM_DELLINK:
			rtnl_dellink(hdr);
			break;
		case RTM_NEWADDR:
			rtnl_newaddr(hdr);
			break;
		case RTM_DELADDR:
			rtnl_deladdr(hdr);
			break;
		case RTM_NEWROUTE:
			rtnl_newroute(hdr);
			break;
		case RTM_DELROUTE:
			rtnl_delroute(hdr);
			break;
		case RTM_NEWNDUSEROPT:
			rtnl_newnduseropt(hdr);
			break;
		}

		len -= hdr->nlmsg_len;
		buf += hdr->nlmsg_len;
	}
}

static gboolean netlink_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
	unsigned char buf[4096];
	struct sockaddr_nl nladdr;
	socklen_t addr_len = sizeof(nladdr);
	ssize_t status;
	int fd;

	if (cond & (G_IO_NVAL | G_IO_HUP | G_IO_ERR))
		return FALSE;

	memset(buf, 0, sizeof(buf));
	memset(&nladdr, 0, sizeof(nladdr));

	fd = g_io_channel_unix_get_fd(chan);

	status = recvfrom(fd, buf, sizeof(buf), 0,
                       (struct sockaddr *) &nladdr, &addr_len);
	if (status < 0) {
		if (errno == EINTR || errno == EAGAIN)
			return TRUE;

		return FALSE;
	}

	if (status == 0)
		return FALSE;

	if (nladdr.nl_pid != 0) { /* not sent by kernel, ignore */
		DBG("Received msg from %u, ignoring it", nladdr.nl_pid);
		return TRUE;
	}

	rtnl_message(buf, status);

	return TRUE;
}

static int send_getlink(void)
{
	struct rtnl_request *req;

	DBG("");

	req = g_try_malloc0(RTNL_REQUEST_SIZE);
	if (!req)
		return -ENOMEM;

	req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
	req->hdr.nlmsg_type = RTM_GETLINK;
	req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
	req->hdr.nlmsg_pid = 0;
	req->hdr.nlmsg_seq = request_seq++;
	req->msg.rtgen_family = AF_INET;

	return queue_request(req);
}

static int send_getaddr(void)
{
	struct rtnl_request *req;

	DBG("");

	req = g_try_malloc0(RTNL_REQUEST_SIZE);
	if (!req)
		return -ENOMEM;

	req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
	req->hdr.nlmsg_type = RTM_GETADDR;
	req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
	req->hdr.nlmsg_pid = 0;
	req->hdr.nlmsg_seq = request_seq++;
	req->msg.rtgen_family = AF_INET;

	return queue_request(req);
}

static int send_getroute(void)
{
	struct rtnl_request *req;

	DBG("");

	req = g_try_malloc0(RTNL_REQUEST_SIZE);
	if (!req)
		return -ENOMEM;

	req->hdr.nlmsg_len = RTNL_REQUEST_SIZE;
	req->hdr.nlmsg_type = RTM_GETROUTE;
	req->hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
	req->hdr.nlmsg_pid = 0;
	req->hdr.nlmsg_seq = request_seq++;
	req->msg.rtgen_family = AF_INET;

	return queue_request(req);
}

static gboolean update_timeout_cb(gpointer user_data)
{
	__connman_rtnl_request_update();

	return TRUE;
}

static void update_interval_callback(guint min)
{
	if (update_timeout > 0)
		g_source_remove(update_timeout);

	if (min < G_MAXUINT) {
		update_interval = min;
		update_timeout = g_timeout_add_seconds(update_interval,
						update_timeout_cb, NULL);
	} else {
		update_timeout = 0;
		update_interval = G_MAXUINT;
	}
}

static gint compare_interval(gconstpointer a, gconstpointer b)
{
	guint val_a = GPOINTER_TO_UINT(a);
	guint val_b = GPOINTER_TO_UINT(b);

	return val_a - val_b;
}

unsigned int __connman_rtnl_update_interval_add(unsigned int interval)
{
	guint min;

	if (interval == 0)
		return 0;

	update_list = g_slist_insert_sorted(update_list,
			GUINT_TO_POINTER(interval), compare_interval);

	min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));
	if (min < update_interval) {
		update_interval_callback(min);
		__connman_rtnl_request_update();
	}

	return update_interval;
}

unsigned int __connman_rtnl_update_interval_remove(unsigned int interval)
{
	guint min = G_MAXUINT;

	if (interval == 0)
		return 0;

	update_list = g_slist_remove(update_list, GINT_TO_POINTER(interval));

	if (update_list)
		min = GPOINTER_TO_UINT(g_slist_nth_data(update_list, 0));

	if (min > update_interval)
		update_interval_callback(min);

	return min;
}

int __connman_rtnl_request_update(void)
{
	return send_getlink();
}

int __connman_rtnl_init(void)
{
	struct sockaddr_nl addr;
	int sk;

	DBG("");

	interface_list = g_hash_table_new_full(g_direct_hash, g_direct_equal,
							NULL, free_interface);

	sk = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC, NETLINK_ROUTE);
	if (sk < 0)
		return -1;

	memset(&addr, 0, sizeof(addr));
	addr.nl_family = AF_NETLINK;
	addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
				RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE |
				(1<<(RTNLGRP_ND_USEROPT-1));

	if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
		close(sk);
		return -1;
	}

	channel = g_io_channel_unix_new(sk);
	g_io_channel_set_close_on_unref(channel, TRUE);

	g_io_channel_set_encoding(channel, NULL, NULL);
	g_io_channel_set_buffered(channel, FALSE);

	channel_watch = g_io_add_watch(channel,
				G_IO_IN | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
				netlink_event, NULL);

	return 0;
}

void __connman_rtnl_start(void)
{
	DBG("");

	send_getlink();
	send_getaddr();
	send_getroute();
}

void __connman_rtnl_cleanup(void)
{
	GSList *list;

	DBG("");

	for (list = watch_list; list; list = list->next) {
		struct watch_data *watch = list->data;

		DBG("removing watch %d", watch->id);

		g_free(watch);
		list->data = NULL;
	}

	g_slist_free(watch_list);
	watch_list = NULL;

	g_slist_free(update_list);
	update_list = NULL;

	for (list = request_list; list; list = list->next) {
		struct rtnl_request *req = list->data;

		DBG("%s len %d type %d flags 0x%04x seq %d",
				type2string(req->hdr.nlmsg_type),
				req->hdr.nlmsg_len, req->hdr.nlmsg_type,
				req->hdr.nlmsg_flags, req->hdr.nlmsg_seq);

		g_free(req);
		list->data = NULL;
	}

	g_slist_free(request_list);
	request_list = NULL;

	if (channel_watch) {
		g_source_remove(channel_watch);
		channel_watch = 0;
	}

	g_io_channel_shutdown(channel, TRUE, NULL);
	g_io_channel_unref(channel);

	channel = NULL;

	g_hash_table_destroy(interface_list);
}
