libxt_CLASSIFY.c revision 1829ed482efbc8b390cc760d012b3a4450494e1a
16ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Shared library add-on to iptables to add CLASSIFY target support. */
26ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik#include <stdio.h>
36ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik#include <string.h>
46ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik#include <stdlib.h>
56ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik#include <getopt.h>
66ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
7e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI#include <xtables.h>
8e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI#include <linux/netfilter/x_tables.h>
9e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI#include <linux/netfilter/xt_CLASSIFY.h>
106ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik#include <linux/types.h>
116ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik#include <linux/pkt_sched.h>
126ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
136ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
1472118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_help(void)
156ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
166ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf(
178b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"CLASSIFY target options:\n"
188b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"  --set-class [MAJOR:MINOR]    Set skb->priority value\n");
196ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
206ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
2172118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóthstatic const struct option CLASSIFY_opts[] = {
22500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy	{ "set-class", 1, NULL, '1' },
239ee386a1b6d7704b259460152c959ab0e79e02aaMax Kellermann	{ .name = NULL }
246ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik};
256ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
2672118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóthstatic int CLASSIFY_string_to_priority(const char *s, unsigned int *p)
276ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
286ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	unsigned int i, j;
296ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
306ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	if (sscanf(s, "%x:%x", &i, &j) != 2)
316ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		return 1;
326ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
336ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	*p = TC_H_MAKE(i<<16, j);
346ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	return 0;
356ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
366ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
376ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic int
3872118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_parse(int c, char **argv, int invert, unsigned int *flags,
39c0a9ab93f49a3d2508c95d0ca1a01c1089983731Yasuyuki KOZAKAI      const void *entry,
40193df8ee3507f0c02762c88a16916c4ea950bd99Yasuyuki KOZAKAI      struct xt_entry_target **target)
416ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
42e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	struct xt_classify_target_info *clinfo
43e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI		= (struct xt_classify_target_info *)(*target)->data;
446ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
456ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	switch (c) {
466ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	case '1':
4772118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth		if (CLASSIFY_string_to_priority(optarg, &clinfo->priority))
481829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
496ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik				   "Bad class value `%s'", optarg);
506ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		if (*flags)
511829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
526ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik			           "CLASSIFY: Can't specify --set-class twice");
536ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		*flags = 1;
546ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		break;
556ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
566ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	default:
576ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		return 0;
586ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	}
596ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
606ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	return 1;
616ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
626ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
636ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
6472118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_final_check(unsigned int flags)
656ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
666ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	if (!flags)
671829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
686ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		           "CLASSIFY: Parameter --set-class is required");
696ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
706ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
716ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
7272118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_print_class(unsigned int priority, int numeric)
736ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
746ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf("%x:%x ", TC_H_MAJ(priority)>>16, TC_H_MIN(priority));
756ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
766ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
776ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
7872118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_print(const void *ip,
79193df8ee3507f0c02762c88a16916c4ea950bd99Yasuyuki KOZAKAI      const struct xt_entry_target *target,
806ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik      int numeric)
816ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
82e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	const struct xt_classify_target_info *clinfo =
83e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI		(const struct xt_classify_target_info *)target->data;
846ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf("CLASSIFY set ");
8572118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	CLASSIFY_print_class(clinfo->priority, numeric);
866ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
876ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
886ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
8972118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_save(const void *ip, const struct xt_entry_target *target)
906ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
91e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	const struct xt_classify_target_info *clinfo =
92e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI		(const struct xt_classify_target_info *)target->data;
936ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
946ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf("--set-class %.4x:%.4x ",
956ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	       TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority));
966ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
976ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
9872118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóthstatic struct xtables_target classify_target = {
9923545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt	.family		= AF_UNSPEC,
100e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	.name		= "CLASSIFY",
1018b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version	= XTABLES_VERSION,
102e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	.size		= XT_ALIGN(sizeof(struct xt_classify_target_info)),
103e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	.userspacesize	= XT_ALIGN(sizeof(struct xt_classify_target_info)),
10472118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.help		= CLASSIFY_help,
10572118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.parse		= CLASSIFY_parse,
10672118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.final_check	= CLASSIFY_final_check,
10772118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.print		= CLASSIFY_print,
10872118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.save		= CLASSIFY_save,
10972118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.extra_opts	= CLASSIFY_opts,
1106ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik};
1116ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
1126ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikvoid _init(void)
1136ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
11472118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	xtables_register_target(&classify_target);
1156ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
116