/*
 * (C) 2013 by Pablo Neira Ayuso <pablo@netfilter.org>
 * (C) 2013 by Giuseppe Longo <giuseppelng@gmail.com>
 *
 * 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.
 *
 * This code has been sponsored by Sophos Astaro <http://www.sophos.com>
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <net/if_arp.h>

#include <xtables.h>
#include <libiptc/libxtc.h>
#include <net/if_arp.h>
#include <netinet/if_ether.h>

#include <linux/netfilter_arp/arp_tables.h>
#include <linux/netfilter/nf_tables.h>

#include "nft-shared.h"
#include "nft.h"

/* a few names */
char *opcodes[] =
{
	"Request",
	"Reply",
	"Request_Reverse",
	"Reply_Reverse",
	"DRARP_Request",
	"DRARP_Reply",
	"DRARP_Error",
	"InARP_Request",
	"ARP_NAK",
};

static char *
addr_to_dotted(const struct in_addr *addrp)
{
	static char buf[20];
	const unsigned char *bytep;

	bytep = (const unsigned char *) &(addrp->s_addr);
	sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]);
	return buf;
}

static char *
addr_to_host(const struct in_addr *addr)
{
	struct hostent *host;

	if ((host = gethostbyaddr((char *) addr,
					sizeof(struct in_addr), AF_INET)) != NULL)
		return (char *) host->h_name;

	return (char *) NULL;
}

static char *
addr_to_network(const struct in_addr *addr)
{
	struct netent *net;

	if ((net = getnetbyaddr((long) ntohl(addr->s_addr), AF_INET)) != NULL)
		return (char *) net->n_name;

	return (char *) NULL;
}

static char *
addr_to_anyname(const struct in_addr *addr)
{
	char *name;

	if ((name = addr_to_host(addr)) != NULL ||
		(name = addr_to_network(addr)) != NULL)
		return name;

	return addr_to_dotted(addr);
}

static char *
mask_to_dotted(const struct in_addr *mask)
{
	int i;
	static char buf[20];
	u_int32_t maskaddr, bits;

	maskaddr = ntohl(mask->s_addr);

	if (maskaddr == 0xFFFFFFFFL)
		/* we don't want to see "/32" */
		return "";

	i = 32;
	bits = 0xFFFFFFFEL;
	while (--i >= 0 && maskaddr != bits)
		bits <<= 1;
	if (i >= 0)
		sprintf(buf, "/%d", i);
	else
		/* mask was not a decent combination of 1's and 0's */
		sprintf(buf, "/%s", addr_to_dotted(mask));

	return buf;
}

static void print_mac(const unsigned char *mac, int l)
{
	int j;

	for (j = 0; j < l; j++)
		printf("%02x%s", mac[j],
			(j==l-1) ? "" : ":");
}

static void print_mac_and_mask(const unsigned char *mac, const unsigned char *mask, int l)
{
	int i;

	print_mac(mac, l);
	for (i = 0; i < l ; i++)
		if (mask[i] != 255)
			break;
	if (i == l)
		return;
	printf("/");
	print_mac(mask, l);
}

static uint8_t arpt_to_ipt_flags(uint16_t invflags)
{
	uint8_t result = 0;

	if (invflags & ARPT_INV_VIA_IN)
		result |= IPT_INV_VIA_IN;

	if (invflags & ARPT_INV_VIA_OUT)
		result |= IPT_INV_VIA_OUT;

	if (invflags & ARPT_INV_SRCIP)
		result |= IPT_INV_SRCIP;

	if (invflags & ARPT_INV_TGTIP)
		result |= IPT_INV_DSTIP;

	if (invflags & ARPT_INV_ARPPRO)
		result |= IPT_INV_PROTO;

	if (invflags & ARPT_INV_MASK)
		result |= IPT_INV_MASK;

	return result;
}

