libxt_CLASSIFY.c revision 6ab626bb74153c180f98e8ba6c8bff88d2d45ebc
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
76ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik#include <iptables.h>
86ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik#include <linux/netfilter_ipv4/ip_tables.h>
96ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik#include <linux/netfilter_ipv4/ipt_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
156ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikhelp(void)
166ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
176ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf(
186ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik"CLASSIFY target v%s options:\n"
196ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik"  --set-class [MAJOR:MINOR]    Set skb->priority value\n"
206ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik"\n",
216ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef KadlecsikIPTABLES_VERSION);
226ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
236ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
246ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic struct option opts[] = {
256ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	{ "set-class", 1, 0, '1' },
266ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	{ 0 }
276ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik};
286ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
296ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Initialize the target. */
306ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
316ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikinit(struct ipt_entry_target *t, unsigned int *nfcache)
326ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
336ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
346ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
356ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikint string_to_priority(const unsigned char *s, unsigned int *p)
366ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
376ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	unsigned int i, j;
386ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
396ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	if (sscanf(s, "%x:%x", &i, &j) != 2)
406ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		return 1;
416ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
426ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	*p = TC_H_MAKE(i<<16, j);
436ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	return 0;
446ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
456ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
466ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Function which parses command options; returns true if it
476ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik   ate an option */
486ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic int
496ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikparse(int c, char **argv, int invert, unsigned int *flags,
506ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik      const struct ipt_entry *entry,
516ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik      struct ipt_entry_target **target)
526ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
536ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	struct ipt_classify_target_info *clinfo
546ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		= (struct ipt_classify_target_info *)(*target)->data;
556ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
566ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	switch (c) {
576ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	case '1':
586ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		if (string_to_priority(optarg, &clinfo->priority))
596ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik			exit_error(PARAMETER_PROBLEM,
606ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik				   "Bad class value `%s'", optarg);
616ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		if (*flags)
626ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik			exit_error(PARAMETER_PROBLEM,
636ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik			           "CLASSIFY: Can't specify --set-class twice");
646ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		*flags = 1;
656ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		break;
666ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
676ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	default:
686ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		return 0;
696ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	}
706ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
716ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	return 1;
726ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
736ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
746ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
756ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikfinal_check(unsigned int flags)
766ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
776ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	if (!flags)
786ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		exit_error(PARAMETER_PROBLEM,
796ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		           "CLASSIFY: Parameter --set-class is required");
806ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
816ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
826ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
836ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikprint_class(unsigned int priority, int numeric)
846ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
856ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf("%x:%x ", TC_H_MAJ(priority)>>16, TC_H_MIN(priority));
866ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
876ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
886ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Prints out the targinfo. */
896ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
906ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikprint(const struct ipt_ip *ip,
916ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik      const struct ipt_entry_target *target,
926ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik      int numeric)
936ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
946ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	const struct ipt_classify_target_info *clinfo =
956ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		(const struct ipt_classify_target_info *)target->data;
966ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf("CLASSIFY set ");
976ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	print_class(clinfo->priority, numeric);
986ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
996ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
1006ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Saves the union ipt_targinfo in parsable form to stdout. */
1016ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void
1026ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsiksave(const struct ipt_ip *ip, const struct ipt_entry_target *target)
1036ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
1046ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	const struct ipt_classify_target_info *clinfo =
1056ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik		(const struct ipt_classify_target_info *)target->data;
1066ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
1076ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	printf("--set-class %.4x:%.4x ",
1086ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	       TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority));
1096ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
1106ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
1116ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic
1126ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstruct iptables_target classify
1136ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik= { NULL,
1146ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    "CLASSIFY",
1156ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    IPTABLES_VERSION,
1166ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    IPT_ALIGN(sizeof(struct ipt_classify_target_info)),
1176ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    IPT_ALIGN(sizeof(struct ipt_classify_target_info)),
1186ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    &help,
1196ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    &init,
1206ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    &parse,
1216ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    &final_check,
1226ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    &print,
1236ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    &save,
1246ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik    opts
1256ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik};
1266ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik
1276ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikvoid _init(void)
1286ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{
1296ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik	register_target(&classify);
1306ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}
131