Blob Blame History Raw
From 18272a1f3cf8c3fe287c1bf8a007d0ef4de4cf2f Mon Sep 17 00:00:00 2001
Message-Id: <18272a1f3cf8c3fe287c1bf8a007d0ef4de4cf2f.1467043686.git.marcelo.leitner@gmail.com>
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Date: Thu, 23 Jun 2016 18:27:26 -0300
Subject: [PATCH] sctp_status: fix hostname resolution

getaddrinfo already returns the IP address in binary format for the
given hostname/IP address, so there is no need to use inet_pton()
afterwards.

Such usage, actually, was causing localhost6 to be evaluated as ::.

Also, fix a leak on getaddrinfo results.

Signed-off-by: Marcelo R. Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
---
 src/apps/sctp_status.c | 38 +++++++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 15 deletions(-)

diff --git a/src/apps/sctp_status.c b/src/apps/sctp_status.c
index 5bb48efc18074cb706112b10aa0d4a098954c3cd..46e9ca2af08ade626517a2d52bf0289d6be362e6 100644
--- a/src/apps/sctp_status.c
+++ b/src/apps/sctp_status.c
@@ -280,11 +280,12 @@ int main(int argc, char *argv[]) {
 			case AF_INET:
 				t_addr = (struct sockaddr_in *)&s_rem;
 
-				t_addr->sin_family = AF_INET;
+				memcpy(t_addr, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr->sin_family = res->ai_family;
 				t_addr->sin_port = htons(remote_port);
-				inet_pton(AF_INET, remote_host, &t_addr->sin_addr);
 
-				r_len = sizeof (struct sockaddr_in);
+				r_len = res->ai_addrlen;
 #ifdef __FreeBSD__
 				t_addr->sin_len = r_len;
 #endif
@@ -292,13 +293,14 @@ int main(int argc, char *argv[]) {
 			case AF_INET6:
 				t_addr6 = (struct sockaddr_in6 *)&s_rem;
 
+				memcpy(t_addr6, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr6->sin6_family = res->ai_family;
+				t_addr6->sin6_port = htons(remote_port);
 				if (interface)
 					t_addr6->sin6_scope_id = if_nametoindex(interface);
-				t_addr6->sin6_family = AF_INET6;
-				t_addr6->sin6_port = htons(remote_port);
-				inet_pton(AF_INET6, remote_host, &t_addr6->sin6_addr);
 
-				r_len = sizeof (struct sockaddr_in6);
+				r_len = res->ai_addrlen;
 
 #ifdef __FreeBSD__
 				t_addr6->sin6_len = r_len;
@@ -311,6 +313,8 @@ int main(int argc, char *argv[]) {
 
 		DEBUG_PRINT(DEBUG_MAX, "remote:addr=%s, port=%s, family=%d\n",
 			    host_s, serv_s, res->ai_family);
+
+		freeaddrinfo(res);
         }
 
 	if (local_host != NULL) {
@@ -342,11 +346,13 @@ int main(int argc, char *argv[]) {
 		switch (res->ai_family) {
 			case AF_INET:
 				t_addr = (struct sockaddr_in *)&s_loc;
-				t_addr->sin_family = AF_INET;
+
+				memcpy(t_addr, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr->sin_family = res->ai_family;
 				t_addr->sin_port = htons(local_port);
-				inet_pton(AF_INET, local_host, &t_addr->sin_addr);
 
-				l_len = sizeof (struct sockaddr_in);
+				l_len = res->ai_addrlen;
 #ifdef __FreeBSD__
 				t_addr->sin_len = l_len;
 #endif
@@ -354,14 +360,14 @@ int main(int argc, char *argv[]) {
 			case AF_INET6:
 				t_addr6 = (struct sockaddr_in6 *)&s_loc;
 
+				memcpy(t_addr6, res->ai_addr,
+				       res->ai_addrlen);
+				t_addr6->sin6_family = res->ai_family;
+				t_addr6->sin6_port = htons(local_port);
 				if (interface)
 					t_addr6->sin6_scope_id = if_nametoindex(interface);
-				t_addr6->sin6_family = AF_INET6;
-				t_addr6->sin6_port = htons(local_port);
 
-				inet_pton(AF_INET6, local_host, &t_addr6->sin6_addr);
-
-				l_len = sizeof (struct sockaddr_in6);
+				l_len = res->ai_addrlen;
 
 #ifdef __FreeBSD__
 				t_addr6->sin6_len = l_len;
@@ -377,6 +383,8 @@ int main(int argc, char *argv[]) {
 
 		DEBUG_PRINT(DEBUG_MAX, "local:addr=%s, port=%s, family=%d\n",
 			    host_s, serv_s, res->ai_family);
+
+		freeaddrinfo(res);
         }
 
 	/* Let the testing begin. */
-- 
2.5.5