libxt_quota.c revision 422342e47c18e70757231f2210b13df8e1f5931c
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;
305b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	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;
375b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	printf("--quota %llu ", (unsigned long long) q->quota);
38e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
39e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
40e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte/* parse quota option */
41e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic int
42e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welteparse_quota(const char *s, u_int64_t * quota)
43e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
447a236f4cc685a420c1a782a5db614a93baf37ccfJan Engelhardt	*quota = strtoull(s, NULL, 10);
45e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
462bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI#ifdef DEBUG_XT_QUOTA
475b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	printf("Quota: %llu\n", *quota);
48e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte#endif
49e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
50a80975497968e69b23f56bf15d346c65bec381f2Jan Engelhardt	if (*quota == UINT64_MAX)
511829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "quota invalid: '%s'\n", s);
525b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	else
535b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		return 1;
54e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
55e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
56e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic int
57181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtquota_parse(int c, char **argv, int invert, unsigned int *flags,
585b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	    const void *entry, struct xt_entry_match **match)
59e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
605b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	struct xt_quota_info *info = (struct xt_quota_info *) (*match)->data;
61e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
625b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	switch (c) {
635b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	case '1':
64bf97128c7262f17a02fec41cdae75b472ba77f88Jan Engelhardt		if (xtables_check_inverse(optarg, &invert, NULL, 0, argv))
651829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM, "quota: unexpected '!'");
665b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		if (!parse_quota(optarg, &info->quota))
671829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
685b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann				   "bad quota: '%s'", optarg);
69e4540fcb86c2d7f4cdf51c49872847a03a11b433Samuel Ortiz
70e4540fcb86c2d7f4cdf51c49872847a03a11b433Samuel Ortiz		if (invert)
71e4540fcb86c2d7f4cdf51c49872847a03a11b433Samuel Ortiz			info->flags |= XT_QUOTA_INVERT;
72e4540fcb86c2d7f4cdf51c49872847a03a11b433Samuel Ortiz
735b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		break;
74e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
755b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	default:
765b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		return 0;
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