libxt_CLASSIFY.c revision 23545c2a7a31c68c1e49c7c901b632c2f1c59968
1/* Shared library add-on to iptables to add CLASSIFY target support. */
2#include <stdio.h>
3#include <string.h>
4#include <stdlib.h>
5#include <getopt.h>
6
7#include <xtables.h>
8#include <linux/netfilter/x_tables.h>
9#include <linux/netfilter/xt_CLASSIFY.h>
10#include <linux/types.h>
11#include <linux/pkt_sched.h>
12
13/* Function which prints out usage message. */
14static void
15CLASSIFY_help(void)
16{
17	printf(
18"CLASSIFY target v%s options:\n"
19"  --set-class [MAJOR:MINOR]    Set skb->priority value\n"
20"\n",
21IPTABLES_VERSION);
22}
23
24static const struct option CLASSIFY_opts[] = {
25	{ "set-class", 1, NULL, '1' },
26	{ .name = NULL }
27};
28
29static int CLASSIFY_string_to_priority(const char *s, unsigned int *p)
30{
31	unsigned int i, j;
32
33	if (sscanf(s, "%x:%x", &i, &j) != 2)
34		return 1;
35
36	*p = TC_H_MAKE(i<<16, j);
37	return 0;
38}
39
40/* Function which parses command options; returns true if it
41   ate an option */
42static int
43CLASSIFY_parse(int c, char **argv, int invert, unsigned int *flags,
44      const void *entry,
45      struct xt_entry_target **target)
46{
47	struct xt_classify_target_info *clinfo
48		= (struct xt_classify_target_info *)(*target)->data;
49
50	switch (c) {
51	case '1':
52		if (CLASSIFY_string_to_priority(optarg, &clinfo->priority))
53			exit_error(PARAMETER_PROBLEM,
54				   "Bad class value `%s'", optarg);
55		if (*flags)
56			exit_error(PARAMETER_PROBLEM,
57			           "CLASSIFY: Can't specify --set-class twice");
58		*flags = 1;
59		break;
60
61	default:
62		return 0;
63	}
64
65	return 1;
66}
67
68static void
69CLASSIFY_final_check(unsigned int flags)
70{
71	if (!flags)
72		exit_error(PARAMETER_PROBLEM,
73		           "CLASSIFY: Parameter --set-class is required");
74}
75
76static void
77CLASSIFY_print_class(unsigned int priority, int numeric)
78{
79	printf("%x:%x ", TC_H_MAJ(priority)>>16, TC_H_MIN(priority));
80}
81
82/* Prints out the targinfo. */
83static void
84CLASSIFY_print(const void *ip,
85      const struct xt_entry_target *target,
86      int numeric)
87{
88	const struct xt_classify_target_info *clinfo =
89		(const struct xt_classify_target_info *)target->data;
90	printf("CLASSIFY set ");
91	CLASSIFY_print_class(clinfo->priority, numeric);
92}
93
94/* Saves the union ipt_targinfo in parsable form to stdout. */
95static void
96CLASSIFY_save(const void *ip, const struct xt_entry_target *target)
97{
98	const struct xt_classify_target_info *clinfo =
99		(const struct xt_classify_target_info *)target->data;
100
101	printf("--set-class %.4x:%.4x ",
102	       TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority));
103}
104
105static struct xtables_target classify_target = {
106	.family		= AF_UNSPEC,
107	.name		= "CLASSIFY",
108	.version	= IPTABLES_VERSION,
109	.size		= XT_ALIGN(sizeof(struct xt_classify_target_info)),
110	.userspacesize	= XT_ALIGN(sizeof(struct xt_classify_target_info)),
111	.help		= CLASSIFY_help,
112	.parse		= CLASSIFY_parse,
113	.final_check	= CLASSIFY_final_check,
114	.print		= CLASSIFY_print,
115	.save		= CLASSIFY_save,
116	.extra_opts	= CLASSIFY_opts,
117};
118
119void _init(void)
120{
121	xtables_register_target(&classify_target);
122}
123