[환경 설정 방법]
1. Winpcap 개발자팩 다운로드후 필요한 곳에 lib파일과 헤더 파일을 복사나 이동 시켜 놓는다.
http://www.winpcap.org/devel.htm

2. Winpcap 다운로드후 설치한다.
http://www.winpcap.org/install/default.htm

3. VS6.0의 VC++ 에서의 설정
   a) Winpacp 개발자팩압출을 푼후 그곳에 있는 Include Lib폴더를 Tools -> Option -> Directory에 추가
   b) Setting->link->General의 Object/Lib 부분에 wpcap.lib ws2_32.lib 추가
   c) Setting->C++->General의 Preprocessor부분에 WPCAP, HAVE_REMOTE 추가
   d) 컴파일시 pcap_next_ex()의 3번째 인자에서 에러발생시 그 앞에  (const unsigned char**)를 붙인다.

위와 같이 설정이 끝났다면 아래 소스파일을 실행시켜 볼수 있는 환경이 구축 된 것이다.



  1. 2009.12.21 09:54

    비밀댓글입니다

  2. Michael Kors outlet 2013.07.28 14:13

    슬퍼서 우는거 아니야..바람이 불어서 그래..눈이 셔서..

  3. 방문 2013.12.10 19:45

    안녕하세요. 패킷캡쳐 공부하다가 우연히들리게됬습니다.
    protocol.h <헤더파일 없나요?
    제발답변부탁드립니다.ㅠ

pcap을 이용한 packet captuer 프로그램을 작성해 보게 되었다.

네트워크 상에 떠다니는 패킷을 pcap library를 이용하여 낚아채와서 화면에 찍을 수 있다는 점에서 대단히 흥미로운 경험이 되었다고 생각된다.

이것을 실행 시키기 위해서는 리눅스용 pcap library가 설치 되어 있어야 한다.
헤더 파일의 위치가 다를 경우 적절하게 수정해 줄 필요가 있다

이 프로그램의 소스는 아래와 같다.


1. Winpcap 개발자팩 다운로드 

http://www.winpcap.org/devel.htm

2. Winpcap 다운로드

http://www.winpcap.org/install/default.htm

3. VS6.0의 VC++ 에서의 설정

   a) Winpacp 개발자팩압출을 푼후 그곳에 있는 Include Lib폴더를 Tools -> Option -> Directory에 추가

   b) Setting->link->General의 Object/Lib 부분에 wpcap.lib ws2_32.lib 추가

   c) Setting->C++->General의 Preprocessor부분에 WPCAP, HAVE_REMOTE 추가

   d) 컴파일시 pcap_next_ex()의 3번째 인자에서 에러발생시 그 앞에  (const unsigned char**)를 붙인다


/////////////////////////////////////////////////////////////////////////
/*
typedef uint32_t in_addr_t
struct in_addr
{
in_addr_t s_addr;  // 32bit짜리인 int 형 변수이다.
}
char * inet_ntoa(struct in_addr)  // 결국 struct in_addr 은 int s_addr이고, 여기서는 int in으로 사용을 하였다.
{
함수의 구현
}
*/
///////////////////////////////////////////////////////////////////////////
//*함수의 구현*

char * inet_ntoa(int in) 
{
static char buf[16] = "000.000.000.000";  // NULL 포함
char *p = (char *) &in;
int pos = 0;
pos = pos + sprintf(buf[pos], "%d.", *p);    // step 1.
++p;
pos = pos + sprintf(buf[pos], "%d.", *p)    // step 2.
++p;
pos = pos + sprintf(buf[pos], "%d.", *p);   // step 3.
++p;
pos = pos + sprintf(buf[pos], "%d.", *p);   // step 4.
}
/////////////////////////////////////////////////////////////////////////
step 1.
in    :  0x64 32 64 64
buf  : "100. ___________";
pos :  4

step 2:
int : 0x64 32 63 64
p : In의 시작 주소
buf : "100, 50. _______"
pos : 8

step 3:
int : 0x64 32 63 64
p : In의 시작 주소
buf : "100, 50. 99. ___"
pos : 12

step 4:
int : 0x64 32 63 64
p : In의 시작 주소
buf : "100, 50. 99 . 98"
pos : 12
/////////////////////////////////////////////////////////////////////////
패킷 구조는 아래 그림과 같다

Ethernet frame 구조

- Preamble : 패킷(프레임) 동기등을 위해 각 프레임의 헤더 맨 앞에 붙이는 영역
-SFD(Start of frame delimiter)
  : 프레임의 시작부근에서 프리엠블 바로 뒤에 붙어지는 10101011로 구성된 1byte 짜리 비트열이다.
    SFD비트열 부근부터 바이트 단위로 구성되어 있다는 사실을 알리는 프레임 동기용 비트열
-Destination address : 목적지 MAC 주소
-Source address : 송신지 MAC 주소
-Type : 상위 계층 프로토콜 종류를 표시 0x600 이상이면 Type(DIX 2.0), 0x600이하이면 Length(802.3)로 해석된다.
 . Type :  많은 타임을 가지고 있으며 대표적인 Type은 IP(Internet Protocol)을 들 수 있다.
 . Length : 길이(3~1500 byte)를 나타낸다.
-DATA : 상위 프로토콜 데이터 패킷( IP, TCP or UDP, 실제 전송될 데이터 )
-FCS( Frame Check Sequence ) : 프레임에 문제가 있는지 판별에 사용, CRC를 사용한다.
 . 순환중복검사(CRC :Cyclic Redundancy Check)는 에러검출 방법중의 하나로 송신측에서 데이타로 부터 다항식에 의해 추출된 결과를 여분의 오류검사필드(FCS:Frame Check Sequence)에 덧붙여 보내면, 수신측에서는 동일한 방법으로 추출한 결과와의 일치성으로 오류검사를 하는 기술이다.

IP Packet 구조
-Version(4 bits):IP 버전을 표시(ex IPv4 or IPv6)
-HL(Header Length)
 : IP 패킷에서 헤더가 차지하는 길이
  IP패킷은 "헤더+데이터+옵션"으고 구성되므로 헤더의 길이를 알면 데이터의 시작점을 할 수 있다.
-TOS(Type Of Service)
: 서피브 타입 및 수준을 표시함(패킷이 얼마나 빨리 처리/전달 되어야 하는가에 대한 정보)
  111 : 네트워크용 컨트롤용
  110 : 인터네트워크 컨트롤용
  101 : CRITIC/ECP
  100 : 플래쉬 오버라이드용
  011 : 플래쉬 용
  010 : 즉시 처리용
  001 : 우선 처리용
  000 : 일반 처리용
-Total Length(16bit)
 : 패킷의 전체 길이를 표시
-Identification(16bit)
 : 하나의 패킷이 여러 조각으로 분할되었을 경우 각 조각을 구분하기 위하여 부여하는 정보
-Flags(3 bits)
 : 패킷 분할에 관한 컨트롤 정보
  Bit 0 : 항성 0으로 예약되어 있음
  Bit 1 : (DF) 0 = 분할가능, 1 = 분할불가
  Bit 2 : (MF) 0 = 마지막 조각, 1 = 이후 조각 더 있음
-Fragment Offset(13 bits)
 : 이 조각(Fragment)이 어느 데이터그램(IP패킷)에 소속되는지 표시
- TTL(Time to Live) (8 bits)
 : 이 패킷이 인터넷에서 사용될 수 있는 시간을 표시 
  일반적으로 라우터를 하나 거칠 때마다 1씩 줄어들어 0 이 되면 폐기함
-Protocol(8 bits)
 : 상위 계층의 프로토콜을 표시 (ex: tcp/udp 등)
-Header Checksum(32 bits)
 : 해더 부분에 대하여 에러 발생시 에러 정정을 위한 체크
-Source Address(32 bits) : 출발시 IP 주소
-Destination Address(32 bits) : 목적지 IP 주소
-Option(27 bits) : 선택사양, 보안단계, 소스경로, Route recode, timestamp등

TCP Packet 구조
-Source port(16 bits) : 상위 Application에 따른 값이 결정되며 송신지 포트 번호를 나타냄
-Destination port(16 bits) : 수신지 포트 번호를 나타냄
-Sequence Number(23 bits)  : 패킷의 송신 Data의 일변번호를 나타냄
-Acknowlegement number(32 bits) : 수신 Data의 일련 번호를 나타냄(수신될 다음번 바이트의 예상 일련번호)
-Data offset(4 bits): 패킷내의 데이터 오프셋
-Reserved(6 bits)
-Control(6 bits) : TCP의 연결 및 종료를 제어합니다.
 : URG(긴급 포인터)
   ACK(승인)
   PSH(푸쉬기능)
   RST(접속의 리셋)
   SYN(동기화 일련번호)
   FIN(송신자로부터 더이상의 데이터 없음) 등
