Nota: DNAT y SNAT no se puede realizar en el pre .-Routing Hook (Esto no funcionará)
Configuración de prueba / * Encabezados opcionales no es necesario, si usted no ‘t quiere Eliminar * / # include / * Estos son necesarios para la funcionalidad NETFILTER * / # include # define DRIVER_AUTHOR_NAME # define DEST_PORT_NUM 2905 / * NETFILTER * / {/ * Copie el Socket Buffer * / struct / * Intialise la UDP Encabezado * / struct / * Extraer el encabezado IP * / struct / * Si la Cabecera IP es cero o SockBuff es Zero acaba de aceptar * / / * Señale la UDP Encabezado * / / * Filter sólo UDP de paquetes * / {/ * Recuperar UDP Encabezado * /
/>
Netfilter Kernel código fuente: muniTestNetfilter.c # include
# include
# define DRIVER_DESCRIPTION «NETFILTER»
estructura estática nf_hook_ops test_hookPreRouting;
estructura estática nf_hook_ops test_HookPostRouting;
/ *
* preRoutingHookEntryFunc -> Función Pre Routing
* /
static unsigned int preRoutingHookEntryFunc (
unsigned int unHookNum,
struct sk_buff * skb,
const struct net_device * INDEVICE,
const struct net_device * OUTDEVICE,
int (* okfn) (struct sk_buff *))
sk_buff * sockBuff = skb ;
udphdr * uh = NULL;
iphdr * iph = ip_hdr (SKB),
if (NULL == sockBuff | | NULL == iph)
retorno NF_ACCEPT;
uh = (struct udphdr *) (sockBuff-> data + (IPH- > DIH * 4));
if ((IPH-> protocolo == IPPROTO_UDP) &&
(Ntohs (uh-> dest) == DEST_PORT_NUM))
printk (KERN_INFO «Recived paquete antes de [Pre-Hook] con IPDest:% x: PortNum:% d»
; «IPSrc% x: PortNum:% d n»,
ntohl (IPH-> daddr), ntohs (uh-> dest),
ntohl (IPH-> saddr), ntohs (uh-> fuente));
;
/ * Realizar la DNAT en Pre-enrutamiento * /
/ * Cambiar la dirección IP Dest y mencione apropiada electrónico * /
iph-> daddr = htonl (0x0a0c075f);
printk (KERN_INFO » Recived paquete después [Pre-Hook] con IPDest:% x: PortNum:% d «
; «IPSrc% x: PortNum:% d n»,
ntohl ( iph-> daddr), ntohs (uh-> dest),
ntohl ( iph-> saddr), ntohs (uh-> fuente));
} / * Todos los paquetes Justo NF_ACCEPT
* Si se trata de paquetes de país, entonces se irá a LOCAL_IN
* Aplicación a los demás por no locales Los paquetes que irá
* GANCHO POST y salida
* /
retorno NF_ACCEPT;
}
/ *
* postRoutingHookEntryFunc -> Función Publica Routing
* * GANCHO POSTE será llamado para los paquetes locales sin fines de
* HOOK PRE_HOOK-POST través
* ADELANTE demás LOCAL_OUT – HOOK POST para los paquetes generados local del sistema (PING)
* * /
estática unsigned int postRoutingHookEntryFunc (
unsigned int unHookNum, />
estructura const net_device * INDEVICE, />
int (* okfn) (struct sk_buff *))
{/ * Copie el Socket Buffer * /
struct sk_buff * sockBuff = skb;
/ * Intialise la UDP Encabezado * / struct
udphdr * uh = NULL;
/ * Extraer el encabezado IP * / struct iphdr
* iph = ip_hdr (SKB),
/ * Si el hdr IP es Cero o Cero SockBuff es simplemente aceptar * /
if (NULL == sockBuff | | NULL == iph)
retorno NF_ACCEPT;
/ * Señale la UDP Encabezado * /
uh = (struct udphdr *) (sockBuff-> data + (IPH-> DIH * 4));
/ * Filter sólo UDP de paquetes * /
if ((IPH-> protocolo == IPPROTO_UDP) &&
(Ntohs (uh-> dest) == DEST_PORT_NUM))
{/ * Recuperar UDP Encabezado * /
printk (KERN_INFO «Recived Paquete En ANTES [HOOK Post] IPDest:% x: PortNum:% d»
«IPSrc% x: PortNum:% d n»,
; ntohl (IPH-> daddr), ntohs (uh-> dest),
; ntohl (IPH-> saddr), ntohs (uh-> fuente));
/ * Realizar el SNAT en POST-enrutamiento * /
/ * Cambiar la dirección SourceIP y mencione dirección apropiada * /
/ * Módulo de salida * /
module_exit (muni_test_netfilter_exit);
/ * Algunas MÓDULO /> PARÁMETROS * /
MODULE_AUTHOR (DRIVER_AUTHOR_NAME);
module_description (DRIVER_DESCRIPTION);
MODULE_VERSION («2.6.34.10»);
Kernel Haz archivo
obj-m + = natTest.o
natTest-OBJS: = muniTestNetfilter.o
todos:
make-C / lib / modules / $ (shell uname-r) / build M = $ módulos (PWD)
limpia:
make-C / lib / modules / $ (shell uname-r) / build M = $ (PWD) limpia
código de espacio de usuario (Se utiliza para enviar y recibir tráfico UDP)
============
# include
# include
# include
# define BUFFSIZE 5096
int sendlen, receivelen;
int i, contar, sentCnt = 0;
unsigned char buffer [BUFFSIZE];
/ * Socket cliente * / struct
sockaddr_in receivesocket;
/ * socket de servidor * / struct
sockaddr_in sendsocket;
/ * Calcetín FD /> * / int
unsigned int ch;
noOfTimes internos sin firmar;
/ * Enviar UDP de datos * / int
sendUDPData ();
/ * Recibir llamen de vuelta Función * /
void * recvNetfilterData (void *);
int main (int argc, char * argv []) {int
ret = 0;
/ * Crear el socket UDP * /
if ((sockfd = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) <0) {
perror («socket»);
return -1;}
/ * mi dirección o parámetros (Estos son necesarios para la unión del Puerto y
Dirección IP)
Enlazar a mi propio puerto y dirección * /
memset (& receivesocket, 0, sizeof (receivesocket));
receivesocket.sin_family = AF_INET ;
receivesocket.sin_addr.s_addr = htonl (INADDR_ANY);
receivesocket.sin_port = htons (2905);
; receivelen = sizeof (receivesocket);
/ * Vincular el mi Socket * /
if (bind (sockfd, (struct sockaddr *) y receivesocket , receivelen) <0) {
perror («bind»);
; return -1;}
/ * Dirección de servidor o parámetros, Envío de direcciones del sistema y el puerto Num * /
memset (& sendsocket, 0, sizeof (sendsocket));
sendsocket.sin_family = AF_INET;
/ * dar dirección IP correcta * /
sendsocket.sin_addr.s_addr = inet_addr («10.12.7.75»);
sendsocket.sin_port = htons (2905);
/ * Crear Tema Seperate * /
/ * Iniciar el Tema de recepción * /
pthread_t ThreadID;
si (pthread_create (& ThreadID, NULL, recvNetfilterData, NULL))
{printf («Error al crear proceso receptor n» );
return 0;}
/ * Hacer Loop -> Enviar UDP de datos * /
hacer
{printf («Escriba su elección :. t n «); printf />
; printf («2 exit n.»);
scanf («% d», & ch);
printf (» n»);
interruptor (ch)
{case />
printf («Introduzca la longitud de la carga útil n»);
scanf («% d», & sendlen);
printf («Introduzca las veces que desea enviar los datos n»);
scanf («% d», & noOfTimes);
/ * Enviar UDP de datos * /
sendUDPData ();
romper; />
printf («Invalid Choice n»);
break;}
} while (ch! = 2);
return 0;}
/ *
* sendUDPData
* / int
sendUDPData ()
{ ; int cuenta = 0;
memset (buffer, 31, sendlen);
; for (cuenta = 0; cuenta
(Struct sockaddr *) y sendsocket, sizeof (sendsocket))! = Sendlen)
{ ; perror («sendto»);
return -1;}
> else {
sentCnt + +;
;}}
return 0;}
/ *
* Vaciado de datos
* /
vacío dumpdata (unsigned char * de datos, unsigned int len)
{
; unsigned int uIndx;
if (data) {
for (uIndx = 0; uIndx
if (uIndx% 4 == 0)
{
; printf («»);}
printf («% 02x», los datos [uIndx]);}
} printf />
}
/ *
* recvNetfilterData ()
* /
void * recvNetfilterData (void * args) {
unsigned char buf [5096];
int receivedLen = 0;
while (1)
{
memset (buf, 0, BUFFSIZE);
/ * recibe las datos de otros sistemas * /
if ((receivedLen = recvfrom (sockfd, buf, BUFFSIZE, 0, NULL, NULL)) <0) {
perror («recvfrom»);
; return 0;}
else if (receivedLen == 0)
{printf />
{
/ * Imprimir El datos * /
printf («llam Byte de longitud% d n», receivedLen);
dumpdata (buf, receivedLen);
}}
}