1 /* Shared library add-on to iptables for condition match */ 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <getopt.h> 6 #include <iptables.h> 7 8 #include<linux/netfilter_ipv4/ip_tables.h> 9 #include<linux/netfilter_ipv4/ipt_condition.h> 10 11 12 static void 13 help(void) 14 { 15 printf("condition match v%s options:\n" 16 "--condition [!] filename " 17 "Match on boolean value stored in /proc file\n", 18 IPTABLES_VERSION); 19 } 20 21 22 static struct option opts[] = { 23 { .name = "condition", .has_arg = 1, .flag = 0, .val = 'X' }, 24 { .name = 0 } 25 }; 26 27 static int 28 parse(int c, char **argv, int invert, unsigned int *flags, 29 const struct ipt_entry *entry, unsigned int *nfcache, 30 struct ipt_entry_match **match) 31 { 32 struct condition_info *info = 33 (struct condition_info *) (*match)->data; 34 35 if (c == 'X') { 36 if (*flags) 37 exit_error(PARAMETER_PROBLEM, 38 "Can't specify multiple conditions"); 39 40 check_inverse(optarg, &invert, &optind, 0); 41 42 if (strlen(argv[optind - 1]) < CONDITION_NAME_LEN) 43 strcpy(info->name, argv[optind - 1]); 44 else 45 exit_error(PARAMETER_PROBLEM, 46 "File name too long"); 47 48 info->invert = invert; 49 *flags = 1; 50 return 1; 51 } 52 53 return 0; 54 } 55 56 57 static void 58 final_check(unsigned int flags) 59 { 60 if (!flags) 61 exit_error(PARAMETER_PROBLEM, 62 "Condition match: must specify --condition"); 63 } 64 65 66 static void 67 print(const struct ipt_ip *ip, 68 const struct ipt_entry_match *match, int numeric) 69 { 70 const struct condition_info *info = 71 (const struct condition_info *) match->data; 72 73 printf("condition %s%s ", (info->invert) ? "!" : "", info->name); 74 } 75 76 77 static void 78 save(const struct ipt_ip *ip, 79 const struct ipt_entry_match *match) 80 { 81 const struct condition_info *info = 82 (const struct condition_info *) match->data; 83 84 printf("--condition %s\"%s\" ", (info->invert) ? "! " : "", info->name); 85 } 86 87 88 static struct iptables_match condition = { 89 .name = "condition", 90 .version = IPTABLES_VERSION, 91 .size = IPT_ALIGN(sizeof(struct condition_info)), 92 .userspacesize = IPT_ALIGN(sizeof(struct condition_info)), 93 .help = &help, 94 .parse = &parse, 95 .final_check = &final_check, 96 .print = &print, 97 .save = &save, 98 .extra_opts = opts 99 }; 100 101 102 void 103 ipt_condition_init(void) 104 { 105 register_match(&condition); 106 } 107