@@ -345,6 +345,7 @@ static const struct timeval netdown_timeout = {
345345static int iface_get_id (int fd , const char * device , char * ebuf );
346346static int iface_get_mtu (int fd , const char * device , char * ebuf );
347347static int iface_get_arptype (int fd , const char * device , char * ebuf );
348+ static int iface_exists (const char * device , char * ebuf );
348349static int iface_bind (int fd , int ifindex , char * ebuf , int protocol );
349350static 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