/* vi: set sw=4 ts=4: */
/*
 * 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>
 *
 * Changes:
 *
 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
 * initially integrated into busybox by Bernhard Reutner-Fischer
 */

#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>

#include "ip_common.h"  /* #include "libbb.h" is inside */
#include "rt_names.h"
#include "utils.h"

/*
static void usage(void) __attribute__((noreturn));

static void usage(void)
{
	fprintf(stderr, "Usage: ip rule [ list | add | del ] SELECTOR ACTION\n");
	fprintf(stderr, "SELECTOR := [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK ]\n");
	fprintf(stderr, "            [ dev STRING ] [ pref NUMBER ]\n");
	fprintf(stderr, "ACTION := [ table TABLE_ID ] [ nat ADDRESS ]\n");
	fprintf(stderr, "          [ prohibit | reject | unreachable ]\n");
	fprintf(stderr, "          [ realms [SRCREALM/]DSTREALM ]\n");
	fprintf(stderr, "TABLE_ID := [ local | main | default | NUMBER ]\n");
	exit(-1);
}
*/

static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
					struct nlmsghdr *n, void *arg UNUSED_PARAM)
{
	struct rtmsg *r = NLMSG_DATA(n);
	int len = n->nlmsg_len;
	int host_len = -1;
	struct rtattr * tb[RTA_MAX+1];

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

	len -= NLMSG_LENGTH(sizeof(*r));
	if (len < 0)
		return -1;

	memset(tb, 0, sizeof(tb));
	parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);

	if (r->rtm_family == AF_INET)
		host_len = 32;
	else if (r->rtm_family == AF_INET6)
		host_len = 128;
/*	else if (r->rtm_family == AF_DECnet)
		host_len = 16;
	else if (r->rtm_family == AF_IPX)
		host_len = 80;
*/
	printf("%u:\t", tb[RTA_PRIORITY] ?
					*(unsigned*)RTA_DATA(tb[RTA_PRIORITY])
					: 0);
	printf("from ");
	if (tb[RTA_SRC]) {
		if (r->rtm_src_len != host_len) {
			printf("%s/%u",
				rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_SRC])),
				r->rtm_src_len
			);
		} else {
			fputs(format_host(r->rtm_family,
						RTA_PAYLOAD(tb[RTA_SRC]),
						RTA_DATA(tb[RTA_SRC])),
				stdout
			);
		}
	} else if (r->rtm_src_len) {
		printf("0/%d", r->rtm_src_len);
	} else {
		printf("all");
	}
	bb_putchar(' ');

	if (tb[RTA_DST]) {
		if (r->rtm_dst_len != host_len) {
			printf("to %s/%u ", rt_addr_n2a(r->rtm_family,
							 RTA_DATA(tb[RTA_DST])),
				r->rtm_dst_len
				);
		} else {
			printf("to %s ", format_host(r->rtm_family,
						       RTA_PAYLOAD(tb[RTA_DST]),
						       RTA_DATA(tb[RTA_DST])));
		}
	} else if (r->rtm_dst_len) {
		printf("to 0/%d ", r->rtm_dst_len);
	}

	if (r->rtm_tos) {
		printf("tos %s ", rtnl_dsfield_n2a(r->rtm_tos));
	}
	if (tb[RTA_PROTOINFO]) {
		printf("fwmark %#x ", *(uint32_t*)RTA_DATA(tb[RTA_PROTOINFO]));
	}

	if (tb[RTA_IIF]) {
		printf("iif %s ", (char*)RTA_DATA(tb[RTA_IIF]));
	}

	if (r->rtm_table)
		printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table));

	if (tb[RTA_FLOW]) {
		uint32_t to = *(uint32_t*)RTA_DATA(tb[RTA_FLOW]);
		uint32_t from = to>>16;
		to &= 0xFFFF;
		if (from) {
			printf("realms %s/",
				rtnl_rtrealm_n2a(from));
		}
		printf("%s ",
			rtnl_rtrealm_n2a(to));
	}

	if (r->rtm_type == RTN_NAT) {
		if (tb[RTA_GATEWAY]) {
			printf("map-to %s ",
				format_host(r->rtm_family,
					    RTA_PAYLOAD(tb[RTA_GATEWAY]),
					    RTA_DATA(tb[RTA_GATEWAY]))
			);
		} else
			printf("masquerade");
	} else if (r->rtm_type != RTN_UNICAST)
		fputs(rtnl_rtntype_n2a(r->rtm_type), stdout);

	bb_putchar('\n');
	/*fflush_all();*/
	return 0;
}

/* Return value becomes exitcode. It's okay to not return at all */
static int iprule_list(char **argv)
{
	struct rtnl_handle rth;
	int af = preferred_family;

	if (af == AF_UNSPEC)
		af = AF_INET;

	if (*argv) {
		//bb_error_msg("\"rule show\" needs no arguments");
		bb_warn_ignoring_args(*argv);
		return -1;
	}

	xrtnl_open(&rth);

	xrtnl_wilddump_request(&rth, af, RTM_GETRULE);
	xrtnl_dump_filter(&rth, print_rule, NULL);

	return 0;
}

