blob: dcf54488edd5099c63c6d8dbf75574ef2995d8c9 [file] [log] [blame]
Marc Bouchere6869a82000-03-20 06:03:29 +00001/* Shared library add-on to iptables 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 <iptables.h>
9#include <linux/netfilter_ipv4/ipt_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",
19NETFILTER_VERSION);
20}
21
22static struct option opts[] = {
23 { "mark", 1, 0, '1' },
24 {0}
25};
26
27/* Initialize the match. */
28static void
29init(struct ipt_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 ipt_entry *entry,
40 unsigned int *nfcache,
41 struct ipt_entry_match **match)
42{
43 struct ipt_mark_info *markinfo = (struct ipt_mark_info *)(*match)->data;
44
45 switch (c) {
46 char *end;
47 case '1':
48 if (check_inverse(optarg, &invert))
49 optind++;
50 markinfo->mark = strtoul(optarg, &end, 0);
51 if (*end == '/') {
52 markinfo->mask = strtoul(end+1, &end, 0);
53 } else
54 markinfo->mask = 0xffffffff;
55 if (*end != '\0' || end == optarg)
56 exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
57 if (invert)
58 markinfo->invert = 1;
59 *flags = 1;
60 break;
61
62 default:
63 return 0;
64 }
65 return 1;
66}
67
68static void
69print_mark(unsigned long mark, unsigned long mask, int invert, int numeric)
70{
71 if (invert)
72 fputc('!', stdout);
Rusty Russell7e53bf92000-03-20 07:03:28 +000073
Marc Bouchere6869a82000-03-20 06:03:29 +000074 if(mask != 0xffffffff)
75 printf("0x%lx/0x%lx ", mark, mask);
76 else
77 printf("0x%lx ", mark);
78}
79
80/* Final check; must have specified --mark. */
81static void
82final_check(unsigned int flags)
83{
84 if (!flags)
85 exit_error(PARAMETER_PROBLEM,
86 "MARK match: You must specify `--mark'");
87}
88
89/* Prints out the matchinfo. */
90static void
91print(const struct ipt_ip *ip,
92 const struct ipt_entry_match *match,
93 int numeric)
94{
95 printf("MARK match ");
96 print_mark(((struct ipt_mark_info *)match->data)->mark,
97 ((struct ipt_mark_info *)match->data)->mask,
98 ((struct ipt_mark_info *)match->data)->invert, numeric);
99}
100
101/* Saves the union ipt_matchinfo in parsable form to stdout. */
102static void
103save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
104{
105 printf("--mark ");
106 print_mark(((struct ipt_mark_info *)match->data)->mark,
107 ((struct ipt_mark_info *)match->data)->mask,
108 ((struct ipt_mark_info *)match->data)->invert, 0);
109}
110
111struct iptables_match mark
112= { NULL,
113 "mark",
114 NETFILTER_VERSION,
115 sizeof(struct ipt_mark_info),
116 &help,
117 &init,
118 &parse,
119 &final_check,
120 &print,
121 &save,
122 opts
123};
124
125void _init(void)
126{
127 register_match(&mark);
128}