/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* NOTICE: This is a clean room re-implementation of libnl */

#include <malloc.h>
#include <unistd.h>
#include <linux/netlink.h>
#include "netlink-types.h"

/* Allocate a new netlink message with the default maximum payload size. */
struct nl_msg *nlmsg_alloc(void)
{
	/* Whole page will store nl_msg + nlmsghdr + genlmsghdr + payload */
	const int page_sz = getpagesize();
	struct nl_msg *nm;
	struct nlmsghdr *nlh;

	/* Netlink message */
	nm = (struct nl_msg *) malloc(page_sz);
	if (!nm)
		goto fail;

	/* Netlink message header pointer */
	nlh = (struct nlmsghdr *) ((char *) nm + sizeof(struct nl_msg));

	/* Initialize */
	memset(nm, 0, page_sz);
	nm->nm_size = page_sz;

	nm->nm_src.nl_family = AF_NETLINK;
	nm->nm_src.nl_pid = getpid();

	nm->nm_dst.nl_family = AF_NETLINK;
	nm->nm_dst.nl_pid = 0; /* Kernel */

	/* Initialize and add to netlink message */
	nlh->nlmsg_len = NLMSG_HDRLEN;
	nm->nm_nlh = nlh;

	/* Add to reference count and return nl_msg */
	nlmsg_get(nm);
	return nm;
fail:
	return NULL;
}

/* Return pointer to message payload. */
void *nlmsg_data(const struct nlmsghdr *nlh)
{
	return (char *) nlh + NLMSG_HDRLEN;
}

/* Add reference count to nl_msg */
void nlmsg_get(struct nl_msg *nm)
{
	nm->nm_refcnt++;
}

/* Release a reference from an netlink message. */
void nlmsg_free(struct nl_msg *nm)
{
	if (nm) {
		nm->nm_refcnt--;
		if (nm->nm_refcnt <= 0)
			free(nm);
	}

}

/* Return actual netlink message. */
struct nlmsghdr *nlmsg_hdr(struct nl_msg *n)
{
	return n->nm_nlh;
}

/* Return head of attributes data / payload section */
struct nlattr *nlmsg_attrdata(const struct nlmsghdr *nlh, int hdrlen)
{
	unsigned char *data = nlmsg_data(nlh);
	return (struct nlattr *)(data + NLMSG_ALIGN(hdrlen));
}

/* Returns pointer to end of netlink message */
void *nlmsg_tail(const struct nlmsghdr *nlh)
{
	return (void *)((char *)nlh + NLMSG_ALIGN(nlh->nlmsg_len));
}

/* Next netlink message in message stream */
struct nlmsghdr *nlmsg_next(struct nlmsghdr *nlh, int *remaining)
{
	struct nlmsghdr *next_nlh = NULL;
	int len = nlmsg_len(nlh);

	len = NLMSG_ALIGN(len);
	if (*remaining > 0 &&
	    len <= *remaining &&
	    len >= (int) sizeof(struct nlmsghdr)) {
		next_nlh = (struct nlmsghdr *)((char *)nlh + len);
		*remaining -= len;
	}

	return next_nlh;
}

int nlmsg_datalen(const struct nlmsghdr *nlh)
{
	return nlh->nlmsg_len - NLMSG_HDRLEN;
}

/* Length of attributes data */
int nlmsg_attrlen(const struct nlmsghdr *nlh, int hdrlen)
{
	return nlmsg_datalen(nlh) - NLMSG_ALIGN(hdrlen);
}

/* Length of netlink message */
int nlmsg_len(const struct nlmsghdr *nlh)
{
	return nlh->nlmsg_len;
}

/* Check if the netlink message fits into the remaining bytes */
int nlmsg_ok(const struct nlmsghdr *nlh, int rem)
{
	return rem >= (int)sizeof(struct nlmsghdr) &&
		rem >= nlmsg_len(nlh) &&
		nlmsg_len(nlh) >= (int) sizeof(struct nlmsghdr) &&
		nlmsg_len(nlh) <= (rem);
}

int nlmsg_padlen(int payload)
{
	return NLMSG_ALIGN(payload) - payload;
}
