libxt_CLASSIFY.c revision 8b7c64d6ba156a99008fcd810cba874c73294333
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 Kadlecsik/* Function which prints out usage message. */
146ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
1572118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_help(void)
166ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
176ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf(
188b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"CLASSIFY target options:\n"
198b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"  --set-class [MAJOR:MINOR]    Set skb->priority value\n");
206ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
216ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
2272118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóthstatic const struct option CLASSIFY_opts[] = {
23500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy	{ "set-class", 1, NULL, '1' },
249ee386a1b6d7704b259460152c959ab0e79e02aaMax Kellermann	{ .name = NULL }
256ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik};
266ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
2772118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóthstatic int CLASSIFY_string_to_priority(const char *s, unsigned int *p)
286ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
296ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	unsigned int i, j;
306ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
316ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	if (sscanf(s, "%x:%x", &i, &j) != 2)
326ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		return 1;
336ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
346ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	*p = TC_H_MAKE(i<<16, j);
356ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	return 0;
366ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
376ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
386ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Function which parses command options; returns true if it
396ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik   ate an option */
406ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic int
4172118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_parse(int c, char **argv, int invert, unsigned int *flags,
42c0a9ab93f49a3d2508c95d0ca1a01c1089983731Yasuyuki KOZAKAI      const void *entry,
43193df8ee3507f0c02762c88a16916c4ea950bd99Yasuyuki KOZAKAI      struct xt_entry_target **target)
446ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
45e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	struct xt_classify_target_info *clinfo
46e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI		= (struct xt_classify_target_info *)(*target)->data;
476ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
486ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	switch (c) {
496ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	case '1':
5072118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth		if (CLASSIFY_string_to_priority(optarg, &clinfo->priority))
516ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik			exit_error(PARAMETER_PROBLEM,
526ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik				   "Bad class value `%s'", optarg);
536ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		if (*flags)
546ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik			exit_error(PARAMETER_PROBLEM,
556ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik			           "CLASSIFY: Can't specify --set-class twice");
566ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		*flags = 1;
576ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		break;
586ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
596ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	default:
606ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		return 0;
616ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	}
626ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
636ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	return 1;
646ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
656ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
666ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
6772118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_final_check(unsigned int flags)
686ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
696ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	if (!flags)
706ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		exit_error(PARAMETER_PROBLEM,
716ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		           "CLASSIFY: Parameter --set-class is required");
726ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
736ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
746ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
7572118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_print_class(unsigned int priority, int numeric)
766ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
776ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf("%x:%x ", TC_H_MAJ(priority)>>16, TC_H_MIN(priority));
786ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
796ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
806ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Prints out the targinfo. */
816ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
8272118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_print(const void *ip,
83193df8ee3507f0c02762c88a16916c4ea950bd99Yasuyuki KOZAKAI      const struct xt_entry_target *target,
846ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik      int numeric)
856ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
86e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	const struct xt_classify_target_info *clinfo =
87e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI		(const struct xt_classify_target_info *)target->data;
886ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf("CLASSIFY set ");
8972118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	CLASSIFY_print_class(clinfo->priority, numeric);
906ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
916ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
926ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Saves the union ipt_targinfo in parsable form to stdout. */
936ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
9472118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_save(const void *ip, const struct xt_entry_target *target)
956ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
96e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	const struct xt_classify_target_info *clinfo =
97e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI		(const struct xt_classify_target_info *)target->data;
986ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
996ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf("--set-class %.4x:%.4x ",
1006ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	       TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority));
1016ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
1026ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
10372118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóthstatic struct xtables_target classify_target = {
10423545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt	.family		= AF_UNSPEC,
105e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	.name		= "CLASSIFY",
1068b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	.version	= XTABLES_VERSION,
107e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	.size		= XT_ALIGN(sizeof(struct xt_classify_target_info)),
108e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI	.userspacesize	= XT_ALIGN(sizeof(struct xt_classify_target_info)),
10972118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.help		= CLASSIFY_help,
11072118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.parse		= CLASSIFY_parse,
11172118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.final_check	= CLASSIFY_final_check,
11272118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.print		= CLASSIFY_print,
11372118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.save		= CLASSIFY_save,
11472118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	.extra_opts	= CLASSIFY_opts,
1156ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik};
1166ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
1176ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikvoid _init(void)
1186ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
11972118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth	xtables_register_target(&classify_target);
1206ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
121