pcap_open_live() Vs pcap_create() & pcap_activate()
libpcap에선 handler를 얻기 위해 pcap_open_live() 혹은 pcap_create() & pcap_activate() 함수를 사용한다.
이 함수들의 다른점은 무엇인지 알아보자.
What is difference?
본론부터 말하자면, 전혀 다르지 않다.
그 이유는 pcap_open_live() 함수의 소스코드를 보면 알 수 있는데,
[libpcap github]
pcap_t * pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf) { pcap_t *p; int status; #ifdef HAVE_REMOTE char host[PCAP_BUF_SIZE + 1]; char port[PCAP_BUF_SIZE + 1]; char name[PCAP_BUF_SIZE + 1]; int srctype; /* * Retrofit - we have to make older applications compatible with * remote capture. * So we're calling pcap_open_remote() from here; this is a very * dirty hack. * Obviously, we cannot exploit all the new features; for instance, * we cannot send authentication, we cannot use a UDP data connection, * and so on. */ if (pcap_parsesrcstr(device, &srctype, host, port, name, errbuf)) return (NULL); if (srctype == PCAP_SRC_IFREMOTE) { /* * Although we already have host, port and iface, we prefer * to pass only 'device' to pcap_open_rpcap(), so that it has * to call pcap_parsesrcstr() again. * This is less optimized, but much clearer. */ return (pcap_open_rpcap(device, snaplen, promisc ? PCAP_OPENFLAG_PROMISCUOUS : 0, to_ms, NULL, errbuf)); } if (srctype == PCAP_SRC_FILE) { pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown URL scheme \"file\""); return (NULL); } if (srctype == PCAP_SRC_IFLOCAL) { /* * If it starts with rpcap://, that refers to a local device * (no host part in the URL). Remove the rpcap://, and * fall through to the regular open path. */ if (strncmp(device, PCAP_SRC_IF_STRING, strlen(PCAP_SRC_IF_STRING)) == 0) { size_t len = strlen(device) - strlen(PCAP_SRC_IF_STRING) + 1; if (len > 0) device += strlen(PCAP_SRC_IF_STRING); } } #endif /* HAVE_REMOTE */ p = pcap_create(device, errbuf); if (p == NULL) return (NULL); status = pcap_set_snaplen(p, snaplen); if (status < 0) goto fail; status = pcap_set_promisc(p, promisc); if (status < 0) goto fail; status = pcap_set_timeout(p, to_ms); if (status < 0) goto fail; /* * Mark this as opened with pcap_open_live(), so that, for * example, we show the full list of DLT_ values, rather * than just the ones that are compatible with capturing * when not in monitor mode. That allows existing applications * to work the way they used to work, but allows new applications * that know about the new open API to, for example, find out the * DLT_ values that they can select without changing whether * the adapter is in monitor mode or not. */ p->oldstyle = 1; status = pcap_activate(p); if (status < 0) goto fail; return (p); fail: if (status == PCAP_ERROR) pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device, p->errbuf); else if (status == PCAP_ERROR_NO_SUCH_DEVICE || status == PCAP_ERROR_PERM_DENIED || status == PCAP_ERROR_PROMISC_PERM_DENIED) pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", device, pcap_statustostr(status), p->errbuf); else pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device, pcap_statustostr(status)); pcap_close(p); return (NULL); }
보면 pcap_open_live()함수 안에 pcap_create()등의 함수들이 들어가 잇는 걸 볼 수 있다.
위 코드가 이해하기 힘들다면 아래 간략하게 만든 코드를 보자,
pcap_t * pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf) { pcap_t *p; int status; p = pcap_create(source, errbuf); if (p == NULL) return (NULL); status = pcap_set_snaplen(p, snaplen); if (status < 0) goto fail; status = pcap_set_promisc(p, promisc); if (status < 0) goto fail; status = pcap_set_timeout(p, to_ms); if (status < 0) goto fail; [some code to make the backwards-compatibility stuff work a little better elided] status = pcap_activate(p); if (status < 0) goto fail; return (p); fail: [error-message-generation-code elided] pcap_close(p); return (NULL); }
>> 즉, pcap_open_live() 함수는 단순히 pcap_create()와 pcap_activate()와 같은 handler를 얻어올 때 많이 사용되는 함수들을 묶어 놓은 것에 불과 한 것이다.