-Window(16 bits) : 메시지 전송시 흐름제어 합니다.
-Checksum(16 bits) : 에러 check를 합니다. TCP 메시지 검사 및 목적지에 제대로 도작했는지 확인합니다.
-Urgent Position(16 bits) : TCP 긴급 포인터
-Options(24 bits) : TCP 옵션들
 : SEG_SEQ : 패킷의 일련번호
   SEG_ACK : 패킷의 확인번호
   SEG_FLAG : 제어비트
-Padding(8 bits)
-Data


winpcap/pcap.h 함수 분석
1. typedef void(*  pcap_handler )(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) 
[ 기능 ]
패킷을 받는 콜백 함수의 프로토타입
[ 파라미터 ]
u_char *user : pcap_dispatch() pcap_loop()를 호출할 때 전달하는 u_char 포인터
const struct pcap_pkthdr *pkt_header : 패킷의 정보를 기지고 있는 pcap_pkthdr 구조체
const u_char *pkt_data : 패킷의 데이터를 가리키고 있는 u_char 포인터
 
2. pcap_t *pcap_open_live (char *device, int snaplen, int promisc, int to_ms, char *ebuf)
[ 기능 ]
네트워크의 패킷들을 보기위해 필요한 packet capture descriptor를 얻기위해 사용된다.
[ 파라미터 ]
char *device : 사용할 네트워크 디바이스를 지시하는 스트링 
int snaplen : 캡쳐할 최대 bytes
int promisc : NIC promiscuous mode로 동작할 지 여부
int to_ms : millisecond 단위의 read timeout
char *ebuf : pcap_open_live()가 실패할 경우에만 에러 메시지가 저장된다. 보통 NULL
[ 반환 ]
성공 : 패킷 캡쳐 descriptor
실패 : NULL
 
3. pcap_t * pcap_open_dead (int linktype, int snaplen)
[ 기능 ]
libpcap의 다른 함수를 호출할 때 pcap_t structure를 생성한다. 
4. pcap_t *pcap_open_offline(char *fname, char *ebuf)
[ 기능 ]
기존에 저장된 파일에서 패킷을 읽기 위해 사용된다. 
stdin에서 읽기 위해서는 파일 이름을 "-"으로 한다. 
[ 파라미터 ]
char *fname : 오픈할 파일의 이름 
char *ebuf : 실패할 경우 에러 메시지가 저장된다 .
[ 리턴 ]
성공 : descriptor
실패 : NULL
 
5. pcap_dumper_t *pcap_dump_open(pcap_t *p, char *fname) 
[ 기능 ]
캡쳐한 내용을 파일에 저장하기 위해서 파일을 오픈한다. 
stdout을 지시하려면 파일이름을 "-"를 이용한다.
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor 
char *fname : 오픈할 파일의 이름
[ 리턴 ]
성공 : pcap_dumper_t로 패킷 덤프와 관련된 구조체
실패 : NULL
 
6. int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
[ 기능 ]
블록킹과 논블록킹 모드를 바꾼다.
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor 
int nonblock : non-zero 혹은 zero 값을 지닌다.
char *errbuf : 실패시 에러 메시지가 채워진다.
[ 리턴 ]
성공 : 0
실패 : -1
 
7. int  pcap_getnonblock (pcap_t *p, char *errbuf) 
[ 기능 ]
인터페이스의 non-blocking 상태를 얻는다.
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor 
char *errbuf : 실패시 에러 메시지가 채워진다.
[ 리턴 ]
성공 : 0
실패 : -1
 
8. int  pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
[ 기능 ]
pcap_open_live()로 열린 네트워크 디바이스의 리스트를 구한다.
[ 파라미터 ]
pcap_if_t **alldevsp : 네트워크 다비이스의 리스트 포인터
char *errbuf : 실패시 에러 메시지가 채워진다.
[ 반환 ]
성공 : 0
실패 : -1
 
9. void  pcap_freealldevs (pcap_if_t *alldevsp)
[ 기능 ]
pcap_findalldevs()에 의해 리턴된 인터페이스 리스트를 해제한다.
[ 파라미터 ]
pcap_if_t **alldevsp : 네트워크 다비이스의 리스트 포인터
 
10. char *  pcap_lookupdev (char *errbuf) 
[ 기능 ]
패킷을 캡쳐할 적당한 네트워크 디바이스(NIC : Network Interface Card)를 찾아
그 디바이스를 지칭하는 스트링을 리턴한다. 
네트워크 디바이스를 지칭하는 스트링은 각 운영체제 별로 표현되는 별명(alias) 
말하며 Linux의 경우 "eth0", "eth1" 식으로 표현되고 BSD 계열은 각 네트워크 
디바이스 벤더별로 별도로 명명된다.
[ 파라미터 ]
char *errbuf : 실패시 에러 메시지가 채워진다.
[ 리턴 ]
성공 : 네트워크 디바이스의 별명(alias)
실패 : NULL
 
