IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Placer des hook sur des requêtes ARP dans un module linux en utilisant netfilter.


Sujet :

Réseau C

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2014
    Messages : 34
    Points : 25
    Points
    25
    Par défaut Placer des hook sur des requêtes ARP dans un module linux en utilisant netfilter.
    Bonjour tout le monde,

    Je débute dans la programmation de module linux et avec l'utilisation de netfilter en C.

    J'aimerais pouvoir faire un programme/module linux permettant de mettre en place des fonctions hook afin de pouvoir DROP ou ACCEPT les paquets ARP.

    Pour le moment, j'ai tenté de faire ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/netfilter_arp/arp_tables.h>
     
    static struct nf_hook_ops netfilter_ops_in;
    static struct nf_hook_ops netfilter_ops_out;
     
    static unsigned int main_hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff*)) {
      printk(KERN_ALERT "ARP !\n");
      return NF_ACCEPT;
    }
     
    static int __init mon_module_init(void) {
      printk(KERN_ALERT "init. \n");
      netfilter_ops_in.hook = main_hook;
      netfilter_ops_in.pf = NF_ARP;
      netfilter_ops_in.hooknum = NF_ARP_IN;
     
     
      netfilter_ops_out.hook = main_hook;
      netfilter_ops_out.pf = NF_ARP;
      netfilter_ops_out.hooknum = NF_ARP_OUT;
      netfilter_ops_out.priority = NF_INET_LOCAL_OUT;
     
      nf_register_hook(&netfilter_ops_out);
     
      return 0;
    }
     
    static void __exit mon_module_cleanup(void) {
      printk(KERN_ALERT "exit.\n");
      nf_unregister_hook(&netfilter_ops_out);
    }
     
    module_init(mon_module_init);
    module_exit(mon_module_cleanup);
    Mais je n'ai jamais réussis a avoir mon message : "ARP !\n" dans mon log : /var/log/syslog

    Alors que j'ai bien les messages d'init et d'exit et que ma génération de paquets ARP fonctionne (Je l'ai vérifié avec wireshark).

    De plus, quand je compile, j'obtiens ce warning :
    warning: assignment from incompatible pointer type [enabled by default]
    netfilter_ops_out.hook = main_hook;
    Merci d'avance pour votre aide,

  2. #2
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    L'argument skb doit être de type struct sk_buff ** dans la déclaration de ton handler.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2014
    Messages : 34
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    L'argument skb doit être de type struct sk_buff ** dans la déclaration de ton handler.
    J'ai corrigé l'argument de ma fonction, mais ça ne corrige toujours pas mon problème.
    J'ai toujours le même warning, et ma fonction n'est jamais appelé malgré des ARP envoyés et reçus.

  4. #4
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Oublie les tests pour le moment, il faut déjà faire taire le warning.

    Peux-tu poster :
    • la dernière version du .c qui le génère ;
    • la commande exacte de compilation ;
    • la sortie exacte et complète du compilateur ?

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2014
    Messages : 34
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Oublie les tests pour le moment, il faut déjà faire taire le warning.

    Peux-tu poster :
    • la dernière version du .c qui le génère ;
    • la commande exacte de compilation ;
    • la sortie exacte et complète du compilateur ?
    Voici la dernière version de mon .c (j'ai juste modifié le paramètre)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/netfilter_arp/arp_tables.h>
     
    static struct nf_hook_ops netfilter_ops_in;
    static struct nf_hook_ops netfilter_ops_out;
     
    static unsigned int main_hook(unsigned int hooknum, struct sk_buff **skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff*)) {
      printk(KERN_ALERT "ARP !\n");
      return NF_ACCEPT;
    }
     
    static int __init mon_module_init(void) {
      printk(KERN_ALERT "init. \n");
      netfilter_ops_in.hook = main_hook;
      netfilter_ops_in.pf = NF_ARP;
      netfilter_ops_in.hooknum = NF_ARP_IN;
     
      netfilter_ops_out.hook = main_hook;
      netfilter_ops_out.pf = NF_ARP;
      netfilter_ops_out.hooknum = NF_ARP_OUT;
      netfilter_ops_out.priority = NF_INET_LOCAL_OUT;
      nf_register_hook(&netfilter_ops_out);
     
      return 0;
    }
     
    static void __exit mon_module_cleanup(void) {
      printk(KERN_ALERT "exit.\n");
      nf_unregister_hook(&netfilter_ops_out);
    }
     
    module_init(mon_module_init);
    module_exit(mon_module_cleanup);
    Le makefile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    obj-m += arp_mod.o
     
    default:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
     
    clean:
      make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
    La sortie exacte de la compilation :
    make -C /lib/modules/3.13.0-45-generic/build M=/home/jeremy/Documents/Projets/C/test modules
    make[1]: entrant dans le répertoire « /usr/src/linux-headers-3.13.0-45-generic »
    CC [M] /home/jeremy/Documents/Projets/C/test/arp_mod.o
    /home/jeremy/Documents/Projets/C/test/arp_mod.c: In function ‘mon_module_init’:
    /home/jeremy/Documents/Projets/C/test/arp_mod.c:16:25: warning: assignment from incompatible pointer type [enabled by default]
    netfilter_ops_in.hook = main_hook;
    ^
    /home/jeremy/Documents/Projets/C/test/arp_mod.c:20:26: warning: assignment from incompatible pointer type [enabled by default]
    netfilter_ops_out.hook = main_hook;
    ^
    Building modules, stage 2.
    MODPOST 1 modules
    CC /home/jeremy/Documents/Projets/C/test/arp_mod.mod.o
    LD [M] /home/jeremy/Documents/Projets/C/test/arp_mod.ko
    make[1]: quittant le répertoire « /usr/src/linux-headers-3.13.0-45-generic »

  6. #6
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Tu as bien vérifié le type de hook de struct nf_hook_ops dans le header correspondant pour ta version de l'API ?

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2014
    Messages : 34
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Tu as bien vérifié le type de hook de struct nf_hook_ops dans le header correspondant pour ta version de l'API ?
    C'est bon, j'ai corrigé l'erreur du warning.

    En fait je cherchais dans le mauvais répertoire, du coup je ne trouvais pas la déclaration de cette structure.

    Pour info, voici ce que j'avais dans mon header :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    typedef unsigned int nf_hookfn(const struct nf_hook_ops *ops,
                 struct sk_buff *skb,
                 const struct net_device *in,
                 const struct net_device *out,
                 int (*okfn)(struct sk_buff *));
     
    struct nf_hook_ops {
      struct list_head list;
     
      /* User fills in from here down. */
      nf_hookfn *hook;
      struct module *owner;
      void    *priv;
      u_int8_t  pf;
      unsigned int  hooknum;
      /* Hooks are ordered in ascending priority. */
      int   priority;
    };
    (chez moi, skb est bien un simple pointeur)

    Voici la nouvelle version de mon .c :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/netfilter_arp/arp_tables.h>
     
    static struct nf_hook_ops netfilter_ops_in;
    static struct nf_hook_ops netfilter_ops_out;
     
    static unsigned int main_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) {
      printk(KERN_ALERT "ARP !\n");
      return NF_ACCEPT;
    }
     
    static int __init mon_module_init(void) {
      printk(KERN_ALERT "init. \n");
      netfilter_ops_in.hook = main_hook;
      netfilter_ops_in.pf = NF_ARP;
      netfilter_ops_in.hooknum = NF_ARP_IN;
     
      netfilter_ops_out.hook = main_hook;
      netfilter_ops_out.pf = NF_ARP;
      netfilter_ops_out.hooknum = NF_ARP_OUT;
      netfilter_ops_out.priority = NF_INET_LOCAL_OUT;
      nf_register_hook(&netfilter_ops_out);
     
      return 0;
    }
     
    static void __exit mon_module_cleanup(void) {
      printk(KERN_ALERT "exit.\n");
      nf_unregister_hook(&netfilter_ops_out);
    }
     
    module_init(mon_module_init);
    module_exit(mon_module_cleanup);
    En revanche, ça ne corrige pas le problème que cette fonction n'est jamais appelé.

  8. #8
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par astro01 Voir le message
    (chez moi, skb est bien un simple pointeur)
    Noté, ma doc doit dater de l'interface 2.6, je vais m'en séparer de ce pas (quoique j'ai encore un serveur sous 2.6...).


    As-tu vérifié le résultat de nf_register_hook (soit directement soit via l'appelant grâce au return) ?

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2014
    Messages
    34
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2014
    Messages : 34
    Points : 25
    Points
    25
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Noté, ma doc doit dater de l'interface 2.6, je vais m'en séparer de ce pas (quoique j'ai encore un serveur sous 2.6...).


    As-tu vérifié le résultat de nf_register_hook (soit directement soit via l'appelant grâce au return) ?
    Oui, j'ai testé avec ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/netfilter_arp/arp_tables.h>
     
    static struct nf_hook_ops netfilter_ops_in;
    static struct nf_hook_ops netfilter_ops_out;
     
    static unsigned int main_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *)) {
      printk(KERN_ALERT "ARP !\n");
      return NF_ACCEPT;
    }
     
    static int __init mon_module_init(void) {
      int res=0;
      printk(KERN_ALERT "init. \n");
      netfilter_ops_in.hook = main_hook;
      netfilter_ops_in.pf = NF_ARP;
      netfilter_ops_in.hooknum = NF_ARP_IN;
     
      netfilter_ops_out.hook = main_hook;
      netfilter_ops_out.pf = NF_ARP;
      netfilter_ops_out.hooknum = NF_ARP_OUT;
      netfilter_ops_out.priority = NF_INET_LOCAL_OUT;
      res = nf_register_hook(&netfilter_ops_out);
      printk(KERN_ALERT "ret=%d. \n", res);
     
      return 0;
    }
     
    static void __exit mon_module_cleanup(void) {
      printk(KERN_ALERT "exit.\n");
      nf_unregister_hook(&netfilter_ops_out);
    }
     
    module_init(mon_module_init);
    module_exit(mon_module_cleanup);
    La fonction nf_register_hook me retourne 0.
    J'ai bien ret=0 dans mon log.

  10. #10
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    J'ai voulu tester ton code ce week-end mais l'API netfilter sur ma machine est beaucoup trop récente (kernel 4.5). Je regarderai à nouveau lorsque j'aurai un peu plus de temps.

    Tu as essayé d'intercepter d'autres types de paquets qu'ARP en modifiant le code ?

  11. #11
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonsoir,
    Citation Envoyé par astro01 Voir le message
    Bonjour tout le monde,

    Je débute dans la programmation de module linux et avec l'utilisation de netfilter en C.

    J'aimerais pouvoir faire un programme/module linux permettant de mettre en place des fonctions hook afin de pouvoir DROP ou ACCEPT les paquets ARP.

    Pour le moment, j'ai tenté de faire ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/init.h>
    #include <linux/netfilter_arp/arp_tables.h>
    
    static struct nf_hook_ops netfilter_ops_in;
    static struct nf_hook_ops netfilter_ops_out;
    
    static unsigned int main_hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff*)) {
      printk(KERN_ALERT "ARP !\n");
      return NF_ACCEPT;
    }
    
    static int __init mon_module_init(void) {
      printk(KERN_ALERT "init. \n");
      netfilter_ops_in.hook = main_hook;
      netfilter_ops_in.pf = NF_ARP;
      netfilter_ops_in.hooknum = NF_ARP_IN;
    
    
      netfilter_ops_out.hook = main_hook;
      netfilter_ops_out.pf = NF_ARP;
      netfilter_ops_out.hooknum = NF_ARP_OUT;
      netfilter_ops_out.priority = NF_INET_LOCAL_OUT;
    
      nf_register_hook(&netfilter_ops_out);
    
      return 0;
    }
    
    static void __exit mon_module_cleanup(void) {
      printk(KERN_ALERT "exit.\n");
      nf_unregister_hook(&netfilter_ops_out);
    }
    
    module_init(mon_module_init);
    module_exit(mon_module_cleanup);
    Mais je n'ai jamais réussis a avoir mon message : "ARP !\n" dans mon log : /var/log/syslog

    Alors que j'ai bien les messages d'init et d'exit et que ma génération de paquets ARP fonctionne (Je l'ai vérifié avec wireshark).

    De plus, quand je compile, j'obtiens ce warning :


    Merci d'avance pour votre aide,

    Tout d'abord, il faut comprendre qu'un programme fait toujours ce qui est écrit et pas forcément ce qu'on a souhaité qu'il fasse donc, il faut relire le code tel qu'il est écrit et non comme celui qu'on a voulu écrire.

    C'est tout à fait normal que le module affiche uniquement le message "ARP" car c'est bien ce que vous lui avez demandé de faire (votre code source mis en gras ci-dessus). La fonction "static unsigned int main_hook" en temps normal traite les données ou les rejets selon votre implémentation. En clair, il a la charge de traiter tous les paquets ou autres. Dans votre exemple, il ne fait pas son travail (juste émettre une alerte info (ARP) vu que vous lui avez demandé de le faire).

    Ensuite votre fonction "static unsigned int main_hook" renvoie la constante "NF_ACCEPT" qui veux dire que le ou les paquets peuvent continuer à transiter (circuler) normalement donc on accepte tout, même ce dont on ne traite pas.

    La fonction d'initialisation du module (point d'entrée du module), permet d'initialiser l'ensemble du module et certaines règles mais en aucun cas elle a la charge de traiter les paquets. C'est votre fonction "static unsigned int main_hook" qui doit s'en charger.

    Donc, au final, il n'y a pas d'erreur de programmation mais il y a une erreur humaine (oubli de traiter les paquets).

    Si vous souhaitez, par exemple, afficher tous les paquet émis, voici un exemple de code source. A vous de vous en inspirer et à l'aide de la documentation vous pouvez allez plus loin.
    Dans mon exemple je liste les data émit :
    Attention, le code source ci-dessous est susceptible de contenir des erreurs.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
     
    /*
     ============================================================================
     Name        : VIGILANTE
     Author      : SAMBIA39
     Version     : 0.1
     Copyright   : Copyright (c) 09/07/2016 SAMBIA39
     Description : Ansi-style
     ============================================================================
     */
     
    #define ui_int			unsigned int
    #define PTR_NULL		(char)0
    #define EXIT_SUCCESS	0
    #define EXIT_FAILURE	1
     
    //Flag pour la conversion addresse ip
    #define FLAG_S_ADDR_A	0x000000FF
    #define FLAG_S_ADDR_B	0x0000FF00
    #define FLAG_S_ADDR_C	0x00FF0000
    #define FLAG_S_ADDR_D	0xFF000000
     
     
    #include <linux/ip.h>
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/skbuff.h>
    #include <linux/netfilter.h>
    #include <linux/netfilter_ipv4.h>
     
    MODULE_LICENSE("Dual BSD/GPL");
     
    /*
    *	Structure des DATA TRAME
    */
    typedef struct s_hoock_snif{
        struct iphdr *ptr_ipHead;
        struct sk_buff *ptr_socket_buff;
        struct nf_hook_ops nfhook;
    }DATA_SNIF_TRAME;
     
    DATA_SNIF_TRAME TRAME;
     
    /*
    *    Fonction qui se charge de
    *    traiter tout les paquet
    *    dans cette exemple il 
    *    liste les connexions
    */
    static ui_int f_hook_snif_arp( ui_int idhook,
        struct sk_buff *ptr_buff,
        int (*foksnif)(struct sk_buff*), 
        const struct net_device *ptr_rsx_out, 
        const struct net_device *ptr_rsx_in ){
     
        /*
        *    Journalisation active 
        *    Tout type de paquet même
        *    ceux qui ne sont pas analyser
        *    sont lister donc module passive
        */
        TRAME.ptr_socket_buff = ptr_buff;
        if( !TRAME.ptr_socket_buff )
            return NF_ACCEPT;
     
        //Acquisition de l'en-tête data
        TRAME.ptr_ipHead = (struct iphdr*)skb_network_header(
            TRAME.ptr_socket_buff);
     
        //Affichage si il y'a en-tête
        if( TRAME.ptr_ipHead ){
            printk(KERN_INFO 
                "ARP IP \t:%d.%d.%d.%d\tINTERCEPTER\n",
                (TRAME.ptr_ipHead->saddr & FLAG_S_ADDR_A),
                (TRAME.ptr_ipHead->saddr & FLAG_S_ADDR_B) >> 8,
                (TRAME.ptr_ipHead->saddr & FLAG_S_ADDR_C) >> 16,
                (TRAME.ptr_ipHead->saddr & FLAG_S_ADDR_D) >> 24);
        }
        return NF_ACCEPT;  // Accepte tout type de connexion
    }
     
    /*
    *    Initialisation du module
    *    et chargement.
    */   
    static int __init f_inter_arp_init( void ){
     
        printk( KERN_ALERT "VIGILANTE DATA ARP v0.0.1\n" );
        TRAME.nfhook.hooknum = 1;
        TRAME.nfhook.pf = AF_INET;
        TRAME.nfhook.hook = f_hook_snif_arp;
        TRAME.nfhook.priority = NF_IP_PRI_FIRST;
        nf_register_hook(&TRAME.nfhook);
        printk(KERN_INFO "START INTERCEPTIONS DES ARP\n" );
        return EXIT_SUCCESS;
    }
     
    /*
    *    Décharge module (hook)
    */    
    static void __exit f_inter_arp_exit( void ){
        nf_unregister_hook(&TRAME.nfhook);
        printk(KERN_ALERT "ARRET INTERCEPTION DES ARP\n" );
    }
     
    //Appel des fonction
    module_init( f_inter_arp_init );
    module_exit( f_inter_arp_exit );


    Citation Envoyé par Matt_Houston Voir le message
    Tu as bien vérifié le type de hook de struct nf_hook_ops dans le header correspondant pour ta version de l'API ?
    Oui, vu qu'il a spécifié qu'il compile en utilisant le bonne APi
    $(shell uname -r)/build M=$(PWD) et encore une fois le problème vient de l'implémentation du code, pas de la compilation.


    Citation Envoyé par Matt_Houston Voir le message
    J'ai voulu tester ton code ce week-end mais l'API netfilter sur ma machine est beaucoup trop récente (kernel 4.5). Je regarderai à nouveau lorsque j'aurai un peu plus de temps.
    Tu as essayé d'intercepter d'autres types de paquets qu'ARP en modifiant le code ?
    J'ai un noyau récent et ça compile sans problème sur ma vm je suis étonné que cela ne fonctionne pas chez vous (très bizarre)
    Pour ce qui est de la gestion d'autres paquets ou l'interception, oui cela est possible.
    En modifiant le code source que j'ai posté, on peut intercepter d'autres data voire même y mettre fin.
    L'exemple du code source suivant intercepte certains types de protocoles et en laisse passer d'autres (c'est un pare-feu rudimentaire).
    Attention le code source ci-dessous est susceptible de contenir des erreurs.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
     
    /*
    ============================================================================
     Name        : VIGILANTE
     Author      : SAMBIA39
     Version     : 0.1
     Copyright   : Copyright (c) 09/07/2016 SAMBIA39
     Description : Ansi-style
     ============================================================================
     */
     
    /*
    *	Constante
    *	utile
    */
    #define MAX_TOL			3						
    #define MAX_SEC			(MAX_TOL * MAX_TOL)+1
    #define ui_int			unsigned int
    #define PRIVATE			static 
    #define PTR_NULL		(char)0
    #define SYS_ERROR		-1
    #define EXIT_SUCCESS	0
    #define EXIT_FAILURE	1
     
    /*
    *	Flag conversion
    *	adresse ip
    */
    #define FLAG_S_ADDR_A	0x000000FF
    #define FLAG_S_ADDR_B	0x0000FF00
    #define FLAG_S_ADDR_C	0x00FF0000
    #define FLAG_S_ADDR_D	0xFF000000
     
    /*	
    *	Pour l'exemple je vais 
    *	utiliser les constantes
    *	suivantes.
    */
    #define FLAG_PROTO_ICE		8   // ICMP_ECHO 
    #define FLAG_PROTO_TCP		6	// Transmission control protocol 
    #define FLAG_PROTO_ICMP		1	// Internet control message protocol 
    #define FLAG_PROTO_UDP  	17	// User datagram protocol 
    #define FLAG_PROTO_SCTP 	132	// Stream Control Transmission Protocol 
     
    /*
    *	En-tête 
    *	Lunix-netfilter
    *   Pour l'exemple
    */
    #include <linux/in.h>         
    #include <linux/ip.h>
    #include <linux/in6.h>
    #include <linux/tcp.h>
    #include <linux/udp.h>
    #include <linux/icmp.h>
    #include <linux/igmp.h>
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/skbuff.h>
    #include <linux/netfilter.h>
    #include <linux/netfilter_ipv4.h>
     
    MODULE_LICENSE("Dual BSD/GPL");
     
    /*
    *	Structure des protocoles
    *	TCP - UDP - ICMP & SCTP
    */
    typedef struct s_hoock_type_arp{
    	struct icmphdr  *ptr_Icm;			// Protocol ICMP
    	struct udphdr 	*ptr_Udp;			// Protocol UDP
    	struct tcphdr 	*ptr_Tcp;			// Protocol TCP
    	struct sctphdr	*ptr_Sct;			// Protocol	SCTP
    }PROTOCOL;
     
    /*
    *	Structure des DATA TRAME
    */
    typedef struct s_hoock_snif{
    	PROTOCOL PROTO;
    	struct iphdr *ptr_ipHead;
    	struct nf_hook_ops nfhook;
    	struct sk_buff *ptr_socket_buff;
    }DATA_SNIF_TRAME;
     
    DATA_SNIF_TRAME TRAME;
     
    /*
    *    Fonction qui se charge de
    *    traiter tout les paquet
    *    dans cette exemple il 
    *    liste les connexions
    */
    PRIVATE ui_int f_hook_snif_arp( ui_int idhook,
    	struct sk_buff *ptr_buff,
    	int (*foksnif)(struct sk_buff*), 
    	const struct net_device *ptr_rsx_out, 
    	const struct net_device *ptr_rsx_in ){
     
    	/*
    	*	Règle de ban data
    	*/
    	PRIVATE int iTolerance;
    	PRIVATE int iSecure_drop;
     
    	/*
    	*    Journalisation active 
    	*    Tout type de paquet même
    	*    ceux qui ne sont pas analyser
    	*    sont lister donc module passive
    	*/
    	TRAME.ptr_socket_buff = ptr_buff;
    	if( !TRAME.ptr_socket_buff )
    		return NF_ACCEPT;
     
    	TRAME.ptr_ipHead = (struct iphdr*)skb_network_header(
    		TRAME.ptr_socket_buff);
     
    	if( TRAME.ptr_ipHead ){
    		printk(KERN_INFO 
    			"ARP IP \t:%d.%d.%d.%d\tINTERCEPTER\n",
    			(TRAME.ptr_ipHead->saddr & FLAG_S_ADDR_A),
    			(TRAME.ptr_ipHead->saddr & FLAG_S_ADDR_B) >> 8,
    			(TRAME.ptr_ipHead->saddr & FLAG_S_ADDR_C) >> 16,
    			(TRAME.ptr_ipHead->saddr & FLAG_S_ADDR_D) >> 24);
     
    		/*
    		*    Traitement des datas selon le 
    		*    protocole 
    		*	 TCP & UDP sont accepter
    		*    PING-ECHO est tolérée MAX 3
    		*    PING est tolérer MAX 10 
    		*    ( mémo code a revoir pour la gestion ping)
    		*/
    		switch( TRAME.ptr_ipHead->protocol ){
    			case FLAG_PROTO_TCP:
    				TRAME.PROTO.ptr_Tcp = 
    					(struct tcphdr*)( 
    						(__u32 *)TRAME.ptr_ipHead+TRAME.ptr_ipHead->ihl);
    				//f_printk_hack_spoof_addr( TRAME.ptr_ipHead );
    				printk(KERN_INFO "\t[DATA_TCP]\tSRC\t:%d\tDST\t:%d\n",
    					TRAME.PROTO.ptr_Tcp->source,
    					TRAME.PROTO.ptr_Tcp->dest );
    				return NF_ACCEPT;
    				break; // non executé
     
    			case FLAG_PROTO_UDP:
    				TRAME.PROTO.ptr_Udp = 
    					(struct udphdr*)(
    						(__u32 *)TRAME.ptr_ipHead+TRAME.ptr_ipHead->ihl);
    				printk(KERN_INFO "\t[DATA_UDP]\tSRC\t:%d\tDST\t:%d\n", 
    					TRAME.PROTO.ptr_Udp->source,
    					TRAME.PROTO.ptr_Udp->dest );
    				return NF_ACCEPT;
    				break; //non executé
     
    			case FLAG_PROTO_SCTP:
    				TRAME.PROTO.ptr_Sct =
    					(struct sctphdr*)(
    						(__u32 *)TRAME.ptr_ipHead+TRAME.ptr_ipHead->ihl);
    				printk(KERN_INFO "\t[DATA_SCT DETECTER]\n");
    				return NF_ACCEPT;
    				break; //non executé
     
    			case FLAG_PROTO_ICE:
    				TRAME.PROTO.ptr_Icm =
    					(struct udphdr*)(
    						(__u32 *)TRAME.ptr_ipHead+TRAME.ptr_ipHead->ihl);
    				printk(KERN_ALERT "\t[DATA_ICM PING-ECHO BANNI]\n");
    				return NF_DROP;
    				break;	//non executé
     
    			case FLAG_PROTO_ICMP:
    				if( MAX_TOL == iTolerance ){
    					printk(KERN_ALERT "\t[DATA_ICM SECURITER PING DROP -> %d/%d]\n",
    						 iTolerance, MAX_TOL );
    					return NF_DROP;
    				}
    				TRAME.PROTO.ptr_Icm =
    					(struct icmphdr*)(
    						(__u32 *)TRAME.ptr_ipHead+TRAME.ptr_ipHead->ihl);
    				printk(KERN_ALERT "\t[PING TOLERER %d/%d]\n",iTolerance, MAX_TOL);
    				++iTolerance;
    				return NF_ACCEPT;
    				break;	//non executé
     
    			default:
    				if( MAX_SEC == iSecure_drop){
    					printk(KERN_ALERT"\t[SECURITER AUTRE PROTO BANNI-> %d/%d]\n",
    						iSecure_drop, MAX_SEC );
    					return NF_DROP;
    				}
    				printk(KERN_ALERT"\t[SECURITER AUTRE PROTO TOLERER-> %d/%d]\n",
    					iSecure_drop, MAX_SEC );
    				++iSecure_drop;
    				return NF_ACCEPT;
    				break; // non executé
    		}
    	}
    	return NF_ACCEPT;
    }
     
    /*
    *    Initialisation du module
    *    et chargement.
    */   
    static int __init f_inter_arp_init( void ){
     
    	printk( KERN_ALERT "VIGILANTE DATA ARP v0.0.1\n" );
    	TRAME.nfhook.hooknum = 1;
    	TRAME.nfhook.pf = AF_INET;
    	TRAME.nfhook.hook = f_hook_snif_arp;
    	TRAME.nfhook.priority = NF_IP_PRI_FIRST;
    	nf_register_hook(&TRAME.nfhook);
    	printk(KERN_INFO "START INTERCEPTIONS DES ARP\n" );
    	return EXIT_SUCCESS;
    }
     
    /*
    *    Décharge module (hook)
    */    
    static void __exit f_inter_arp_exit( void ){
    	nf_unregister_hook(&TRAME.nfhook);
    	printk(KERN_ALERT "ARRET INTERCEPTION DES ARP\n" );
    }
     
    //Appel des fonction
    module_init( f_inter_arp_init );
    module_exit( f_inter_arp_exit );

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

Discussions similaires

  1. Réponses: 5
    Dernier message: 21/12/2015, 18h20
  2. Réponses: 1
    Dernier message: 30/09/2014, 16h29
  3. Trigger pour mettre des droits sur des procedures et des vues
    Par briino dans le forum Développement
    Réponses: 3
    Dernier message: 23/09/2009, 09h44
  4. des requetes sur des champs basés dans l'ecran forms
    Par moezsokrati dans le forum Forms
    Réponses: 6
    Dernier message: 15/01/2009, 13h23
  5. [Hook] utilisation des hook sur SVN
    Par billone007 dans le forum Subversion
    Réponses: 1
    Dernier message: 22/11/2006, 16h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo