/*
 *
 *  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 <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);
}