11. int  pcap_lookupnet (char *device, bpf_u_int32 *netp, bpf_u_int32 *maskp, char *errbuf)
[ 기능 ]
네트워크 디바이스의 네트워크 주소와 netmask 정보를 가져오기위해 사용된다. 
[ 파라미터 ]
char *device : 네트워크 디바이스의 별명(alias) 
bpf_u_int32 *netp : 네트워크 디바이스의 네트워크 주소가 저장될 주소 
bpf_u_int32 *maskp : 네트워크 디바이스의 netmask가 저장될 주소 
char *errbuf : 에러 발생시 에러 메시지 저장
[ 리턴 ]
성공 : 0
실패 : -1
 
12. int  pcap_dispatch (pcap_t *p, int cnt, pcap_handler callback, u_char *user)
[ 기능 ]
프로세스 패킷을 구성할 때 사용된다.
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor 
int cnt : 읽을 패킷의 갯수
pcap_handler callback : 패킷을 처리할 루틴
u_char *user : 패킷 데이타 포인터
[ 리턴 ]
성공 : 읽은 패킷의 수
실패 : -1
 
13. int  pcap_loop (pcap_t *p, int cnt, pcap_handler callback, u_char *user)
[ 기능 ]
패킷의 그룹을 모은다.
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor 
int cnt : 읽을 패킷의 갯수
pcap_handler callback : 패킷을 처리할 루틴
u_char *user : 패킷 데이타 포인터
[ 리턴 ]
성공 : 읽은 패킷의 수
실패 : -1
 