static int nft_arp_add(struct nft_rule *r, void *data)
{
	struct arpt_entry *fw = data;
	uint8_t flags = arpt_to_ipt_flags(fw->arp.invflags);
	struct xt_entry_target *t;
	char *targname;
	int ret;

	if (fw->arp.iniface[0] != '\0')
		add_iniface(r, fw->arp.iniface, flags);

	if (fw->arp.outiface[0] != '\0')
		add_outiface(r, fw->arp.outiface, flags);

	if (fw->arp.arhrd != 0) {
		add_payload(r, offsetof(struct arphdr, ar_hrd), 2);
		add_cmp_u16(r, fw->arp.arhrd, NFT_CMP_EQ);
	}

	if (fw->arp.arpro != 0) {
	        add_payload(r, offsetof(struct arphdr, ar_pro), 2);
		add_cmp_u16(r, fw->arp.arpro, NFT_CMP_EQ);
	}

	if (fw->arp.arhln != 0)
		add_proto(r, offsetof(struct arphdr, ar_hln), 1,
			  fw->arp.arhln, flags);

	add_proto(r, offsetof(struct arphdr, ar_pln), 1, 4, 0);

	if (fw->arp.arpop != 0) {
		add_payload(r, offsetof(struct arphdr, ar_op), 2);
		add_cmp_u16(r, fw->arp.arpop, NFT_CMP_EQ);
	}

	if (fw->arp.src_devaddr.addr[0] != '\0') {
		add_payload(r, sizeof(struct arphdr), fw->arp.arhln);
		add_cmp_ptr(r, NFT_CMP_EQ, fw->arp.src_devaddr.addr, fw->arp.arhln);
	}

	if (fw->arp.src.s_addr != 0)
		add_addr(r, sizeof(struct arphdr) + fw->arp.arhln,
			 &fw->arp.src.s_addr, 4, flags);

	if (fw->arp.tgt_devaddr.addr[0] != '\0') {
		add_payload(r, sizeof(struct arphdr) + fw->arp.arhln + 4, fw->arp.arhln);
		add_cmp_ptr(r, NFT_CMP_EQ, fw->arp.tgt_devaddr.addr, fw->arp.arhln);
	}

	if (fw->arp.tgt.s_addr != 0)
		add_addr(r, sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr),
			 &fw->arp.tgt.s_addr, 4, flags);

	/* Counters need to me added before the target, otherwise they are
	 * increased for each rule because of the way nf_tables works.
	 */
	if (add_counters(r, fw->counters.pcnt, fw->counters.bcnt) < 0)
		return -1;

	t = nft_arp_get_target(fw);
	targname = t->u.user.name;

	/* Standard target? */
	if (strcmp(targname, XTC_LABEL_ACCEPT) == 0)
		ret = add_verdict(r, NF_ACCEPT);
	else if (strcmp(targname, XTC_LABEL_DROP) == 0)
		ret = add_verdict(r, NF_DROP);
	else if (strcmp(targname, XTC_LABEL_RETURN) == 0)
		ret = add_verdict(r, NFT_RETURN);
	else if (xtables_find_target(targname, XTF_TRY_LOAD) != NULL)
		ret = add_target(r, t);
	else
		ret = add_jumpto(r, targname, NFT_JUMP);

	return ret;
}

static uint16_t ipt_to_arpt_flags(uint8_t invflags)
{
	uint16_t result = 0;

	if (invflags & IPT_INV_VIA_IN)
		result |= ARPT_INV_VIA_IN;

	if (invflags & IPT_INV_VIA_OUT)
		result |= ARPT_INV_VIA_OUT;

	if (invflags & IPT_INV_SRCIP)
		result |= ARPT_INV_SRCIP;

	if (invflags & IPT_INV_DSTIP)
		result |= ARPT_INV_TGTIP;

	if (invflags & IPT_INV_PROTO)
		result |= ARPT_INV_ARPPRO;

	if (invflags & IPT_INV_MASK)
		result |= ARPT_INV_MASK;

	return result;
}

static void nft_arp_parse_meta(struct nft_rule_expr *e, uint8_t key,
			       void *data)
{
	struct arpt_entry *fw = data;
	uint8_t flags;

	parse_meta(e, key, fw->arp.iniface, fw->arp.iniface_mask,
		   fw->arp.outiface, fw->arp.outiface_mask,
		   &flags);

	fw->arp.invflags |= ipt_to_arpt_flags(flags);
}

static void nft_arp_parse_target(struct xtables_target *target, void *data)
{
	struct arpt_entry *fw = data;
	struct xt_entry_target **t;

	fw->target_offset = offsetof(struct arpt_entry, elems);
	fw->next_offset = fw->target_offset + target->t->u.target_size;

	t = (void *) &fw->elems;
	*t = target->t;
}

