blob: 5137adb844c38c6f4d527eac9405aeb58e41e236 [file] [log] [blame]
/*
* ==[ FILENAME: ebtc_test.c ]==================================================
*
* Project
*
* Library for ethernet bridge tables.
*
*
* Description
*
* Test for this library.
*
*
* Copyright
*
* Copyright 2005 by Jens Götze
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
* USA.
*
*
* =============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <util.h>
#include <libebtc.h>
int insert_entry (const char *chain, ebtc_handle_t *handle)
{
/* ---- VAR ---- */
unsigned int size = 0;
struct ebt_entry *entry;
struct ebt_standard_target
*std_target;
struct ebt_entry_target *target;
/* ---- CODE ---- */
/* Allocate memory */
size += EBTC_ALIGN(sizeof(struct ebt_entry));
size += EBTC_ALIGN(sizeof(struct ebt_standard_target));
entry = (struct ebt_entry *)malloc(size);
if (!entry) {
eprintf("Can't allocate memory\n");
return -1;
}
memset(entry, 0, size);
size = EBTC_ALIGN(sizeof(*entry));
std_target = (struct ebt_standard_target *)((char *)entry + size);
/* Prepare entry */
entry->bitmask = EBT_ENTRY_OR_ENTRIES | EBT_NOPROTO;
entry->watchers_offset = EBTC_ALIGN(sizeof(*entry));
entry->target_offset = entry->watchers_offset;
entry->next_offset = entry->target_offset + EBTC_ALIGN(sizeof(*std_target));
/* Prepare target */
target = &std_target->target;
target->target_size = EBTC_ALIGN(sizeof(*std_target));
target->target_size -= EBTC_ALIGN(sizeof(*target));
snprintf(target->u.name, EBT_FUNCTION_MAXNAMELEN, "standard");
std_target->verdict = EBT_CONTINUE;
/* Append */
if (ebtc_insert_entry(chain, entry, 0, handle)) {
eprintf("Can't insert entry\n");
free(entry);
return -1;
}
free(entry);
return 0;
}
int replace_entry (const char *chain, ebtc_handle_t *handle)
{
/* ---- VAR ---- */
unsigned int size = 0;
struct ebt_entry *entry;
struct ebt_standard_target
*std_target;
struct ebt_entry_target *target;
/* ---- CODE ---- */
/* Allocate memory */
size += EBTC_ALIGN(sizeof(struct ebt_entry));
size += EBTC_ALIGN(sizeof(struct ebt_standard_target));
entry = (struct ebt_entry *)malloc(size);
if (!entry) {
eprintf("Can't allocate memory\n");
return -1;
}
memset(entry, 0, size);
size = EBTC_ALIGN(sizeof(*entry));
std_target = (struct ebt_standard_target *)((char *)entry + size);
/* Prepare entry */
entry->bitmask = EBT_ENTRY_OR_ENTRIES | EBT_NOPROTO;
entry->watchers_offset = EBTC_ALIGN(sizeof(*entry));
entry->target_offset = entry->watchers_offset;
entry->next_offset = entry->target_offset + EBTC_ALIGN(sizeof(*std_target));
/* Prepare target */
target = &std_target->target;
target->target_size = EBTC_ALIGN(sizeof(*std_target));
target->target_size -= EBTC_ALIGN(sizeof(*target));
snprintf(target->u.name, EBT_FUNCTION_MAXNAMELEN, "standard");
std_target->verdict = EBT_ACCEPT;
/* Append */
if (ebtc_replace_entry(chain, entry, 1, handle)) {
eprintf("Can't replace entry\n");
free(entry);
return -1;
}
free(entry);
return 0;
}
int append_entry (const char *chain, ebtc_handle_t *handle, char *chainname)
{
/* ---- VAR ---- */
unsigned int size = 0;
struct ebt_entry *entry;
struct ebt_standard_target
*std_target;
struct ebt_entry_target *target;
/* ---- CODE ---- */
/* Allocate memory */
size += EBTC_ALIGN(sizeof(struct ebt_entry));
size += EBTC_ALIGN(sizeof(struct ebt_standard_target));
entry = (struct ebt_entry *)malloc(size);
if (!entry) {
eprintf("Can't allocate memory\n");
return -1;
}
memset(entry, 0, size);
size = EBTC_ALIGN(sizeof(*entry));
std_target = (struct ebt_standard_target *)((char *)entry + size);
/* Prepare entry */
entry->bitmask = EBT_ENTRY_OR_ENTRIES | EBT_NOPROTO;
entry->watchers_offset = EBTC_ALIGN(sizeof(*entry));
entry->target_offset = entry->watchers_offset;
entry->next_offset = entry->target_offset + EBTC_ALIGN(sizeof(*std_target));
/* Prepare target */
if (ebtc_target_jumptochain(std_target, chainname, handle)) {
eprintf("Can't jump to chain\n");
return -1;
}
/* Append */
if (ebtc_append_entry(chain, entry, handle)) {
eprintf("Can't append entry\n");
free(entry);
return -1;
}
free(entry);
return 0;
}
int main ()
{
/* ---- VAR ---- */
int i;
const char *chain;
const char *policy;
ebtc_handle_t handle;
const struct ebt_entry *rule;
struct ebt_counter counter_new;
const struct ebt_counter
*counter;
/* ---- CODE ---- */
/* Open ebtables handle */
handle = ebtc_init("filter", EBTC_INIT_WITHFLUSH);
if (!handle) {
eprintf("Can't open ebtables (%s)\n", ebtc_strerror(NULL));
return 1;
}
if (ebtc_commit(&handle)) {
eprintf("Can't commit ebtables changes\n");
return 1;
}
/* Open ebtables handle */
handle = ebtc_init("filter", EBTC_INIT_WITHFLUSH);
if (!handle) {
eprintf("Can't open ebtables (%s)\n", ebtc_strerror(NULL));
return 1;
}
/* Entry functions */
if (append_entry("FORWARD", &handle, "CONTINUE")) {
eprintf("Can't append entry\n");
ebtc_free(&handle);
return 1;
}
if (append_entry("FORWARD", &handle, "CONTINUE")) {
eprintf("Can't append entry\n");
ebtc_free(&handle);
return 1;
}
if (insert_entry("FORWARD", &handle)) {
eprintf("Can't insert entry\n");
ebtc_free(&handle);
return 1;
}
if (replace_entry("FORWARD", &handle)) {
eprintf("Can't replace entry\n");
ebtc_free(&handle);
return 1;
}
/* Set policies */
policy = ebtc_get_policy("FORWARD", &handle);
if (!policy) {
eprintf("Can't get policy of chain\n");
ebtc_free(&handle);
return 1;
}
printf("Chain policy before change: %s\n", policy);
if (ebtc_set_policy("FORWARD", "DROP", &handle)) {
eprintf("Can't set policy\n");
ebtc_free(&handle);
return 1;
}
policy = ebtc_get_policy("FORWARD", &handle);
if (!policy) {
eprintf("Can't get policy of chain\n");
ebtc_free(&handle);
return 1;
}
printf("Chain policy after change: %s\n", policy);
printf("\n");
/* Create chain */
if (ebtc_create_chain("test_prerename", &handle)) {
eprintf("Can't create chain\n");
ebtc_free(&handle);
return 1;
}
if (ebtc_rename_chain("test_prerename", "test", &handle)) {
eprintf("Can't rename chain\n");
ebtc_free(&handle);
return 1;
}
/* Delete chain */
printf("Chains before delete:\n");
chain = ebtc_first_chain(&handle);
while (chain) {
printf(" Chain: '%s'\n", chain);
chain = ebtc_next_chain(&handle);
}
if (ebtc_delete_chain("test", &handle)) {
eprintf("Can't delete chain\n");
ebtc_free(&handle);
return 1;
}
printf("Chains after delete:\n");
chain = ebtc_first_chain(&handle);
while (chain) {
printf(" Chain: '%s'\n", chain);
chain = ebtc_next_chain(&handle);
}
printf("\n");
/* Delete entry test */
if (append_entry("INPUT", &handle, "RETURN")) {
eprintf("Can't append entry\n");
ebtc_free(&handle);
return 1;
}
counter_new.bcnt = 1;
counter_new.pcnt = 2;
if (ebtc_set_counter("INPUT", 0, &counter_new, &handle)) {
eprintf("Can't set counter\n");
ebtc_free(&handle);
return -1;
}
if (insert_entry("INPUT", &handle)) {
eprintf("Can't insert entry\n");
ebtc_free(&handle);
return 1;
}
printf("Rule list in chain INPUT before delete\n");
i = 0;
rule = ebtc_first_rule("INPUT", &handle);
while (rule) {
counter = ebtc_read_counter("INPUT", i++, &handle);
printf(" Entry jump to '%s' (bcnt = %lld; pcnt = %lld)\n",
ebtc_get_target(rule, &handle), counter->bcnt, counter->pcnt);
rule = ebtc_next_rule("INPUT", &handle);
}
if (ebtc_delete_entry("INPUT", 0, &handle)) {
eprintf("Can't delete entry\n");
ebtc_free(&handle);
return 1;
}
if (ebtc_zero_counter("INPUT", 0, &handle)) {
eprintf("Can't zero counter\n");
ebtc_free(&handle);
return 1;
}
printf("Rule list in chain INPUT after delete\n");
i = 0;
rule = ebtc_first_rule("INPUT", &handle);
while (rule) {
counter = ebtc_read_counter("INPUT", i++, &handle);
printf(" Entry jump to '%s' (bcnt = %lld; pcnt = %lld)\n",
ebtc_get_target(rule, &handle), counter->bcnt, counter->pcnt);
rule = ebtc_next_rule("INPUT", &handle);
}
printf("\n");
/* Counter test */
if (append_entry("OUTPUT", &handle, "DROP")) {
eprintf("Can't append entry\n");
ebtc_free(&handle);
return 1;
}
if (ebtc_zero_entries("OUTPUT", &handle)) {
eprintf("Can't zero counter of chain\n");
return 1;
}
/* Jump to chain */
if (ebtc_create_chain("test2", &handle)) {
eprintf("Can't create chain\n");
ebtc_free(&handle);
return 1;
}
if (append_entry("OUTPUT", &handle, "test2")) {
eprintf("Can't append entry\n");
ebtc_free(&handle);
return 1;
}
/* Submit changes to kernel */
if (ebtc_commit(&handle)) {
eprintf("Can't commit ebtables changes (%s)\n", ebtc_strerror(NULL));
return 1;
}
printf("Test successful finished.\n\n");
return 0;
}