14 void  pcap_dump (u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
[ 기능 ]
pcap_dump_open()을 통해 저장할 파일을 결정했다면 이 함수로 실제 저장이 이루어진다. 
callback 루틴을 호출할 때와 같은 파라미터를 가진다.
[ 파라미터 ]
u_char *user : 사용자 데이터 
struct pcap_pkthdr *h : 패킷의 정보를 가리키고 있는 포인터 
u_char *sp : 패킷의 데이터를 가리키고 있는 u_char 포인터
 
15. int  pcap_compile (pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)
[ 기능 ]
스트링 형태의 필터링 룰을 해석해 bpf_program 구조체에 저장한다.
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
struct bpf_program *fp : 필터링 룰에 따라 결정될 구조체 
char *str : 스트링 형태의 필터링 룰 
int optimize : 결과 코드를 수행할 때 최적화 여부 
bpf_u_int32 netmask : 네트워크의 mask
 
16. int  pcap_compile_nopcap (int snaplen_arg, int linktype_arg, struct bpf_program *program, char *buf, int optimize, bpf_u_int32 mask)
[ 기능 ]
어댑터를 열지 않고 패킷 필터를 컴파일한다.
커널레벨의 필터링룰에 의해 인터프리트될 수 있는 프로그램에서
높은레벨의 필터링표현을 변환한다.
[ 파라미터 ]
int snaplen_arg : 
int linktype_arg :
struct bpf_program *program : 필터링 룰에 따라 결정될 구조체
char *buf : 스트링 형태의 필터링 룰
int optimize : 결과 코드를 수행할 때 최적화를 물어본다
bpf_u_int32 mask : mask
[ 리턴 ]
성공 :
실패 : -1
 
17. int  pcap_setfilter (pcap_t *p, struct bpf_program *fp)
[ 기능 ]
pcap_compile()을 통해 결정된 bpf_program 구조체를 적용할 때 사용된다. 
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
struct bpf_program *fp : 보통 pcap_compile()에서 결과 
[ 리턴 ]
성공 : 0
실패 : -1
 
18. void  pcap_freecode (struct bpf_program *fp)
[ 기능 ]
필터를 해제한다.
[ 파라미터 ]
struct bpf_program *fp : 보통 pcap_compile()에서 결과
 
19. u_char *  pcap_next (pcap_t *p, struct pcap_pkthdr *h)
[ 기능 ]
다음 패킷의 포인터를 리턴한다. 내부적으로 pcap_dispatch()를 호출한다.
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
struct pcap_pkthdr *h : 패킷의 정보를 가리키고 있는 포인터
[ 리턴 ]
성공 : 패킷을 가리키는 포인터
실패 : NULL
 
20. int  pcap_datalink (pcap_t *p)
[ 기능 ]
link type을 리턴한다.
pcap_t의 멤버 중 linktype.
linke type bpf.h에 정의되어 있다. 
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
[ 리턴 ]
성공 : link type
 
21. int  pcap_snapshot (pcap_t *p)
[ 기능 ]
pcap_open_live()가 호출될 때 지정된 길이인 snapshot length를 리턴한다.
pcap_t의 멤버 중 snapshot
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor
[ 리턴 ]
성공 : snapshot length
실패 :
 
22. int  pcap_is_swapped (pcap_t *p)
[ 기능 ]
사용하고 있는 저장 파일과 사용하는 시스템이 같은 byte order를 사용하는지 여부를
알 수 있다. 
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
[ 리턴 ]
0 : 같은 byte order를 사용할 경우 
1 : 다른 byte order를 사용할 경우
 
23. int pcap_major_version(pcap_t *p)
[ 기능 ]
저장 파일에 사용된 pcap의 메이저 버전을 리턴한다.
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
[ 리턴 ]
성공 : pcap의 메이저 버전
 
24. int pcap_minor_version(pcap_t *p)
[ 기능 ]
저장 파일에 사용된 pcap의 마이너 버전을 리턴한다.
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
[ 리턴 ]
성공 : pcap의 마이너 버전
 
25. int pcap_stats(pcap_t *p, struct pcap_stat *ps) 
[ 기능 ]
패킷 캡쳐에 관한 상태 정보를 ps에 저장한다. 송수신된 패킷의 갯수나 에러 발생 정보 등의 통계 정보를 알 수 있다.
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
struct pcap_stat *ps : 패킷 캡쳐 상태 정보 구조체
[ 리턴 ]
성공 : 0
실패 : -1
 
26. FILE *pcap_file(pcap_t *p) 
[ 기능 ]
p가 가리키는 패킷 캡쳐에서 사용하는 저장 파일의 FILE 포인터를 넘겨준다.
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
[ 리턴 ]
성공 : 파일 포인터
 
27. int pcap_fileno(pcap_t *p) 
[ 기능 ]
p가 가리키는 패킷 캡쳐에서 사용하는 저장 파일의 descriptor를 넘겨준다.
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
[ 리턴 ]
성공 : file descriptor
 
 
28. void pcap_perror(pcap_t *p, char *prefix) 
[ 기능 ]
최근에 발생한 에러에 대해 에러메시지를 stderr에 출력한다.
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
char *prefix : 메시지를 출력할 때 앞에 추가할 내용 
 
29. char *pcap_geterr(pcap_t *p) 
[ 기능 ]
최근에 발생한 에러에 대한 메시지를 리턴한다. 
[ 파라미터 ]
pcap_t *p : 패킷 캡쳐 descriptor 
[ 리턴 ]
성공 : 최근 발생한 에러 메시지
 
30. char *pcap_strerror(int error)
[ 기능 ] 
strerror(1)이 없을 경우를 위해 제공된다.
[ 파라미터 ] 
int error : error number 
[ 리턴 ]
성공 : error 메시지
 
31. void  pcap_close (pcap_t *p)
[ 기능 ]
패킷을 닫고 메모리 해제
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
 
32. void pcap_dump_close(pcap_dumper_t *p)
[ 기능 ]
저장 파일을 닫는다.
[ 파라미터 ]
pcap_dumper_t *p : 패킷 덤프 descriptor
 
33. int  pcap_setbuff (pcap_t *p, int dim)
[ 기능 ]
어댑터와 연결된 커널 버퍼의 크기를 지정한다.
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
int dim : 버퍼의 사이즈
[ 리턴 ]
성공 : 0
실패 : -1
 
34. int  pcap_setmode (pcap_t *p, int mode)
[ 기능 ]
인터페이스 p의 모드를 지정한다.
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
int mode : 모드(MODE_CAPT : 기본캡춰모드, MODE_STAT : 통계모드)
 
35. int  pcap_sendpacket (pcap_t *p, u_char *buf, int size) 
[ 기능 ]
로우 패킷을 보낸다.
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
u_char *buf : 보내어진 패킷의 데이터
int size : 버퍼 크기
[ 리턴 ]
성공 : 0
실패 : -1
 
36. int  pcap_setmintocopy (pcap_t *p, int size)
[ 기능 ]
싱글 호출에서 커널에 의해 받아진 데이터의 최소 크기를 지정한다.
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
int size : 사이즈
[ 리턴 ]
성공 : 0
실패 : -1
 
37. HANDLE  pcap_getevent (pcap_t *p)
[ 기능 ]
인터페이스 p와 연결된 이벤트의 핸들을 구한다.
[ 파라미터 ]
pcap_t *p : pcap_open_offline()이나 pcap_open_live()에서 return되는 descriptor
[ 리턴 ]
성공 : 핸들
 
pcap_send_queue *  pcap_sendqueue_alloc (u_int memsize)
[ 기능 ]
send queue를 할당한다.
[ 파라미터 ]
u_int memsize : 큐의 최소 사이즈
 
38. void pcap_sendqueue_destroy  (  pcap_send_queue *queue  )   
[ 기능 ]
send queue를 해제한다.
[ 파라미터 ]
pcap_send_queue *queue : 큐 포인터
 
39. int  pcap_sendqueue_queue (pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
[ 기능 ]
send queue의 끝에 패킷을 추가한다.
[ 파라미터 ]
pcap_send_queue *queue :
const struct pcap_pkthdr *pkt_header : 패킷의 헤더와 길이를 포함하는 pcap_pkthdr 자료구조의 포인터
const u_char *pkt_data : 패킷의 데이터를 포함하는 버퍼의 포인터
 
40. u_int  pcap_sendqueue_transmit (pcap_t *p, pcap_send_queue *queue, int sync)
[ 기능 ]
로우 패킷의 큐를 네트워크로 보낸다.
[ 파라미터 ]
pcap_t *p : 보내어진 패킷을 가진 어댑터의 포인터
pcap_send_queue *queue : 보내기 위한 패킷을 포함하는 pcap_send_queue 자료구조의 포인터
int sync : 동기화, 비동기화의 여부로 non-zero(TRUE)일 경우 동기화가 된다.
[ 리턴 ]
성공 : 실제 보내어진 바이트 수
 
41. int  pcap_next_ex (pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data)
[ 기능 ]
오프라인 캡처로부터 혹은 인터페이스로부터 패킷을 읽는다.
[ 파라미터 ]
pcap_t *p : 보내어진 패킷을 가진 어댑터의 포인터
struct pcap_pkthdr **pkt_header :
u_char **pkt_data :
 
[ 리턴 ]
1 : 성공
0 : timeout이 만기될 경우
-1 : 에러 발생
-2 : EOF
 
42. int  pcap_live_dump (pcap_t *p, char *filename, int maxsize, int maxpacks) 
[ 기능 ]
인터페이스로부터 네트워크 트래픽 덤프를 파일로 저장한다.
[ 파라미터 ]
pcap_t *p : 어댑터의 포인터
char *filename : 파일 이름
int maxsize : 최대 사이즈
int maxpacks : 최대 패킷
[ 리턴 ]
성공 : 1
실패 : 0
 
43. int  pcap_live_dump_ended (pcap_t *p, int sync)
[ 기능 ]
커널 덤프 프로세스의 상태를 구한다.
[ 파라미터 ]
pcap_t *p : 어댑터의 포인터
int sync : nonzero면 덤프가 끝날때까지 함수는 블록킹 된다.
[ 리턴 ]
성공 : 1
실패 : -1
 
44. pcap_stat *  pcap_stats_ex (pcap_t *p, int *pcap_stat_size)
[ 기능 ]
현재 캡춰한 통계를 보여준다.
[ 파라미터 ]
pcap_t *p : 어댑터의 포인터
int *pcap_stat_size : pcap_stat 자료구조의 사이트를 포함한다.
[ 리턴 ]
성공 : pcap_stat 포인터로 현재 디바이스의 통계를 저장
실패 : NULL
 
char* pcap_strerror  (  int    error  )   
[ 기능 ]
strerror()가 이용가능하지 않을때 제공된다.
[ 파라미터 ]
int error : 에러
[ 리턴 ]
성공 : 에러 메시지
윈도우 기반에서 TCP / IP에서의 가장 간단한 프로그램이라고 할 수 있는 Echo 서버 와 클라이언트를 구현해보자.
본 프로그램을 돌리기 위해서는 ms visual studio 6.0기준으로  project 탭에서 setting메뉴의 link 탭에서 ws2_32.lib를 추가 해주던지
아니면 소스코드로 다음과 같이 입력해주면 된다. 
#pragma comment(lib,"ws2_32.lib")
전처리 부분이므로 써주는 위치또한 전처리문을 적는 곳에 적어주면 된다.

1) Echo server란?
 - client에서 전송하는 데이터를 다시 클라이언트로 뿌려주는 서버를 의미한다. 
   실질적으로 쓰일 일은 거의 없지만 TCP / IP 프로그램의 입문으로 적당하다고 할 수 있겠다.
  ex) 조금은 다르게 사용되지만 던파라는 게임을 아신다면 보보라는 크리쳐를 아시는 분들도 있을 것이다. 
       이 보보라는 크리처의 기능이 외치기 기능인데 게이머가 챗창에 친 말을 다시 반복시켜주는 역활을 하는 크리쳐이다.
       그중 챗창으로 썼던 말을 반복 해주는 부분까지는 Echo 서버의 기능이다. 

