/*
 * f_tcindex.c		Traffic control index filter
 *
 * Written 1998,1999 by Werner Almesberger
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <string.h>
#include <netinet/in.h>

#include "utils.h"
#include "tc_util.h"

static void explain(void)
{
	fprintf(stderr," Usage: ... tcindex [ hash SIZE ] [ mask MASK ] [ shift SHIFT ]\n");
	fprintf(stderr, "                    [ pass_on | fall_through ]\n");
	fprintf(stderr,"                    [ classid CLASSID ] [ action ACTION_SPEC ]\n");
}

static int tcindex_parse_opt(struct filter_util *qu, char *handle, int argc,
			     char **argv, struct nlmsghdr *n)
{
	struct tcmsg *t = NLMSG_DATA(n);
	struct rtattr *tail;
	char *end;

	if (handle) {
		t->tcm_handle = strtoul(handle, &end, 0);
		if (*end) {
			fprintf(stderr, "Illegal filter ID\n");
			return -1;
		}
	}
	if (!argc) return 0;
	tail = NLMSG_TAIL(n);
	addattr_l(n, 4096, TCA_OPTIONS, NULL, 0);
	while (argc) {
		if (!strcmp(*argv, "hash")) {
			int hash;

			NEXT_ARG();
			hash = strtoul(*argv, &end, 0);
			if (*end || !hash || hash > 0x10000) {
				explain();
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_HASH, &hash,
				  sizeof(hash));
		} else if (!strcmp(*argv,"mask")) {
			__u16 mask;

			NEXT_ARG();
			mask = strtoul(*argv, &end, 0);
			if (*end) {
				explain();
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_MASK, &mask,
				  sizeof(mask));
		} else if (!strcmp(*argv,"shift")) {
			int shift;

			NEXT_ARG();
			shift = strtoul(*argv, &end, 0);
			if (*end) {
				explain();
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_SHIFT, &shift,
			    sizeof(shift));
		} else if (!strcmp(*argv,"fall_through")) {
			int value = 1;

			addattr_l(n, 4096, TCA_TCINDEX_FALL_THROUGH, &value,
			    sizeof(value));
		} else if (!strcmp(*argv,"pass_on")) {
			int value = 0;

			addattr_l(n, 4096, TCA_TCINDEX_FALL_THROUGH, &value,
			    sizeof(value));
		} else if (!strcmp(*argv,"classid")) {
			__u32 handle;

			NEXT_ARG();
			if (get_tc_classid(&handle, *argv)) {
				fprintf(stderr, "Illegal \"classid\"\n");
				return -1;
			}
			addattr_l(n, 4096, TCA_TCINDEX_CLASSID, &handle, 4);
		} else if (!strcmp(*argv,"police")) {
			NEXT_ARG();
			if (parse_police(&argc, &argv, TCA_TCINDEX_POLICE, n)) {
				fprintf(stderr, "Illegal \"police\"\n");
				return -1;
			}
			continue;
		} else if (!strcmp(*argv,"action")) {
			NEXT_ARG();
			if (parse_action(&argc, &argv, TCA_TCINDEX_ACT, n)) {
				fprintf(stderr, "Illegal \"action\"\n");
				return -1;
			}
			continue;
		} else {
			explain();
			return -1;
		}
		argc--;
		argv++;
	}
	tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
	return 0;
}


static int tcindex_print_opt(struct filter_util *qu, FILE *f,
			     struct rtattr *opt, __u32 handle)
{
	struct rtattr *tb[TCA_TCINDEX_MAX+1];

	if (opt == NULL)
		return 0;

	parse_rtattr_nested(tb, TCA_TCINDEX_MAX, opt);

	if (handle != ~0) fprintf(f, "handle 0x%04x ", handle);
	if (tb[TCA_TCINDEX_HASH]) {
		__u16 hash;

		if (RTA_PAYLOAD(tb[TCA_TCINDEX_HASH]) < sizeof(hash))
			return -1;
		hash = rta_getattr_u16(tb[TCA_TCINDEX_HASH]);
		fprintf(f, "hash %d ", hash);
	}
	if (tb[TCA_TCINDEX_MASK]) {
		__u16 mask;

		if (RTA_PAYLOAD(tb[TCA_TCINDEX_MASK]) < sizeof(mask))
			return -1;
		mask = rta_getattr_u16(tb[TCA_TCINDEX_MASK]);
		fprintf(f, "mask 0x%04x ", mask);
	}
	if (tb[TCA_TCINDEX_SHIFT]) {
		int shift;

		if (RTA_PAYLOAD(tb[TCA_TCINDEX_SHIFT]) < sizeof(shift))
			return -1;
		shift = rta_getattr_u32(tb[TCA_TCINDEX_SHIFT]);
		fprintf(f, "shift %d ", shift);
	}
	if (tb[TCA_TCINDEX_FALL_THROUGH]) {
		int fall_through;

		if (RTA_PAYLOAD(tb[TCA_TCINDEX_FALL_THROUGH]) <
		    sizeof(fall_through))
			return -1;
		fall_through = rta_getattr_u32(tb[TCA_TCINDEX_FALL_THROUGH]);
		fprintf(f, fall_through ? "fall_through " : "pass_on ");
	}
	if (tb[TCA_TCINDEX_CLASSID]) {
		SPRINT_BUF(b1);
		fprintf(f, "classid %s ", sprint_tc_classid(*(__u32 *)
		    RTA_DATA(tb[TCA_TCINDEX_CLASSID]), b1));
	}
	if (tb[TCA_TCINDEX_POLICE]) {
		fprintf(f, "\n");
		tc_print_police(f, tb[TCA_TCINDEX_POLICE]);
	}
	if (tb[TCA_TCINDEX_ACT]) {
		fprintf(f, "\n");
		tc_print_action(f, tb[TCA_TCINDEX_ACT], 0);
	}
	return 0;
}

struct filter_util tcindex_filter_util = {
	.id = "tcindex",
	.parse_fopt = tcindex_parse_opt,
	.print_fopt = tcindex_print_opt,
};
