[glux] Net Sniff

Pietro Bertera dr.iggy@iol.it
Sat, 08 Mar 2003 00:48:09 +0100


This is a multi-part message in MIME format.
--------------000801050707080105060301
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

Ciao all,
Sto lavorando ad un modulo del kernel per potere fare traffic shaping 
*avanzato* (parola grossa...).

Mi è stato utilie farmi un modulino che piazza 5 hook rispettivamente 
nelle in:
NF_IP_PRE_ROUTING, NF_IP_POST_ROUTING, NF_IP_LOCAL_IN, NF_IP_LOCAL_OUT, 
NF_IP_FORWARD

(che guarda caso ;) corrispondono con le catene predefinite di iptables:
PREROUTING, POSTROUTING, INPUT, OUTPUT, FORWARD)

e che per ogni pacchetto che passa in una catena stampa:
CATENA---> S: s_addr:s_port D: d_addr:d_port

mi sembra utile per iniziare a studiare l'architttura di netfilter.

Nota: se lo lanciate da un terminale sotto X non vedrete nulla (anzi 
potrebbe anche rompere le palle) perchè i terminali di X non leggono i 
messaggi del kernel (a mano di avviarli con un opzione particolare che 
non ricordo)
se lo installate fuori da X (crtl-alt-Fn) vedrete l'output

Ogni domanda, commento, proposta è sempre ben accetta.


P.S.: non è un vero sniffer perchè non legge dalla sk di rete ma dal 
kernel e non legge il payload dei pacchetti.

Ciao



--------------000801050707080105060301
Content-Type: text/x-csrc;
 name="NetSniff.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="NetSniff.c"

/*             Sat Mar  8 00:05:40 2003
 *
 *					Bertera Pietro 
 *		e-mail: p.bertera@valtellinux.it dr.iggy@iol.it
 *
 *					compile with:
 * gcc -Wall -DMODULE -D__KERNEL__ -DDEBUG -c NetSniff.c -I/usr/src/linux/include
 *
 *					run with:
 * insmod NetSnif.o
 *
 *  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 Library 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.
 */
 

#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif

#include <asm/uaccess.h>

#include <linux/module.h>

#include <linux/sched.h>
#include <linux/kernel.h> 
#include <linux/slab.h>	   
#include <linux/errno.h>  
#include <linux/types.h>  
#include <linux/interrupt.h> 

#include <linux/netdevice.h>   
#include <linux/etherdevice.h> 
#include <linux/ip.h>          
#include <linux/tcp.h>         
#include <linux/udp.h>		   
#include <linux/skbuff.h>


#include <linux/netfilter.h> 
#include <linux/netfilter_ipv4.h>

#include <linux/config.h>
#include <linux/in.h>
#include <linux/socket.h>

MODULE_LICENSE("GPL");

unsigned int netshaper_in_hook(unsigned int hooknum,
                             struct sk_buff **skb_p,
                             const struct net_device *in,
                             const struct net_device *out,
                             int (*okfn)(struct sk_buff *))
{   
    int retval = NF_ACCEPT;
	struct 	sk_buff *skb = (*skb_p); 				/* puntatore a sk_buff */		
	struct 	iphdr  *iph  = skb->nh.iph;				/* puntatore a header ip */
    struct 	tcphdr *tcph = skb->h.th; 				/* header tcp */
	struct 	udphdr *udph = skb->h.uh;				/* header udp */

	__u32   saddr = iph->saddr;						/* indirizzo sorgente */
	__u32 	daddr = iph->daddr; 					/* indirizzo destinazione */
	__u8	protocol_type  = iph->protocol; 		/* tipo di protocollo */
	__u16  	dport = 0;								/* porta destinazione */
	__u16	sport = 0;								/* porta sorgente */
	

	if(protocol_type == IPPROTO_TCP){				/* tcp */
		dport = tcph->dest;
		sport = tcph->source;
	}
	
	if(protocol_type == IPPROTO_UDP){	 			/* udp */
		dport = udph->dest;
		sport = udph->source;
	}
	
	printk("INPUT	--> S: %d.%d.%d.%d:%d  D: %d.%d.%d.%d:%d\n",NIPQUAD(saddr),sport,NIPQUAD(daddr),dport);
	
    return retval; 
}

