Logo Search packages:      
Sourcecode: ebtables version File versions  Download package

ebt_802_3.c

#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 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:
                  check_option(flags, _802_3_SAP);
                  if (check_inverse(optarg))
                        info->invflags |= EBT_802_3_SAP;

                  if (optind > argc)
                        print_error("Missing 802.3-sap argument");
                  i = strtoul(argv[optind - 1], &end, 16);
                  if (i > 255 || *end != '\0') 
                        print_error("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:
                  check_option(flags, _802_3_TYPE);
                  if (check_inverse(optarg))
                        info->invflags |= EBT_802_3_TYPE;
                  if (optind > argc)
                        print_error("Missing 802.3-type argument");
                  i = strtoul(argv[optind - 1], &end, 16);
                  if (i > 65535 || *end != '\0') {
                        print_error("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))
            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       = EBT_802_3_MATCH,
      .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) __attribute__ ((constructor));
static void _init(void)
{
              register_match(&_802_3_match);
}

Generated by  Doxygen 1.6.0   Back to index