[xdm PATCH 3/3] xdmcp: use getnameinfo() to get a name from a struct sockaddr

Julien Cristau jcristau at debian.org
Tue Mar 23 11:40:50 PDT 2010


xdm uses gethostbyaddr and inet_ntop to get the display name.  This
fails for e.g. link-local ipv6 addresses.  Use getnameinfo instead,
which gives us what we want.

Signed-off-by: Julien Cristau <jcristau at debian.org>
---
I'm not sure this is correct, I don't quite understand where the
connectionType/connectionAddress are coming from, and why/if they should
be used instead of the originalAddress.  But I tested that I could get a
login window with 'X -query fe80::dead:beff:feef:0123%eth0', which
didn't work before because the interface was lost when going from
address to display name.

 xdmcp.c |   43 +++++++++++++++----------------------------
 1 files changed, 15 insertions(+), 28 deletions(-)

diff --git a/xdmcp.c b/xdmcp.c
index 66a5e0f..640d845 100644
--- a/xdmcp.c
+++ b/xdmcp.c
@@ -516,6 +516,7 @@ NetworkAddressToName(
     CARD16	connectionType,
     ARRAY8Ptr   connectionAddress,
     struct sockaddr   *originalAddress,
+    int addrlen,
     CARD16	displayNumber)
 {
     switch (connectionType)
@@ -526,39 +527,34 @@ NetworkAddressToName(
 	{
 	    CARD8		*data;
 	    struct hostent	*hostent;
-	    char 		*hostname = NULL;
+	    char 		hostname[NI_MAXHOST];
 	    char		*name;
 	    char		*localhost;
 	    int			 multiHomed = 0;
 	    struct addrinfo	 hints, *ai = NULL, *nai;
 	    int 		 type;
+	    int 		 rc;
 
-	    if (connectionType == FamilyInternet6)
-		type = AF_INET6;
-	    else
-		type = AF_INET;
+	    rc = getnameinfo(originalAddress, addrlen, hostname, NI_MAXHOST,
+	                     NULL, 0, 0);
 
-	    data = connectionAddress->data;
-	    hostent = gethostbyaddr ((char *)data,
-				     connectionAddress->length, type);
-	    if (hostent) {
+	    if (!rc) {
 		if (sourceAddress) {
 		    bzero(&hints, sizeof(hints));
 		    hints.ai_flags = AI_CANONNAME;
-		    if (getaddrinfo(hostent->h_name, NULL, &hints, &ai) == 0) {
-			hostname = ai->ai_canonname;
+		    if (getaddrinfo(hostname, NULL, &hints, &ai) == 0) {
 			for (nai = ai->ai_next; nai!=NULL; nai=nai->ai_next) {
 			    if ((ai->ai_protocol == nai->ai_protocol) &&
-				(ai->ai_addrlen == nai->ai_addrlen) &&
-			        (memcmp(ai->ai_addr,nai->ai_addr,
-					ai->ai_addrlen) != 0) ) {
+			        (ai->ai_addrlen == nai->ai_addrlen) &&
+			        (memcmp(ai->ai_addr, nai->ai_addr,
+			                ai->ai_addrlen) != 0) ) {
 				multiHomed = 1;
 			    }
 			}
 		    }
-		} else {
-		    hostname = hostent->h_name;
 		}
+	    } else {
+		hostname[0] = '\0';
 	    }
 
 	    localhost = localHostname ();
@@ -566,7 +562,7 @@ NetworkAddressToName(
 	    /*
 	     * protect against bogus host names
 	     */
-	    if (hostname && hostname[0] && (hostname[0] != '.')
+	    if (hostname[0] && (hostname[0] != '.')
 			&& !multiHomed)
 	    {
 		if (!strcmp (localhost, hostname))
@@ -615,17 +611,7 @@ NetworkAddressToName(
 			freeaddrinfo(ai);
 		    return NULL;
 		}
-		if (multiHomed) {
-		    if (connectionType == FamilyInternet) {
-			data = (CARD8 *)
-			  &((struct sockaddr_in *)originalAddress)->
-			  sin_addr;
-		    } else {
-			data = (CARD8 *)
-			  &((struct sockaddr_in6 *)originalAddress)->sin6_addr;
-		    }
-		}
-		if (inet_ntop(type, data, name, INET6_ADDRSTRLEN) == NULL) {
+		if (getnameinfo(originalAddress, addrlen, name, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST) != 0) {
 		    free(name);
 		    if (ai)
 			freeaddrinfo(ai);
@@ -1200,6 +1186,7 @@ manage (
 	    name = NetworkAddressToName (pdpy->connectionType,
 					 &pdpy->connectionAddress,
 					 from,
+					 fromlen,
 					 pdpy->displayNumber);
 	    Debug ("Computed display name: %s for: %s\n",
 		   name, (char *)pdpy->connectionAddress.data);
-- 
1.7.0



More information about the xorg-devel mailing list