6. 2. pcap_lookupdev()
char *pcap_lookupdev(errbuf)
register char *errbuf;
pcap_if_t 타입의 주소값을 저장하는 alldevs 선언
{
pcap_if_t *alldevs;
만약 IF_NAMESIZE가 정의 되어있지 않으면
#ifndef IF_NAMESIZE IF_NAMESIZE 는 IFNAMSIZ로 정의
#define IF_NAMESIZE IFNAMSIZ 케릭터 배열 device[]의 크기는 IF_NAMESIZE
#endif +1
그리고 스트링 ret 선언
static char device[IF_NAMESIZE + 1];
char *ret; 함수 pcap_findalldevs() 의 반환값으로
exception에러 검출 후 그에 따른 조치
if (pcap_findalldevs(&alldevs, errbuf) == -1) 그리고 디바이스가 검색되지 않았을 경우에도
return (NULL); 최종 반환하는 ret에 NULL값을 대입.
if (alldevs == NULL || (alldevs->flags &
PCAP_IF_LOOPBACK)) { 포인터 인자를 사용했기에 name에 접근이 가능
(void)strlcpy(errbuf, "no suitable device found", 위의 반환값에서 오류가 검출되지 않았으면
PCAP_ERRBUF_SIZE); name값을 device에 복사 그리고 ret에 복사
ret = NULL;
}
else {
(void)strlcpy(device, alldevs-
>name, sizeof(device));
ret = device;
함수 pcap_freealldevs() 로 포인터 변수 alldevs를 초
}
기화
pcap_freealldevs(alldevs);
및 결과 반환
7. 2-1. pcap_findalldevs()
int pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf){
pcap_if_t *devlist = NULL;
int ret = 0;
const char *desc; 만약 PacketGetAdapterNames() 함수로 디바이스의 길이를 먼저 파악.
char *AdaptersName; 반환값 이 부정이면 -1을 반환하여 에러처리
ULONG NameLength;
char *name;
if (!PacketGetAdapterNames(NULL, &NameLength)){
DWORD last_error = GetLastError();
메모리할당 if (last_error != ERROR_INSUFFICIENT_BUFFER){
오류 snprintf(errbuf, PCAP_ERRBUF_SIZE,"PacketGetAdapterNames: %s“,pcap_win32strerror()); return
(-1);}} 길이가 양수이면 Adapters 메모리할당을
if (NameLength > 0) {AdaptersName = (char*) malloc(NameLength);} 하고 0 또는 음수이면 0을 리턴 하고 종료.
else {*alldevsp = NULL; return 0; }
if (AdaptersName == NULL){snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters."); return
(-1);}
if (!PacketGetAdapterNames(AdaptersName,만약 PacketGetAdapterNames() 함수로 어뎁터의 이름을 얻지 못했으면 -1을 반환하여 에러처
&NameLength))
리
{snprintf(errbuf, PCAP_ERRBUF_SIZE, "PacketGetAdapterNames: %s", pcap_win32strerror()); free(AdaptersName);
return (-1);}
desc = &AdaptersName[0]; 얻은 이름을 name에 대입.
while (*desc != '0' || *(desc + 1) != '0') lookupdev함수에서 이 name을 참조함.
desc++;
desc += 2;
name = &AdaptersName[0];
while (*name != '0') {
if (pcap_add_if_win32(&devlist, name, desc, errbuf) == -1) {ret = -1; break}
name += strlen(name) + 1;
desc += strlen(desc) + 1;}
if (ret != -1) {
if (pcap_platform_finddevs(&devlist, errbuf) < 0) ret = -1;}
if (ret == -1) {
if (devlist != NULL) {pcap_freealldevs(devlist); devlist = NULL;}}
8. 2-2. pcap_freealldevs()
void pcap_freealldevs(pcap_if_t *alldevs)
{ 인자로 받은 alldevs를 차례로 하나씩 순회 Linked List
pcap_if_t *curdev, *nextdev;
pcap_addr_t *curaddr, *nextaddr;
for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
nextdev = curdev->next;
for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
nextaddr = curaddr->next;
순회된 각 디바이스의 if (curaddr->addr){free(curaddr->addr);}
주소정보가 담긴 구조체를 if (curaddr->netmask){free(curaddr->netmask);}
순회면서 주소 정보들을 반환. if (curaddr->broadaddr){free(curaddr->broadaddr);}
if (curaddr->dstaddr){free(curaddr->dstaddr);}
free(curaddr);
}
free(curdev->name);
if (curdev->description != NULL)
free(curdev->description);
free(curdev);
}
}
디바이스의 이름을 반환하고,
만약 디바이스의 디스크립션이 존재하면 그것도 반환한다.
마지막으로 디바이스 자체를 반환한다음 다음 디바이스로 순회
9. 2-2. pcap_freealldevs()
pcap_if_t alldevs pcap_if_t alldevs
addres addres
s s
addr -> free addr -> free
netmsk ->free netmsk ->free
broadaddr ->free broadaddr ->free
dstaddr ->free dstaddr ->free
next next
addres addres
s s
addr -> free null addr -> free null
netmsk ->free netmsk ->free
broadaddr ->free broadaddr ->free
dstaddr ->free dstaddr ->free
next next
addres addres
s s
addr -> free addr -> free
netmsk ->free netmsk ->free
broadaddr ->free broadaddr ->free
dstaddr ->free dstaddr ->free
next next next next
11. 3. pcap_open_live()
pcap_t *pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf)
{
pcap_t *p; pcap_t, status 선언 및
int status; 함수 pcap_create()함수로 pcap_t을 생성한다.
p = pcap_create(source, errbuf); 생성이 정상적으로 되지 않을 경우 NULL 을 반환하고 종료.
if (p == NULL)
return (NULL);
status = pcap_set_snaplen(p, snaplen);
if (status < 0)
goto fail;
status = pcap_set_promisc(p, promisc); 3개의 set 함수에는 pcap_check_activated() 라는 함수가 있다. 이 함수도 디바이스의 개
if (status < 0) 방 여부를 체크한다. 이상이 없다고 판단되면, 포인터로 pcap_t에 접근하여 각각 값을 set
goto fail; 한다. set까지 완료되면 0을 반환한다. 만약 0보다 작은 값을 반환하면 goto fail.
status = pcap_set_timeout(p, to_ms);
if (status < 0)
goto fail; 포인터로 pcap_t에 접근하여 oldstyle을 1로 입력.
p->oldstyle = 1; 모든 에러를 통과하면 함수 pcap_activate() 로 디바이스를 연다.
status = pcap_activate(p);
이때도 반환값으로 열기가 성공했는지 못했는지 검출하여 에러가 있으면 goto fail.
if (status < 0)
에러가 없다면 정상적으로 디바이스가 열린것으로 간주하여 pcap_t의 주소를 반환.
goto fail;
return (p);
fail:
if (status == PCAP_ERROR)
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, p->errbuf);
else if (status == PCAP_ERROR_NO_SUCH_DEVICE|| status == PCAP_ERROR_PERM_DENIED || status ==
PCAP_ERROR_PROMISC_PERM_DENIED)
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source, pcap_statustostr(status), p->errbuf);
else
snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, pcap_statustostr(status));
pcap_close(p);
return (NULL);
}
13. 3-2. pcap_set_ 3가지 ()
함수 pcap_check_activated() 로
현재 활성화인지 판단.
int pcap_set_snaplen(pcap_t *p, int snaplen){ 활성화이면 에러. 아니면 패스
if (pcap_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
p->snapshot = snaplen;
정보 저장 후 종료
return (0);
}
int pcap_set_promisc(pcap_t *p, int promisc){
if (pcap_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
p->opt.promisc = promisc;
return (0);
}
int pcap_set_timeout(pcap_t *p, int timeout_ms){
if (pcap_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
p->md.timeout = timeout_ms;
return (0);
}
14. 3-3. pcap_check_activated()
int pcap_check_activated(pcap_t *p)
{
if (p->activated) {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform "
" operation on activated capture");
return (-1);
}
return (0);
}
activated값이 0이 아니면 -1반환
activated값이 0이면 0반환
15. 3-4. pcap_activate()
ㅇint pcap_activate(pcap_t *p)
{
int status; 활성화인지 판단
if (pcap_check_activated(p))
return (PCAP_ERROR_ACTIVATED);
status = p->activate_op(p); activate_op() 함수의 반환값이 0이거
if (status >= 0) 나
p->activated = 1; 0보다 크면 pcap_t을 활성화시키고,
else { 그렇지 않으면 에러
if (p->errbuf[0] == '0') {
snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s",
pcap_statustostr(status));
}
initialize_ops(p);
}
return (status);
}