[tac_plus] [PATCH] fix ipv6 addresses logging

Luca Boccassi lboccass at Brocade.com
Mon Dec 29 16:49:45 UTC 2014


Hi,

This small patch fixes printing IPv6 addresses in the log. Hope it can
be useful. Please let me know in case the preferred format for patches
is different.

Kind regards,
Luca Boccassi
Brocade Communications Systems


---
 tac_plus.c |   54
++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 46 insertions(+), 8 deletions(-)

--- a/tac_plus.c
+++ b/tac_plus.c
@@ -262,6 +262,28 @@ open_logfile(void)
 }
 
 /*
+ * Checks if the sockaddr_storage is IPv4 mapped in IPv6 sockaddr, and
if so
+ * converts it back in place to IPv4 sockaddr_in. This is done to avoid
+ * printing an IPv4 address in the unfriendly format ::ffff:192.168.0.1
+ */
+static void
+sockaddr_v6_mapped_convert_to_v4 (struct sockaddr_storage *name,
+       socklen_t *name_len) {
+    struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)name;
+
+    if (IN6_IS_ADDR_V4MAPPED(&from6->sin6_addr)) {
+       struct sockaddr_in addr4;
+       memset(&addr4, 0, sizeof(addr4));
+       addr4.sin_family = AF_INET;
+       addr4.sin_port = from6->sin6_port;
+       memcpy(&addr4.sin_addr.s_addr, from6->sin6_addr.s6_addr + 12,
+           sizeof(addr4.sin_addr.s_addr));
+       memcpy(name, &addr4, sizeof(addr4));
+       *name_len = sizeof(addr4);
+    }
+}
+
+/*
  * We will eventually be called from inetd or via the rc scripts
directly
  * Parse arguments and act appropiately.
  */
@@ -374,9 +396,9 @@ main(int argc, char **argv)
 
     if (!standalone) {
        /* running under inetd */
-       char host[NI_MAXHOST];
+       char host[NI_MAXHOST], host_ip[INET6_ADDRSTRLEN];
        int on;
-       struct sockaddr_in name;
+       struct sockaddr_storage name;
        socklen_t name_len;
 
        name_len = sizeof(name);
@@ -402,8 +424,16 @@ main(int argc, char **argv)
 
            if (session.peerip)
                free(session.peerip);
-           session.peerip = tac_strdup((char
*)inet_ntop(name.sin_family,
-                                       &name.sin_addr, host,
name_len));
+
+           if (name.ss_family == AF_INET6)
+               sockaddr_v6_mapped_convert_to_v4(&name, &name_len);
+           if (getnameinfo((struct sockaddr *)&name, name_len, host_ip,
+                           INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST))
{
+               strncpy(host_ip, "unknown", INET6_ADDRSTRLEN - 1);
+               host_ip[INET6_ADDRSTRLEN - 1] = '\0';
+           }
+           session.peerip = tac_strdup(host_ip);
+
            if (debug & DEBUG_AUTHEN_FLAG)
                report(LOG_INFO, "session.peerip is %s",
session.peerip);
        }
@@ -585,8 +615,8 @@ main(int argc, char **argv)
 #else
        int pid;
 #endif
-       char host[NI_MAXHOST];
-       struct sockaddr_in from;
+       char host[NI_MAXHOST], host_ip[INET6_ADDRSTRLEN];
+       struct sockaddr_storage from;
        socklen_t from_len;
        int newsockfd, status;
        int flags;
@@ -637,8 +667,16 @@ main(int argc, char **argv)
 
        if (session.peerip)
            free(session.peerip);
-       session.peerip = tac_strdup((char *)inet_ntop(from.sin_family,
-                                   &from.sin_addr, host, from_len));
+
+       if (from.ss_family == AF_INET6)
+           sockaddr_v6_mapped_convert_to_v4(&from, &from_len);
+       if (getnameinfo((struct sockaddr *)&from, from_len, host_ip,
+                       INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST)) {
+           strncpy(host_ip, "unknown", INET6_ADDRSTRLEN - 1);
+           host_ip[INET6_ADDRSTRLEN - 1] = '\0';
+       }
+       session.peerip = tac_strdup(host_ip);
+
        if (debug & DEBUG_PACKET_FLAG)
            report(LOG_DEBUG, "session request from %s sock=%d",
                   session.peer, newsockfd);



More information about the tac_plus mailing list