Skip to content

Commit 02956d2

Browse files
committed
check interface exists - linux
1 parent 8b097c7 commit 02956d2

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

pcap-linux.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ static const struct timeval netdown_timeout = {
345345
static int iface_get_id(int fd, const char *device, char *ebuf);
346346
static int iface_get_mtu(int fd, const char *device, char *ebuf);
347347
static int iface_get_arptype(int fd, const char *device, char *ebuf);
348+
static int iface_exists(const char *device, char *ebuf);
348349
static int iface_bind(int fd, int ifindex, char *ebuf, int protocol);
349350
static int enter_rfmon_mode(pcap_t *handle, int sock_fd,
350351
const char *device);
@@ -2426,6 +2427,17 @@ setup_socket(pcap_t *handle, int is_any_device)
24262427
int err = 0;
24272428
struct packet_mreq mr;
24282429

2430+
/*
2431+
* Check if the interface exists before attempting to open
2432+
* the privileged packet socket, so we can return the correct
2433+
* error for non-existent interfaces.
2434+
*/
2435+
if (!is_any_device) {
2436+
status = iface_exists(device, handle->errbuf);
2437+
if (status != 0)
2438+
return status;
2439+
}
2440+
24292441
/*
24302442
* Open a socket with protocol family packet. If cooked is true,
24312443
* we open a SOCK_DGRAM socket for the cooked interface, otherwise
@@ -4812,6 +4824,50 @@ pcap_setfilter_linux(pcap_t *handle, struct bpf_program *filter)
48124824
return 0;
48134825
}
48144826

4827+
/*
4828+
* Check if the given interface exists. Return 0 on success,
4829+
* PCAP_ERROR_NO_SUCH_DEVICE if the interface doesn't exist,
4830+
* or PCAP_ERROR on other failures.
4831+
*/
4832+
static int
4833+
iface_exists(const char *device, char *ebuf)
4834+
{
4835+
int fd;
4836+
struct ifreq ifr;
4837+
4838+
if (strlen(device) >= sizeof(ifr.ifr_name)) {
4839+
ebuf[0] = '\0';
4840+
return PCAP_ERROR_NO_SUCH_DEVICE;
4841+
}
4842+
4843+
fd = socket(AF_INET, SOCK_DGRAM, 0);
4844+
if (fd < 0) {
4845+
pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
4846+
errno, "socket");
4847+
return PCAP_ERROR;
4848+
}
4849+
4850+
memset(&ifr, 0, sizeof(ifr));
4851+
pcapint_strlcpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
4852+
4853+
if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) {
4854+
int save_errno = errno;
4855+
close(fd);
4856+
4857+
if (save_errno == ENODEV) {
4858+
ebuf[0] = '\0';
4859+
return PCAP_ERROR_NO_SUCH_DEVICE;
4860+
} else {
4861+
pcapint_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
4862+
save_errno, "SIOCGIFINDEX on %s", device);
4863+
return PCAP_ERROR;
4864+
}
4865+
}
4866+
4867+
close(fd);
4868+
return 0;
4869+
}
4870+
48154871
/*
48164872
* Return the index of the given device name. Fill ebuf and return
48174873
* -1 on failure.

0 commit comments

Comments
 (0)