Home | History | Annotate | Download | only in extensions
      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