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