1e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte/*
2e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte * Shared library add-on to iptables to add quota support
3e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte *
4e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte * Sam Johnston <samj@samj.net>
5e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte */
6e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte#include <stdio.h>
72bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI#include <xtables.h>
8ae35309923339354b48adac4fa703bd3f5e6dd2bPhil Oester#include <linux/netfilter/xt_quota.h>
9e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
101e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardtenum {
111e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt	O_QUOTA = 0,
121e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt};
131e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt
141e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardtstatic const struct xt_option_entry quota_opts[] = {
151e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt	{.name = "quota", .id = O_QUOTA, .type = XTTYPE_UINT64,
1667db7615580f5c3490a39310f5adcb4e767ea6a8Jan Engelhardt	 .flags = XTOPT_MAND | XTOPT_INVERT | XTOPT_PUT,
1767db7615580f5c3490a39310f5adcb4e767ea6a8Jan Engelhardt	 XTOPT_POINTER(struct xt_quota_info, quota)},
181e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt	XTOPT_TABLEEND,
19e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte};
20e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
21181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void quota_help(void)
22e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
238b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	printf("quota match options:\n"
24ce06c99ee107102a7168493b55970b53380ebbb6Jan Engelhardt	       "[!] --quota quota		quota (bytes)\n");
25e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
26e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
27e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic void
28181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtquota_print(const void *ip, const struct xt_entry_match *match, int numeric)
29e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
3069f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt	const struct xt_quota_info *q = (const void *)match->data;
3173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" quota: %llu bytes", (unsigned long long)q->quota);
32e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
33e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
34e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic void
35181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtquota_save(const void *ip, const struct xt_entry_match *match)
36e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
3769f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt	const struct xt_quota_info *q = (const void *)match->data;
389c60365e043a430f74115bbfaf58ce0df7585f49Jan Engelhardt
399c60365e043a430f74115bbfaf58ce0df7585f49Jan Engelhardt	if (q->flags & XT_QUOTA_INVERT)
409c60365e043a430f74115bbfaf58ce0df7585f49Jan Engelhardt		printf("! ");
4173866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" --quota %llu", (unsigned long long) q->quota);
42e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
43e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
441e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardtstatic void quota_parse(struct xt_option_call *cb)
45e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
461e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt	struct xt_quota_info *info = cb->data;
47e4540fcb86c2d7f4cdf51c49872847a03a11b433Samuel Ortiz
481e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt	xtables_option_parse(cb);
491e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt	if (cb->invert)
501e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt		info->flags |= XT_QUOTA_INVERT;
51b65b9fe5096bd49a9ec2f0f6c2f23d274cfc88eeJP Abgrall	info->quota = cb->val.u64;
528a5270b14908b3173de080a958e50e21e2f046deJan Engelhardt}
538a5270b14908b3173de080a958e50e21e2f046deJan Engelhardt
540ea82bc43e9262cdbb9880ca56bb514db4c77f8ePatrick McHardystatic struct xtables_match quota_match = {
5542979363f3958b4436c6d2503753c182c58e55eaJan Engelhardt	.family		= NFPROTO_UNSPEC,
562bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI	.name		= "quota",
578b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version	= XTABLES_VERSION,
582bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI	.size		= XT_ALIGN(sizeof (struct xt_quota_info)),
59422342e47c18e70757231f2210b13df8e1f5931cChangli Gao	.userspacesize	= offsetof(struct xt_quota_info, master),
60181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.help		= quota_help,
61181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.print		= quota_print,
62181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.save		= quota_save,
631e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt	.x6_parse	= quota_parse,
641e6c1ee1bf2822d5fdf61725148700a410fb8b86Jan Engelhardt	.x6_options	= quota_opts,
65e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte};
66e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
67e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltevoid
68e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte_init(void)
69e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
70181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	xtables_register_match(&quota_match);
71e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
72