Home | History | Annotate | Download | only in extensions
      1 /*
      2  * Shared library add-on to iptables to add SECMARK target support.
      3  *
      4  * Based on the MARK target.
      5  *
      6  * IPv6 version.
      7  *
      8  * Copyright (C) 2006 Red Hat, Inc., James Morris <jmorris (at) redhat.com>
      9  */
     10 #include <stdio.h>
     11 #include <string.h>
     12 #include <stdlib.h>
     13 #include <getopt.h>
     14 #include <ip6tables.h>
     15 #include <linux/netfilter/xt_SECMARK.h>
     16 
     17 #define PFX "SECMARK target: "
     18 
     19 static void help(void)
     20 {
     21 	printf(
     22 "SECMARK target v%s options:\n"
     23 "  --selctx value                     Set the SELinux security context\n"
     24 "\n",
     25 IPTABLES_VERSION);
     26 }
     27 
     28 static struct option opts[] = {
     29 	{ "selctx", 1, 0, '1' },
     30 	{ 0 }
     31 };
     32 
     33 /* Initialize the target. */
     34 static void init(struct ip6t_entry_target *t, unsigned int *nfcache)
     35 { }
     36 
     37 /*
     38  * Function which parses command options; returns true if it
     39  * ate an option.
     40  */
     41 static int parse(int c, char **argv, int invert, unsigned int *flags,
     42                  const struct ip6t_entry *entry, struct ip6t_entry_target **target)
     43 {
     44 	struct xt_secmark_target_info *info =
     45 		(struct xt_secmark_target_info*)(*target)->data;
     46 
     47 	switch (c) {
     48 	case '1':
     49 		if (*flags & SECMARK_MODE_SEL)
     50 			exit_error(PARAMETER_PROBLEM, PFX
     51 				   "Can't specify --selctx twice");
     52 		info->mode = SECMARK_MODE_SEL;
     53 
     54 		if (strlen(optarg) > SECMARK_SELCTX_MAX-1)
     55 			exit_error(PARAMETER_PROBLEM, PFX
     56 				   "Maximum length %u exceeded by --selctx"
     57 				   " parameter (%zu)",
     58 				   SECMARK_SELCTX_MAX-1, strlen(optarg));
     59 
     60 		strcpy(info->u.sel.selctx, optarg);
     61 		*flags |= SECMARK_MODE_SEL;
     62 		break;
     63 	default:
     64 		return 0;
     65 	}
     66 
     67 	return 1;
     68 }
     69 
     70 static void final_check(unsigned int flags)
     71 {
     72 	if (!flags)
     73 		exit_error(PARAMETER_PROBLEM, PFX "parameter required");
     74 }
     75 
     76 static void print_secmark(struct xt_secmark_target_info *info)
     77 {
     78 	switch (info->mode) {
     79 	case SECMARK_MODE_SEL:
     80 		printf("selctx %s ", info->u.sel.selctx);\
     81 		break;
     82 
     83 	default:
     84 		exit_error(OTHER_PROBLEM, PFX "invalid mode %hhu\n", info->mode);
     85 	}
     86 }
     87 
     88 static void print(const struct ip6t_ip6 *ip,
     89 		  const struct ip6t_entry_target *target, int numeric)
     90 {
     91 	struct xt_secmark_target_info *info =
     92 		(struct xt_secmark_target_info*)(target)->data;
     93 
     94 	printf("SECMARK ");
     95 	print_secmark(info);
     96 }
     97 
     98 /* Saves the target info in parsable form to stdout. */
     99 static void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target)
    100 {
    101 	struct xt_secmark_target_info *info =
    102 		(struct xt_secmark_target_info*)target->data;
    103 
    104 	printf("--");
    105 	print_secmark(info);
    106 }
    107 
    108 static struct ip6tables_target secmark = {
    109 	.name		= "SECMARK",
    110 	.version	= IPTABLES_VERSION,
    111 	.size		= IP6T_ALIGN(sizeof(struct xt_secmark_target_info)),
    112 	.userspacesize	= IP6T_ALIGN(sizeof(struct xt_secmark_target_info)),
    113 	.help		= &help,
    114 	.init		= &init,
    115 	.parse		= &parse,
    116 	.final_check	= &final_check,
    117 	.print		= &print,
    118 	.save		= &save,
    119 	.extra_opts	= opts
    120 };
    121 
    122 void _init(void)
    123 {
    124 	register_target6(&secmark);
    125 }
    126