pcap_open_live() Vs pcap_create() & pcap_activate()
libpcap에선 handler를 얻기 위해 pcap_open_live() 혹은 pcap_create() & pcap_activate() 함수를 사용한다.
이 함수들의 다른점은 무엇인지 알아보자.
What is difference?
본론부터 말하자면, 전혀 다르지 않다.
그 이유는 pcap_open_live() 함수의 소스코드를 보면 알 수 있는데,
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를 얻어올 때 많이 사용되는 함수들을 묶어 놓은 것에 불과 한 것이다.