]> The Tcpdump Group git mirrors - libpcap/commitdiff
Update description fetching code for FreeBSD, fix code for OpenBSD.
authorGuy Harris <[email protected]>
Wed, 28 Apr 2010 19:29:19 +0000 (12:29 -0700)
committerGuy Harris <[email protected]>
Wed, 28 Apr 2010 19:29:19 +0000 (12:29 -0700)
Update from Jason (Xin) Li to reflect changes to the FreeBSD
SIOCGIFDESCR implementation - it now doesn't return an error if the
buffer is too short, it sets the buffer pointer to NULL.  No FreeBSD
release has SIOCGIFDESCR, so this doesn't break on any release.

The loop, trying to increase the buffer size until it's big enough,
works only on FreeBSD, as that's the only OS where you get told what
length to use; OpenBSD clamps the description length at IFDESCRSIZE, so
we just use that.

inet.c

diff --git a/inet.c b/inet.c
index 0b16a659072ddc133827f5f5e9885f694b61aaf7..178eb81f4ff63f35a361c4dc5803c671b58cd824 100644 (file)
--- a/inet.c
+++ b/inet.c
@@ -431,26 +431,54 @@ add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
        strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
        s = socket(AF_INET, SOCK_DGRAM, 0);
        if (s >= 0) {
+#ifdef __FreeBSD__
+               /*
+                * On FreeBSD, if the buffer isn't big enough for the
+                * description, the ioctl succeeds, but the description
+                * isn't copied, ifr_buffer.length is set to the description
+                * length, and ifr_buffer.buffer is set to NULL.
+                */
                for (;;) {
                        free(description);
                        if ((description = malloc(descrlen)) != NULL) {
-#ifdef __FreeBSD__
                                ifrdesc.ifr_buffer.buffer = description;
                                ifrdesc.ifr_buffer.length = descrlen;
-#else /* __FreeBSD__ */
-                               ifrdesc.ifr_data = (caddr_t)description;
-#endif /* __FreeBSD__ */
-                               if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0)
-                                       break;
-#ifdef __FreeBSD__
-                               else if (errno == ENAMETOOLONG)
-                                       descrlen = ifrdesc.ifr_buffer.length;
-#endif /* __FreeBSD__ */
-                               else
+                               if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
+                                       if (ifrdesc.ifr_buffer.buffer ==
+                                           description)
+                                               break;
+                                       else
+                                               descrlen = ifrdesc.ifr_buffer.length;
+                               } else {
+                                       /*
+                                        * Failed to get interface description.
+                                        */
+                                       free(description);
+                                       description = NULL;
                                        break;
+                               }
                        } else
                                break;
                }
+#else /* __FreeBSD__ */
+               /*
+                * The only other OS that currently supports
+                * SIOCGIFDESCR is OpenBSD, and it has no way
+                * to get the description length - it's clamped
+                * to a maximum of IFDESCRSIZE.
+                */
+               if ((description = malloc(descrlen)) != NULL) {
+                       ifrdesc.ifr_data = (caddr_t)description;
+                       if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
+                               /*
+                                * Failed to get interface description.
+                                */
+                               free(description);
+                               description = NULL;
+                       }
+               } else
+                       break;
+#endif /* __FreeBSD__ */
                close(s);
                if (description != NULL && strlen(description) == 0) {
                        free(description);