2) 동작 화면
  - 이와 같이 밑의 client에서 데이터를 보내면 그 데이터를 서버에서 받아서 다시 client로 뿌려주는 역활을 하게 된다.

그럼 소스를 보도록 하자.
<Server>의 Source code이다.

<Client>의 Source code이다.
이 네트워크 프로그램은 각각의 순서가 굉장히 중요하다.
프로그램이 순서에 맞게 진행되지 않는다면 필연적으로 에러가 발생하므로 주의를 요하자.
  1. 무플방지위원회 2009.05.06 09:39

    무플을 방지합시다

  2. Cheap Oakley sunglasses 2013.07.29 06:36

    당신 매력있어, 자기가 얼마나 매력있는지 모르는게 당신매력이야

  3. nike air max uk 2013.08.04 18:14

    귀를 기울여봐 가슴이 뛰는 소리가 들리면 네가 사랑하는 그 사람 널 사랑하고 있는거야.

  4. IWANTCPPECHO 2016.03.21 19:16

    이거.. 혹시 MFC나 API로 바꿔써야 하나요..?

beginthreadex 를 쓰기 위해서 #include <process.h>를 선언했는데;;;; 김영지 / comadolphin  
김영지님께 메시지 보내기    김영지님의 블로그가 없습니다  

 _beginthreadex 를 쓰기 위해서 #include <process.h>를 선언했는데 '_beginthreadex' : undeclared identifier가 나요

 

