iptables-1.2.9-2.3.1.src.rpm
[iptables.git] / extensions / libip6t_mark.c
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. */
12 static void
13 help(void)
14 {
15         printf(
16 "MARK match v%s options:\n"
17 "[!] --mark value[/mask]         Match nfmark value with optional mask\n"
18 "\n",
19 IPTABLES_VERSION);
20 }
21
22 static struct option opts[] = {
23         { "mark", 1, 0, '1' },
24         {0}
25 };
26
27 /* Initialize the match. */
28 static void
29 init(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 */
37 static int
38 parse(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
67 static void
68 print_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. */
80 static void
81 final_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. */
89 static void
90 print(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. */
101 static void
102 save(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
110 static
111 struct 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
126 void _init(void)
127 {
128         register_match6(&mark);
129 }