libxt_quota.c revision 73866357e4a7a0fdc1b293bf8863fee2bd56da9e
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 */
632b8e61e4e5bd405d9ad07bf9468498dfbb19f9eJan Engelhardt#include <stdbool.h>
7ae35309923339354b48adac4fa703bd3f5e6dd2bPhil Oester#include <stddef.h>
8e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte#include <stdio.h>
9e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte#include <stdlib.h>
10e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte#include <getopt.h>
112bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI#include <xtables.h>
12e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
13ae35309923339354b48adac4fa703bd3f5e6dd2bPhil Oester#include <linux/netfilter/xt_quota.h>
14e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
15181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic const struct option quota_opts[] = {
1632b8e61e4e5bd405d9ad07bf9468498dfbb19f9eJan Engelhardt	{.name = "quota", .has_arg = true, .val = '1'},
1732b8e61e4e5bd405d9ad07bf9468498dfbb19f9eJan Engelhardt	XT_GETOPT_TABLEEND,
18e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte};
19e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
20181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void quota_help(void)
21e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
228b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	printf("quota match options:\n"
23ce06c99ee107102a7168493b55970b53380ebbb6Jan Engelhardt	       "[!] --quota quota		quota (bytes)\n");
24e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
25e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
26e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic void
27181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtquota_print(const void *ip, const struct xt_entry_match *match, int numeric)
28e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
2969f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt	const struct xt_quota_info *q = (const void *)match->data;
3073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" quota: %llu bytes", (unsigned long long)q->quota);
31e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
32e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
33e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic void
34181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtquota_save(const void *ip, const struct xt_entry_match *match)
35e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
3669f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt	const struct xt_quota_info *q = (const void *)match->data;
379c60365e043a430f74115bbfaf58ce0df7585f49Jan Engelhardt
389c60365e043a430f74115bbfaf58ce0df7585f49Jan Engelhardt	if (q->flags & XT_QUOTA_INVERT)
399c60365e043a430f74115bbfaf58ce0df7585f49Jan Engelhardt		printf("! ");
4073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf(" --quota %llu", (unsigned long long) q->quota);
41e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
42e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
43e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte/* parse quota option */
44e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic int
457ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtparse_quota(const char *s, uint64_t * quota)
46e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
477a236f4cc685a420c1a782a5db614a93baf37ccfJan Engelhardt	*quota = strtoull(s, NULL, 10);
48e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
492bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI#ifdef DEBUG_XT_QUOTA
505b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	printf("Quota: %llu\n", *quota);
51e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte#endif
52e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
53a80975497968e69b23f56bf15d346c65bec381f2Jan Engelhardt	if (*quota == UINT64_MAX)
541829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "quota invalid: '%s'\n", s);
555b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	else
565b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		return 1;
57e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
58e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
59e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic int
60181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtquota_parse(int c, char **argv, int invert, unsigned int *flags,
615b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	    const void *entry, struct xt_entry_match **match)
62e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
635b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	struct xt_quota_info *info = (struct xt_quota_info *) (*match)->data;
64e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
655b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	switch (c) {
665b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	case '1':
67bf97128c7262f17a02fec41cdae75b472ba77f88Jan Engelhardt		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
681829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM, "quota: unexpected '!'");
695b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		if (!parse_quota(optarg, &info->quota))
701829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
715b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann				   "bad quota: '%s'", optarg);
72e4540fcb86c2d7f4cdf51c49872847a03a11b433Samuel Ortiz
73e4540fcb86c2d7f4cdf51c49872847a03a11b433Samuel Ortiz		if (invert)
74e4540fcb86c2d7f4cdf51c49872847a03a11b433Samuel Ortiz			info->flags |= XT_QUOTA_INVERT;
75e4540fcb86c2d7f4cdf51c49872847a03a11b433Samuel Ortiz
765b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		break;
775b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	}
785b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	return 1;
79e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
80e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
810ea82bc43e9262cdbb9880ca56bb514db4c77f8ePatrick McHardystatic struct xtables_match quota_match = {
8242979363f3958b4436c6d2503753c182c58e55eaJan Engelhardt	.family		= NFPROTO_UNSPEC,
832bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI	.name		= "quota",
848b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version	= XTABLES_VERSION,
852bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI	.size		= XT_ALIGN(sizeof (struct xt_quota_info)),
86422342e47c18e70757231f2210b13df8e1f5931cChangli Gao	.userspacesize	= offsetof(struct xt_quota_info, master),
87181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.help		= quota_help,
88181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.parse		= quota_parse,
89181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.print		= quota_print,
90181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.save		= quota_save,
91181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.extra_opts	= quota_opts,
92e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte};
93e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
94e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltevoid
95e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte_init(void)
96e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
97181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	xtables_register_match(&quota_match);
98e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
99