Domanda

In sostanza, voglio scrivere un modulo del kernel che aggiunge un possibile filtro per ebtables. Poi ho bisogno di dire ebtables di usare il mio filtro su un ponte che ho creato.

La ragione per cui ho bisogno di scrivere il mio modulo è che io voglio introdurre ritardo tra pacchetti consecutivi (per qualche motivo il test). Per dimostrare, la mia rete ha origine un traffico in questo modo:

+++-----------------+++-----------------+++-----------------+++-----------------

dove spettacoli + traffico di un pacchetto e - significa nessun pacchetto sulla linea. Voglio mettere un ponte in mezzo in modo che il modello dei pacchetti cambierebbe a questo:

+----+----+---------+----+----+---------+----+----+---------+----+----+---------

Questo significa che avrei assicurarsi che non vi sarebbe una certa quantità di ritardo tra l'arrivo di ogni pacchetto.

Ora ho scritto il seguente codice semplice, che ho praticamente preso da linux-source / net / bridge / netfilter / ebt_ip.c:

static bool match(const struct sk_buff *skb, const struct xt_match_param *par)
{
    printk(KERN_INFO"match called\n");
    return true;  // match everything!
}

static bool check(const struct xt_mtchk_param *par)
{
    printk(KERN_INFO"check called\n");
    return true;  // pass everything!
}

static struct xt_match reg __read_mostly = {
    .name = "any",   // I made this up, but I tried also putting ip for example which didn't change anything.
    .revision = 0,
    .family = NFPROTO_BRIDGE,
    .match = match,
    .checkentry = check,
    .matchsize = XT_ALIGN(4),  // don't know what this is, so I just gave it an `int`
    .me = THIS_MODULE
};

int init_module(void)
{
    return xt_register_match(&reg);
}

void cleanup_module(void)
{
    xt_unregister_match(&reg);
}

I caricare correttamente il modulo. Ma è come se non c'è. Non ricevo i log all'interno di funzioni match e check in modo che il ponte è chiaramente non prendendo in considerazione il mio filtro. Che cosa sto facendo di sbagliato?

Ho provato molte combinazioni di caricare il mio filtro prima, l'istituzione del primo ponte o l'impostazione di regole ebtables prima, ma nessuno di loro cambiare nulla.

P.S. Il ponte stesso funziona. Sono certo che ebtables è anche a tutti gli effetti, perché se aggiungo una politica di abbandonare pacchetti, non li ricevo sul computer finale. Quello che non riesco a capire è come dire ebtables di prendere in considerazione il mio filtro anche.

È stato utile?

Soluzione

Per usare un modulo del kernel, è anche bisogno di scrivere un plugin appropriato per il programma userspace, e successivamente, inserire una regola la invoca.

Se non si dispone di alcuna opzione, non specificare qualsiasi parametro .matchsize a struct xt_match (pari a specificare 0).

Altri suggerimenti

Ho ottenuto questo lavoro, non nel modo più elegante, ma in ogni caso, vi scrivo qui per un futuro Wanderer:

Diciamo che il nome del filtro è: "qualsiasi"

User-spazio plug

È necessario intestazioni che non sono disponibili al di fuori della fonte ebtables. Quindi, ottenere il codice sorgente, e passare alla cartella di estensioni. Nel Makefile, aggiungere any a EXT_FUNC (cioè gli obiettivi da costruire) e scrivere il file sorgente ebt_any.c simile al seguente:

#include <stdio.h>
#include <getopt.h>
#include "../include/ebtables_u.h"

/*struct whatever
{
        int a;
};*/

static struct option _any_opts[] =
{
        {"use-any", required_argument, 0, 0},
        {'\0'}
};

static void _any_help(void)
{
        printf("any match options: nothing!\n");
}

static void _any_init(struct ebt_entry_match *match)
{
        printf("any_init\n");
}

static void _any_check(const struct ebt_u_entry *entry, const struct ebt_entry_match *match, const char *name,
        unsigned int hookmask, unsigned int time)
{
        printf("any_check\n");
}

static int _any_parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, unsigned int *flags, struct ebt_entry_match **match)
{
        printf("any_parse: %d\n", c);
        if (c == 0)
                return 1;
        return 0;       // return true for anything
}

static int _any_compare(const struct ebt_entry_match *m1, const struct ebt_entry_match *m2)
{
/*      struct whatever *w1 = (struct whatever *)m1->data;
        struct whatever *w2 = (struct whatever *)m2->data;
        if (w1->a != w2->a)
                return 0;*/
        return 1;
}

static void _any_print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match)
{       
        printf("any_print");
}

static struct ebt_u_match _reg = {
        .name           = "any",
//      .size           = sizeof(struct whatever),
        .help           = _any_help,
        .init           = _any_init,
        .parse          = _any_parse,
        .final_check    = _any_check,
        .print          = _any_print,
        .compare        = _any_compare,
        .extra_ops      = _any_opts,
};

void _init(void)
{
        ebt_register_match(&_reg);
}

Nota: se si dispone di dati che vanno dal user-space di spazio del kernel, scrivere qualcosa invece di struct whatever. Ho commentato fuori perché io non sto usando niente.

Nota: , anche se il programma non richiede un'opzione (come la mia, che avrebbe dovuto abbinare tutto), è necessario dare una scelta in ogni caso perché è così che ebtables sa usare il filtro .

Nota: alcune di queste funzioni sembrare inutile, ma se non li scrive, si ottiene un "BUG: unione sbagliata". Errore

Kernel-spazio modulo

Il modulo del kernel-space è più semplice:

#include <linux/netfilter/x_tables.h>
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Shahbaz Youssefi");
MODULE_ALIAS("ebt_any");

/*struct whatever
{
        int a;
};*/

static bool match(const struct sk_buff *skb, const struct xt_match_param *par)
{
        printk(KERN_INFO"Matching\n");
        return true;
}

static bool check(const struct xt_mtchk_param *par)
{
        printk(KERN_INFO"Checking\n");
        return true;
}

static struct xt_match reg __read_mostly = {
        .name           = "any",
        .match          = match,
//      .matchsize      = sizeof(struct whatever),
        .checkentry     = check,
        .me             = THIS_MODULE
};

int init_module(void)
{       
        int ret = 0;
        printk("Bridge initializing...\n");
        ret = xt_register_match(&reg);
        printk("Bridge initializing...done!\n");
        return ret;
}

void cleanup_module(void)
{
        printk("Bridge exiting...\n");
        xt_unregister_match(&reg);
        printk("Bridge exiting...done!\n");
}

Nota. se si utilizza struct whatever in user-space, è necessario utilizzare lo stesso nello spazio del kernel

Nota: in user-space a differenza di plugin che uso ebtables intestazioni / funzioni, gli usi dei moduli del kernel xtables invece !!

compilazione modulo (abbastanza standard) ed installarlo per il carico automatico. In alternativa, è possibile insmod e rmmod il modulo da soli prima di aggiungere / dopo la rimozione di regole ebtables.

Come fare ebtables utilizzare il filtro

Basta aggiungere una regola che contiene --use-any some_value e si sta bene. Ad esempio:

ebtables -A FORWARD --use-any 1 -j ACCEPT

Nota. questo --use-any rappresenta l'option che è stato dato a ebt_u_match reg.extra_ops (che è stato definito nella matrice _any_opts) nel plugin spazio utente

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top