@@ -345,6 +345,7 @@ static const struct timeval netdown_timeout = {
345
345
static int iface_get_id (int fd , const char * device , char * ebuf );
346
346
static int iface_get_mtu (int fd , const char * device , char * ebuf );
347
347
static int iface_get_arptype (int fd , const char * device , char * ebuf );
348
+ static int iface_exists (const char * device , char * ebuf );
348
349
static int iface_bind (int fd , int ifindex , char * ebuf , int protocol );
349
350
static int enter_rfmon_mode (pcap_t * handle , int sock_fd ,
350
351
const char * device );
@@ -2426,6 +2427,17 @@ setup_socket(pcap_t *handle, int is_any_device)
2426
2427
int err = 0 ;
2427
2428
struct packet_mreq mr ;
2428
2429
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
+
2429
2441
/*
2430
2442
* Open a socket with protocol family packet. If cooked is true,
2431
2443
* 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)
4812
4824
return 0 ;
4813
4825
}
4814
4826
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
+
4815
4871
/*
4816
4872
* Return the index of the given device name. Fill ebuf and return
4817
4873
* -1 on failure.
0 commit comments