• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Shared library add-on to iptables to add TOS target support. */
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <getopt.h>
6 
7 #include <iptables.h>
8 #include <linux/netfilter_ipv4/ip_tables.h>
9 #include <linux/netfilter_ipv4/ipt_TOS.h>
10 
11 struct tosinfo {
12 	struct ipt_entry_target t;
13 	struct ipt_tos_target_info tos;
14 };
15 
16 /* TOS names and values. */
17 static
18 struct TOS_value
19 {
20 	unsigned char TOS;
21 	const char *name;
22 } TOS_values[] = {
23 	{ IPTOS_LOWDELAY,    "Minimize-Delay" },
24 	{ IPTOS_THROUGHPUT,  "Maximize-Throughput" },
25 	{ IPTOS_RELIABILITY, "Maximize-Reliability" },
26 	{ IPTOS_MINCOST,     "Minimize-Cost" },
27 	{ IPTOS_NORMALSVC,   "Normal-Service" },
28 };
29 
30 /* Function which prints out usage message. */
31 static void
help(void)32 help(void)
33 {
34 	unsigned int i;
35 
36 	printf(
37 "TOS target v%s options:\n"
38 "  --set-tos value                   Set Type of Service field to one of the\n"
39 "                                following numeric or descriptive values:\n",
40 IPTABLES_VERSION);
41 
42 	for (i = 0; i < sizeof(TOS_values)/sizeof(struct TOS_value);i++)
43 		printf("                                     %s %u (0x%02x)\n",
44 		       TOS_values[i].name,
45                        TOS_values[i].TOS,
46                        TOS_values[i].TOS);
47 	fputc('\n', stdout);
48 }
49 
50 static struct option opts[] = {
51 	{ "set-tos", 1, 0, '1' },
52 	{ 0 }
53 };
54 
55 /* Initialize the target. */
56 static void
init(struct ipt_entry_target * t,unsigned int * nfcache)57 init(struct ipt_entry_target *t, unsigned int *nfcache)
58 {
59 }
60 
61 static void
parse_tos(const char * s,struct ipt_tos_target_info * info)62 parse_tos(const char *s, struct ipt_tos_target_info *info)
63 {
64 	unsigned int i, tos;
65 
66 	if (string_to_number(s, 0, 255, &tos) != -1) {
67 		if (tos == IPTOS_LOWDELAY
68 		    || tos == IPTOS_THROUGHPUT
69 		    || tos == IPTOS_RELIABILITY
70 		    || tos == IPTOS_MINCOST
71 		    || tos == IPTOS_NORMALSVC) {
72 		    	info->tos = (u_int8_t )tos;
73 		    	return;
74 		}
75 	} else {
76 		for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++)
77 			if (strcasecmp(s,TOS_values[i].name) == 0) {
78 				info->tos = TOS_values[i].TOS;
79 				return;
80 			}
81 	}
82 	exit_error(PARAMETER_PROBLEM, "Bad TOS value `%s'", s);
83 }
84 
85 /* Function which parses command options; returns true if it
86    ate an option */
87 static int
parse(int c,char ** argv,int invert,unsigned int * flags,const struct ipt_entry * entry,struct ipt_entry_target ** target)88 parse(int c, char **argv, int invert, unsigned int *flags,
89       const struct ipt_entry *entry,
90       struct ipt_entry_target **target)
91 {
92 	struct ipt_tos_target_info *tosinfo
93 		= (struct ipt_tos_target_info *)(*target)->data;
94 
95 	switch (c) {
96 	case '1':
97 		if (*flags)
98 			exit_error(PARAMETER_PROBLEM,
99 			           "TOS target: Cant specify --set-tos twice");
100 		parse_tos(optarg, tosinfo);
101 		*flags = 1;
102 		break;
103 
104 	default:
105 		return 0;
106 	}
107 
108 	return 1;
109 }
110 
111 static void
final_check(unsigned int flags)112 final_check(unsigned int flags)
113 {
114 	if (!flags)
115 		exit_error(PARAMETER_PROBLEM,
116 		           "TOS target: Parameter --set-tos is required");
117 }
118 
119 static void
print_tos(u_int8_t tos,int numeric)120 print_tos(u_int8_t tos, int numeric)
121 {
122 	unsigned int i;
123 
124 	if (!numeric) {
125 		for (i = 0; i<sizeof(TOS_values)/sizeof(struct TOS_value); i++)
126 			if (TOS_values[i].TOS == tos) {
127 				printf("%s ", TOS_values[i].name);
128 				return;
129 			}
130 	}
131 	printf("0x%02x ", tos);
132 }
133 
134 /* Prints out the targinfo. */
135 static void
print(const struct ipt_ip * ip,const struct ipt_entry_target * target,int numeric)136 print(const struct ipt_ip *ip,
137       const struct ipt_entry_target *target,
138       int numeric)
139 {
140 	const struct ipt_tos_target_info *tosinfo =
141 		(const struct ipt_tos_target_info *)target->data;
142 	printf("TOS set ");
143 	print_tos(tosinfo->tos, numeric);
144 }
145 
146 /* Saves the union ipt_targinfo in parsable form to stdout. */
147 static void
save(const struct ipt_ip * ip,const struct ipt_entry_target * target)148 save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
149 {
150 	const struct ipt_tos_target_info *tosinfo =
151 		(const struct ipt_tos_target_info *)target->data;
152 
153 	printf("--set-tos 0x%02x ", tosinfo->tos);
154 }
155 
156 static struct iptables_target tos = {
157 	.next		= NULL,
158 	.name		= "TOS",
159 	.version	= IPTABLES_VERSION,
160 	.size		= IPT_ALIGN(sizeof(struct ipt_tos_target_info)),
161 	.userspacesize	= IPT_ALIGN(sizeof(struct ipt_tos_target_info)),
162 	.help		= &help,
163 	.init		= &init,
164 	.parse		= &parse,
165 	.final_check	= &final_check,
166 	.print		= &print,
167 	.save		= &save,
168 	.extra_opts	= opts
169 };
170 
ipt_TOS_init(void)171 void ipt_TOS_init(void)
172 {
173 	register_target(&tos);
174 }
175