/* Return value becomes exitcode. It's okay to not return at all */
static int iprule_modify(int cmd, char **argv)
{
	static const char keywords[] ALIGN1 =
		"from\0""to\0""preference\0""order\0""priority\0"
		"tos\0""fwmark\0""realms\0""table\0""lookup\0""dev\0"
		"iif\0""nat\0""map-to\0""type\0""help\0";
	enum {
		ARG_from = 1, ARG_to, ARG_preference, ARG_order, ARG_priority,
		ARG_tos, ARG_fwmark, ARG_realms, ARG_table, ARG_lookup, ARG_dev,
		ARG_iif, ARG_nat, ARG_map_to, ARG_type, ARG_help
	};
	bool table_ok = 0;
	struct rtnl_handle rth;
	struct {
		struct nlmsghdr n;
		struct rtmsg    r;
		char            buf[1024];
	} req;
	smalluint key;

	memset(&req, 0, sizeof(req));

	req.n.nlmsg_type = cmd;
	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
	req.n.nlmsg_flags = NLM_F_REQUEST;
	req.r.rtm_family = preferred_family;
	req.r.rtm_protocol = RTPROT_BOOT;
	if (RT_SCOPE_UNIVERSE != 0)
		req.r.rtm_scope = RT_SCOPE_UNIVERSE;
	/*req.r.rtm_table = 0; - already is */
	if (RTN_UNSPEC != 0)
		req.r.rtm_type = RTN_UNSPEC;

	if (cmd == RTM_NEWRULE) {
		req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL;
		req.r.rtm_type = RTN_UNICAST;
	}

	while (*argv) {
		key = index_in_substrings(keywords, *argv) + 1;
		if (key == 0) /* no match found in keywords array, bail out. */
			invarg_1_to_2(*argv, applet_name);
		if (key == ARG_from) {
			inet_prefix dst;
			NEXT_ARG();
			get_prefix(&dst, *argv, req.r.rtm_family);
			req.r.rtm_src_len = dst.bitlen;
			addattr_l(&req.n, sizeof(req), RTA_SRC, &dst.data, dst.bytelen);
		} else if (key == ARG_to) {
			inet_prefix dst;
			NEXT_ARG();
			get_prefix(&dst, *argv, req.r.rtm_family);
			req.r.rtm_dst_len = dst.bitlen;
			addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen);
		} else if (key == ARG_preference ||
			   key == ARG_order ||
			   key == ARG_priority
		) {
			uint32_t pref;
			NEXT_ARG();
			pref = get_u32(*argv, "preference");
			addattr32(&req.n, sizeof(req), RTA_PRIORITY, pref);
		} else if (key == ARG_tos) {
			uint32_t tos;
			NEXT_ARG();
			if (rtnl_dsfield_a2n(&tos, *argv))
				invarg_1_to_2(*argv, "TOS");
			req.r.rtm_tos = tos;
		} else if (key == ARG_fwmark) {
			uint32_t fwmark;
			NEXT_ARG();
			fwmark = get_u32(*argv, "fwmark");
			addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark);
		} else if (key == ARG_realms) {
			uint32_t realm;
			NEXT_ARG();
			if (get_rt_realms(&realm, *argv))
				invarg_1_to_2(*argv, "realms");
			addattr32(&req.n, sizeof(req), RTA_FLOW, realm);
		} else if (key == ARG_table ||
			   key == ARG_lookup
		) {
			uint32_t tid;
			NEXT_ARG();
			if (rtnl_rttable_a2n(&tid, *argv))
				invarg_1_to_2(*argv, "table ID");
			req.r.rtm_table = tid;
			table_ok = 1;
		} else if (key == ARG_dev ||
			   key == ARG_iif
		) {
			NEXT_ARG();
			addattr_l(&req.n, sizeof(req), RTA_IIF, *argv, strlen(*argv)+1);
		} else if (key == ARG_nat ||
			   key == ARG_map_to
		) {
			NEXT_ARG();
			addattr32(&req.n, sizeof(req), RTA_GATEWAY, get_addr32(*argv));
			req.r.rtm_type = RTN_NAT;
		} else {
			int type;

			if (key == ARG_type) {
				NEXT_ARG();
			}
			if (key == ARG_help)
				bb_show_usage();
			if (rtnl_rtntype_a2n(&type, *argv))
				invarg_1_to_2(*argv, "type");
			req.r.rtm_type = type;
		}
		argv++;
	}

	if (req.r.rtm_family == AF_UNSPEC)
		req.r.rtm_family = AF_INET;

	if (!table_ok && cmd == RTM_NEWRULE)
		req.r.rtm_table = RT_TABLE_MAIN;

	xrtnl_open(&rth);

	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
		return 2;

	return 0;
}

/* Return value becomes exitcode. It's okay to not return at all */
int FAST_FUNC do_iprule(char **argv)
{
	static const char ip_rule_commands[] ALIGN1 =
		"add\0""delete\0""list\0""show\0";
	if (*argv) {
		int cmd = index_in_substrings(ip_rule_commands, *argv);
		if (cmd < 0)
			invarg_1_to_2(*argv, applet_name);
		argv++;
		if (cmd < 2)
			return iprule_modify((cmd == 0) ? RTM_NEWRULE : RTM_DELRULE, argv);
	}
	return iprule_list(argv);
}
