aboutsummaryrefslogtreecommitdiff
path: root/pcap-linux.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2018-12-02 18:11:05 -0800
committerGuy Harris <guy@alum.mit.edu>2018-12-02 18:11:05 -0800
commit26cdd83c269988cfeb755fc0ebdfe2308c92f6dd (patch)
tree78f12946e39966ad08e657f1f02ecf897fb128c1 /pcap-linux.c
parent822f7c533b6fa1d72db2b339bdd05993d8f43c12 (diff)
Pull the opening of the PF_PACKET socket back into activate_new().
Diffstat (limited to 'pcap-linux.c')
-rw-r--r--pcap-linux.c66
1 files changed, 34 insertions, 32 deletions
diff --git a/pcap-linux.c b/pcap-linux.c
index c0fb7d0e..19bd8659 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -349,9 +349,9 @@ static int get_if_flags(const char *, bpf_u_int32 *, char *);
static int is_wifi(int, const char *);
static void map_arphrd_to_dlt(pcap_t *, int, int, const char *, int);
static int pcap_activate_linux(pcap_t *);
-static int activate_old(pcap_t *);
+static int activate_old(pcap_t *, int);
#ifdef HAVE_PF_PACKET_SOCKETS
-static int activate_new(pcap_t *, int, int);
+static int activate_new(pcap_t *, int);
#ifdef HAVE_PACKET_RING
static int activate_mmap(pcap_t *, int *);
#endif
@@ -1673,27 +1673,27 @@ pcap_activate_linux(pcap_t *handle)
* to be compatible with older kernels for a while so we are
* trying both methods with the newer method preferred.
*
- * Try to open a PF_PACKET socket. If the "any" device was
- * specified, we open a SOCK_DGRAM socket for the cooked
+ * Try to activate with a PF_PACKET socket. If the "any" device
+ * was specified, we open a SOCK_DGRAM socket for the cooked
* interface, otherwise we first try a SOCK_RAW socket for
* the raw interface.
*/
- int sock_fd = open_pf_packet_socket(handle, is_any_device);
- if (sock_fd < 0) {
- if (sock_fd != PCAP_ERROR_NO_PF_PACKET_SOCKETS) {
+ ret = activate_new(handle, is_any_device);
+ if (ret < 0) {
+ if (ret != PCAP_ERROR_NO_PF_PACKET_SOCKETS) {
/*
* Fatal error; the return value is the error code,
* and handle->errbuf has been set to an appropriate
* error message.
*/
- return sock_fd;
+ return ret;
}
/*
* We don't support PF_PACKET/SOCK_whatever
* sockets; try the old mechanism.
*/
- ret = activate_old(handle);
+ ret = activate_old(handle, is_any_device);
if (ret != 0) {
/*
* Both methods to open the packet socket
@@ -1707,20 +1707,6 @@ pcap_activate_linux(pcap_t *handle)
goto fail;
}
} else {
- /*
- * We have a PF_PACKET socket.
- * Try setting it up.
- */
- ret = activate_new(handle, sock_fd, is_any_device);
- if (ret < 0) {
- /*
- * Failure. ret has the error return, and
- * handle->errbuf has been set appropriately.
- */
- status = ret;
- goto fail;
- }
-
#ifdef HAVE_PACKET_RING
/*
* Success.
@@ -1766,7 +1752,7 @@ pcap_activate_linux(pcap_t *handle)
* We don't support PF_PACKET/SOCK_whatever sockets, so we must
* try the old mechanism.
*/
- ret = activate_old(handle);
+ ret = activate_old(handle, is_any_device);
if (ret != 0) {
/*
* That failed.
@@ -3748,11 +3734,11 @@ set_dlt_list_cooked(pcap_t *handle _U_, int sock_fd _U_)
* Returns 0 on success and a PCAP_ERROR_ value on failure.
*/
static int
-activate_new(pcap_t *handle, int sock_fd, int is_any_device)
+activate_new(pcap_t *handle, int is_any_device)
{
struct pcap_linux *handlep = handle->priv;
const char *device = handle->opt.device;
- int arptype;
+ int sock_fd, arptype;
#ifdef HAVE_PACKET_AUXDATA
int val;
#endif
@@ -3763,6 +3749,14 @@ activate_new(pcap_t *handle, int sock_fd, int is_any_device)
socklen_t len = sizeof(bpf_extensions);
#endif
+ sock_fd = open_pf_packet_socket(handle, is_any_device);
+ if (sock_fd < 0) {
+ /*
+ * Failed; return its return value.
+ */
+ return sock_fd;
+ }
+
/* It seems the kernel supports the new interface. */
handlep->sock_packet = 0;
@@ -6913,7 +6907,7 @@ iface_get_offload(pcap_t *handle _U_)
* Returns 0 on success and a PCAP_ERROR_ value on an error.
*/
static int
-activate_old(pcap_t *handle)
+activate_old(pcap_t *handle, int is_any_device)
{
struct pcap_linux *handlep = handle->priv;
int err;
@@ -6927,7 +6921,7 @@ activate_old(pcap_t *handle)
* PF_INET/SOCK_PACKET sockets must be bound to a device, so we
* can't support the "any" device.
*/
- if (strcmp(device, "any") == 0) {
+ if (is_any_device) {
pcap_strlcpy(handle->errbuf, "pcap_activate: The \"any\" device isn't supported on 2.0[.x]-kernel systems",
PCAP_ERRBUF_SIZE);
return PCAP_ERROR;
@@ -6960,15 +6954,19 @@ activate_old(pcap_t *handle)
handlep->cooked = 0;
/* Bind to the given device */
- if (iface_bind_old(handle->fd, device, handle->errbuf) == -1)
+ if (iface_bind_old(handle->fd, device, handle->errbuf) == -1) {
+ close(handle->fd);
return PCAP_ERROR;
+ }
/*
* Try to get the link-layer type.
*/
arptype = iface_get_arptype(handle->fd, device, handle->errbuf);
- if (arptype < 0)
- return PCAP_ERROR;
+ if (arptype < 0) {
+ close(handle->fd);
+ return arptype;
+ }
/*
* Try to find the DLT_ type corresponding to that
@@ -6989,6 +6987,7 @@ activate_old(pcap_t *handle)
if (ioctl(handle->fd, SIOCGIFFLAGS, &ifr) == -1) {
pcap_fmt_errmsg_for_errno(handle->errbuf,
PCAP_ERRBUF_SIZE, errno, "SIOCGIFFLAGS");
+ close(handle->fd);
return PCAP_ERROR;
}
if ((ifr.ifr_flags & IFF_PROMISC) == 0) {
@@ -7010,6 +7009,7 @@ activate_old(pcap_t *handle)
* the interface in promiscuous
* mode, just give up.
*/
+ close(handle->fd);
return PCAP_ERROR;
}
@@ -7080,8 +7080,10 @@ activate_old(pcap_t *handle)
* to work well.
*/
mtu = iface_get_mtu(handle->fd, device, handle->errbuf);
- if (mtu == -1)
+ if (mtu == -1) {
+ close(handle->fd);
return PCAP_ERROR;
+ }
handle->bufsize = MAX_LINKHEADER_SIZE + mtu;
if (handle->bufsize < (u_int)handle->snapshot)
handle->bufsize = (u_int)handle->snapshot;