Skip to content

Commit 33c7808

Browse files
author
Afshin Paydar
committed
open a non-existent interface should always return 'no such interface'
Signed-off-by: Afshin Paydar <[email protected]>
1 parent 5fc0c26 commit 33c7808

File tree

2 files changed

+77
-6
lines changed

2 files changed

+77
-6
lines changed

pcap-bpf.c

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@
4141
#ifdef HAVE_SYS_IOCCOM_H
4242
#include <sys/ioccom.h>
4343
#endif
44+
45+
/*
46+
* On some platforms, <sys/sockio.h> is needed for SIOCGIF* macros.
47+
* Include it conditionally based on what the build system detects.
48+
*/
49+
#if defined(HAVE_SOLARIS) || defined(__HAIKU__)
50+
#include <sys/sockio.h>
51+
#endif
52+
4453
#include <sys/utsname.h>
4554

4655
#if defined(__FreeBSD__) && defined(SIOCIFCREATE2)
@@ -626,6 +635,58 @@ bpf_open(char *errbuf)
626635
#define BPF_BIND_SUCCEEDED 0
627636
#define BPF_BIND_BUFFER_TOO_BIG 1
628637

638+
/*
639+
* Check if an interface exists without requiring special privileges.
640+
* Returns 0 if the interface exists, PCAP_ERROR_NO_SUCH_DEVICE if it doesn't,
641+
* or another negative error code on other failures.
642+
*/
643+
static int
644+
check_interface_exists(const char *name, char *errbuf)
645+
{
646+
#ifndef _WIN32
647+
int fd;
648+
struct ifreq ifr;
649+
650+
if (strlen(name) >= sizeof(ifr.ifr_name)) {
651+
/* The name is too long, so it can't possibly exist. */
652+
errbuf[0] = '\0';
653+
return PCAP_ERROR_NO_SUCH_DEVICE;
654+
}
655+
656+
fd = socket(AF_INET, SOCK_DGRAM, 0);
657+
if (fd < 0) {
658+
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
659+
errno, "socket");
660+
return PCAP_ERROR;
661+
}
662+
663+
memset(&ifr, 0, sizeof(ifr));
664+
pcapint_strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
665+
666+
if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) {
667+
int save_errno = errno;
668+
close(fd);
669+
670+
if (save_errno == ENXIO || save_errno == ENODEV) {
671+
/* Interface doesn't exist */
672+
errbuf[0] = '\0';
673+
return PCAP_ERROR_NO_SUCH_DEVICE;
674+
} else {
675+
/* Some other error occurred */
676+
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
677+
save_errno, "SIOCGIFFLAGS on %s", name);
678+
return PCAP_ERROR;
679+
}
680+
}
681+
682+
close(fd);
683+
return 0;
684+
#else
685+
/* On Windows, skip the check for now */
686+
return 0;
687+
#endif
688+
}
689+
629690
static int
630691
bpf_bind(int fd, const char *name, char *errbuf)
631692
{
@@ -1923,6 +1984,16 @@ pcap_activate_bpf(pcap_t *p)
19231984
int flags = MAP_ANON;
19241985
#endif
19251986

1987+
/*
1988+
* Check if the interface exists before trying to open BPF device.
1989+
* This avoids reporting permission errors when the real issue is
1990+
* that the interface doesn't exist.
1991+
*/
1992+
status = check_interface_exists(p->opt.device, p->errbuf);
1993+
if (status != 0) {
1994+
goto bad;
1995+
}
1996+
19261997
fd = bpf_open(p->errbuf);
19271998
if (fd < 0) {
19281999
status = fd;

pcap-linux.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5164,13 +5164,13 @@ iface_get_ts_types(const char *device, pcap_t *handle, char *ebuf)
51645164

51655165
case ENODEV:
51665166
/*
5167-
* OK, no such device.
5168-
* The user will find that out when they try to
5169-
* activate the device; just return an empty
5170-
* list of time stamp types.
5167+
* No such device.
5168+
*
5169+
* There's nothing more to say, so clear the
5170+
* error message.
51715171
*/
5172-
handle->tstamp_type_list = NULL;
5173-
return 0;
5172+
ebuf[0] = '\0';
5173+
return PCAP_ERROR_NO_SUCH_DEVICE;
51745174

51755175
default:
51765176
/*

0 commit comments

Comments
 (0)