/*
 * (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 = 0;

	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)));
		strncat(buf, mask_to_dotted(&(fw.arp.smsk)),
			sizeof(buf) - strlen(buf) - 1);
		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)));
		strncat(buf, mask_to_dotted(&(fw.arp.tmsk)),
			sizeof(buf) - strlen(buf) - 1);
		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,
	.parse_target		= nft_arp_parse_target,
};