static void nft_arp_parse_immediate(const char *jumpto, bool nft_goto,
				    void *data)
{
	struct xtables_target *target;
	size_t size;

	target = xtables_find_target(XT_STANDARD_TARGET,
				     XTF_LOAD_MUST_SUCCEED);

	size = XT_ALIGN(sizeof(struct xt_entry_target)) + target->size;

	target->t = xtables_calloc(1, size);
	target->t->u.target_size = size;
	strcpy(target->t->u.user.name, jumpto);
	target->t->u.user.revision = target->revision;

	nft_arp_parse_target(target, data);
}

static void nft_arp_parse_payload(struct nft_rule_expr_iter *iter,
				  uint32_t offset, void *data)
{
	struct arpt_entry *fw = data;
	struct in_addr addr;
	unsigned short int ar_hrd, ar_pro, ar_op, ar_hln;
	bool inv;

	switch (offset) {
	case offsetof(struct arphdr, ar_hrd):
		get_cmp_data(iter, &ar_hrd, sizeof(ar_hrd), &inv);
		fw->arp.arhrd = ar_hrd;
		fw->arp.arhrd_mask = 0xffff;
		if (inv)
			fw->arp.invflags |= ARPT_INV_ARPHRD;
		break;
	case offsetof(struct arphdr, ar_pro):
		get_cmp_data(iter, &ar_pro, sizeof(ar_pro), &inv);
		fw->arp.arpro = ar_pro;
		fw->arp.arpro_mask = 0xffff;
		if (inv)
			fw->arp.invflags |= ARPT_INV_ARPPRO;
		break;
	case offsetof(struct arphdr, ar_op):
		get_cmp_data(iter, &ar_op, sizeof(ar_op), &inv);
		fw->arp.arpop = ar_op;
		fw->arp.arpop_mask = 0xffff;
		if (inv)
			fw->arp.invflags |= ARPT_INV_ARPOP;
		break;
	case offsetof(struct arphdr, ar_hln):
		get_cmp_data(iter, &ar_hln, sizeof(ar_op), &inv);
		fw->arp.arhln = ar_hln;
		fw->arp.arhln_mask = 0xff;
		if (inv)
			fw->arp.invflags |= ARPT_INV_ARPOP;
		break;
	default:
		if (!fw->arp.arhln)
			break;

		if (offset == sizeof(struct arphdr) + fw->arp.arhln) {
			get_cmp_data(iter, &addr, sizeof(addr), &inv);
			fw->arp.src.s_addr = addr.s_addr;
			fw->arp.smsk.s_addr = 0xffffffff;
			if (inv)
				fw->arp.invflags |= ARPT_INV_SRCIP;
		} else if (offset == sizeof(struct arphdr) + fw->arp.arhln + sizeof(struct in_addr)) {
			get_cmp_data(iter, &addr, sizeof(addr), &inv);
			fw->arp.tgt.s_addr = addr.s_addr;
			fw->arp.tmsk.s_addr = 0xffffffff;
			if (inv)
				fw->arp.invflags |= ARPT_INV_TGTIP;
		}
		break;
	}
}

void nft_rule_to_arpt_entry(struct nft_rule *r, struct arpt_entry *fw)
{
	struct nft_rule_expr_iter *iter;
	struct nft_rule_expr *expr;
	int family = nft_rule_attr_get_u8(r, NFT_RULE_ATTR_FAMILY);

	iter = nft_rule_expr_iter_create(r);
	if (iter == NULL)
		return;

	expr = nft_rule_expr_iter_next(iter);
	while (expr != NULL) {
		const char *name =
			nft_rule_expr_get_str(expr, NFT_RULE_EXPR_ATTR_NAME);

		if (strcmp(name, "counter") == 0)
			nft_parse_counter(expr, iter, &fw->counters);
		else if (strcmp(name, "payload") == 0)
			nft_parse_payload(expr, iter, family, fw);
		else if (strcmp(name, "meta") == 0)
			nft_parse_meta(expr, iter, family, fw);
		else if (strcmp(name, "immediate") == 0)
			nft_parse_immediate(expr, iter, family, fw);
		else if (strcmp(name, "target") == 0)
			nft_parse_target(expr, iter, family, fw);

		expr = nft_rule_expr_iter_next(iter);
	}

	nft_rule_expr_iter_destroy(iter);
}

