[Iftop-users] Porting iftop 1.0 to FreeBSD

Frédéric Perrin frederic.perrin at resel.fr
Mon, 06 Dec 2010 10:16:50 +0100


--=-=-=
Content-Type: multipart/signed; boundary="==-=-=";
	micalg=pgp-sha1; protocol="application/pgp-signature"

--==-=-=
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable

Hello,

Today I compiled iftop-1.0pre1 if a FreeBSD system. I had to make the
following changes:

=2D config/int_ghba_r.c uses AF_INET, which is defined in <sys/socket.h>,
  without #include'ing it ;

=2D add =C2=AB #define define s6_addr32 __u6_addr.__u6_addr32 =C2=BB in con=
fig.h
  (this is used in addr_hash and ns_hash.c). FreeBSD has a note in
  <netinet6/in6.h> saying it is not standard ;

=2D in resolver.c, only the getnameinfo() method tries to resolve ip6
  addresses. I ported the AF guessing to the gethostbyaddr{,_r} methods,
  as I am not familiar with the libresolv or the ares librairies. This
  enables reverse ip6 resolution.

The patch is attached. Could you please review it, and apply it if it
DTRT ?

=2D-=20
Fred


--==-=-=
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)

iEYEARECAAYFAkz8qgIACgkQlSqR5GqTBEOE7gCeLtLltULeaFsZjyUAl2SnaFVC
3WoAn0dvcU6X7aaW+LPC0XVAZyWAI1ei
=H/xF
-----END PGP SIGNATURE-----
--==-=-=--

--=-=-=
Content-Type: text/x-patch
Content-Disposition: inline; filename=iftop.fBSD.patch
Content-Description: FreeBSD port effort

diff -ur iftop-1.0pre1.orig/config/int_ghba_r.c iftop-1.0pre1/config/int_ghba_r.c
--- iftop-1.0pre1.orig/config/int_ghba_r.c	2002-11-04 13:27:35.000000000 +0100
+++ iftop-1.0pre1/config/int_ghba_r.c	2010-12-04 12:43:29.000000000 +0100
@@ -6,6 +6,7 @@
 
 static const char rcsid[] = "$Id: int_ghba_r.c,v 1.1 2002/11/04 12:27:35 chris Exp $";
 
+#include <sys/socket.h>
 #include <sys/types.h>
 
 #include <errno.h>
diff -ur iftop-1.0pre1.orig/config.h.in iftop-1.0pre1/config.h.in
--- iftop-1.0pre1.orig/config.h.in	2010-11-27 12:41:51.000000000 +0100
+++ iftop-1.0pre1/config.h.in	2010-12-03 17:11:59.000000000 +0100
@@ -158,3 +158,9 @@
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef size_t
+
+/* fBSD doesn't define this in user-land code, with a note saying this
+/* is not standard */
+#ifndef s6_addr32
+#  define s6_addr32 __u6_addr.__u6_addr32
+#endif
diff -ur iftop-1.0pre1.orig/resolver.c iftop-1.0pre1/resolver.c
--- iftop-1.0pre1.orig/resolver.c	2010-11-27 11:56:44.000000000 +0100
+++ iftop-1.0pre1/resolver.c	2010-12-05 14:48:00.000000000 +0100
@@ -37,6 +37,22 @@
 
 extern options_t options;
 
+int guess_af(struct in6_addr *addr)
+{
+    /* If the upper three (network byte order) uint32-parts
+     * are null, then there ought to be an IPv4 address here.
+     * Any such IPv6 would have to be 'xxxx::'. Neglectable? */
+    uint32_t* probe;
+    int af;
+
+    probe = (uint32_t *) addr;
+    return (probe[1] || probe[2] || probe[3]) ? AF_INET6 : AF_INET;
+}
+
+socklen_t aflength(int af)
+{
+    return af == AF_INET6 ? sizeof(struct in6_addr) : sizeof(struct in_addr);
+}
 
 /* 
  * We have a choice of resolver methods. Real computers have getnameinfo or
@@ -60,18 +76,11 @@
     struct sockaddr_in6 sin6;
     char buf[NI_MAXHOST]; /* 1025 */
     int res, af;
-    uint32_t* probe;
 
     memset(&sin, '\0', sizeof(sin));
     memset(&sin6, '\0', sizeof(sin6));
 
-    /* If the upper three (network byte order) uint32-parts
-     * are null, then there ought to be an IPv4 address here.
-     * Any such IPv6 would have to be 'xxxx::'. Neglectable? */
-    probe = (uint32_t *) addr;
-    af = (probe[1] || probe[2] || probe[3]) ? AF_INET6 : AF_INET;
-
-    switch (af) {
+    switch (guess_af(addr)) {
         case AF_INET:
             sin.sin_family = af;
             sin.sin_port = 0;
@@ -106,26 +115,29 @@
  * Some implementations of libc choose to implement gethostbyaddr_r as
  * a non thread-safe wrapper to gethostbyaddr.  An interesting choice...
  */
-char* do_resolve(struct in_addr * addr) {
+char* do_resolve(struct in6_addr * addr) {
     struct hostent hostbuf, *hp;
     size_t hstbuflen = 1024;
     char *tmphstbuf;
     int res;
     int herr;
+    int af;
     char * ret = NULL;
 
     /* Allocate buffer, remember to free it to avoid memory leakage.  */            
     tmphstbuf = xmalloc (hstbuflen);
 
+    af = guess_af(addr);
+
     /* Some machines have gethostbyaddr_r returning an integer error code; on
      * others, it returns a struct hostent*. */
 #ifdef GETHOSTBYADDR_R_RETURNS_INT
-    while ((res = gethostbyaddr_r((char*)addr, sizeof(struct in_addr), AF_INET,
+    while ((res = gethostbyaddr_r((char*)addr, aflength(af), af,
                                   &hostbuf, tmphstbuf, hstbuflen,
                                   &hp, &herr)) == ERANGE)
 #else
     /* ... also assume one fewer argument.... */
-    while ((hp = gethostbyaddr_r((char*)addr, sizeof(struct in_addr), AF_INET,
+    while ((hp = gethostbyaddr_r((char*)addr, aflength(af), af,
                            &hostbuf, tmphstbuf, hstbuflen, &herr)) == NULL
             && errno == ERANGE)
 #endif
@@ -152,22 +164,24 @@
 #elif defined(USE_GETHOSTBYADDR)
 
 /**
- * Implementation using gethostbyname. Since this is nonreentrant, we have to
+ * Implementation using gethostbyaddr. Since this is nonreentrant, we have to
  * wrap it in a mutex, losing all benefit of multithreaded resolution.
  */
 char *do_resolve(struct in_addr *addr) {
     static pthread_mutex_t ghba_mtx = PTHREAD_MUTEX_INITIALIZER;
     char *s = NULL;
     struct hostent *he;
+    int af;
+    af = guess_af(*addr);
+
     pthread_mutex_lock(&ghba_mtx);
-    he = gethostbyaddr((char*)addr, sizeof *addr, AF_INET);
+    he = gethostbyaddr((char*)addr, aflength(af), af);
     if (he)
         s = xstrdup(he->h_name);
     pthread_mutex_unlock(&ghba_mtx);
     return s;
 }
 
-
 #elif defined(USE_LIBRESOLV)
 
 #include <arpa/nameser.h>
@@ -299,7 +313,7 @@
 #elif defined(USE_FORKING_RESOLVER)
 
 /**
- * Resolver which forks a process, then uses gethostbyname.
+ * Resolver which forks a process, then uses gethostbyaddr.
  */
 
 #include <signal.h>

--=-=-=--