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