1 /* 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 7 #include <iptables.h> 8 #include <linux/netfilter_ipv4/ip_tables.h> 9 #include <linux/netfilter_ipv4/ipt_CLASSIFY.h> 10 #include <linux/types.h> 11 #include <linux/pkt_sched.h> 12 13 /* Function which prints out usage message. */ 14 static void 15 help(void) 16 { 17 printf( 18 "CLASSIFY target v%s options:\n" 19 " --set-class [MAJOR:MINOR] Set skb->priority value\n" 20 "\n", 21 IPTABLES_VERSION); 22 } 23 24 static struct option opts[] = { 25 { "set-class", 1, 0, '1' }, 26 { 0 } 27 }; 28 29 /* Initialize the target. */ 30 static void 31 init(struct ipt_entry_target *t, unsigned int *nfcache) 32 { 33 } 34 35 int string_to_priority(const char *s, unsigned int *p) 36 { 37 unsigned int i, j; 38 39 if (sscanf(s, "%x:%x", &i, &j) != 2) 40 return 1; 41 42 *p = TC_H_MAKE(i<<16, j); 43 return 0; 44 } 45 46 /* Function which parses command options; returns true if it 47 ate an option */ 48 static int 49 parse(int c, char **argv, int invert, unsigned int *flags, 50 const struct ipt_entry *entry, 51 struct ipt_entry_target **target) 52 { 53 struct ipt_classify_target_info *clinfo 54 = (struct ipt_classify_target_info *)(*target)->data; 55 56 switch (c) { 57 case '1': 58 if (string_to_priority(optarg, &clinfo->priority)) 59 exit_error(PARAMETER_PROBLEM, 60 "Bad class value `%s'", optarg); 61 if (*flags) 62 exit_error(PARAMETER_PROBLEM, 63 "CLASSIFY: Can't specify --set-class twice"); 64 *flags = 1; 65 break; 66 67 default: 68 return 0; 69 } 70 71 return 1; 72 } 73 74 static void 75 final_check(unsigned int flags) 76 { 77 if (!flags) 78 exit_error(PARAMETER_PROBLEM, 79 "CLASSIFY: Parameter --set-class is required"); 80 } 81 82 static void 83 print_class(unsigned int priority, int numeric) 84 { 85 printf("%x:%x ", TC_H_MAJ(priority)>>16, TC_H_MIN(priority)); 86 } 87 88 /* Prints out the targinfo. */ 89 static void 90 print(const struct ipt_ip *ip, 91 const struct ipt_entry_target *target, 92 int numeric) 93 { 94 const struct ipt_classify_target_info *clinfo = 95 (const struct ipt_classify_target_info *)target->data; 96 printf("CLASSIFY set "); 97 print_class(clinfo->priority, numeric); 98 } 99 100 /* Saves the union ipt_targinfo in parsable form to stdout. */ 101 static void 102 save(const struct ipt_ip *ip, const struct ipt_entry_target *target) 103 { 104 const struct ipt_classify_target_info *clinfo = 105 (const struct ipt_classify_target_info *)target->data; 106 107 printf("--set-class %.4x:%.4x ", 108 TC_H_MAJ(clinfo->priority)>>16, TC_H_MIN(clinfo->priority)); 109 } 110 111 static struct iptables_target classify = { 112 .next = NULL, 113 .name = "CLASSIFY", 114 .version = IPTABLES_VERSION, 115 .size = IPT_ALIGN(sizeof(struct ipt_classify_target_info)), 116 .userspacesize = IPT_ALIGN(sizeof(struct ipt_classify_target_info)), 117 .help = &help, 118 .init = &init, 119 .parse = &parse, 120 .final_check = &final_check, 121 .print = &print, 122 .save = &save, 123 .extra_opts = opts 124 }; 125 126 void ipt_CLASSIFY_init(void) 127 { 128 register_target(&classify); 129 } 130