Blame extensions/libxt_connbytes.c

Packit 7b22a4
#include <stdio.h>
Packit 7b22a4
#include <string.h>
Packit 7b22a4
#include <xtables.h>
Packit 7b22a4
#include <linux/netfilter/xt_connbytes.h>
Packit 7b22a4
Packit 7b22a4
enum {
Packit 7b22a4
	O_CONNBYTES = 0,
Packit 7b22a4
	O_CONNBYTES_DIR,
Packit 7b22a4
	O_CONNBYTES_MODE,
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
static void connbytes_help(void)
Packit 7b22a4
{
Packit 7b22a4
	printf(
Packit 7b22a4
"connbytes match options:\n"
Packit 7b22a4
" [!] --connbytes from:[to]\n"
Packit 7b22a4
"     --connbytes-dir [original, reply, both]\n"
Packit 7b22a4
"     --connbytes-mode [packets, bytes, avgpkt]\n");
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static const struct xt_option_entry connbytes_opts[] = {
Packit 7b22a4
	{.name = "connbytes", .id = O_CONNBYTES, .type = XTTYPE_UINT64RC,
Packit 7b22a4
	 .flags = XTOPT_MAND | XTOPT_INVERT},
Packit 7b22a4
	{.name = "connbytes-dir", .id = O_CONNBYTES_DIR, .type = XTTYPE_STRING,
Packit 7b22a4
	 .flags = XTOPT_MAND},
Packit 7b22a4
	{.name = "connbytes-mode", .id = O_CONNBYTES_MODE,
Packit 7b22a4
	 .type = XTTYPE_STRING, .flags = XTOPT_MAND},
Packit 7b22a4
	XTOPT_TABLEEND,
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
static void connbytes_parse(struct xt_option_call *cb)
Packit 7b22a4
{
Packit 7b22a4
	struct xt_connbytes_info *sinfo = cb->data;
Packit 7b22a4
	unsigned long long i;
Packit 7b22a4
Packit 7b22a4
	xtables_option_parse(cb);
Packit 7b22a4
	switch (cb->entry->id) {
Packit 7b22a4
	case O_CONNBYTES:
Packit 7b22a4
		sinfo->count.from = cb->val.u64_range[0];
Packit 7b22a4
		sinfo->count.to   = UINT64_MAX;
Packit 7b22a4
		if (cb->nvals == 2)
Packit 7b22a4
			sinfo->count.to = cb->val.u64_range[1];
Packit 7b22a4
Packit 7b22a4
		if (sinfo->count.to < sinfo->count.from)
Packit 7b22a4
			xtables_error(PARAMETER_PROBLEM, "%llu should be less than %llu",
Packit 7b22a4
					(unsigned long long)sinfo->count.from,
Packit 7b22a4
					(unsigned long long)sinfo->count.to);
Packit 7b22a4
		if (cb->invert) {
Packit 7b22a4
			i = sinfo->count.from;
Packit 7b22a4
			sinfo->count.from = sinfo->count.to;
Packit 7b22a4
			sinfo->count.to = i;
Packit 7b22a4
		}
Packit 7b22a4
		break;
Packit 7b22a4
	case O_CONNBYTES_DIR:
Packit 7b22a4
		if (strcmp(cb->arg, "original") == 0)
Packit 7b22a4
			sinfo->direction = XT_CONNBYTES_DIR_ORIGINAL;
Packit 7b22a4
		else if (strcmp(cb->arg, "reply") == 0)
Packit 7b22a4
			sinfo->direction = XT_CONNBYTES_DIR_REPLY;
Packit 7b22a4
		else if (strcmp(cb->arg, "both") == 0)
Packit 7b22a4
			sinfo->direction = XT_CONNBYTES_DIR_BOTH;
Packit 7b22a4
		else
Packit 7b22a4
			xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
				   "Unknown --connbytes-dir `%s'", cb->arg);
Packit 7b22a4
		break;
Packit 7b22a4
	case O_CONNBYTES_MODE:
Packit 7b22a4
		if (strcmp(cb->arg, "packets") == 0)
Packit 7b22a4
			sinfo->what = XT_CONNBYTES_PKTS;
Packit 7b22a4
		else if (strcmp(cb->arg, "bytes") == 0)
Packit 7b22a4
			sinfo->what = XT_CONNBYTES_BYTES;
Packit 7b22a4
		else if (strcmp(cb->arg, "avgpkt") == 0)
Packit 7b22a4
			sinfo->what = XT_CONNBYTES_AVGPKT;
Packit 7b22a4
		else
Packit 7b22a4
			xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
				   "Unknown --connbytes-mode `%s'", cb->arg);
Packit 7b22a4
		break;
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void print_mode(const struct xt_connbytes_info *sinfo)
Packit 7b22a4
{
Packit 7b22a4
	switch (sinfo->what) {
Packit 7b22a4
		case XT_CONNBYTES_PKTS:
Packit 7b22a4
			fputs(" packets", stdout);
Packit 7b22a4
			break;
Packit 7b22a4
		case XT_CONNBYTES_BYTES:
Packit 7b22a4
			fputs(" bytes", stdout);
Packit 7b22a4
			break;
Packit 7b22a4
		case XT_CONNBYTES_AVGPKT:
Packit 7b22a4
			fputs(" avgpkt", stdout);
Packit 7b22a4
			break;
Packit 7b22a4
		default:
Packit 7b22a4
			fputs(" unknown", stdout);
Packit 7b22a4
			break;
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void print_direction(const struct xt_connbytes_info *sinfo)
Packit 7b22a4
{
Packit 7b22a4
	switch (sinfo->direction) {
Packit 7b22a4
		case XT_CONNBYTES_DIR_ORIGINAL:
Packit 7b22a4
			fputs(" original", stdout);
Packit 7b22a4
			break;
Packit 7b22a4
		case XT_CONNBYTES_DIR_REPLY:
Packit 7b22a4
			fputs(" reply", stdout);
Packit 7b22a4
			break;
Packit 7b22a4
		case XT_CONNBYTES_DIR_BOTH:
Packit 7b22a4
			fputs(" both", stdout);
Packit 7b22a4
			break;
Packit 7b22a4
		default:
Packit 7b22a4
			fputs(" unknown", stdout);
Packit 7b22a4
			break;
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void print_from_to(const struct xt_connbytes_info *sinfo, const char *prefix)
Packit 7b22a4
{
Packit 7b22a4
	unsigned long long from, to;
Packit 7b22a4
Packit 7b22a4
	if (sinfo->count.from > sinfo->count.to) {
Packit 7b22a4
		fputs(" !", stdout);
Packit 7b22a4
		from = sinfo->count.to;
Packit 7b22a4
		to = sinfo->count.from;
Packit 7b22a4
	} else {
Packit 7b22a4
		to = sinfo->count.to;
Packit 7b22a4
		from = sinfo->count.from;
Packit 7b22a4
	}
Packit 7b22a4
	printf(" %sconnbytes %llu", prefix, from);
Packit 7b22a4
	if (to && to < UINT64_MAX)
Packit 7b22a4
		printf(":%llu", to);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void
Packit 7b22a4
connbytes_print(const void *ip, const struct xt_entry_match *match, int numeric)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connbytes_info *sinfo = (const void *)match->data;
Packit 7b22a4
Packit 7b22a4
	print_from_to(sinfo, "");
Packit 7b22a4
Packit 7b22a4
	fputs(" connbytes mode", stdout);
Packit 7b22a4
	print_mode(sinfo);
Packit 7b22a4
Packit 7b22a4
	fputs(" connbytes direction", stdout);
Packit 7b22a4
	print_direction(sinfo);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void connbytes_save(const void *ip, const struct xt_entry_match *match)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connbytes_info *sinfo = (const void *)match->data;
Packit 7b22a4
Packit 7b22a4
	print_from_to(sinfo, "--");
Packit 7b22a4
Packit 7b22a4
	fputs(" --connbytes-mode", stdout);
Packit 7b22a4
	print_mode(sinfo);
Packit 7b22a4
Packit 7b22a4
	fputs(" --connbytes-dir", stdout);
Packit 7b22a4
	print_direction(sinfo);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
Packit 7b22a4
static int connbytes_xlate(struct xt_xlate *xl,
Packit 7b22a4
			   const struct xt_xlate_mt_params *params)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connbytes_info *info = (void *)params->match->data;
Packit 7b22a4
	unsigned long long from, to;
Packit 7b22a4
	bool invert = false;
Packit 7b22a4
Packit 7b22a4
	xt_xlate_add(xl, "ct ");
Packit 7b22a4
Packit 7b22a4
	switch (info->direction) {
Packit 7b22a4
	case XT_CONNBYTES_DIR_ORIGINAL:
Packit 7b22a4
		xt_xlate_add(xl, "original ");
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNBYTES_DIR_REPLY:
Packit 7b22a4
		xt_xlate_add(xl, "reply ");
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNBYTES_DIR_BOTH:
Packit 7b22a4
		break;
Packit 7b22a4
	default:
Packit 7b22a4
		return 0;
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	switch (info->what) {
Packit 7b22a4
	case XT_CONNBYTES_PKTS:
Packit 7b22a4
		xt_xlate_add(xl, "packets ");
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNBYTES_BYTES:
Packit 7b22a4
		xt_xlate_add(xl, "bytes ");
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNBYTES_AVGPKT:
Packit 7b22a4
		xt_xlate_add(xl, "avgpkt ");
Packit 7b22a4
		break;
Packit 7b22a4
	default:
Packit 7b22a4
		return 0;
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	if (info->count.from > info->count.to) {
Packit 7b22a4
		invert = true;
Packit 7b22a4
		from = info->count.to;
Packit 7b22a4
		to = info->count.from;
Packit 7b22a4
	} else {
Packit 7b22a4
		to = info->count.to;
Packit 7b22a4
		from = info->count.from;
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	if (from == to)
Packit 7b22a4
		xt_xlate_add(xl, "%llu", from);
Packit 7b22a4
	else if (to == UINT64_MAX)
Packit 7b22a4
		xt_xlate_add(xl, "%s %llu", invert ? "lt" : "ge", from);
Packit 7b22a4
	else
Packit 7b22a4
		xt_xlate_add(xl, "%s%llu-%llu", invert ? "!= " : "", from, to);
Packit 7b22a4
	return 1;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static struct xtables_match connbytes_match = {
Packit 7b22a4
	.family		= NFPROTO_UNSPEC,
Packit 7b22a4
	.name 		= "connbytes",
Packit 7b22a4
	.version 	= XTABLES_VERSION,
Packit 7b22a4
	.size 		= XT_ALIGN(sizeof(struct xt_connbytes_info)),
Packit 7b22a4
	.userspacesize	= XT_ALIGN(sizeof(struct xt_connbytes_info)),
Packit 7b22a4
	.help		= connbytes_help,
Packit 7b22a4
	.print		= connbytes_print,
Packit 7b22a4
	.save 		= connbytes_save,
Packit 7b22a4
	.x6_parse	= connbytes_parse,
Packit 7b22a4
	.x6_options	= connbytes_opts,
Packit 7b22a4
	.xlate		= connbytes_xlate,
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
void _init(void)
Packit 7b22a4
{
Packit 7b22a4
	xtables_register_match(&connbytes_match);
Packit 7b22a4
}