PDF de programación - Entorno de programación de nivel 1: La librería PCAP

Imágen de pdf Entorno de programación de nivel 1: La librería PCAP

Entorno de programación de nivel 1: La librería PCAPgráfica de visualizaciones

Publicado el 7 de Julio del 2019
674 visualizaciones desde el 7 de Julio del 2019
189,5 KB
6 paginas
Creado hace 6a (14/02/2018)
Entorno de programación de nivel 1: La librería PCAP

La librería libpcap nos permite capturar paquetes desde un programa C. En sistemas Windows,
la librería se llama Winpcap.

Para compilar cualquier programa que haga uso de la librería libpcap necesitamos incluir el
fichero de cabecera pcap.h en las fuentes (#include <pcap.h>) y añadir en la cadena de
compilación la orden –lpcap.

También se puede usar el makefile junto con el resto de archivos de cabecera y librería que se
ha colgado en el Moodle de la asignatura.

Para instalarla la librería en un sistema basado en Debian (Ubuntu por ejemplo) se puede
ejecutar: sudo apt_get install libpcap_dev

Veamos primero las funciones básicas que nos permite la libpcap:

Capturar de un interfaz

Para abrir un interfaz para captura:

pcap_t *pcap_open_live(const char *device, int snaplen,int promisc, int to_ms, char *errbuf);

• Device: es el nombre de la interfaz que se quiere abrir (eth0, eth1...).


snaplen: es la cantidad de bytes que se quieren guardar por cada paquete. Es útil
cuando no nos interesa la carga útil del paquete y así reduciríamos el tamaño de la
captura. Por defecto usaremos el valor 1514 (MTU Ethernet).
promisc: indica si queremos abrirla en modo promiscuo (promisc=1) o no (promisc=0).
to_ms duración del timeout de lectura. Tiempo que se espera para leer varios
paquetes en una misma transacción.




• En errbuf se guarda el mensaje de error, si procede.

La función nos devuelve el puntero al descriptor de fichero pcap. Este descriptor es necesario
cuando vayamos a realizar alguna operación sobre el tráfico. Por ejemplo leer un paquete. A
efectos prácticos esta estructura es similar a un FILE *

Hay que recordar que para abrir una interfaz es necesario tener permisos de superusuario.

Ejemplo:

p=pcap_open_live(“eth0”,0,1, 100, errbuf);

Abre para la interfaz eth0 en modo promiscuo, capturando el paquete en su totalidad, con un
timeout de lectura de 100 ms.

En caso de error, guarda el mensaje en la cadena errbuf. En esta práctica no se realizarán
capturas sobre interfaces.





Recibir tramas:

Para la recepción de tramas vamos a utilizar la función:

int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);

• p: es un puntero a una estructura pcap_t previamente rellena por la función



pcap_open_live.
callback: función que será ejecutada cada vez se reciba una trama. Esta función es la
función de notificación de nivel 1. Esta función tiene la siguiente interfaz:

o

typedef void (*pcap_handler)(u_char *user, const struct pcap_pkthdr *h,
const u_char *bytes);

• user: información a nivel de usuario que se desea pasar cada vez que se reciba una

trama. Si no se desea pasar nada se debe rellenar con NULL.

Ejemplo:

void attendPacket(u_char *user,const struct pcap_pkthdr *h,const u_char *packet)

{

}

printf(“Paquete recibido\n”);

Int main(int argc,char *argv[])

{

if((p=pcap_open_live("eth0",1514,1,timeout, errbuff))==NULL)

return -1;

pcap_loop(p,-1,attendPacket,NULL);

pcap_close(p);

}

ATENCIÓN: La función pcap_loop es bloqueante, es decir, una vez llamemos a la función no se
ejecutará el código que está a continuación antes que no salgamos del loop de captura. Para
salir del loop de captura se debe utilizar la función pcap_breakloop.





void pcap_breakloop(pcap_t *p);

• p: descriptor pcap que se está utilizando para la captura.

La función pcap_breakloop debe ser llamada en la función FinalizarNivel1a.

Enviar paquetes:

Para el envío de tramas Ethernet vamos a usar la función:

int pcap_sendpacket(pcap_t *p, const u_char *buf, int size);

• p: es un puntero a una estructura pcap_t previamente rellena por la función

pcap_open_live.

• buf: Buffer donde está almacenado el paquete que se desea enviar.


size: Tamaño del paquete a enviar.

La función devuelve el número de bytes que han sido correctamente enviados.

Cerrar Captura:

Las capturas abiertas con pcap_open_live, se cierran con pcap_close.

void pcap_close(pcap_t *p);

• p es el fichero a cerrar





Uso de hilos:

La función pcap_loop debe ser llamada en IniciarNivel1a. Para evitar el bloqueo en la función
de
inicialización se propone hacer uso de hilos. Los hilos permiten ejecutar tareas
concurrentemente en el S.O. Para lanzar un hilo se utiliza la función:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)

(void *), void *arg);



thread: estructura de hilo que será rellena por la función pthread_create. Esta
estructura se usará posteriormente para comprobar la finalización del hilo.

• Attr: atributos de ejecución del hilo. En nuestro caso pasaremos NULL para utilizar los

atributos por defecto.

• Start_routine: puntero a función que se ejecutará en el nuevo hilo que se cree. Esta

función debe tener el siguiente prototipo:
o void * threadFunction(void *args)

• arg: conjunto de argumentos que serán pasados a la función anterior (start_routine)
como primer argumento. En nuestro caso no hará falta usar este valor y se puede
pasar a NULL.

Es importante entender el concepto que hay detrás de los hilos. Cuando se llama a la función
pthread_create se crean 2 flujos de ejecución en paralelo. El primero continúa con el programa
principal ejecutando las instrucciones posteriores a pthread_create. El segundo ejecutará en
paralelo la función pasada como segundo argumento. Una vez que dicha función retorna, se
considera que el hilo ha terminado. Para comprobar que el hilo ha acabado se usa la función:

int pthread_join(pthread_t t,void **retval);




t:Identificador de hilo del cual queremos comprobar su finalización.
retval: valor de retorno de
la función pasada como segundo argumento a
pthread_create. En nuestro caso este valor será NULL ya que la función de hilo no
debe devolver nada.





Ejemplo:

void * startCapture(void *arg)
{

printf(“Esto es el hilo y se ejecuta en paralelo\n”);

}

pthread_t tid;
int main(int argc,char *argv[])
{

printf(“iniciamos el programa y vamos a crear un hilo\n”);
pthread_create(&tid,NULL,startCapture,NULL);
printf(“Esto es el main\n”);
pthread_join(tid,NULL);
return 0;

}

Para utilizar hilos en un programa en C se debe hacer un include de pthread.h y compilar
utilizando la opción –lpthread.

¿Cómo funciona la recepción de un paquete en el nivel1a?

A continuación se presenta un gráfico de llamadas que representa las funciones que se llaman
cada vez que se recibe un paquete.



Función de callback de
nivel Superior



Función de callback.
AttendPacket



pcap_loop

Nueva trama



NOTA FINAL: La comunicación entre la parte emisora y la parte receptora de un programa
debe realizarse a través de variables globales. Estas variables globales deben ser protegidas
con semáforos (pthread_mutex) si van a ser accedidas concurrentemente. Hay que tener en
cuenta que la parte receptora y la emisora ejecutarán en paralelo generalmente ya que
llamaremos a la función pcap_loop dentro de un nuevo hilo.
  • Links de descarga
http://lwp-l.com/pdf16240

Comentarios de: Entorno de programación de nivel 1: La librería PCAP (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad