Home | History | Annotate | Download | only in extensions
      1 /*
      2  * Shared library add-on to iptables to add CONNSECMARK target support.
      3  *
      4  * Based on the MARK and CONNMARK targets.
      5  *
      6  * Copyright (C) 2006 Red Hat, Inc., James Morris <jmorris (at) redhat.com>
      7  */
      8 #include <stdio.h>
      9 #include <string.h>
     10 #include <stdlib.h>
     11 #include <getopt.h>
     12 #include <iptables.h>
     13 #include <linux/netfilter/xt_CONNSECMARK.h>
     14 
     15 #define PFX "CONNSECMARK target: "
     16 
     17 static void help(void)
     18 {
     19 	printf(
     20 "CONNSECMARK target v%s options:\n"
     21 "  --save                   Copy security mark from packet to conntrack\n"
     22 "  --restore                Copy security mark from connection to packet\n"
     23 "\n",
     24 IPTABLES_VERSION);
     25 }
     26 
     27 static struct option opts[] = {
     28 	{ "save", 0, 0, '1' },
     29 	{ "restore", 0, 0, '2' },
     30 	{ 0 }
     31 };
     32 
     33 static int parse(int c, char **argv, int invert, unsigned int *flags,
     34                  const struct ipt_entry *entry, struct ipt_entry_target **target)
     35 {
     36 	struct xt_connsecmark_target_info *info =
     37 		(struct xt_connsecmark_target_info*)(*target)->data;
     38 
     39 	switch (c) {
     40 	case '1':
     41 		if (*flags & CONNSECMARK_SAVE)
     42 			exit_error(PARAMETER_PROBLEM, PFX
     43 				   "Can't specify --save twice");
     44 		info->mode = CONNSECMARK_SAVE;
     45 		*flags |= CONNSECMARK_SAVE;
     46 		break;
     47 
     48 	case '2':
     49 		if (*flags & CONNSECMARK_RESTORE)
     50 			exit_error(PARAMETER_PROBLEM, PFX
     51 				   "Can't specify --restore twice");
     52 		info->mode = CONNSECMARK_RESTORE;
     53 		*flags |= CONNSECMARK_RESTORE;
     54 		break;
     55 
     56 	default:
     57 		return 0;
     58 	}
     59 
     60 	return 1;
     61 }
     62 
     63 static void final_check(unsigned int flags)
     64 {
     65 	if (!flags)
     66 		exit_error(PARAMETER_PROBLEM, PFX "parameter required");
     67 
     68 	if (flags == (CONNSECMARK_SAVE|CONNSECMARK_RESTORE))
     69 		exit_error(PARAMETER_PROBLEM, PFX "only one flag of --save "
     70 		           "or --restore is allowed");
     71 }
     72 
     73 static void print_connsecmark(struct xt_connsecmark_target_info *info)
     74 {
     75 	switch (info->mode) {
     76 	case CONNSECMARK_SAVE:
     77 		printf("save ");
     78 		break;
     79 
     80 	case CONNSECMARK_RESTORE:
     81 		printf("restore ");
     82 		break;
     83 
     84 	default:
     85 		exit_error(OTHER_PROBLEM, PFX "invalid mode %hhu\n", info->mode);
     86 	}
     87 }
     88 
     89 static void print(const struct ipt_ip *ip,
     90 		  const struct ipt_entry_target *target, int numeric)
     91 {
     92 	struct xt_connsecmark_target_info *info =
     93 		(struct xt_connsecmark_target_info*)(target)->data;
     94 
     95 	printf("CONNSECMARK ");
     96 	print_connsecmark(info);
     97 }
     98 
     99 static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target)
    100 {
    101 	struct xt_connsecmark_target_info *info =
    102 		(struct xt_connsecmark_target_info*)target->data;
    103 
    104 	printf("--");
    105 	print_connsecmark(info);
    106 }
    107 
    108 static struct iptables_target connsecmark = {
    109 	.next		= NULL,
    110 	.name		= "CONNSECMARK",
    111 	.version	= IPTABLES_VERSION,
    112 	.revision	= 0,
    113 	.size		= IPT_ALIGN(sizeof(struct xt_connsecmark_target_info)),
    114 	.userspacesize	= IPT_ALIGN(sizeof(struct xt_connsecmark_target_info)),
    115 	.parse		= &parse,
    116 	.help		= &help,
    117 	.final_check	= &final_check,
    118 	.print		= &print,
    119 	.save		= &save,
    120 	.extra_opts	= opts
    121 };
    122 
    123 void ipt_CONNSECMARK_init(void)
    124 {
    125 	register_target(&connsecmark);
    126 }
    127