/*
 * em_ipset.c		IPset Ematch
 *
 * (C) 2012 Florian Westphal <fw@strlen.de>
 *
 * Parts taken from iptables libxt_set.h:
 * Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
 *                         Patrick Schaaf <bof@bof.de>
 *                         Martin Josefsson <gandalf@wlug.westbo.se>
 * Copyright (C) 2003-2010 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
 *
 * 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.
 */

#include <stdbool.h>
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <getopt.h>

#include <xtables.h>
#include <linux/netfilter/ipset/ip_set.h>

#ifndef IPSET_INVALID_ID
typedef __u16 ip_set_id_t;

enum ip_set_dim {
	IPSET_DIM_ZERO = 0,
	IPSET_DIM_ONE,
	IPSET_DIM_TWO,
	IPSET_DIM_THREE,
	IPSET_DIM_MAX = 6,
};
#endif /* IPSET_INVALID_ID */

#include <linux/netfilter/xt_set.h>
#include "m_ematch.h"

#ifndef IPSET_INVALID_ID
#define IPSET_INVALID_ID	65535
#define SO_IP_SET		83

union ip_set_name_index {
	char name[IPSET_MAXNAMELEN];
	__u16 index;
};

#define IP_SET_OP_GET_BYNAME	0x00000006	/* Get set index by name */
struct ip_set_req_get_set {
	unsigned int op;
	unsigned int version;
	union ip_set_name_index set;
};

#define IP_SET_OP_GET_BYINDEX	0x00000007	/* Get set name by index */
/* Uses ip_set_req_get_set */

#define IP_SET_OP_VERSION	0x00000100	/* Ask kernel version */
struct ip_set_req_version {
	unsigned int op;
	unsigned int version;
};
#endif /* IPSET_INVALID_ID */

extern struct ematch_util ipset_ematch_util;

static int get_version(unsigned int *version)
{
	int res, sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
	struct ip_set_req_version req_version;
	socklen_t size = sizeof(req_version);

	if (sockfd < 0) {
		fputs("Can't open socket to ipset.\n", stderr);
		return -1;
	}

	req_version.op = IP_SET_OP_VERSION;
	res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size);
	if (res != 0) {
		perror("xt_set getsockopt");
		close(sockfd);
		return -1;
	}

	*version = req_version.version;
	return sockfd;
}

static int do_getsockopt(struct ip_set_req_get_set *req)
{
	int sockfd, res;
	socklen_t size = sizeof(struct ip_set_req_get_set);

	sockfd = get_version(&req->version);
	if (sockfd < 0)
		return -1;
	res = getsockopt(sockfd, SOL_IP, SO_IP_SET, req, &size);
	if (res != 0)
		perror("Problem when communicating with ipset");
	close(sockfd);
	if (res != 0)
		return -1;

	if (size != sizeof(struct ip_set_req_get_set)) {
		fprintf(stderr,
			"Incorrect return size from kernel during ipset lookup, (want %zu, got %zu)\n",
			sizeof(struct ip_set_req_get_set), (size_t)size);
		return -1;
	}

	return res;
}

static int
get_set_byid(char *setname, unsigned int idx)
{
	struct ip_set_req_get_set req;
	int res;

	req.op = IP_SET_OP_GET_BYINDEX;
	req.set.index = idx;
	res = do_getsockopt(&req);
	if (res != 0)
		return -1;
	if (req.set.name[0] == '\0') {
		fprintf(stderr,
			"Set with index %i in kernel doesn't exist.\n", idx);
		return -1;
	}

	strncpy(setname, req.set.name, IPSET_MAXNAMELEN);
	return 0;
}

static int
get_set_byname(const char *setname, struct xt_set_info *info)
{
	struct ip_set_req_get_set req;
	int res;

	req.op = IP_SET_OP_GET_BYNAME;
	strlcpy(req.set.name, setname, IPSET_MAXNAMELEN);
	res = do_getsockopt(&req);
	if (res != 0)
		return -1;
	if (req.set.index == IPSET_INVALID_ID)
		return -1;
	info->index = req.set.index;
	return 0;
}

static int
parse_dirs(const char *opt_arg, struct xt_set_info *info)
{
	char *saved = strdup(opt_arg);
	char *ptr, *tmp = saved;

	if (!tmp) {
		perror("strdup");
		return -1;
	}

	while (info->dim < IPSET_DIM_MAX && tmp != NULL) {
		info->dim++;
		ptr = strsep(&tmp, ",");
		if (strncmp(ptr, "src", 3) == 0)
			info->flags |= (1 << info->dim);
		else if (strncmp(ptr, "dst", 3) != 0) {
			fputs("You must specify (the comma separated list of) 'src' or 'dst'\n", stderr);
			free(saved);
			return -1;
		}
	}

	if (tmp)
		fprintf(stderr, "Can't be more src/dst options than %u", IPSET_DIM_MAX);
	free(saved);
	return tmp ? -1 : 0;
}

static void ipset_print_usage(FILE *fd)
{
	fprintf(fd,
	    "Usage: ipset(SETNAME FLAGS)\n" \
	    "where: SETNAME:= string\n" \
	    "       FLAGS  := { FLAG[,FLAGS] }\n" \
	    "       FLAG   := { src | dst }\n" \
	    "\n" \
	    "Example: 'ipset(bulk src,dst)'\n");
}

static int ipset_parse_eopt(struct nlmsghdr *n, struct tcf_ematch_hdr *hdr,
			    struct bstr *args)
{
	struct xt_set_info set_info = {};
	int ret;

#define PARSE_ERR(CARG, FMT, ARGS...) \
	em_parse_error(EINVAL, args, CARG, &ipset_ematch_util, FMT, ##ARGS)

	if (args == NULL)
		return PARSE_ERR(args, "ipset: missing set name");

	if (args->len >= IPSET_MAXNAMELEN)
		return PARSE_ERR(args, "ipset: set name too long (max %u)", IPSET_MAXNAMELEN - 1);
	ret = get_set_byname(args->data, &set_info);
	if (ret < 0)
		return PARSE_ERR(args, "ipset: unknown set name '%s'", args->data);

	if (args->next == NULL)
		return PARSE_ERR(args, "ipset: missing set flags");

	args = bstr_next(args);
	if (parse_dirs(args->data, &set_info))
		return PARSE_ERR(args, "ipset: error parsing set flags");

	if (args->next) {
		args = bstr_next(args);
		return PARSE_ERR(args, "ipset: unknown parameter");
	}

	addraw_l(n, MAX_MSG, hdr, sizeof(*hdr));
	addraw_l(n, MAX_MSG, &set_info, sizeof(set_info));

#undef PARSE_ERR
	return 0;
}

static int ipset_print_eopt(FILE *fd, struct tcf_ematch_hdr *hdr, void *data,
			    int data_len)
{
	int i;
	char setname[IPSET_MAXNAMELEN];
	const struct xt_set_info *set_info = data;

	if (data_len != sizeof(*set_info)) {
		fprintf(stderr, "xt_set_info struct size mismatch\n");
		return -1;
	}

	if (get_set_byid(setname, set_info->index))
		return -1;
	fputs(setname, fd);
	for (i = 1; i <= set_info->dim; i++) {
		fprintf(fd, "%s%s", i == 1 ? " " : ",", set_info->flags & (1 << i) ? "src" : "dst");
	}

	return 0;
}

struct ematch_util ipset_ematch_util = {
	.kind = "ipset",
	.kind_num = TCF_EM_IPSET,
	.parse_eopt = ipset_parse_eopt,
	.print_eopt = ipset_print_eopt,
	.print_usage = ipset_print_usage
};