static void
nft_arp_print_firewall(struct nft_rule *r, unsigned int num,
		       unsigned int format)
{
	struct arpt_entry fw = {};
	const char *targname;
	struct xtables_target *target = NULL;
	const struct xt_entry_target *t;
	char buf[BUFSIZ];
	int i;
	char iface[IFNAMSIZ+2];
	int print_iface = 0;

	nft_rule_to_arpt_entry(r, &fw);

	if (format & FMT_LINENUMBERS)
		printf("%u ", num);

	if (fw.target_offset) {
		t = nft_arp_get_target(&fw);
		targname = t->u.user.name;
		target = xtables_find_target(targname, XTF_TRY_LOAD);
		if (!(format & FMT_NOTARGET))
			printf("-j %s ", targname);
	}

	iface[0] = '\0';

	if (fw.arp.iniface[0] != '\0') {
		strcat(iface, fw.arp.iniface);
		print_iface = 1;
	}
	else if (format & FMT_VIA) {
		print_iface = 1;
		if (format & FMT_NUMERIC) strcat(iface, "*");
		else strcat(iface, "any");
	}
	if (print_iface)
		printf("%s-i %s ", fw.arp.invflags & ARPT_INV_VIA_IN ? "! ": "", iface);

	print_iface = 0;
	iface[0] = '\0';

	if (fw.arp.outiface[0] != '\0') {
		strcat(iface, fw.arp.outiface);
		print_iface = 1;
	}
	else if (format & FMT_VIA) {
		print_iface = 1;
		if (format & FMT_NUMERIC) strcat(iface, "*");
		else strcat(iface, "any");
	}
	if (print_iface)
		printf("%s-o %s ", fw.arp.invflags & ARPT_INV_VIA_OUT ? "! " : "", iface);

	if (fw.arp.smsk.s_addr != 0L) {
		printf("%s", fw.arp.invflags & ARPT_INV_SRCIP
			? "! " : "");
		if (format & FMT_NUMERIC)
			sprintf(buf, "%s", addr_to_dotted(&(fw.arp.src)));
		else
			sprintf(buf, "%s", addr_to_anyname(&(fw.arp.src)));
		strcat(buf, mask_to_dotted(&(fw.arp.smsk)));
		printf("-s %s ", buf);
	}

	for (i = 0; i < ARPT_DEV_ADDR_LEN_MAX; i++)
		if (fw.arp.src_devaddr.mask[i] != 0)
			break;
	if (i == ARPT_DEV_ADDR_LEN_MAX)
		goto after_devsrc;
	printf("%s", fw.arp.invflags & ARPT_INV_SRCDEVADDR
		? "! " : "");
	printf("--src-mac ");
	print_mac_and_mask((unsigned char *)fw.arp.src_devaddr.addr,
		(unsigned char *)fw.arp.src_devaddr.mask, ETH_ALEN);
	printf(" ");
after_devsrc:

	if (fw.arp.tmsk.s_addr != 0L) {
		printf("%s",fw.arp.invflags & ARPT_INV_TGTIP
			? "! " : "");
		if (format & FMT_NUMERIC)
			sprintf(buf, "%s", addr_to_dotted(&(fw.arp.tgt)));
		else
			sprintf(buf, "%s", addr_to_anyname(&(fw.arp.tgt)));
		strcat(buf, mask_to_dotted(&(fw.arp.tmsk)));
		printf("-d %s ", buf);
	}

	for (i = 0; i <ARPT_DEV_ADDR_LEN_MAX; i++)
		if (fw.arp.tgt_devaddr.mask[i] != 0)
			break;
	if (i == ARPT_DEV_ADDR_LEN_MAX)
		goto after_devdst;
	printf("%s",fw.arp.invflags & ARPT_INV_TGTDEVADDR
		? "! " : "");
	printf("--dst-mac ");
	print_mac_and_mask((unsigned char *)fw.arp.tgt_devaddr.addr,
		(unsigned char *)fw.arp.tgt_devaddr.mask, ETH_ALEN);
	printf(" ");
after_devdst:

	if (fw.arp.arhln_mask != 0) {
		printf("%s",fw.arp.invflags & ARPT_INV_ARPHLN
			? "! " : "");
		printf("--h-length %d", fw.arp.arhln);
		if (fw.arp.arhln_mask != 255)
			printf("/%d", fw.arp.arhln_mask);
		printf(" ");
	}

	if (fw.arp.arpop_mask != 0) {
		int tmp = ntohs(fw.arp.arpop);

		printf("%s",fw.arp.invflags & ARPT_INV_ARPOP
			? "! " : "");
		if (tmp <= NUMOPCODES && !(format & FMT_NUMERIC))
			printf("--opcode %s", opcodes[tmp-1]);
		else
			printf("--opcode %d", tmp);
		if (fw.arp.arpop_mask != 65535)
			printf("/%d", ntohs(fw.arp.arpop_mask));
		printf(" ");
	}

	if (fw.arp.arhrd_mask != 0) {
		uint16_t tmp = ntohs(fw.arp.arhrd);

		printf("%s", fw.arp.invflags & ARPT_INV_ARPHRD
			? "! " : "");
		if (tmp == 1 && !(format & FMT_NUMERIC))
			printf("--h-type %s", "Ethernet");
		else
			printf("--h-type %u", tmp);
		if (fw.arp.arhrd_mask != 65535)
			printf("/%d", ntohs(fw.arp.arhrd_mask));
		printf(" ");
	}

	if (fw.arp.arpro_mask != 0) {
		int tmp = ntohs(fw.arp.arpro);

		printf("%s", fw.arp.invflags & ARPT_INV_ARPPRO
			? "! " : "");
		if (tmp == 0x0800 && !(format & FMT_NUMERIC))
			printf("--proto-type %s", "IPv4");
		else
			printf("--proto-type 0x%x", tmp);
		if (fw.arp.arpro_mask != 65535)
			printf("/%x", ntohs(fw.arp.arpro_mask));
		printf(" ");
	}

	if (target) {
		if (target->print)
			/* Print the target information. */
			target->print(&fw.arp, t, format & FMT_NUMERIC);
	}

	if (!(format & FMT_NOCOUNTS)) {
		printf(", pcnt=");
		xtables_print_num(fw.counters.pcnt, format);
		printf("-- bcnt=");
		xtables_print_num(fw.counters.bcnt, format);
	}

	if (!(format & FMT_NONEWLINE))
		fputc('\n', stdout);
}

