From 1003145f9370553f2a7c061a9b001e9f6231687f Mon Sep 17 00:00:00 2001
From: Mats Erik Andersson <gnu@gisladisker.se>
Date: Sat, 25 Jul 2015 23:39:26 +0200
Subject: [PATCH 06/60] ifconfig: Symbolic name as peer address.

---
 ChangeLog           |  9 +++++++
 ifconfig/changeif.c | 58 ++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c194a545..72806b79 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2015-07-25  Mats Erik Andersson  <gnu@gisladisker.se>
+
+	ifconfig: Symbolic name as peer address.
+
+	* ifconfig/changeif.c (set_dstaddr): Adapt code block used
+	by set_address(), thereby first using either getaddrinfo()
+	or gethostbyname() to resolve a possibly symbolic peer
+	destination, then setting the established address.
+
 2015-07-25  Mats Erik Andersson  <gnu@gisladisker.se>
 
 	ifconfig: Support changing of hardware address.
diff --git a/ifconfig/changeif.c b/ifconfig/changeif.c
index dfcae9ff..a040587b 100644
--- a/ifconfig/changeif.c
+++ b/ifconfig/changeif.c
@@ -163,13 +163,65 @@ set_dstaddr (int sfd, struct ifreq *ifr, char *dstaddr)
   error (0, 0,
          "don't know how to set an interface peer address on this system");
   return -1;
-#else
-  SIOCSIF (DSTADDR, dstaddr)
+#else /* !SIOCSIFDSTADDR */
+# if HAVE_DECL_GETADDRINFO
+  int rc;
+  char addr[INET_ADDRSTRLEN];
+  struct addrinfo hints, *ai, *res;
+
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_family = AF_INET;
+
+  rc = getaddrinfo (dstaddr, NULL, &hints, &res);
+  if (rc)
+    {
+      error (0, 0, "cannot resolve `%s': %s", dstaddr, gai_strerror (rc));
+      return -1;
+    }
+  for (ai = res; ai; ai = ai->ai_next)
+    if (ai->ai_family == AF_INET)
+      break;
+
+  if (ai == NULL)
+    {
+      error (0, 0, "`%s' refers to an unknown address type", dstaddr);
+      freeaddrinfo (res);
+      return -1;
+    }
+
+  rc = getnameinfo (ai->ai_addr, ai->ai_addrlen,
+		    addr, sizeof (addr), NULL, 0,
+		    NI_NUMERICHOST);
+  freeaddrinfo (res);
+  if (rc)
+    {
+      error (0, 0, "cannot resolve `%s': %s", dstaddr, gai_strerror (rc));
+      return -1;
+    }
+# else /* !HAVE_DECL_GETADDRINFO */
+  char *addr;
+  struct hostent *host = gethostbyname (dstaddr);
+
+  if (!host)
+    {
+      error (0, 0, "cannot resolve `%s': %s", dstaddr, hstrerror (h_errno));
+      return -1;
+    }
+  if (host->h_addrtype != AF_INET)
+    {
+      error (0, 0, "`%s' refers to an unknown address type", dstaddr);
+      return -1;
+    }
+
+  addr = inet_ntoa (*((struct in_addr *) host->h_addr));
+# endif /* !HAVE_DECL_GETADDRINFO */
+
+  SIOCSIF (DSTADDR, addr)
   if (verbose)
     printf ("Set interface peer address of `%s' to %s.\n",
 	    ifr->ifr_name, inet_ntoa (sin->sin_addr));
   return 0;
-#endif
+#endif /* SIOCSIFDSTADDR */
 }
 
 int
-- 
2.26.0.292.g33ef6b2f38

