blob: 5b5cb0398d559afaca40508b494ce90baff84cdb [file] [log] [blame]
/* ebt_pkttype
*
* Authors:
* Bart De Schuymer <bdschuym@pandora.be>
*
* April, 2003
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <netdb.h>
#include "../include/ebtables_u.h"
#include <linux/if_packet.h>
#include <linux/netfilter_bridge/ebt_pkttype.h>
char *classes[] =
{
"host",
"broadcast",
"multicast",
"otherhost",
"outgoing",
"loopback",
"fastroute",
"\0"
};
static struct option opts[] =
{
{ "pkttype-type" , required_argument, 0, '1' },
{ 0 }
};
static void print_help()
{
printf(
"pkttype options:\n"
"--pkttype-type [!] type: class the packet belongs to\n"
"Possible values: broadcast, multicast, host, otherhost, or any other byte value (which would be pretty useless).\n");
}
static void init(struct ebt_entry_match *match)
{
struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data;
pt->invert = 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_pkttype_info *ptinfo = (struct ebt_pkttype_info *)(*match)->data;
char *end;
long int i;
switch (c) {
case '1':
ebt_check_option2(flags, 1);
if (ebt_check_inverse2(optarg))
ptinfo->invert = 1;
i = strtol(optarg, &end, 16);
if (*end != '\0') {
int j = 0;
i = -1;
while (classes[j][0])
if (!strcasecmp(optarg, classes[j++])) {
i = j - 1;
break;
}
}
if (i < 0 || i > 255)
ebt_print_error2("Problem with specified pkttype class");
ptinfo->pkt_type = (uint8_t)i;
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)
{
}
static void print(const struct ebt_u_entry *entry,
const struct ebt_entry_match *match)
{
struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data;
int i = 0;
printf("--pkttype-type %s", pt->invert ? "! " : "");
while (classes[i++][0]);
if (pt->pkt_type < i - 1)
printf("%s ", classes[pt->pkt_type]);
else
printf("%d ", pt->pkt_type);
}
static int compare(const struct ebt_entry_match *m1,
const struct ebt_entry_match *m2)
{
struct ebt_pkttype_info *pt1 = (struct ebt_pkttype_info *)m1->data;
struct ebt_pkttype_info *pt2 = (struct ebt_pkttype_info *)m2->data;
if (pt1->invert != pt2->invert ||
pt1->pkt_type != pt2->pkt_type)
return 0;
return 1;
}
static struct ebt_u_match pkttype_match =
{
.name = "pkttype",
.size = sizeof(struct ebt_pkttype_info),
.help = print_help,
.init = init,
.parse = parse,
.final_check = final_check,
.print = print,
.compare = compare,
.extra_ops = opts,
};
void _init(void)
{
ebt_register_match(&pkttype_match);
}