그래서 msdn library에 있는 MSVCRT.LIB LIBCMT.LIB 것도 링크 시켜줬는데;;

 

_beginthreadex 못 읽어요.

 

에러좀 잡아주세요

이 글에 평점 주기:  
  2005-05-04 오후 3:20:03   /  번호: 515895  / 평점:  (9.0)  
 Re: ... 김한주 / johnhj  
김한주님께 메시지 보내기    김한주님의 블로그가 없습니다  
컴파일러 옵션때문인거 같네요.
프로젝트 세팅창의 C/C++ 탭에
Compiler Option 부분에...
/ML (혹은 /MLd) 로 된 부분을 /MT (혹은 /MTd)로 설정하고 compile해보세요..

아래는 msdn 발췌입니다.
 * This program requires the multithreaded library. For example,
 * compile with the following command line:
 *     CL /MT /D "_X86_" BEGTHRD.C
 *
 * If you are using the Visual C++ development environment, select the 
 * Multi-Threaded runtime library in the compiler Project Settings 
 * dialog box.

그럼 ^^
이 글에 평점 주기:  
  2005-05-04 오후 3:38:50   /  번호: 515898  / 평점:  (-)  
 Re: 그런데 warning이 뜨는데요...;; 김영지 / comadolphin  
김영지님께 메시지 보내기    김영지님의 블로그가 없습니다  

 ignoring unknown option '/Mtd'

라는 warning뜨는데요.

원래 뜨는건가요?

 

c/c++에서 /mtd로 고쳐줄때 editbox에서 바로 고쳐주는거 맞죠?

이 글에 평점 주기:  
  2005-05-04 오후 3:42:21   /  번호: 515901  / 평점:  (-)  
 Re: 대소문자... 김한주 / johnhj  
김한주님께 메시지 보내기    김한주님의 블로그가 없습니다  

대소문자 구분합니다^^

/Mtd  > /MTd로 해야 될거구요...

 

아래 장황한 상세 설명스크랩입니다.

 

