blob: 5029738df1481bbb78799d25462d334d1b9e4498 [file] [log] [blame]
Bart De Schuymera501b782002-07-20 16:15:39 +00001#include <stdio.h>
2#include <stdlib.h>
3#include <sys/socket.h>
4#include <string.h>
5#include <getopt.h>
6#include "../include/ebtables_u.h"
7#include <linux/netfilter_bridge/ebt_mark_m.h>
8
9#define MARK '1'
10
11static struct option opts[] =
12{
13 { "mark" , required_argument, 0, MARK },
14 { 0 }
15};
16
17static void print_help()
18{
19 printf(
20"mark option:\n"
Bart De Schuymer22682502002-07-21 15:18:30 +000021"--mark [!] [value][/mask]: Match nfmask value (see man page)\n");
Bart De Schuymera501b782002-07-20 16:15:39 +000022}
23
24static void init(struct ebt_entry_match *match)
25{
26 struct ebt_mark_m_info *markinfo = (struct ebt_mark_m_info *)match->data;
27
28 markinfo->mark = 0;
29 markinfo->mask = 0;
30 markinfo->invert = 0;
Bart De Schuymer22682502002-07-21 15:18:30 +000031 markinfo->bitmask = 0;
Bart De Schuymera501b782002-07-20 16:15:39 +000032}
33
34#define OPT_MARK 0x01
35static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
36 unsigned int *flags, struct ebt_entry_match **match)
37{
38 struct ebt_mark_m_info *markinfo = (struct ebt_mark_m_info *)
39 (*match)->data;
40 char *end;
41
42 switch (c) {
43 case MARK:
44 check_option(flags, MARK);
45 if (check_inverse(optarg))
46 markinfo->invert = 1;
47 if (optind > argc)
48 print_error("No mark specified");
49 markinfo->mark = strtoul(argv[optind - 1], &end, 0);
Bart De Schuymer22682502002-07-21 15:18:30 +000050 markinfo->bitmask = EBT_MARK_AND;
51 if (*end == '/') {
52 if (end == argv[optind - 1])
53 markinfo->bitmask = EBT_MARK_OR;
Bart De Schuymera501b782002-07-20 16:15:39 +000054 markinfo->mask = strtoul(end+1, &end, 0);
Bart De Schuymer22682502002-07-21 15:18:30 +000055 } else
Bart De Schuymera501b782002-07-20 16:15:39 +000056 markinfo->mask = 0xffffffff;
57 if ( *end != '\0' || end == argv[optind - 1])
58 print_error("Bad mark value '%s'", argv[optind - 1]);
59 break;
60 default:
61 return 0;
62 }
63 return 1;
64}
65
66static void final_check(const struct ebt_u_entry *entry,
67 const struct ebt_entry_match *match, const char *name,
68 unsigned int hook_mask, unsigned int time)
69{
70}
71
72static void print(const struct ebt_u_entry *entry,
73 const struct ebt_entry_match *match)
74{
75 struct ebt_mark_m_info *markinfo =
76 (struct ebt_mark_m_info *)match->data;
77
78 printf("--mark ");
79 if (markinfo->invert)
80 printf("! ");
Bart De Schuymer22682502002-07-21 15:18:30 +000081 if (markinfo->bitmask == EBT_MARK_OR)
82 printf("/0x%lx ", markinfo->mask);
83 else if(markinfo->mask != 0xffffffff)
Bart De Schuymera501b782002-07-20 16:15:39 +000084 printf("0x%lx/0x%lx ", markinfo->mark, markinfo->mask);
85 else
86 printf("0x%lx ", markinfo->mark);
87}
88
89static int compare(const struct ebt_entry_match *m1,
90 const struct ebt_entry_match *m2)
91{
92 struct ebt_mark_m_info *markinfo1 = (struct ebt_mark_m_info *)m1->data;
93 struct ebt_mark_m_info *markinfo2 = (struct ebt_mark_m_info *)m2->data;
94
95 if (markinfo1->invert != markinfo2->invert)
96 return 0;
97 if (markinfo1->mark != markinfo2->mark)
98 return 0;
99 if (markinfo1->mask != markinfo2->mask)
100 return 0;
Bart De Schuymer22682502002-07-21 15:18:30 +0000101 if (markinfo1->bitmask != markinfo2->bitmask)
102 return 0;
Bart De Schuymera501b782002-07-20 16:15:39 +0000103 return 1;
104}
105
106static struct ebt_u_match mark_match =
107{
108 EBT_MARK_MATCH,
109 sizeof(struct ebt_mark_m_info),
110 print_help,
111 init,
112 parse,
113 final_check,
114 print,
115 compare,
116 opts,
117};
118
119static void _init(void) __attribute((constructor));
120static void _init(void)
121{
122 register_match(&mark_match);
123}