blob: 65a19e52fcc686fc6e6aef7588566f44b525a8ce [file] [log] [blame]
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +00001/* 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
Yasuyuki KOZAKAIe4cc20b2007-08-04 08:23:13 +00007#include <xtables.h>
8#include <linux/netfilter/x_tables.h>
9#include <linux/netfilter/xt_CLASSIFY.h>
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000010#include <linux/types.h>
11#include <linux/pkt_sched.h>
12
13/* Function which prints out usage message. */
14static void
László Attila Tóth72118882007-10-08 05:12:42 +000015CLASSIFY_help(void)
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000016{
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
László Attila Tóth72118882007-10-08 05:12:42 +000024static const struct option CLASSIFY_opts[] = {
Patrick McHardy500f4832007-09-08 15:59:04 +000025 { "set-class", 1, NULL, '1' },
26 { }
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000027};
28
László Attila Tóth72118882007-10-08 05:12:42 +000029static int CLASSIFY_string_to_priority(const char *s, unsigned int *p)
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000030{
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
László Attila Tóth72118882007-10-08 05:12:42 +000043CLASSIFY_parse(int c, char **argv, int invert, unsigned int *flags,
Yasuyuki KOZAKAIc0a9ab92007-07-24 06:02:05 +000044 const void *entry,
Yasuyuki KOZAKAI193df8e2007-07-24 05:57:28 +000045 struct xt_entry_target **target)
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000046{
Yasuyuki KOZAKAIe4cc20b2007-08-04 08:23:13 +000047 struct xt_classify_target_info *clinfo
48 = (struct xt_classify_target_info *)(*target)->data;
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000049
50 switch (c) {
51 case '1':
László Attila Tóth72118882007-10-08 05:12:42 +000052 if (CLASSIFY_string_to_priority(optarg, &clinfo->priority))
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000053 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
László Attila Tóth72118882007-10-08 05:12:42 +000069CLASSIFY_final_check(unsigned int flags)
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000070{
71 if (!flags)
72 exit_error(PARAMETER_PROBLEM,
73 "CLASSIFY: Parameter --set-class is required");
74}
75
76static void
László Attila Tóth72118882007-10-08 05:12:42 +000077CLASSIFY_print_class(unsigned int priority, int numeric)
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000078{
79 printf("%x:%x ", TC_H_MAJ(priority)>>16, TC_H_MIN(priority));
80}
81
82/* Prints out the targinfo. */
83static void
László Attila Tóth72118882007-10-08 05:12:42 +000084CLASSIFY_print(const void *ip,
Yasuyuki KOZAKAI193df8e2007-07-24 05:57:28 +000085 const struct xt_entry_target *target,
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000086 int numeric)
87{
Yasuyuki KOZAKAIe4cc20b2007-08-04 08:23:13 +000088 const struct xt_classify_target_info *clinfo =
89 (const struct xt_classify_target_info *)target->data;
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000090 printf("CLASSIFY set ");
László Attila Tóth72118882007-10-08 05:12:42 +000091 CLASSIFY_print_class(clinfo->priority, numeric);
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000092}
93
94/* Saves the union ipt_targinfo in parsable form to stdout. */
95static void
László Attila Tóth72118882007-10-08 05:12:42 +000096CLASSIFY_save(const void *ip, const struct xt_entry_target *target)
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +000097{
Yasuyuki KOZAKAIe4cc20b2007-08-04 08:23:13 +000098 const struct xt_classify_target_info *clinfo =
99 (const struct xt_classify_target_info *)target->data;
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +0000100
101 printf("--set-class %.4x:%.4x ",
102 TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority));
103}
104
László Attila Tóth72118882007-10-08 05:12:42 +0000105static struct xtables_target classify_target = {
Yasuyuki KOZAKAIe4cc20b2007-08-04 08:23:13 +0000106 .family = AF_INET,
Pablo Neira8caee8b2004-12-28 13:11:59 +0000107 .name = "CLASSIFY",
108 .version = IPTABLES_VERSION,
Yasuyuki KOZAKAIe4cc20b2007-08-04 08:23:13 +0000109 .size = XT_ALIGN(sizeof(struct xt_classify_target_info)),
110 .userspacesize = XT_ALIGN(sizeof(struct xt_classify_target_info)),
László Attila Tóth72118882007-10-08 05:12:42 +0000111 .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,
Yasuyuki KOZAKAIe4cc20b2007-08-04 08:23:13 +0000117};
118
László Attila Tóth72118882007-10-08 05:12:42 +0000119static struct xtables_target classify_target6 = {
Yasuyuki KOZAKAIe4cc20b2007-08-04 08:23:13 +0000120 .family = AF_INET6,
121 .name = "CLASSIFY",
122 .version = IPTABLES_VERSION,
123 .size = XT_ALIGN(sizeof(struct xt_classify_target_info)),
124 .userspacesize = XT_ALIGN(sizeof(struct xt_classify_target_info)),
László Attila Tóth72118882007-10-08 05:12:42 +0000125 .help = CLASSIFY_help,
126 .parse = CLASSIFY_parse,
127 .final_check = CLASSIFY_final_check,
128 .print = CLASSIFY_print,
129 .save = CLASSIFY_save,
130 .extra_opts = CLASSIFY_opts,
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +0000131};
132
133void _init(void)
134{
László Attila Tóth72118882007-10-08 05:12:42 +0000135 xtables_register_target(&classify_target);
136 xtables_register_target(&classify_target6);
Joszef Kadlecsik6ab626b2003-04-11 10:14:10 +0000137}