@@ -626,6 +626,58 @@ bpf_open(char *errbuf)
626626#define BPF_BIND_SUCCEEDED 0
627627#define BPF_BIND_BUFFER_TOO_BIG 1
628628
629+ /*
630+ * Check if an interface exists without requiring special privileges.
631+ * Returns 0 if the interface exists, PCAP_ERROR_NO_SUCH_DEVICE if it doesn't,
632+ * or another negative error code on other failures.
633+ */
634+ static int
635+ check_interface_exists (const char * name , char * errbuf )
636+ {
637+ #ifndef _WIN32
638+ int fd ;
639+ struct ifreq ifr ;
640+
641+ if (strlen (name ) >= sizeof (ifr .ifr_name )) {
642+ /* The name is too long, so it can't possibly exist. */
643+ errbuf [0 ] = '\0' ;
644+ return PCAP_ERROR_NO_SUCH_DEVICE ;
645+ }
646+
647+ fd = socket (AF_INET , SOCK_DGRAM , 0 );
648+ if (fd < 0 ) {
649+ pcapint_fmt_errmsg_for_errno (errbuf , PCAP_ERRBUF_SIZE ,
650+ errno , "socket" );
651+ return PCAP_ERROR ;
652+ }
653+
654+ memset (& ifr , 0 , sizeof (ifr ));
655+ pcapint_strlcpy (ifr .ifr_name , name , sizeof (ifr .ifr_name ));
656+
657+ if (ioctl (fd , SIOCGIFFLAGS , & ifr ) < 0 ) {
658+ int save_errno = errno ;
659+ close (fd );
660+
661+ if (save_errno == ENXIO || save_errno == ENODEV ) {
662+ /* Interface doesn't exist */
663+ errbuf [0 ] = '\0' ;
664+ return PCAP_ERROR_NO_SUCH_DEVICE ;
665+ } else {
666+ /* Some other error occurred */
667+ pcapint_fmt_errmsg_for_errno (errbuf , PCAP_ERRBUF_SIZE ,
668+ save_errno , "SIOCGIFFLAGS on %s" , name );
669+ return PCAP_ERROR ;
670+ }
671+ }
672+
673+ close (fd );
674+ return 0 ;
675+ #else
676+ /* On Windows, skip the check for now */
677+ return 0 ;
678+ #endif
679+ }
680+
629681static int
630682bpf_bind (int fd , const char * name , char * errbuf )
631683{
@@ -1923,6 +1975,16 @@ pcap_activate_bpf(pcap_t *p)
19231975 int flags = MAP_ANON ;
19241976#endif
19251977
1978+ /*
1979+ * Check if the interface exists before trying to open BPF device.
1980+ * This avoids reporting permission errors when the real issue is
1981+ * that the interface doesn't exist.
1982+ */
1983+ status = check_interface_exists (p -> opt .device , p -> errbuf );
1984+ if (status != 0 ) {
1985+ goto bad ;
1986+ }
1987+
19261988 fd = bpf_open (p -> errbuf );
19271989 if (fd < 0 ) {
19281990 status = fd ;
0 commit comments