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