/*
 * ll_map.c
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 *
 * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <net/if.h>

#include "libnetlink.h"
#include "ll_map.h"

struct ll_cache
{
	struct ll_cache   *idx_next;
	unsigned	flags;
	int		index;
	unsigned short	type;
	char		name[IFNAMSIZ];
};

#define IDXMAP_SIZE	1024
static struct ll_cache *idx_head[IDXMAP_SIZE];

static inline struct ll_cache *idxhead(int idx)
{
	return idx_head[idx & (IDXMAP_SIZE - 1)];
}

int ll_remember_index(const struct sockaddr_nl *who,
		      struct nlmsghdr *n, void *arg)
{
	int h;
	struct ifinfomsg *ifi = NLMSG_DATA(n);
	struct ll_cache *im, **imp;
	struct rtattr *tb[IFLA_MAX+1];

	if (n->nlmsg_type != RTM_NEWLINK)
		return 0;

	if (n->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
		return -1;

	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n));
	if (tb[IFLA_IFNAME] == NULL)
		return 0;

	h = ifi->ifi_index & (IDXMAP_SIZE - 1);
	for (imp = &idx_head[h]; (im=*imp)!=NULL; imp = &im->idx_next)
		if (im->index == ifi->ifi_index)
			break;

	if (im == NULL) {
		im = malloc(sizeof(*im));
		if (im == NULL)
			return 0;
		im->idx_next = *imp;
		im->index = ifi->ifi_index;
		*imp = im;
	}

	im->type = ifi->ifi_type;
	im->flags = ifi->ifi_flags;
	strcpy(im->name, RTA_DATA(tb[IFLA_IFNAME]));
	return 0;
}

const char *ll_idx_n2a(unsigned idx, char *buf)
{
	const struct ll_cache *im;

	if (idx == 0)
		return "*";

	for (im = idxhead(idx); im; im = im->idx_next)
		if (im->index == idx)
			return im->name;

	snprintf(buf, IFNAMSIZ, "if%d", idx);
	return buf;
}


const char *ll_index_to_name(unsigned idx)
{
	static char nbuf[IFNAMSIZ];

	return ll_idx_n2a(idx, nbuf);
}

int ll_index_to_type(unsigned idx)
{
	const struct ll_cache *im;

	if (idx == 0)
		return -1;
	for (im = idxhead(idx); im; im = im->idx_next)
		if (im->index == idx)
			return im->type;
	return -1;
}

unsigned ll_index_to_flags(unsigned idx)
{
	const struct ll_cache *im;

	if (idx == 0)
		return 0;

	for (im = idxhead(idx); im; im = im->idx_next)
		if (im->index == idx)
			return im->flags;
	return 0;
}

unsigned ll_name_to_index(const char *name)
{
	static char ncache[IFNAMSIZ];
	static int icache;
	struct ll_cache *im;
	int i;
	unsigned idx;

	if (name == NULL)
		return 0;

	if (icache && strcmp(name, ncache) == 0)
		return icache;

	for (i=0; i<IDXMAP_SIZE; i++) {
		for (im = idx_head[i]; im; im = im->idx_next) {
			if (strcmp(im->name, name) == 0) {
				icache = im->index;
				strcpy(ncache, name);
				return im->index;
			}
		}
	}

	idx = if_nametoindex(name);
	if (idx == 0)
		sscanf(name, "if%u", &idx);
	return idx;
}

int ll_init_map(struct rtnl_handle *rth)
{
	static int initialized;

	if (initialized)
		return 0;

	if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) {
		perror("Cannot send dump request");
		exit(1);
	}

	if (rtnl_dump_filter(rth, ll_remember_index, NULL) < 0) {
		fprintf(stderr, "Dump terminated\n");
		exit(1);
	}

	initialized = 1;

	return 0;
}
