svn commit: r219472 - head/contrib/libpcap

Xin LI delphij at FreeBSD.org
Fri Mar 11 00:38:07 UTC 2011


Author: delphij
Date: Fri Mar 11 00:38:07 2011
New Revision: 219472
URL: http://svn.freebsd.org/changeset/base/219472

Log:
  Merge my change against libpcap trunk revision
  c65292b04b98d6a76d58c5a54ca8f81463bf24de to support new SIOCGIFDESCR
  ioctl interface which was too late for libpcap 1.1.1.
  
  Reported by:	brucec
  Noticed by:	wxs

Modified:
  head/contrib/libpcap/inet.c

Modified: head/contrib/libpcap/inet.c
==============================================================================
--- head/contrib/libpcap/inet.c	Thu Mar 10 23:53:01 2011	(r219471)
+++ head/contrib/libpcap/inet.c	Fri Mar 11 00:38:07 2011	(r219472)
@@ -431,26 +431,54 @@ add_addr_to_iflist(pcap_if_t **alldevs, 
 	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);


More information about the svn-src-all mailing list