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