blob: 4fdc41d91b5f2ba2c90465f834a986eec45c8eb2 [file] [log] [blame]
Bart De Schuymera501b782002-07-20 16:15:39 +00001#include <stdio.h>
2#include <stdlib.h>
Bart De Schuymera501b782002-07-20 16:15:39 +00003#include <string.h>
4#include <getopt.h>
5#include "../include/ebtables_u.h"
6#include <linux/netfilter_bridge/ebt_mark_m.h>
7
8#define MARK '1'
9
10static struct option opts[] =
11{
Bart De Schuymer9895a8e2003-01-11 10:14:24 +000012 { "mark", required_argument, 0, MARK },
Bart De Schuymera501b782002-07-20 16:15:39 +000013 { 0 }
14};
15
16static void print_help()
17{
18 printf(
19"mark option:\n"
Bart De Schuymer22682502002-07-21 15:18:30 +000020"--mark [!] [value][/mask]: Match nfmask value (see man page)\n");
Bart De Schuymera501b782002-07-20 16:15:39 +000021}
22
23static void init(struct ebt_entry_match *match)
24{
25 struct ebt_mark_m_info *markinfo = (struct ebt_mark_m_info *)match->data;
26
Bart De Schuymer9cfd6542002-08-13 16:08:08 +000027 markinfo->mark = 0;
28 markinfo->mask = 0;
29 markinfo->invert = 0;
Bart De Schuymer22682502002-07-21 15:18:30 +000030 markinfo->bitmask = 0;
Bart De Schuymera501b782002-07-20 16:15:39 +000031}
32
33#define OPT_MARK 0x01
34static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
35 unsigned int *flags, struct ebt_entry_match **match)
36{
37 struct ebt_mark_m_info *markinfo = (struct ebt_mark_m_info *)
38 (*match)->data;
39 char *end;
40
41 switch (c) {
42 case MARK:
43 check_option(flags, MARK);
44 if (check_inverse(optarg))
45 markinfo->invert = 1;
46 if (optind > argc)
47 print_error("No mark specified");
48 markinfo->mark = strtoul(argv[optind - 1], &end, 0);
Bart De Schuymer22682502002-07-21 15:18:30 +000049 markinfo->bitmask = EBT_MARK_AND;
50 if (*end == '/') {
51 if (end == argv[optind - 1])
52 markinfo->bitmask = EBT_MARK_OR;
Bart De Schuymera501b782002-07-20 16:15:39 +000053 markinfo->mask = strtoul(end+1, &end, 0);
Bart De Schuymer22682502002-07-21 15:18:30 +000054 } else
Bart De Schuymera501b782002-07-20 16:15:39 +000055 markinfo->mask = 0xffffffff;
56 if ( *end != '\0' || end == argv[optind - 1])
57 print_error("Bad mark value '%s'", argv[optind - 1]);
58 break;
59 default:
60 return 0;
61 }
62 return 1;
63}
64
65static void final_check(const struct ebt_u_entry *entry,
66 const struct ebt_entry_match *match, const char *name,
Bart De Schuymerc9b52932002-08-24 13:26:34 +000067 unsigned int hookmask, unsigned int time)
Bart De Schuymera501b782002-07-20 16:15:39 +000068{
69}
70
71static void print(const struct ebt_u_entry *entry,
72 const struct ebt_entry_match *match)
73{
74 struct ebt_mark_m_info *markinfo =
75 (struct ebt_mark_m_info *)match->data;
76
77 printf("--mark ");
78 if (markinfo->invert)
79 printf("! ");
Bart De Schuymer22682502002-07-21 15:18:30 +000080 if (markinfo->bitmask == EBT_MARK_OR)
81 printf("/0x%lx ", markinfo->mask);
82 else if(markinfo->mask != 0xffffffff)
Bart De Schuymera501b782002-07-20 16:15:39 +000083 printf("0x%lx/0x%lx ", markinfo->mark, markinfo->mask);
84 else
85 printf("0x%lx ", markinfo->mark);
86}
87
88static int compare(const struct ebt_entry_match *m1,
89 const struct ebt_entry_match *m2)
90{
91 struct ebt_mark_m_info *markinfo1 = (struct ebt_mark_m_info *)m1->data;
92 struct ebt_mark_m_info *markinfo2 = (struct ebt_mark_m_info *)m2->data;
93
94 if (markinfo1->invert != markinfo2->invert)
95 return 0;
96 if (markinfo1->mark != markinfo2->mark)
97 return 0;
98 if (markinfo1->mask != markinfo2->mask)
99 return 0;
Bart De Schuymer22682502002-07-21 15:18:30 +0000100 if (markinfo1->bitmask != markinfo2->bitmask)
101 return 0;
Bart De Schuymera501b782002-07-20 16:15:39 +0000102 return 1;
103}
104
105static struct ebt_u_match mark_match =
106{
107 EBT_MARK_MATCH,
108 sizeof(struct ebt_mark_m_info),
109 print_help,
110 init,
111 parse,
112 final_check,
113 print,
114 compare,
Bart De Schuymer9cfd6542002-08-13 16:08:08 +0000115 opts
Bart De Schuymera501b782002-07-20 16:15:39 +0000116};
117
118static void _init(void) __attribute((constructor));
119static void _init(void)
120{
121 register_match(&mark_match);
122}