static bool nft_arp_is_same(const void *data_a,
			    const void *data_b)
{
	const struct arpt_entry *a = data_a;
	const struct arpt_entry *b = data_b;

	if (a->arp.src.s_addr != b->arp.src.s_addr
	    || a->arp.tgt.s_addr != b->arp.tgt.s_addr
	    || a->arp.smsk.s_addr != b->arp.tmsk.s_addr
	    || a->arp.arpro != b->arp.arpro
	    || a->arp.flags != b->arp.flags
	    || a->arp.invflags != b->arp.invflags) {
		DEBUGP("different src/dst/proto/flags/invflags\n");
		return false;
	}

	return is_same_interfaces(a->arp.src_devaddr.addr,
				  a->arp.tgt_devaddr.addr,
				  (unsigned char*)a->arp.src_devaddr.mask,
				  (unsigned char*)a->arp.tgt_devaddr.mask,
				  b->arp.src_devaddr.addr,
				  a->arp.tgt_devaddr.addr,
				  (unsigned char*)b->arp.src_devaddr.mask,
				  (unsigned char*)b->arp.tgt_devaddr.mask);
}

static bool nft_arp_rule_find(struct nft_family_ops *ops, struct nft_rule *r,
			      void *data)
{
	struct arpt_entry *fw = data;
	struct xt_entry_target *t_fw, *t_this;
	char *targname_fw, *targname_this;
	struct arpt_entry this = {};

	/* Delete by matching rule case */
	nft_rule_to_arpt_entry(r, &this);

	if (!ops->is_same(fw, &this))
		return false;

	t_fw = nft_arp_get_target(fw);
	t_this = nft_arp_get_target(&this);

	targname_fw = t_fw->u.user.name;
	targname_this = t_this->u.user.name;

	if (!strcmp(targname_fw, targname_this) &&
	    (!strcmp(targname_fw, "mangle") ||
	    !strcmp(targname_fw, "CLASSIFY"))) {
		if (memcmp(t_fw->data, t_this->data,
		    t_fw->u.user.target_size - sizeof(*t_fw)) != 0) {
			DEBUGP("Different target\n");
			return false;
		}
		return true;
	}

	if (strcmp(targname_fw, targname_this) != 0) {
		DEBUGP("Different verdict\n");
		return false;
	}

	return true;
}

struct nft_family_ops nft_family_ops_arp = {
	.add			= nft_arp_add,
	.is_same		= nft_arp_is_same,
	.print_payload		= NULL,
	.parse_meta		= nft_arp_parse_meta,
	.parse_payload		= nft_arp_parse_payload,
	.parse_immediate	= nft_arp_parse_immediate,
	.print_firewall		= nft_arp_print_firewall,
	.post_parse		= NULL,
	.rule_find		= nft_arp_rule_find,
};
