1/* Shared library add-on to ip6tables to add NFMARK matching support. */ 2#include <stdio.h> 3#include <netdb.h> 4#include <string.h> 5#include <stdlib.h> 6#include <getopt.h> 7 8#include <ip6tables.h> 9#include <linux/netfilter_ipv6/ip6t_mark.h> 10 11/* Function which prints out usage message. */ 12static void 13help(void) 14{ 15 printf( 16"MARK match v%s options:\n" 17"[!] --mark value[/mask] Match nfmark value with optional mask\n" 18"\n", 19IPTABLES_VERSION); 20} 21 22static struct option opts[] = { 23 { "mark", 1, 0, '1' }, 24 {0} 25}; 26 27/* Initialize the match. */ 28static void 29init(struct ip6t_entry_match *m, unsigned int *nfcache) 30{ 31 /* Can't cache this. */ 32 *nfcache |= NFC_UNKNOWN; 33} 34 35/* Function which parses command options; returns true if it 36 ate an option */ 37static int 38parse(int c, char **argv, int invert, unsigned int *flags, 39 const struct ip6t_entry *entry, 40 unsigned int *nfcache, 41 struct ip6t_entry_match **match) 42{ 43 struct ip6t_mark_info *markinfo = (struct ip6t_mark_info *)(*match)->data; 44 45 switch (c) { 46 char *end; 47 case '1': 48 check_inverse(optarg, &invert, &optind, 0); 49 markinfo->mark = strtoul(optarg, &end, 0); 50 if (*end == '/') { 51 markinfo->mask = strtoul(end+1, &end, 0); 52 } else 53 markinfo->mask = 0xffffffff; 54 if (*end != '\0' || end == optarg) 55 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg); 56 if (invert) 57 markinfo->invert = 1; 58 *flags = 1; 59 break; 60 61 default: 62 return 0; 63 } 64 return 1; 65} 66 67static void 68print_mark(unsigned long mark, unsigned long mask, int invert, int numeric) 69{ 70 if (invert) 71 fputc('!', stdout); 72 73 if(mask != 0xffffffff) 74 printf("0x%lx/0x%lx ", mark, mask); 75 else 76 printf("0x%lx ", mark); 77} 78 79/* Final check; must have specified --mark. */ 80static void 81final_check(unsigned int flags) 82{ 83 if (!flags) 84 exit_error(PARAMETER_PROBLEM, 85 "MARK match: You must specify `--mark'"); 86} 87 88/* Prints out the matchinfo. */ 89static void 90print(const struct ip6t_ip6 *ip, 91 const struct ip6t_entry_match *match, 92 int numeric) 93{ 94 printf("MARK match "); 95 print_mark(((struct ip6t_mark_info *)match->data)->mark, 96 ((struct ip6t_mark_info *)match->data)->mask, 97 ((struct ip6t_mark_info *)match->data)->invert, numeric); 98} 99 100/* Saves the union ip6t_matchinfo in parsable form to stdout. */ 101static void 102save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match) 103{ 104 printf("--mark "); 105 print_mark(((struct ip6t_mark_info *)match->data)->mark, 106 ((struct ip6t_mark_info *)match->data)->mask, 107 ((struct ip6t_mark_info *)match->data)->invert, 0); 108} 109 110static 111struct ip6tables_match mark 112= { NULL, 113 "mark", 114 IPTABLES_VERSION, 115 IP6T_ALIGN(sizeof(struct ip6t_mark_info)), 116 IP6T_ALIGN(sizeof(struct ip6t_mark_info)), 117 &help, 118 &init, 119 &parse, 120 &final_check, 121 &print, 122 &save, 123 opts 124}; 125 126void _init(void) 127{ 128 register_match6(&mark); 129} 130