Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 11 Aug 2012 18:11:05 -0400
From:      Curtis Villamizar <curtis@occnc.com>
To:        freebsd-ports@freebsd.org
Cc:        Scott Blachowicz <scott+ports@mail.dsab.rresearch.com>, curtis@occnc.com
Subject:   patch to FreeBSD mail/nmh port for IPv6
Message-ID:  <201208112211.q7BMB54e038664@gateway.ipv6.occnc.com>

next in thread | raw e-mail | index | archive | help

FYI-

The patch below fixes the rcaux function and gethostbystring functions
in the file sbr/client.c such that the support AF_INET6 hosts and
connections.  These are used in the client function, used in POP, and
in smtp.c (sending mail via smtp).

The largish patch below can be copied into the files directory as
/usr/ports/mail/nmh/files/patch-sbr-client-for-afinet6
That can fix it for the FreeBSD mail/nmh port for now.

The port maintainer is on the Cc.  No bug has been reported.

The tarball file in distinfo is nmh-1.3.tar.gz which is far from the
most recent.  It appears that this bug is already fixed in nmh 1.5
(and maybe 1.4, but I didn't look).  It might be better to bring the
distinfo file up to date.  nmh-1.5 is June 2012 and 1.4 is Jan 2012,
so the port is not ancient, just not up to date.

BTW - yes, people still use nmh.  :-)

Curtis



--- sbr/client.c.orig	2006-01-01 19:17:42.000000000 -0800
+++ sbr/client.c	2011-09-02 08:46:06.000000000 -0700
@@ -70,9 +70,6 @@
 # define h_addr h_addr_list[0]
 #endif
 
-#define	inaddr_copy(hp,sin) \
-    memcpy(&((sin)->sin_addr), (hp)->h_addr, (hp)->h_length)
-
 /*
  * static prototypes
  */
@@ -208,8 +205,11 @@
     int sd;
     struct in_addr in;
     register struct addrent *ap;
-    struct sockaddr_in in_socket;
-    register struct sockaddr_in *isock = &in_socket;
+    struct sockaddr_in in_socket4;
+#ifdef AF_INET6
+    struct sockaddr_in6 in_socket6;
+#endif
+    register struct sockaddr *isock;
 
 #ifdef KPOP
     int rem;
@@ -228,12 +228,28 @@
     if ((sd = getport (rproto, hp->h_addrtype, response, len_response)) == NOTOK)
 	return OOPS2;
 
-    memset (isock, 0, sizeof(*isock));
-    isock->sin_family = hp->h_addrtype;
-    inaddr_copy (hp, isock);
-    isock->sin_port = sp->s_port;
+    if (hp->h_addrtype == AF_INET) {
+	memset (&in_socket4, 0, sizeof(in_socket4));
+	in_socket4.sin_family = hp->h_addrtype;
+	memcpy(&in_socket4.sin_addr, hp->h_addr, hp->h_length);
+	in_socket4.sin_port = sp->s_port;
+	in_socket4.sin_len = sizeof(in_socket4);
+	isock = (struct sockaddr *) &in_socket4;
+#ifdef AF_INET6
+    } else if (hp->h_addrtype == AF_INET6) {
+	memset (&in_socket6, 0, sizeof(in_socket6));
+	in_socket6.sin6_family = hp->h_addrtype;
+	memcpy(&in_socket6.sin6_addr, hp->h_addr, hp->h_length);
+	in_socket6.sin6_port = sp->s_port;
+	in_socket6.sin6_len = sizeof(in_socket6);
+	isock = (struct sockaddr *) &in_socket6;
+#endif
+    } else {
+	strncpy (response, "rcaux: unsupported address family", len_response);
+	return OOPS2;
+    }
 
-    if (connect (sd, (struct sockaddr *) isock, sizeof(*isock)) == NOTOK)
+    if (connect (sd, (struct sockaddr *) isock, isock->sa_len) == NOTOK)
 	switch (errno) {
 	    case ENETDOWN: 
 	    case ENETUNREACH: 
@@ -305,7 +321,7 @@
 	return NOTOK;
     }
 
-    if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK) {
+    if ((sd = socket (addrtype, SOCK_STREAM, 0)) == NOTOK) {
 	char *s;
 
 	if ((s = strerror (errno)))
@@ -380,14 +396,41 @@
 #else
     static unsigned long iaddr;
 #endif
+#ifdef AI_ADDRCONFIG
+    /* if AI_ADDRCONFIG is defined, then getaddrinfo is available */
+    int af;
+    struct addrinfo hints;
+    struct addrinfo *ai, *res;
+#endif
 
     iaddr = inet_addr (s);
+    if (
 #ifdef DG
-    if (iaddr.s_addr == NOTOK && strcmp (s, "255.255.255.255"))
+	iaddr.s_addr == NOTOK
 #else
-    if (((int) iaddr == NOTOK) && strcmp (s, "255.255.255.255"))
+	((int) iaddr == NOTOK)
 #endif
+	&& strcmp (s, "255.255.255.255")) {
+#ifndef AI_ADDRCONFIG
 	return gethostbyname (s);
+#else
+	af = PF_UNSPEC;
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_flags = AI_ADDRCONFIG;
+	if (!getaddrinfo(s, NULL, &hints, &res)) {
+	    for (ai = res; ai; ai = ai->ai_next) {
+		if (af == PF_UNSPEC)
+		    af = ai->ai_family;
+	    }
+	    freeaddrinfo(res);
+	}
+	if (af == PF_UNSPEC)
+	    af = AF_INET;
+	/* avoid returning AF_INET is no IPv4 interface is configured */
+	return gethostbyname2 (s, af);
+#endif
+    }
 
     h = &hs;
     h->h_name = s;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208112211.q7BMB54e038664>