unsigned int netshaper_out_hook(unsigned int hooknum,
                             struct sk_buff **skb_p,
                             const struct net_device *in,
                             const struct net_device *out,
                             int (*okfn)(struct sk_buff *))
{  
    int retval = NF_ACCEPT;
	struct 	sk_buff *skb = (*skb_p); 				/* puntatore a sk_buff */		
	struct 	iphdr  *iph  = skb->nh.iph;				/* puntatore a header ip */
    struct 	tcphdr *tcph = skb->h.th; 				/* header tcp */
	struct 	udphdr *udph = skb->h.uh;				/* header udp */
	
	
	__u32   saddr = iph->saddr;						/* indirizzo sorgente */
	__u32 	daddr = iph->daddr; 					/* indirizzo destinazione */
	__u8	protocol_type  = iph->protocol; 		/* tipo di protocollo */
	__u16  	dport = 0;								/* porta destinazione */
	__u16	sport = 0;								/* porta sorgente */
    
	if(protocol_type == IPPROTO_TCP){				/* tcp */
		dport = tcph->dest;
		sport = tcph->source;
	}
	
	if(protocol_type == IPPROTO_UDP){	 			/* udp */
		dport = udph->dest;
		sport = udph->source;
	}
	
	printk("OUTPUT	--> S: %d.%d.%d.%d:%d  D: %d.%d.%d.%d:%d\n",NIPQUAD(saddr),sport,NIPQUAD(daddr),dport);
	
	return retval; 
}

unsigned int netshaper_fw_hook(unsigned int hooknum,
                             struct sk_buff **skb_p,
                             const struct net_device *in,
                             const struct net_device *out,
                             int (*okfn)(struct sk_buff *))
{
    int retval = NF_ACCEPT;
	struct 	sk_buff *skb = (*skb_p); 				/* puntatore a sk_buff */		
	struct 	iphdr  *iph  = skb->nh.iph;				/* puntatore a header ip */
    struct 	tcphdr *tcph = skb->h.th; 				/* header tcp */
	struct 	udphdr *udph = skb->h.uh;				/* header udp */
	
	
	__u32   saddr = iph->saddr;						/* indirizzo sorgente */
	__u32 	daddr = iph->daddr; 					/* indirizzo destinazione */
	__u8	protocol_type  = iph->protocol; 		/* tipo di protocollo */
	__u16  	dport = 0;								/* porta destinazione */
	__u16	sport = 0;								/* porta sorgente */
   
	if(protocol_type == IPPROTO_TCP){				/* tcp */
		dport = tcph->dest;
		sport = tcph->source;
	}
	
	if(protocol_type == IPPROTO_UDP){	 			/* udp */
		dport = udph->dest;
		sport = udph->source;
	}
	
	printk("FORWARD	--> S: %d.%d.%d.%d:%d  D: %d.%d.%d.%d:%d\n",NIPQUAD(saddr),sport,NIPQUAD(daddr),dport);
	
	return retval; 
}

unsigned int netshaper_pre_hook(unsigned int hooknum,
                             struct sk_buff **skb_p,
                             const struct net_device *in,
                             const struct net_device *out,
                             int (*okfn)(struct sk_buff *))
{
    int retval = NF_ACCEPT;
	struct 	sk_buff *skb = (*skb_p); 				/* puntatore a sk_buff */		
	struct 	iphdr  *iph  = skb->nh.iph;				/* puntatore a header ip */
    struct 	tcphdr *tcph = skb->h.th; 				/* header tcp */
	struct 	udphdr *udph = skb->h.uh;				/* header udp */
	
	
	__u32   saddr = iph->saddr;						/* indirizzo sorgente */
	__u32 	daddr = iph->daddr; 					/* indirizzo destinazione */
	__u8	protocol_type  = iph->protocol; 		/* tipo di protocollo */
	__u16  	dport = 0;								/* porta destinazione */
	__u16	sport = 0;								/* porta sorgente */
   
	if(protocol_type == IPPROTO_TCP){				/* tcp */
		dport = tcph->dest;
		sport = tcph->source;
	}
	
	if(protocol_type == IPPROTO_UDP){	 			/* udp */
		dport = udph->dest;
		sport = udph->source;
	}
	
	printk("PREROUTING	--> S: %d.%d.%d.%d:%d  D: %d.%d.%d.%d:%d\n",NIPQUAD(saddr),sport,NIPQUAD(daddr),dport);
	
	return retval; 
}

