Pregunta

Quiero escribir una herramienta de análisis en tiempo real para el tráfico inalámbrico.

¿Alguien sabe cómo leer desde un dispositivo promiscuo (o rastreador) en C?

Sé que necesitas tener acceso de root para hacerlo.Me preguntaba si alguien sabe qué funciones son necesarias para hacer esto.Los enchufes normales no parecen tener sentido aquí.

¿Fue útil?

Solución

En Linux se utiliza un socket PF_PACKET para leer datos desde un dispositivo sin formato, como una interfaz Ethernet que se ejecuta en modo promiscuo:

s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))

Esto enviará copias de cada paquete recibido hasta su socket.Sin embargo, es muy probable que no quieras todos los paquetes.El kernel puede realizar un primer nivel de filtrado usando BPF, el Filtro de paquetes Berkeley.BPF es esencialmente una máquina virtual basada en pila:maneja un pequeño conjunto de instrucciones como:

ldh = load halfword (from packet)  
jeq = jump if equal  
ret = return with exit code  

El código de salida de BPF le dice al kernel si debe copiar el paquete al socket o no.Es posible escribir programas BPF relativamente pequeños directamente, utilizando setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER,).(ADVERTENCIA:El kernel toma una estructura sock_fprog, no una estructura bpf_program, no las mezcle o su programa no funcionará en algunas plataformas).

Para cualquier cosa razonablemente compleja, realmente querrás usar libpcap.BPF está limitado en lo que puede hacer, en particular en la cantidad de instrucciones que puede ejecutar por paquete. libcap se encargará de dividir un filtro complejo en dos partes, con el núcleo realizando un primer nivel de filtrado y el código de espacio de usuario más capaz descartando los paquetes que en realidad no quería ver.

libpcap también abstrae la interfaz del kernel del código de su aplicación.Linux y BSD usan API similares, pero Solaris requiere DLPI y Windows usa algo más.

Otros consejos

Una vez tuve que escuchar en marcos de Ethernet sin formato y terminé creando un contenedor para esto.Llamando a la función con el nombre del dispositivo, por ejemplo eth0 A cambio recibí un enchufe que estaba en modo promiscuo.Lo que hay que hacer es crear un socket sin formato y luego ponerlo en modo promiscuo.Así es como lo hice.

int raw_init (const char *device)
{
    struct ifreq ifr;
    int raw_socket;

    memset (&ifr, 0, sizeof (struct ifreq));

    /* Open A Raw Socket */
    if ((raw_socket = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 1)
    {
        printf ("ERROR: Could not open socket, Got #?\n");
        exit (1);
    }

    /* Set the device to use */
    strcpy (ifr.ifr_name, device);

    /* Get the current flags that the device might have */
    if (ioctl (raw_socket, SIOCGIFFLAGS, &ifr) == -1)
    {
        perror ("Error: Could not retrive the flags from the device.\n");
        exit (1);
    }

    /* Set the old flags plus the IFF_PROMISC flag */
    ifr.ifr_flags |= IFF_PROMISC;
    if (ioctl (raw_socket, SIOCSIFFLAGS, &ifr) == -1)
    {
        perror ("Error: Could not set flag IFF_PROMISC");
        exit (1);
    }
    printf ("Entering promiscuous mode\n");

    /* Configure the device */

    if (ioctl (raw_socket, SIOCGIFINDEX, &ifr) < 0)
    {
        perror ("Error: Error getting the device index.\n");
        exit (1);
    }

    return raw_socket;
}

Luego, cuando tenga su socket, puede usar select para manejar los paquetes a medida que llegan.

Podrías usar la biblioteca pcap (ver http://www.tcpdump.org/pcap.htm) que también utilizan tcpdump y Wireshark.

¿Por qué no usarías algo como alambreshark?

Es de código abierto, por lo que al menos puedes aprender algunas cosas de él si no quieres simplemente usarlo.

WireShark en Linux tiene la capacidad de capturar la información del encabezado PLCP (protocolo de convergencia de capa física).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top