libxt_quota.c revision 42979363f3958b4436c6d2503753c182c58e55ea
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 */
6ae35309923339354b48adac4fa703bd3f5e6dd2bPhil Oester#include <stddef.h>
7e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte#include <stdio.h>
8e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte#include <stdlib.h>
9e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte#include <getopt.h>
102bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI#include <xtables.h>
11e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
12ae35309923339354b48adac4fa703bd3f5e6dd2bPhil Oester#include <linux/netfilter/xt_quota.h>
13e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
14181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic const struct option quota_opts[] = {
155b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	{"quota", 1, NULL, '1'},
169ee386a1b6d7704b259460152c959ab0e79e02aaMax Kellermann	{ .name = NULL }
17e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte};
18e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
19181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtstatic void quota_help(void)
20e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
218b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	printf("quota match options:\n"
228b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	       " --quota quota			quota (bytes)\n");
23e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
24e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
25e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic void
26181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtquota_print(const void *ip, const struct xt_entry_match *match, int numeric)
27e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
2869f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt	const struct xt_quota_info *q = (const void *)match->data;
295b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	printf("quota: %llu bytes", (unsigned long long) q->quota);
30e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
31e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
32e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic void
33181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtquota_save(const void *ip, const struct xt_entry_match *match)
34e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
3569f564e3890976461de0016cd81171ff8bfa8353Jan Engelhardt	const struct xt_quota_info *q = (const void *)match->data;
365b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	printf("--quota %llu ", (unsigned long long) q->quota);
37e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
38e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
39e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte/* parse quota option */
40e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic int
41e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welteparse_quota(const char *s, u_int64_t * quota)
42e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
437a236f4cc685a420c1a782a5db614a93baf37ccfJan Engelhardt	*quota = strtoull(s, NULL, 10);
44e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
452bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI#ifdef DEBUG_XT_QUOTA
465b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	printf("Quota: %llu\n", *quota);
47e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte#endif
48e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
49a80975497968e69b23f56bf15d346c65bec381f2Jan Engelhardt	if (*quota == UINT64_MAX)
501829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "quota invalid: '%s'\n", s);
515b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	else
525b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		return 1;
53e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
54e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
55e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltestatic int
56181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardtquota_parse(int c, char **argv, int invert, unsigned int *flags,
575b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	    const void *entry, struct xt_entry_match **match)
58e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
595b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	struct xt_quota_info *info = (struct xt_quota_info *) (*match)->data;
60e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
615b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	switch (c) {
625b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	case '1':
630f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt		if (xtables_check_inverse(optarg, &invert, NULL, 0))
641829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM, "quota: unexpected '!'");
655b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		if (!parse_quota(optarg, &info->quota))
661829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
675b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann				   "bad quota: '%s'", optarg);
685b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		break;
69e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
705b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	default:
715b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		return 0;
725b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	}
735b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	return 1;
74e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
75e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
760ea82bc43e9262cdbb9880ca56bb514db4c77f8ePatrick McHardystatic struct xtables_match quota_match = {
7742979363f3958b4436c6d2503753c182c58e55eaJan Engelhardt	.family		= NFPROTO_UNSPEC,
782bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI	.name		= "quota",
798b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version	= XTABLES_VERSION,
802bcb16047e048afd1457642fa7bc2aefc8d06d9dYasuyuki KOZAKAI	.size		= XT_ALIGN(sizeof (struct xt_quota_info)),
81ae35309923339354b48adac4fa703bd3f5e6dd2bPhil Oester	.userspacesize	= offsetof(struct xt_quota_info, quota),
82181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.help		= quota_help,
83181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.parse		= quota_parse,
84181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.print		= quota_print,
85181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.save		= quota_save,
86181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	.extra_opts	= quota_opts,
87e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte};
88e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte
89e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Weltevoid
90e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte_init(void)
91e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte{
92181dead3f13befe02769ef479bcbb51801b7fc4eJan Engelhardt	xtables_register_match(&quota_match);
93e746abb15df34da1729de8d669c95f1b0b9ecb7cHarald Welte}
94