]> The Tcpdump Group git mirrors - libpcap/commitdiff
When creating PF_PACKET sockets, fail immediately for most errors.
authorGuy Harris <[email protected]>
Fri, 15 Jul 2011 19:42:52 +0000 (12:42 -0700)
committerGuy Harris <[email protected]>
Fri, 15 Jul 2011 19:42:52 +0000 (12:42 -0700)
If an attempt to create a PF_PACKET socket fails with anything other
than EINVAL or EAFNOSUPPORT, treat it as a fatal error; other errors
probably mean the problem isn't that you have a crufty old kernel with
no PF_PACKET support, so don't try a SOCK_PACKET socket, as it'll
probably fail, too, and cause the kernel to whine that the app is using
an obsolete API.

In all cases where we create a socket, return PCAP_ERROR_PERM_DENIED for
EPERM and EACCES, PCAP_ERROR for all other errors.

Based on a patch from Gerald Combs.

pcap-linux.c

index a70d585f6c965203e4ab95a9bcb74702891e0826..ea7618dd00c47124d399df9af127c0fca7eb86ff 100644 (file)
@@ -2804,9 +2804,28 @@ activate_new(pcap_t *handle)
                socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
 
        if (sock_fd == -1) {
+               if (errno == EINVAL || errno == EAFNOSUPPORT) {
+                       /*
+                        * We don't support PF_PACKET/SOCK_whatever
+                        * sockets; try the old mechanism.
+                        */
+                       return 0;
+               }
+
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
                         pcap_strerror(errno) );
-               return 0;       /* try old mechanism */
+               if (errno == EPERM || errno == EACCES) {
+                       /*
+                        * You don't have permission to open the
+                        * socket.
+                        */
+                       return PCAP_ERROR_PERM_DENIED;
+               } else {
+                       /*
+                        * Other error.
+                        */
+                       return PCAP_ERROR;
+               }
        }
 
        /* It seems the kernel supports the new interface. */
@@ -2903,7 +2922,18 @@ activate_new(pcap_t *handle)
                        if (sock_fd == -1) {
                                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                                    "socket: %s", pcap_strerror(errno));
-                               return PCAP_ERROR;
+                               if (errno == EPERM || errno == EACCES) {
+                                       /*
+                                        * You don't have permission to
+                                        * open the socket.
+                                        */
+                                       return PCAP_ERROR_PERM_DENIED;
+                               } else {
+                                       /*
+                                        * Other error.
+                                        */
+                                       return PCAP_ERROR;
+                               }
                        }
                        handle->md.cooked = 1;
 
@@ -4840,7 +4870,18 @@ activate_old(pcap_t *handle)
        if (handle->fd == -1) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                         "socket: %s", pcap_strerror(errno));
-               return PCAP_ERROR_PERM_DENIED;
+               if (errno == EPERM || errno == EACCES) {
+                       /*
+                        * You don't have permission to open the
+                        * socket.
+                        */
+                       return PCAP_ERROR_PERM_DENIED;
+               } else {
+                       /*
+                        * Other error.
+                        */
+                       return PCAP_ERROR;
+               }
        }
 
        /* It worked - we are using the old interface */