/* * ==[ 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 #include #include #include 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; }