LuvSea
winpcap 라이브러리를 이용한 패키 분석(이더넷 부분 분석) 본문
Winpcap을 라이브러리를 이용한 패킷 네트워크 패킷분석
Winpcap라이브러리를 네트워크 장비를 찾아내고 임의의 네트워크 장비로 지나가는 패킷을 캡쳐할수 있다.
윈도우와 리눅스는 사용하는 함수가 조금 다르지만 기능은 흡사하다.
리눅스에서의 패킷 캡쳐
아래함수는 현재 연결된 네트워크 장비를 찾아 해당 장비의 장비명을 리턴하며 인자로 에러를 처리할 버퍼의 주소를 넘긴다. 아래함수를 통해 얻은 장치명은 pcap_open_live함수를 통해서 장치로부터 오는 패킷을 캡쳐할수 있다.
- 장치를 찾아 장치명알아낸다.
char * pcap_lookupdev(char * errbuf);
- 장치명을 통해 장치ID를 구해낸다.
장치읽기위해 열 때 사용하는 함수는 다음과 같으며 열린 장치는 pcap_close()함수를 이용해서 반드시 닫아 주어야 한다..
pcap_t * pcap_open_live(char * device,int snaplen,int promisc,int to_ms, char * ebuf);
첫 번째 인자는 읽어올 장치의 장치명이며 pcap_lookupdev함수를 통해 얻은 값을 넣어준다.
두 번째 인자는 읽어들일 패킷의 최대 크기
세 번째 인자는 패킷을 읽어들일 방식을 설정하는 값이며 1로 설정하게되면 조건없이 모든 패킷을 읽어들인다.
네 번째 인자는 패킷이 오기 까지의 대기시간을 나타내고 0으로 주면 패킷을 올때까지 무기한 기다린다.
마지막 인자는 에러를 처리할 버퍼의 주소이다.
- 장치 ID를 통해 페킷의 데이터를 읽어 들인다.
열린 장치로부터 패킷을 읽어 들일 때 사용하는 함수는 다음과 같다.
u_char * pcap_next(pcap_t * p,struct pcap_pkthdr * h);
pcap_next 함수는 pcap_open_live 함수를 통해 리턴된 장치ID인 p를 넘겨 캡쳐한 패킷의 기본정보를 h에 담아주고 해당 패킷의 데이터를 리턴하게된다.
- 패킷에서 이더넷 정보 읽어 내기
리턴된 데이터는struct ether_header을 통해서 이더넷 부분의 값을 불러 있다. 총 크기는 14바이트이며 상위 6바이트는 목적지 이더넷 주소이며 다음6 바이트는 출발지의 이더넷 주소다 나머지 하위 2비트는 해당 패킷의 프로토콜 ID가 오게되며 이곳의 데이터를 확인해서 해당 패킷이 TCP 패킷인지 아니면 UDP 패킷인지 등을 알수 있게 된다.struct ether_header 구조체는 다음과같이 구성되어 있다.
struct ether_header
{
u_int8_t ether_dhost[ETH_ALEN]; //목적지 장치의 주소(물리주소) ETH_ALEN 은 6이다.
u_int8_t ether_shost[ETH_ALEN]; //출발지 장치의 주소(물리주소)
u_int16_6 ether_type; //프로토콜 ID를 나타낸다.
}
이더넷 프로토콜 ID는 usr/include/net/ethernet.h 에 정의 되어 있다.
구조체의 사용 예는 다음과 같다.
struct ether_header * header; // 패킷의 이더넷 정보를 읽어낼 구조체 포인터
// pcap_next함수를 통해 리턴된 data를 이더넷 구조체 포인트로 형변환을 해준다. data에는 캡쳐된 //데이터의 정보를 가리키는 시작주소가 들어 있으며 이더넷 구조체를 통해 쉽게 이더넷 정보를 분//리 가능하다.
header = (struct ether_header *)data;
header->dhost[0] - header->dhost[1] - header->dhost[2] - header->dhost[3] 은 목적지의 이더넷 주소이다.
haeder->shost[0] - haeder->shost[1] - haeder->shost[2] - haeder->shost[3] 은 출발지의 이더넷 주소이다.
header->ether_type[0]
- 열린 장치를 닫는다.
장치 ID를 닫는 함수는 pcap_close() 이며 원형은 다음과 같다.
pcap_close(pcap_t * p);
인자로 pcap_open_live 함수를 통해 열린 장치의 ID를 넘겨 장치를 닫아주어야 한다.
간략하게 순서를 요약하면 다음과 같다.
- 연결된 장치명을 구해 낸다.
char * pcap_lookupdev(char * errbuf);
- 장치명을 이용해서 해당 장치의 ID를 획득한다.(장치를 연다.)
pcap_t * pcap_open_live(char * device,int snaplen,int promisc,int to_ms, char * ebuf);
- 열린 장치로 부터 패킷이 오길 기다리다 패킷이 도착하면 캡쳐한다.(대기 시간및 캡처 방식은 장치를 열대 설정)
u_char * pcap_next(pcap_t * p,struct pcap_pkthdr * h)
- 이더넷 구조체를 이용해서 이더넷 정보를 읽어 낸다.
struct ether_header * header;
- 장치 ID를 사용해서 열린 장치의 닫는다.
pcap_close(pcap_t * p);
'sTudy' 카테고리의 다른 글
리눅스 패킷 캡쳐(Packet Capture) , [PCAP] (0) | 2009.08.24 |
---|---|
pcap 을 이용한 패킷 분석( IP 해더 분석 ) (0) | 2009.08.24 |
push와 pop의 구분동작 (0) | 2009.08.10 |
PUSHA와 POPA (0) | 2009.08.10 |
데이터 전송 명령어 mov, movzx, movsx (0) | 2009.08.10 |