1. 네트워크 인터페이스 목록 가져오기
일반적으로 WinPcap 기반 애플리케이션이 가장 먼저 해야 할 일은 적합한 네트워크 인터페이스 목록을 가져오는 것입니다( Libpcap ). 함수가 수행하는 작업: 이 함수는 pcap_if 구조 목록을 반환하며, 각 요소는 인터페이스 정보를 기록합니다. 그 중 이름과 설명은 사람이 읽을 수 있는 형식으로 장치 정보를 기록합니다. 다음 소스 코드는 사용 가능한 네트워크 인터페이스 목록을 인쇄하고 변명이 발견되지 않으면 오류 메시지를 표시합니다.
코드
#include "pcap.h "
main ()
{
pcap_if_t *alldevs;
pcap_if_t *d
int i =0; >char errbuf[PCAP_ERRBUF_SIZE];
/* 목록 가져오기*/
if (pcap_findalldevs(amp; alldevs, errbuf) == -1 )
{
fprintf(stderr, "pcap_findalldevs에 오류가 있습니다: s\n", errbuf)
exit(1)
}
/* 출력 목록*/
for(d=alldevs;d;d=d-gt;next)
{
printf("d .s", i, d-gt; 이름);
if (d-gt; 설명)
printf(" (s)\n", d-gt; 설명 );
else
/* Y-유효한 설명 없음*/
printf(" (설명 없음) \n");
}
if(i==0)
{
/* Y- 유효한 인터페이스가 없습니다. WinPcap이 설치되지 않았기 때문일 수 있습니다. */
printf("\n인터페이스를 찾을 수 없습니다! WinPcap이 설치되어 있는지 확인하세요.\n")
}
/ * 목록은 더 이상 필요하지 않습니다. 무료*/
pcap_freealldevs(alldevs);
}
여기 있습니다. 이 코드를 살펴보세요.
우선, 다른 libpcap 함수와 마찬가지로 pcap_findalldevs()에는 오류 버퍼(errbuf) 매개변수가 있습니다. 이 매개변수는 오류가 발생하면 여기에 오류 설명이 채워집니다. 그러면 pcap_findalldev 시스템의 s() 함수는 UNIX의 libpcap에서도 지원되지만 모든 운영 체제가 "네트워크 인터페이스 설명"(설명) 항목을 지원하는 것은 아닙니다. , 설명이 "null"인 상황에 대비해야 합니다. 이 경우 "None"을 출력합니다.
마지막으로 pcap_freealldevs() 함수를 통해 인터페이스 목록을 해제합니다.
이제 첫 번째 WinPcap 프로그램을 컴파일하고 실행해 보겠습니다. UNIX 또는 Cgywin에서는 다음 명령만 필요합니다:
gcc -o testaprog testprog.c -lpcap
Windows 환경(Y - Microsoft Visual C를 사용하는 경우)에서는 다음을 수행해야 합니다. 프로젝트를 설정하고 "프로그램에서 WinPcap 사용" 섹션의 지침을 따르세요.
그러나 WinPcap 개발자 팩의 예제를 따르는 것이 좋습니다. 필요한 모든 라이브러리와 포함 파일도 포함됩니다.
(Y - 이 장의 끝 부분에서 Microsoft Visual C를 구성하는 방법을 찾을 수 있습니다.)
가정 이제 프로그램을 성공적으로 컴파일했으므로 WinXP 워크스테이션에서 실행해 보겠습니다.
1. {4E273621-5161-46C8-895A-48D0E52A0B83} (Realtek RTL8029(AS ) Ethernet Adapter)
2. {5D24AE04-C486-4A96-83FB-8B5EC6C7F430} (3Com EtherLink PCI)
보시다시피 네트워크 인터페이스의 이름(이 인터페이스를 열 때 이 이름을 libpcap 라이브러리에 전달합니다. 이는 Windows 환경에서 읽기가 거의 불가능하므로(진심으로 동의합니다) 설명을 출력하는 것은 사용자에게 매우 유용합니다.
참고: Microsoft Visual C 프로젝트 설정.
1. WinPcap을 다운로드하여 설치하세요. 권장 버전은 3.0입니다.
2. 마스크에서)
/* Y-mask*/
printf("\tNetmask: s\n", iptos(((struct sockaddr_in *)a-gt; netmask)-gt; sin_addr.s_addr));
if (a-gt; Broadcastaddr) )
/* Y- 브로드캐스트 주소*/
printf("\t브로드캐스트 주소: s\n", iptos( ((struct sockaddr_in *)a-gt; broadaddr)- gt; sin_addr.s_addr));
if (a-gt; dstaddr)
/* Y - 대상 주소* /
printf("\tDestination 주소: s\n", iptos(((struct sockaddr_in *)a-gt; dstaddr)-gt; sin_addr.s_addr));
break;
기본값: p>
/* 알 수 없음*/
printf("\t주소 성: 알 수 없음\n")
break; p>
}
printf("\n");
}
/* tcptracert에서 숫자 IP 주소를 도트 형식으로 변환*/
#define IPTOSBUFFERS 12
char * iptos (u_long in)
{
정적 문자 출력[IPTOSBUFFERS][3*4 3 1]
static short which; >u_char *p;
p = (u_char *)amp;
which = (1 == IPTOSBUFFERS ? 0 : 1); >sprintf(output[which], "d.d.d.d", p[0], p[1], p[2], p[3])
return 출력[which];
}
3. 인터페이스 열기 및 트래픽 캡처
이제 인터페이스에 대한 정보를 얻는 방법을 알았으므로 실제 개방형 인터페이스를 얻고 트래픽을 캡처할 수 있습니다. 이번 강의에서는 네트워크의 모든 패킷을 캡처하고 이에 대한 일부 정보를 출력하는 프로그램을 컴파일합니다.
pcap_open_live() 함수를 사용하여 캡처 장치를 엽니다. 여기서는 snaplen, promisc 및 to_ms 매개변수를 설명해야 합니다.
( Y- 함수 프로토타입: pcap_t * pcap_open_live (char *device, int snaplen , int promisc, int to_ms, char *ebuf) )
"snaplen" 매개변수는 캡처할 패킷 부분을 지정합니다(xBSD 및 Win32 등). 캡처 전용 각 패킷의 일부 가능성: 처리할 데이터의 양을 줄여 캡처 절차의 효율성을 높입니다. 이 예에서는 최대 MTU(65536)보다 높은 값을 사용하여 다음을 보장합니다.
"promisc"는 인터페이스가 무차별 모드로 설정됨을 나타냅니다. 일반적인 상황에서는 인터페이스가 다른 호스트에 대한 자체 패킷을 처리하는 데이터만 처리합니다. 그러나 인터페이스가 무차별 모드에 있으면 모든 트래픽을 처리합니다. 즉, 비스위치 이더넷(예: In)과 같은 공유 매체(Y- 어떻게 번역해야 할지 모르겠습니다)에서 처리합니다. 허브 기반 네트워크), WinPcap은 모든 호스트에서 패킷을 캡처할 수 있습니다. 혼합 모드는 대부분의 캡처 프로그램의 기본 모드이므로 예제에서도 이 모드를 사용합니다.
"to_ms"는 설정에 사용됩니다. 인터페이스(예: pcap_dispatch() 또는 pcap_next_ex())의 읽기(Y-캡처) 작업은 패킷이 캡처되지 않은 경우 지정된 시간이 경과한 후 반환됩니다. 모드에서 to_ms는 정적 보고서 간의 간격도 정의합니다(자세한 내용은 "네트워크 트래픽에 대한 통계 수집" 참조). to_ms를 0으로 설정하면 시간 초과가 발생하지 않으며, 패킷이 도착하지 않으면 캡처 작업이 반환되지 않습니다. 그러나 해당 값을 -1로 설정하면 즉시 반환됩니다.
코드
#include "pcap.h"
/* 패킷 처리 함수 선언*/ p>
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
main( )
{
pcap_if_t *alldevs;
pcap_if_t *d;
int i =0; >
char errbuf[PCAP_ERRBUF_SIZE];
/* 장치 목록 가져오기*/
if ( pcap_findalldevs(amp; alldevs, errbuf) == -1)
{
fprintf(stderr, "pcap_findalldevs에 오류가 있습니다: s\n", errbuf)
exit(1)
}
/* 데이터 목록*/
for(
d=alldevs; d; d=d-gt;next)
{
printf("d.s", i, d-gt; 이름);
if (d-gt; 설명)
printf(" (s)\n", d-gt; 설명)
else
printf(" (설명 없음)\n")
}
if(i==0)
{
printf("\n인터페이스를 찾을 수 없습니다! WinPcap이 설치되어 있는지 확인하세요.\n");
return -1
}
printf(" 인터페이스 번호(1-d): ", i);
scanf("d", amp; inum);
if(inum lt; 1 || inum gt; i )
{
printf("\n인터페이스 번호가 범위를 벗어났습니다.\n")
/* 장치 목록 해제*/
pcap_freealldevs(alldevs);
return -1;
}
/* 선택한 장치로 이동*/
(d=alldevs, i=0; ilt; inum-1; d=d-gt; next, i)
/* 장치 열기*/
if ( (adhandle = pcap_open_live(d-gt;name, //장치 이름
65536, //전체 패킷 캡처
1, //혼합 모드
1000 , / /읽기 시간 초과
errbuf //오류 버퍼
) ) == NULL)
{
/* Y- 열기 실패* /
fprintf(stderr, "\n어댑터를 열 수 없습니다. s는 WinPcap에서 지원되지 않습니다.\n")
/* 릴리스 목록*/
pcap_freealldevs(alldevs);
return -1;
}
printf("\n듣는 중...\n", d -gt; 설명);
/* 더 이상 장치 목록이 필요하지 않습니다. 해제하세요*/
pcap_freealldevs(alldevs)
/* 캡처 시작 */
pcap_loop(adhandle, 0, packet_handler, NULL);
return 0;
}
/* 패킷 처리 콜백 함수 */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_dat
a)
{
struct tm *ltime;
char timestr[16]
/* 타임스탬프를 읽을 수 있는 형식으로 변환* /
ltime=localtime(amp;header-gt;ts.tv_sec)
strftime(timestr, sizeof timestr, "H:M:S", ltime)
p>printf("s,.6d len: d\n", timestr, header-gt; ts.tv_usec, header-gt; len)
}
인터페이스가 열리면 pcap_dispatch() 또는 pcap_loop() 함수가 캡처를 시작합니다. 두 함수는 시간 초과 후 바로 반환되지만 pcap_loop()는 특정 횟수까지 기다려야 합니다. (Y- 두 번째 매개변수는 처리할 데이터 패킷 수를 지정하며, 0은 무제한입니다. 여기서 설정한 시간 초과는 pcap_loop()에 영향을 미치지 않습니다.) 이 예에서는 그 중, pcap_loop()이면 충분하며 pcap_dispatch()는 일반적으로 더 복잡한 프로그램에서 사용됩니다.
두 함수 모두 콜백 매개변수를 가지며 데이터 패킷을 처리하는 데는 packet_handler와 같은 하나의 함수만 사용됩니다. 이 예에서는 새로운 데이터 패킷이 도착할 때마다 libpcap이 이 함수를 호출하여 데이터 패킷에 대한 일부 정보(타임스탬프 및 길이 정보(Y-헤더 매개변수) 포함)도 제공합니다. MAC CRC는 일반적으로 장치(네트워크 카드)가 프레임 확인 작업을 수행할 때 이동되므로 나타나지 않습니다. 또한 대부분의 네트워크 카드는 잘못된 CRC를 삭제합니다. , 따라서 WinPcap은 기본적으로 이를 포착할 수 없습니다.
위의 예는 (pcap_pkthdr 헤더에서) 각 패킷의 타임스탬프와 길이만 출력합니다.
DNF의 크립톤 금 계획이란 무엇인가요?
캠퍼스형을 원한다