2008-09-22 2 views
9

무선 트래픽을위한 실시간 분석 도구를 작성하고 싶습니다.무차별 네트워크 장치에서 읽기

누구든지 C에서 무차별 한 (또는 스니핑) 장치를 읽는 방법을 알고 있습니까?

루트 액세스 권한이 있어야합니다. 누구든지이 작업을 수행하는 데 필요한 기능을 알고 있는지 궁금합니다. 일반 소켓은 여기서는 의미가없는 것처럼 보입니다.

+0

Linux의 경우? 귀하의 게시물은 운영 체제를 나타내지는 않지만 '루트'를 사용하여 리눅스를 사용한다고 가정해야합니까? – GEOCHET

+1

그래, 내가 추측하는 태그도 마찬가지다. – jbleners

답변

16

리눅스에 당신은 무차별 모드로 실행중인 이더넷 인터페이스로 원시 장치로부터 데이터를 읽어 PF_PACKET 소켓을 사용 : 이것은 당신의 소켓까지받은 모든 패킷의 사본을 보내드립니다

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

. 그래도 모든 패킷을 정말로 원하지는 않을 것입니다. 커널은 BPF 인 Berkeley Packet Filter을 사용하여 첫 번째 수준의 필터링을 수행 할 수 있습니다. BPF는 기본적으로 스택 기반 가상 머신입니다 :

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

BPF의 종료 코드가 소켓 여부에 패킷을 복사할지 여부를 커널에게 알려준다 :이 같은 지침의 작은 집합을 처리합니다. setsockopt (s, SOL_SOCKET, SO_ATTACH_FILTER,)를 사용하여 상대적으로 작은 BPF 프로그램을 직접 작성할 수 있습니다. (경고 : 커널은 구조체 bpf_program이 아닌 sock_fprog 구조체를 사용합니다. 일부 플랫폼에서는 프로그램이 작동하지 않습니다.

상당히 복잡하면 무엇보다 libpcap을 사용하고 싶습니다. BPF는 할 수있는 일에서 특히 패킷 당 실행할 수있는 명령어의 수가 제한되어 있습니다. libpcap은 복잡한 필터를 두 조각으로 나눠서 처리합니다. 커널은 첫 번째 필터링 수준을 수행하고 더 많은 사용자 공간 코드는 실제로 보지 않으려는 패킷을 삭제합니다.

libpcap은 또한 응용 프로그램 코드에서 커널 인터페이스를 추상화합니다. Linux와 BSD는 비슷한 API를 사용하지만 Solaris는 DLPI를 필요로하고 Windows는 다른 것을 사용합니다.

+0

답변 해 주셔서 감사합니다! – jbleners

+0

사실, 아니요, libpcap은 필터를 두 부분으로 나누지 않습니다. 그러나 예, libpcap은 여러분이 사용하기를 원하는 것입니다. 이것은 다른 플랫폼에서 무차별 모드로 인터페이스를 설정하는 방법을 알고 있습니다. (예를 들어'ETH_P_ALL'을 사용하는 것은 리눅스에서 충분하지 않습니다. 예를 들어, "SAP promiscuous" 프로토콜 유형에 관계없이 모든 패킷을 가져 오지만, 어댑터가 호스트로 전송되지 않는 호스트 유니 캐스트 패킷으로 전달하지 않는다는 점에서 "물리적으로 난잡한"것은 아닙니다. –

0

WireShark과 같은 것을 사용하지 않는 이유는 무엇입니까?

오픈 소스이므로 최소한 사용하고 싶지 않으면 몇 가지 사항을 배울 수 있습니다.

+0

WireShark가 전체 무선 패킷을 캡처 할 수 있는지 확실하지 않다. 나는 일반 MAC을 위해 구성된 무선 MAC이 아니라고 생각한다. 나는 여러 essids에서 트래픽을 볼 수 있어야합니다. – jbleners

+0

다시, wireshark 소스 코드를 살펴 보겠습니다. – GEOCHET

+1

Windows에서 WireShark가 무선 카드와 작동하지 않습니다 (정차). – leppie

7

한번은 원시 이더넷 프레임에서 수신 대기해야하며이를위한 래퍼를 생성해야합니다. 장치 이름을 가진 함수를 호출함으로써, 예를 들어 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; 
} 

그런 다음 당신은 단지 그들이 도착하는 패킷을 처리하기 위해 선택 사용할 수 있습니다.

0

Linux에서 WireShark는 PLCP (물리층 수렴 프로토콜) 헤더 정보를 캡처 할 수있는 기능이 있습니다.

관련 문제