dect
/
libpcap
Archived
13
0
Fork 0

If attempting to turn memory-mapped access on fails for any reason other

than "the kernel doesn't support memory-mapped access to PF_PACKET
sockets", treat that as an error.  If it fails for that reason, don't
leave gunk behind in the pcap_t's error buffer.

Clean up the error messages a bit (the result of strerror() suffices; we
don't need the numeric value of errno, nor do we need the file
descriptor number of the socket on which we're working).
This commit is contained in:
guy 2008-11-19 10:01:30 +00:00
parent 8fa17a5a55
commit 5cf5f7c1c8
1 changed files with 63 additions and 27 deletions

View File

@ -34,7 +34,7 @@
#ifndef lint #ifndef lint
static const char rcsid[] _U_ = static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.159 2008-11-19 08:20:39 guy Exp $ (LBL)"; "@(#) $Header: /tcpdump/master/libpcap/pcap-linux.c,v 1.160 2008-11-19 10:01:30 guy Exp $ (LBL)";
#endif #endif
/* /*
@ -508,7 +508,6 @@ pcap_activate_linux(pcap_t *handle)
{ {
const char *device; const char *device;
int status = 0; int status = 0;
int activate_ok = 0;
device = handle->opt.source; device = handle->opt.source;
@ -555,27 +554,56 @@ pcap_activate_linux(pcap_t *handle)
*/ */
if ((status = activate_new(handle)) == 1) { if ((status = activate_new(handle)) == 1) {
activate_ok = 1;
/* /*
* Success.
* Try to use memory-mapped access. * Try to use memory-mapped access.
*/ */
if (activate_mmap(handle) == 1) switch (activate_mmap(handle)) {
return 0; /* we succeeded; nothing more to do */
case 1:
/* we succeeded; nothing more to do */
return 0;
case 0:
/*
* Kernel doesn't support it - just continue
* with non-memory-mapped access.
*/
break;
case -1:
/*
* We failed to set up to use it, or kernel
* supports it, but we failed to enable it;
* return an error. handle->errbuf contains
* an error message.
*/
status = PCAP_ERROR;
goto fail;
}
} }
else if (status == 0) { else if (status == 0) {
/* Non-fatal error; try old way */ /* Non-fatal error; try old way */
if ((status = activate_old(handle)) == 1) if ((status = activate_old(handle)) != 1) {
activate_ok = 1;
}
if (!activate_ok) {
/* /*
* Both methods to open the packet socket failed. Tidy * Both methods to open the packet socket failed.
* up and report our failure (ebuf is expected to be * Tidy up and report our failure (handle->errbuf
* set by the functions above). * is expected to be set by the functions above).
*/
goto fail;
}
} else {
/*
* Fatal error with the new way; just fail.
* status has the error return; if it's PCAP_ERROR,
* handle->errbuf has been set appropriately.
*/ */
goto fail; goto fail;
} }
/*
* We set up the socket, but not with memory-mapped access.
*/
if (handle->opt.buffer_size != 0) { if (handle->opt.buffer_size != 0) {
/* /*
* Set the socket buffer size to the specified value. * Set the socket buffer size to the specified value.
@ -1941,10 +1969,10 @@ activate_mmap(pcap_t *handle)
handle->opt.buffer_size = 2*1024*1024; handle->opt.buffer_size = 2*1024*1024;
} }
ret = prepare_tpacket_socket(handle); ret = prepare_tpacket_socket(handle);
if (ret == 0) if (ret != 1)
return ret; return ret;
ret = create_ring(handle); ret = create_ring(handle);
if (ret == 0) if (ret != 1)
return ret; return ret;
/* override some defaults and inherit the other fields from /* override some defaults and inherit the other fields from
@ -1981,11 +2009,13 @@ prepare_tpacket_socket(pcap_t *handle)
len = sizeof(val); len = sizeof(val);
if (getsockopt(handle->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) { if (getsockopt(handle->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) {
if (errno == ENOPROTOOPT) if (errno == ENOPROTOOPT)
return 1; return 1; /* no - just drive on */
/* Yes - treat as a failure. */
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"can't get TPACKET_V2 header len on socket %d: %d-%s", "can't get TPACKET_V2 header len on packet socket: %s",
handle->fd, errno, pcap_strerror(errno)); pcap_strerror(errno));
return 0; return -1;
} }
handle->md.tp_hdrlen = val; handle->md.tp_hdrlen = val;
@ -1993,9 +2023,9 @@ prepare_tpacket_socket(pcap_t *handle)
if (setsockopt(handle->fd, SOL_PACKET, PACKET_VERSION, &val, if (setsockopt(handle->fd, SOL_PACKET, PACKET_VERSION, &val,
sizeof(val)) < 0) { sizeof(val)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"can't activate TPACKET_V2 on socket %d: %d-%s", "can't activate TPACKET_V2 on packet socket: %s",
handle->fd, errno, pcap_strerror(errno)); pcap_strerror(errno));
return 0; return -1;
} }
handle->md.tp_version = TPACKET_V2; handle->md.tp_version = TPACKET_V2;
@ -2004,9 +2034,9 @@ prepare_tpacket_socket(pcap_t *handle)
if (setsockopt(handle->fd, SOL_PACKET, PACKET_RESERVE, &val, if (setsockopt(handle->fd, SOL_PACKET, PACKET_RESERVE, &val,
sizeof(val)) < 0) { sizeof(val)) < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"can't set up reserve on socket %d: %d-%s", "can't set up reserve on packet socket: %s",
handle->fd, errno, pcap_strerror(errno)); pcap_strerror(errno));
return 0; return -1;
} }
#endif /* HAVE_TPACKET2 */ #endif /* HAVE_TPACKET2 */
@ -2058,8 +2088,14 @@ retry:
req.tp_block_nr = req.tp_frame_nr/frames_per_block; req.tp_block_nr = req.tp_frame_nr/frames_per_block;
goto retry; goto retry;
} }
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "can't create rx ring on " if (errno == ENOPROTOOPT) {
"packet socket %d: %d-%s", handle->fd, errno, /*
* We don't have ring buffer support in this kernel.
*/
return 0;
}
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"can't create rx ring on packet socket: %s",
pcap_strerror(errno)); pcap_strerror(errno));
return 0; return 0;
} }