님햐 내 패킷 훔쳐가지 마삼!
* Libpcap(Portable Packet Capturing Library)
패킷을 캡쳐하기 위한 도구로는 BPF(Berkeley Packet Filter), DLPI, NIT, SNOOP, SNIT, SOCK_PACKET,
LSF(Linux Socket Filter), drain등
각 운영체제별로 다양한 도구가 있다.
하지만 여러분이 운영체제별로 패킷을 캡쳐하기 위한 위한 코드를 별도로
구성해야 한다면
시작하기도 전에 포기할지도 모른다.
하지만 이 모든 도구들을 수용하는 Portable한 API가 있는데 이것이 바로 libpcap이다.
라이브러리 사용자는 운영체제의 각기 다른 datalink로의 접근 방법에
상관없이 libpcap을 이용하여 소기의 목적을 달성할 수 있다.
libpcap을 이용한 대표적인 툴이 바로 tcpdump이다.
#include <pcap.h>
를 include 해준다. 하지만 컴파일이 되지 않는다.
/usr/include 디렉토리에서 찾아보지만 pcap.h가 보이지 않는다.
/usr/include/pcap/ 디렉토리에 pcap.h가 있다.
운영체제마다 pcap.h의 위치가 다를 수 있기때문에 확인 후 컴파일 할 것.
1. 랜카드의 이름 알려주는 함수 -> pcap_lookupdev()
원형 : char *pcap_lookupdev(char *errbuf)
리턴값 : 성공시(장치 이름), 실패시(NULL)
네트워크의 디바이스를 가져오는 함수.
가능한 가장 낮은 번호를 가져온다. (리눅스는 아마 eth0을 가져 올 것이다.)
pcap_lookupdev()함수를 이용하여 랜카드의 장치이름을 출력해보았다.
현재 랜카드의 이름이 eth0이라는 것을 알 수 있다.
2. 랜카드를 열어주는 함수 -> pcap_open_live()
원형 : pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to ms, char *ebuf)
리턴값 : 실패시(NULL)
이 함수는 실제로 랜카드를 열어주는 역활을 한다.
첫번째 인자 : 장치의 이름
두번째 인자 : 가져오는 크기
세번째 인자 : 1 -> 아무패킷이나 잡음 , 0 -> 자기 패킷만 잡음
네번째 인자 : 지연시간
다섯번째 인자 : 에러메세지
열었으면 닫아주어야 하는 법
pcap_close()함수를 이용해서 닫아주면 되겠다.
3. 패킷을 호출해 주는 함수 -> pcap_next()
원형 : u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
리턴값 : const unsigned char *를 반환한다.
패킷을 헥사뷰로 한번 열어보겠다.
뭐 대충 이정도로 열린다.
패킷의 정보를 파악해보도록 한다.
랜카드 타입 추출 -> MAC 어드레스 -> 데이터 타입 추출
1. 랜카드의 타입을 추출 하는 함수 -> pcap_datalink()
원형 : int pcap_datalink(pcap_t *)
반환형 : 정수값
함수 설명에 보면 DLT_EN10MB 같은 것들을 반환한다고 나온다.
/usr/include 에서 grep -r DLT_EN10MB * 을 통하여 어디에 잇는지 찾아냈다.
pcap/net/bpf.h 에 나와있다고 나온다.
가보면 정수값들이 define되어 있다.
이제 ethernet header의 구조에 대하여 알아보록 한다.
우선 패킷의 앞 8byte와 뒤 4byte는 랜카드가 알아서 쳐먹으니까 우리는 Mac Frame 내용을 봐야한다.
첫 6 ,6 byte는 MAC ADDRESS가 위치하는 자리이다.
이자리는 IP가 아니라 장치의 번호를 쓴다.
저기 빨간줄의 HWaddr 하드웨어 어드레스가 MAC frame 어드레스에 들어간다.
친절하게 헤더파일에 구조체를 선언해두었음 ^_^
/usr/include/net/ethernet.h 에 구조체를 선언해 두었다.
뒤에 ETH_ALEN은 define값으로 6이다.
/usr/include/linux/if_ether.h 에 define되어 있다.
그냥 가따 쓰면 되겄다.
이제 data의 타입에 대하여 알아보록한다.
MAC 어드레스가 끝난 지점의 2byte가 data의 타입을 결정하는 녀석이다.
/usr/include/net/ethernet.h에서 ethernet_head 정의 뒤에 바로 나온다.
#여기서 잠깐
: 네트워크의 경우 big enddian을 사용하는 점에 주의하자.
아마 data타입을 출력해보면 IP의 경우 0008로 나올 것이다.
ntohs()함수를 이용하여 little enddian으로 바꾸어준다.
* 패킷의 이동 과정
1. 공유기 MAC 어드레스 <- 내 MAC 어드레스
우선 가장가까운 공유기로 패킷을 내보냄.
공유기가 우리의 MAC 어드레스와 IP를 대조하여 IP를 발급하기 때문에 욜로 보낸다.
2. 야동의 노예 MAC 어드레스 <- 공유기 MAC 어드레스
여기서 IP가 일치 할 경우 야동의 노예에게 야동은 전달된다.
만약 멀리 멀리 나가게 된다면
나 -> 공유기 -> 게이트 웨이 -> 라우터 등등 으로 거쳐 찾아가게 된다.
이과정에서 MAC어드레스는 계속해서 변하지만, IP는 변하지 않게 된다!
'코스웨어 > 12년 내장형하드웨어' 카테고리의 다른 글
11월 프로젝트 제안서 - 감정현 (1) | 2012.10.31 |
---|---|
[Micro C/OS]2012/10/29 작업일지(리얼타임 시스템의 개념) - by.이창현 (1) | 2012.10.30 |
[Micro C/OS] 10.29 업무일지 -정철 (0) | 2012.10.29 |
[패킷 아날라이저] 10.27 업무일지 -정철 (1) | 2012.10.26 |
[linux kernel]문자 디바이스 정리 자료입니다. (1) | 2012.10.25 |
[2012내장형]포인터 변수의 오류들 첫번째... (1) | 2012.10.24 |
[WINAPI] 10월 23일 수업소스+결과(BIPMAP 영상처리(?)) - by.LDH (0) | 2012.10.23 |
[WinApi]2012/10/18 작업일지(BMP 파일 구조) - by. 이창현 (0) | 2012.10.22 |