libxt_CLASSIFY.c revision 8b7c64d6ba156a99008fcd810cba874c73294333
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 7e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI#include <xtables.h> 8e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI#include <linux/netfilter/x_tables.h> 9e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI#include <linux/netfilter/xt_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 1572118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_help(void) 166ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{ 176ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik printf( 188b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt"CLASSIFY target options:\n" 198b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt" --set-class [MAJOR:MINOR] Set skb->priority value\n"); 206ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik} 216ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 2272118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóthstatic const struct option CLASSIFY_opts[] = { 23500f483fff529dcd88ec96b9d5054be6cd6363a0Patrick McHardy { "set-class", 1, NULL, '1' }, 249ee386a1b6d7704b259460152c959ab0e79e02aaMax Kellermann { .name = NULL } 256ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}; 266ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 2772118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóthstatic int CLASSIFY_string_to_priority(const char *s, unsigned int *p) 286ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{ 296ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik unsigned int i, j; 306ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 316ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik if (sscanf(s, "%x:%x", &i, &j) != 2) 326ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik return 1; 336ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 346ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik *p = TC_H_MAKE(i<<16, j); 356ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik return 0; 366ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik} 376ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 386ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Function which parses command options; returns true if it 396ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik ate an option */ 406ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic int 4172118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_parse(int c, char **argv, int invert, unsigned int *flags, 42c0a9ab93f49a3d2508c95d0ca1a01c1089983731Yasuyuki KOZAKAI const void *entry, 43193df8ee3507f0c02762c88a16916c4ea950bd99Yasuyuki KOZAKAI struct xt_entry_target **target) 446ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{ 45e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI struct xt_classify_target_info *clinfo 46e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI = (struct xt_classify_target_info *)(*target)->data; 476ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 486ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik switch (c) { 496ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik case '1': 5072118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth if (CLASSIFY_string_to_priority(optarg, &clinfo->priority)) 516ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik exit_error(PARAMETER_PROBLEM, 526ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik "Bad class value `%s'", optarg); 536ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik if (*flags) 546ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik exit_error(PARAMETER_PROBLEM, 556ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik "CLASSIFY: Can't specify --set-class twice"); 566ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik *flags = 1; 576ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik break; 586ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 596ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik default: 606ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik return 0; 616ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik } 626ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 636ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik return 1; 646ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik} 656ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 666ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void 6772118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_final_check(unsigned int flags) 686ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{ 696ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik if (!flags) 706ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik exit_error(PARAMETER_PROBLEM, 716ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik "CLASSIFY: Parameter --set-class is required"); 726ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik} 736ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 746ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void 7572118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_print_class(unsigned int priority, int numeric) 766ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{ 776ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik printf("%x:%x ", TC_H_MAJ(priority)>>16, TC_H_MIN(priority)); 786ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik} 796ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 806ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Prints out the targinfo. */ 816ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void 8272118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_print(const void *ip, 83193df8ee3507f0c02762c88a16916c4ea950bd99Yasuyuki KOZAKAI const struct xt_entry_target *target, 846ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik int numeric) 856ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{ 86e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI const struct xt_classify_target_info *clinfo = 87e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI (const struct xt_classify_target_info *)target->data; 886ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik printf("CLASSIFY set "); 8972118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth CLASSIFY_print_class(clinfo->priority, numeric); 906ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik} 916ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 926ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik/* Saves the union ipt_targinfo in parsable form to stdout. */ 936ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikstatic void 9472118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila TóthCLASSIFY_save(const void *ip, const struct xt_entry_target *target) 956ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{ 96e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI const struct xt_classify_target_info *clinfo = 97e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI (const struct xt_classify_target_info *)target->data; 986ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 996ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik printf("--set-class %.4x:%.4x ", 1006ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority)); 1016ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik} 1026ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 10372118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóthstatic struct xtables_target classify_target = { 10423545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt .family = AF_UNSPEC, 105e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI .name = "CLASSIFY", 1068b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt .version = XTABLES_VERSION, 107e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI .size = XT_ALIGN(sizeof(struct xt_classify_target_info)), 108e4cc20b2367362c2f9c84c0daaccd985e3236118Yasuyuki KOZAKAI .userspacesize = XT_ALIGN(sizeof(struct xt_classify_target_info)), 10972118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth .help = CLASSIFY_help, 11072118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth .parse = CLASSIFY_parse, 11172118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth .final_check = CLASSIFY_final_check, 11272118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth .print = CLASSIFY_print, 11372118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth .save = CLASSIFY_save, 11472118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth .extra_opts = CLASSIFY_opts, 1156ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik}; 1166ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik 1176ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsikvoid _init(void) 1186ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik{ 11972118884b63f36ec0f42ce5a7e5e9569033291abLászló Attila Tóth xtables_register_target(&classify_target); 1206ab626bb74153c180f98e8ba6c8bff88d2d45ebcJoszef Kadlecsik} 121