문제

무선 트래픽에 대한 실시간 분석 도구를 작성하고 싶습니다.

C에서 무차별(또는 스니핑) 장치를 읽는 방법을 아는 사람이 있습니까?

이 작업을 수행하려면 루트 액세스 권한이 필요하다는 것을 알고 있습니다.이 작업을 수행하는 데 어떤 기능이 필요한지 아는 사람이 있는지 궁금합니다.일반 소켓은 여기서는 의미가 없는 것 같습니다.

도움이 되었습니까?

해결책

Linux에서는 PF_PACKET 소켓을 사용하여 무차별 모드에서 실행되는 이더넷 인터페이스와 같은 원시 장치에서 데이터를 읽습니다.

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

이렇게 하면 수신된 모든 패킷의 복사본이 소켓으로 전송됩니다.그러나 실제로는 모든 패킷을 원하지 않을 가능성이 높습니다.커널은 BPF를 사용하여 첫 번째 수준의 필터링을 수행할 수 있습니다. 버클리 패킷 필터.BPF는 본질적으로 스택 기반 가상 머신입니다.다음과 같은 작은 명령 세트를 처리합니다.

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

BPF의 종료 코드는 패킷을 소켓에 복사할지 여부를 커널에 알려줍니다.setockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, )를 사용하여 상대적으로 작은 BPF 프로그램을 직접 작성하는 것이 가능합니다.(경고:커널은 struct bpf_program이 아닌 struct sock_fprog를 사용합니다. 혼합하지 마십시오. 그렇지 않으면 프로그램이 일부 플랫폼에서 작동하지 않습니다.

상당히 복잡한 작업에는 libpcap을 사용하고 싶을 것입니다.BPF는 수행할 수 있는 작업, 특히 패킷당 실행할 수 있는 명령 수에 제한이 있습니다. libpcap 복잡한 필터를 두 부분으로 분할하는 작업을 처리합니다. 커널은 첫 번째 수준의 필터링을 수행하고 더 많은 기능을 갖춘 사용자 공간 코드는 실제로 보고 싶지 않은 패킷을 삭제합니다.

libpcap은 또한 애플리케이션 코드에서 커널 인터페이스를 추상화합니다.Linux와 BSD는 비슷한 API를 사용하지만 Solaris에는 DLPI가 필요하고 Windows에서는 다른 API를 사용합니다.

다른 팁

한때 원시 이더넷 프레임을 수신해야 했고 결국 이에 대한 래퍼를 만들었습니다.장치 이름으로 함수를 호출하면 다음과 같습니다. eth0 나는 그 대가로 무차별 모드에 있는 소켓을 받았습니다.당신이 해야 할 일은 원시 소켓을 생성한 다음 이를 무차별 모드로 전환하는 것입니다.내가 한 방법은 다음과 같습니다.

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

그런 다음 소켓이 있으면 select를 사용하여 패킷이 도착할 때 이를 처리할 수 있습니다.

pcap 라이브러리를 사용할 수 있습니다(참조 http://www.tcpdump.org/pcap.htm) 이는 tcpdump 및 Wireshark에서도 사용됩니다.

왜 다음과 같은 것을 사용하지 않겠습니까? 와이어샤크?

오픈 소스이기 때문에 그냥 사용하고 싶지 않다면 최소한 몇 가지를 배울 수 있습니다.

Linux의 WireShark에는 PLCP(물리적 계층 컨버전스 프로토콜) 헤더 정보를 캡처하는 기능이 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top