Pergunta

Eu quero escrever uma ferramenta de análise em tempo real para o tráfego sem fio.

Alguém sabe como ler a partir de um dispositivo promíscuo (ou sniffing) em C?

Eu sei que você precisa ter acesso root para fazê-lo. Eu queria saber se alguém sabe o que é necessário fazer isto funções. soquetes normais não parece fazer sentido aqui.

Foi útil?

Solução

No Linux você usa um soquete PF_PACKET para ler dados de um dispositivo bruto, como uma interface ethernet em execução no modo promíscuo:

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

Isto irá enviar cópias de cada pacote recebido até ao seu soquete. É bastante provável que você realmente não quer cada pacote, no entanto. O kernel pode realizar um primeiro nível de filtragem usando BPF, o Berkeley Packet Filter . BPF é essencialmente uma máquina virtual baseada em pilha: ele lida com um pequeno conjunto de instruções, tais como:

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

código de saída de BPF diz ao kernel se para copiar o pacote para a tomada ou não. É possível escrever programas relativamente pequenos BPF diretamente, usando setsockopt (s, SOL_SOCKET, SO_ATTACH_FILTER,). (ATENÇÃO: O kernel toma um sock_fprog struct, não um bpf_program struct, não misture os para cima ou para seu programa não irá funcionar em algumas plataformas)

.

Para qualquer coisa razoavelmente complexo, você realmente quer usar libpcap. BPF é limitado no que ele pode fazer, em particular no número de instruções que podem ser executadas por pacote. libcap vai cuidar de divisão de um filtro complexo-se em duas partes, com o kernel realizando um primeiro nível de filtragem e o código de espaço do usuário mais-capable soltando os pacotes que realmente não querem ver.

libpcap também abstrai a interface do kernel fora de seu código do aplicativo. Linux e BSD usar APIs semelhantes, mas Solaris requer DLPI e Windows usa outra coisa.

Outras dicas

Uma vez eu tive que escutar em quadros Ethernet crus e acabou criando um invólucro para isso. Ao chamar a função com o nome do dispositivo, ex eth0 eu tenho uma tomada em troca que estava em modo promíscuo. O que você precisa fazer é criar um socket raw e, em seguida, colocá-lo em modo promíscuo. Aqui está como eu fiz isso.

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;
}

Então, quando você tem seu soquete você pode apenas usar seleccionar a pacotes punho que eles chegam.

Você pode usar a biblioteca pcap (ver http://www.tcpdump.org/pcap.htm ), que também é usado pelo tcpdump e Wireshark.

Por que você não usaria algo como WireShark ?

É open source, assim pelo menos você poderia aprender algumas coisas com ele se você não quer apenas usá-lo.

WireShark no linux tem a capacidade de capturar o PLCP (camada física protocolo de convergência) informações de cabeçalho.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top