Command Line Project Settings Description
/MD Multithreaded DLL Defines _MT and _DLL so that both multithread- and DLL-specific versions of the run-time routines are selected from the standard .H files. This option also causes the compiler to place the library name MSVCRT.LIB into the .OBJ file. 
Applications compiled with this option are statically linked to MSVCRT.LIB. This library provides a layer of code that allows the linker to resolve external references. The actual working code is contained in MSVCRT.DLL, which must be available at run time to applications linked with MSVCRT.LIB.
/MDd Debug Multithreaded DLL Defines _DEBUG_MT, and _DLL so that debug multithread- and DLL-specific versions of the run-time routines are selected from the standard .H files. It also causes the compiler to place the library name MSVCRTD.LIB into the .OBJ file.
/ML Single-Threaded Causes the compiler to place the library name LIBC.LIB into the .OBJ file so that the linker will use LIBC.LIB to resolve external symbols. This is the compiler’s default action. LIBC.LIB does not provide multithread support.
/MLd Debug Single-Threaded Defines _DEBUG and causes the compiler to place the library name LIBCD.LIB into the .OBJ file so that the linker will use LIBCD.LIB to resolve external symbols. LIBCD.LIB does not provide multithread support.
/MT Multithreaded Defines _MT so that multithread-specific versions of the run-time routines are selected from the standard header (.H) files. This option also causes the compiler to place the library name LIBCMT.LIB into the .OBJ file so that the linker will use LIBCMT.LIB to resolve external symbols. Either /MT or /MD (or their debug equivalents /MTd or /MDd) is required to create multithreaded programs.
/MTd Debug Multithreaded Defines _DEBUG and _MT. Defining _MT causes multithread-specific versions of the run-time routines to be selected from the standard .H files. This option also causes the compiler to place the library name LIBCMTD.LIB into the .OBJ file so that the linker will use LIBCMTD.LIB to resolve external symbols. Either /MTd or /MDd (or their non-debug equivalents /MT or MD) is required to create multithreaded programs.
/LD Not applicable Creates a DLL. 
Passes the /DLL option to the linker. The linker looks for, but does not require, a DllMain function. If you do not write a DllMain function, the linker inserts a DllMain function that returns TRUE. 
Links the DLL startup code.
Creates an import library (.LIB), if an export (.EXP) file is not specified on the command line; you link the import library to applications that call your DLL.
Interprets /Fe as naming a DLL rather than an .EXE file; the default program name becomesbasename.DLL instead of basename.EXE.
Changes default run-time library support to /MT if you have not explicitly specified one of the /M options
/LDd Not applicable Creates a debug DLL. Defines _DEBUG.
이 글에 평점 주기:  
  2005-05-04 오후 3:54:39   /  번호: 515903  / 평점:  (-)  
 Re: 감사합니다. 김영지 / comadolphin  
김영지님께 메시지 보내기    김영지님의 블로그가 없습니다  

 감사합니다.

ㅎㅎ

/nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fp"Debug/MSCDecoder.pch" /YX /Fo"Debug/"

이렇게 적었는데;;

 

에러는 /Mtd라고 소문자라고 나오네요;;; 우선 에러는 안나오니깐!! 그걸로 만족해야될꺼 같네요..

<지식인에서 펐음, 출처는 기억이 안남>

struct sockaddr_in과 struct sockaddr중 sockaddr_in을 쓴 상태에서 sockaddr을 캐스팅 시킬수 있는 이유는?

->

sockaddr(2바이트+14바이트)와 sockaddr_in(2바이트+2바이트+4바이트+8바이트)은 정확하게 16바이트로 사이즈가 똑같습니다. 그렇기 때문에 바로 캐스팅이 되는거죠.

 

sockaddr_in은 rfc표준으로 정해진 주소sockaddr(sockaddr은 TCP/IP만을 위한 것이 아니거든요)를 우리가 주로 사용하는 Internet address familly구조(프로토콜들 종류가 많죠?;)에 사용하기 쉽게 하려고 세분화한것이라고 생각하면 쉽습니다. 고로 케스팅 그냥 해주시면 됩니다..

 

sockaddr_in은 다음과 같구요.

 

struct sockaddr_in{
 
 short sin_family;  // 2바이트
 
 unsigned short sin_port;  // 2바이트
 
 IN_ADDR sin_addr;  // 4바이트
 
 char sin_zero[8];  // 8바이트(실제 사용되지는 않구요. sockaddr과 사이즈를 맞추기 위함)
};

 

sockaddr_in중의 IN_ADDR은 다음과 같습니다.

 

struct in_addr {
 
 union {
   
 struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; // 4바이트
   
 struct { u_short s_w1,s_w2; } S_un_w;  // 4바이트
 
 u_long S_addr;  // 4바이트
 
 } S_un;
};

 

단, union으로 정의되었기때문에 총 4바이트가 되는 거죠.

 

sockaddr은 다음과 같습니다.

 

struct sockaddr {
 
 u_short sa_family // 2바이트
 
 char sa_data[14];  // 14바이트
};

 

sockaddr을 사용하지 않고 sockaddr_in이라는 것을 정의하여 사용하는 이유는 사용의 편의를 위해서입니다.

한번 생각해보세요;  14바이트의 배열에다가 포트와 아이피를 그냥 갖다넣기는 좀 번거롭겠죠?



ps) sockaddr과 sockaddr_in은  bind함수 부문에서 사용된다.

+ Recent posts