blob: 953a1159d6bc7b1a71c23641512bcbad9073ebb9 [file] [log] [blame]
Bart De Schuymer8e0e25d2003-05-12 17:00:26 +00001#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <getopt.h>
5#include "../include/ebtables_u.h"
6#include "../include/ethernetdb.h"
7#include <linux/netfilter_bridge/ebt_802_3.h>
8
9#define _802_3_SAP '1'
10#define _802_3_TYPE '2'
11
12static struct option opts[] =
13{
14 { "802_3-sap" , required_argument, 0, _802_3_SAP },
15 { "802_3-type" , required_argument, 0, _802_3_TYPE },
16 { 0 }
17};
18
19static void print_help()
20{
21 printf(
22"802_3 options:\n"
23"--802_3-sap [!] protocol : 802.3 DSAP/SSAP- 1 byte value (hex)\n"
24" DSAP and SSAP are always the same. One SAP applies to both fields\n"
25"--802_3-type [!] protocol : 802.3 SNAP Type- 2 byte value (hex)\n"
26" Type implies SAP value 0xaa\n");
27}
28
29static void init(struct ebt_entry_match *match)
30{
31 struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data;
32
33 info->invflags = 0;
34 info->bitmask = 0;
Bart De Schuymer8e0e25d2003-05-12 17:00:26 +000035}
36
37static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
38 unsigned int *flags, struct ebt_entry_match **match)
39{
40 struct ebt_802_3_info *info = (struct ebt_802_3_info *) (*match)->data;
41 unsigned int i;
42 char *end;
43
44 switch (c) {
45 case _802_3_SAP:
46 check_option(flags, _802_3_SAP);
47 if (check_inverse(optarg))
48 info->invflags |= EBT_802_3_SAP;
49
50 if (optind > argc)
51 print_error("Missing 802.3-sap argument");
52 i = strtoul(argv[optind - 1], &end, 16);
53 if (i > 255 || *end != '\0')
54 print_error("Problem with specified "
55 "sap hex value, %x",i);
56 info->sap = i; /* one byte, so no byte order worries */
57 info->bitmask |= EBT_802_3_SAP;
58 break;
59 case _802_3_TYPE:
60 check_option(flags, _802_3_TYPE);
61 if (check_inverse(optarg))
62 info->invflags |= EBT_802_3_TYPE;
63 if (optind > argc)
64 print_error("Missing 802.3-type argument");
65 i = strtoul(argv[optind - 1], &end, 16);
66 if (i > 65535 || *end != '\0') {
67 print_error("Problem with the specified "
68 "type hex value, %x",i);
69 }
70 info->type = htons(i);
71 info->bitmask |= EBT_802_3_TYPE;
72 break;
73 default:
74 return 0;
75 }
76 return 1;
77}
78
79static void final_check(const struct ebt_u_entry *entry,
80 const struct ebt_entry_match *match, const char *name,
81 unsigned int hookmask, unsigned int time)
82{
83 if (!(entry->bitmask & EBT_802_3))
84 print_error("For 802.3 DSAP/SSAP filtering the protocol "
85 "must be LENGTH");
86}
87
88static void print(const struct ebt_u_entry *entry,
89 const struct ebt_entry_match *match)
90{
91 struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data;
92
93 if (info->bitmask & EBT_802_3_SAP) {
94 printf("--802_3-sap ");
95 if (info->invflags & EBT_802_3_SAP)
96 printf("! ");
97 printf("0x%.2x ", info->sap);
98 }
99 if (info->bitmask & EBT_802_3_TYPE) {
100 printf("--802_3-type ");
101 if (info->invflags & EBT_802_3_TYPE)
102 printf("! ");
103 printf("0x%.4x ", ntohs(info->type));
104 }
105}
106
107static int compare(const struct ebt_entry_match *m1,
108 const struct ebt_entry_match *m2)
109{
110 struct ebt_802_3_info *info1 = (struct ebt_802_3_info *)m1->data;
111 struct ebt_802_3_info *info2 = (struct ebt_802_3_info *)m2->data;
112
113 if (info1->bitmask != info2->bitmask)
114 return 0;
115 if (info1->invflags != info2->invflags)
116 return 0;
117 if (info1->bitmask & EBT_802_3_SAP) {
118 if (info1->sap != info2->sap)
119 return 0;
120 }
121 if (info1->bitmask & EBT_802_3_TYPE) {
122 if (info1->type != info2->type)
123 return 0;
124 }
125 return 1;
126}
127
128static struct ebt_u_match _802_3_match =
129{
130 EBT_802_3_MATCH,
131 sizeof(struct ebt_802_3_info),
132 print_help,
133 init,
134 parse,
135 final_check,
136 print,
137 compare,
138 opts
139};
140
141static void _init(void) __attribute__ ((constructor));
142static void _init(void)
143{
144 register_match(&_802_3_match);
145}