1/* Shared library add-on to iptables to add MARK target support. */ 2#include <stdio.h> 3#include <string.h> 4#include <stdlib.h> 5#include <getopt.h> 6 7#include <ip6tables.h> 8#include <linux/netfilter_ipv6/ip6_tables.h> 9/* For 64bit kernel / 32bit userspace */ 10#include "../include/linux/netfilter_ipv6/ip6t_MARK.h" 11 12/* Function which prints out usage message. */ 13static void 14help(void) 15{ 16 printf( 17"MARK target v%s options:\n" 18" --set-mark value Set nfmark value\n" 19"\n", 20IPTABLES_VERSION); 21} 22 23static struct option opts[] = { 24 { .name = "set-mark", .has_arg = 1, .flag = 0, .val = '1' }, 25 { .name = 0 } 26}; 27 28/* Initialize the target. */ 29static void 30init(struct ip6t_entry_target *t, unsigned int *nfcache) 31{ 32} 33 34/* Function which parses command options; returns true if it 35 ate an option */ 36static int 37parse(int c, char **argv, int invert, unsigned int *flags, 38 const struct ip6t_entry *entry, 39 struct ip6t_entry_target **target) 40{ 41 struct ip6t_mark_target_info *markinfo 42 = (struct ip6t_mark_target_info *)(*target)->data; 43 44 switch (c) { 45 case '1': 46#ifdef KERNEL_64_USERSPACE_32 47 if (string_to_number_ll(optarg, 0, 0, 48 &markinfo->mark)) 49#else 50 if (string_to_number_l(optarg, 0, 0, 51 &markinfo->mark)) 52#endif 53 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg); 54 if (*flags) 55 exit_error(PARAMETER_PROBLEM, 56 "MARK target: Can't specify --set-mark twice"); 57 *flags = 1; 58 break; 59 60 default: 61 return 0; 62 } 63 64 return 1; 65} 66 67static void 68final_check(unsigned int flags) 69{ 70 if (!flags) 71 exit_error(PARAMETER_PROBLEM, 72 "MARK target: Parameter --set-mark is required"); 73} 74 75#ifdef KERNEL_64_USERSPACE_32 76static void 77print_mark(unsigned long long mark) 78{ 79 printf("0x%llx ", mark); 80} 81#else 82static void 83print_mark(unsigned long mark) 84{ 85 printf("0x%lx ", mark); 86} 87#endif 88 89/* Prints out the targinfo. */ 90static void 91print(const struct ip6t_ip6 *ip, 92 const struct ip6t_entry_target *target, 93 int numeric) 94{ 95 const struct ip6t_mark_target_info *markinfo = 96 (const struct ip6t_mark_target_info *)target->data; 97 98 printf("MARK set "); 99 print_mark(markinfo->mark); 100} 101 102/* Saves the union ipt_targinfo in parsable form to stdout. */ 103static void 104save(const struct ip6t_ip6 *ip, const struct ip6t_entry_target *target) 105{ 106 const struct ip6t_mark_target_info *markinfo = 107 (const struct ip6t_mark_target_info *)target->data; 108 109 printf("--set-mark "); 110 print_mark(markinfo->mark); 111} 112 113static 114struct ip6tables_target mark = { 115 .name = "MARK", 116 .version = IPTABLES_VERSION, 117 .size = IP6T_ALIGN(sizeof(struct ip6t_mark_target_info)), 118 .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_mark_target_info)), 119 .help = &help, 120 .init = &init, 121 .parse = &parse, 122 .final_check = &final_check, 123 .print = &print, 124 .save = &save, 125 .extra_opts = opts 126}; 127 128void _init(void) 129{ 130 register_target6(&mark); 131} 132