unsigned int netshaper_post_hook(unsigned int hooknum,
                             struct sk_buff **skb_p,
                             const struct net_device *in,
                             const struct net_device *out,
                             int (*okfn)(struct sk_buff *))
{
    int retval = NF_ACCEPT;
	struct 	sk_buff *skb = (*skb_p); 				/* puntatore a sk_buff */		
	struct 	iphdr  *iph  = skb->nh.iph;				/* puntatore a header ip */
    struct 	tcphdr *tcph = skb->h.th; 				/* header tcp */
	struct 	udphdr *udph = skb->h.uh;				/* header udp */
	
	
	__u32   saddr = iph->saddr;						/* indirizzo sorgente */
	__u32 	daddr = iph->daddr; 					/* indirizzo destinazione */
	__u8	protocol_type  = iph->protocol; 		/* tipo di protocollo */
	__u16  	dport = 0;								/* porta destinazione */
	__u16	sport = 0;								/* porta sorgente */
   
	if(protocol_type == IPPROTO_TCP){				/* tcp */
		dport = tcph->dest;
		sport = tcph->source;
	}
	
	if(protocol_type == IPPROTO_UDP){	 			/* udp */
		dport = udph->dest;
		sport = udph->source;
	}
	
	printk("POSTROUTING	--> S: %d.%d.%d.%d:%d  D: %d.%d.%d.%d:%d\n",NIPQUAD(saddr),sport,NIPQUAD(daddr),dport);
	
	return retval; 
}

struct nf_hook_ops netshaper_in_hook_ops = {  
   hook :       netshaper_in_hook,
   pf :         PF_INET,
   hooknum :    NF_IP_LOCAL_IN,
};

struct nf_hook_ops netshaper_out_hook_ops = { 
   hook :       netshaper_out_hook,   
   pf :         PF_INET,
   hooknum :    NF_IP_LOCAL_OUT,
};

struct nf_hook_ops netshaper_fw_hook_ops = {   
   hook :       netshaper_fw_hook,   
   pf :         PF_INET,
   hooknum :    NF_IP_FORWARD,
};

struct nf_hook_ops netshaper_pre_hook_ops = {   
   hook :       netshaper_pre_hook,   
   pf :         PF_INET,
   hooknum :    NF_IP_PRE_ROUTING,
};

struct nf_hook_ops netshaper_post_hook_ops = {   
   hook :       netshaper_post_hook,   
   pf :         PF_INET,
   hooknum :    NF_IP_POST_ROUTING,
};

static int init_status_flag;
#define IN_HOOK_REGISTERED		0x02
#define OUT_HOOK_REGISTERED		0x04
#define FW_HOOK_REGISTERED		0x06
#define PRE_HOOK_REGISTERED		0x08
#define POST_HOOK_REGISTERED	0x20

void cleanup_module(void)
{

    if (init_status_flag&IN_HOOK_REGISTERED)   
       nf_unregister_hook(&netshaper_in_hook_ops);

    if (init_status_flag&OUT_HOOK_REGISTERED)   
       nf_unregister_hook(&netshaper_out_hook_ops);

	if (init_status_flag&FW_HOOK_REGISTERED)  
       nf_unregister_hook(&netshaper_fw_hook_ops);
	
	if (init_status_flag&PRE_HOOK_REGISTERED)  
       nf_unregister_hook(&netshaper_pre_hook_ops);
	
	if (init_status_flag&POST_HOOK_REGISTERED)  
       nf_unregister_hook(&netshaper_post_hook_ops);
}

int init_module(void)
{
   int result;

       result = nf_register_hook(&netshaper_in_hook_ops);
       if (result < 0) {
           printk(KERN_ERR "can't register netfilter hook");
           cleanup_module();
           return result;
       }
       init_status_flag |= IN_HOOK_REGISTERED;

       result = nf_register_hook(&netshaper_out_hook_ops);
       if (result < 0) {
           printk(KERN_ERR "can't register netfilter hook");
           cleanup_module();
           return result;
       }
       init_status_flag |= OUT_HOOK_REGISTERED;

       result = nf_register_hook(&netshaper_fw_hook_ops);
       if (result < 0) {
           printk(KERN_ERR "can't register netfilter hook");
           cleanup_module();
           return result;
       }
       init_status_flag |= FW_HOOK_REGISTERED;
	   
	   result = nf_register_hook(&netshaper_pre_hook_ops);
       if (result < 0) {
           printk(KERN_ERR "can't register netfilter hook");
           cleanup_module();
           return result;
       }
       init_status_flag |= PRE_HOOK_REGISTERED;
	   
	   result = nf_register_hook(&netshaper_post_hook_ops);
       if (result < 0) {
           printk(KERN_ERR "can't register netfilter hook");
           cleanup_module();
           return result;
       }
       init_status_flag |= POST_HOOK_REGISTERED;
	   
	   printk("Netfilter Sniff run! stop with: #rmmod NetSnif \n");

    return 0; 
}
--------------000801050707080105060301--