From 78fcde1eafe9484a866b7484537f82363fc12b78 Mon Sep 17 00:00:00 2001 From: Mats Erik Andersson Date: Mon, 8 Nov 2010 17:29:36 +0100 Subject: [PATCH] inetd: Environment variables also for IPv6. --- ChangeLog | 14 +++++++++++ src/inetd.c | 76 ++++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/ChangeLog b/ChangeLog index f757a82..fadabfc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2010-11-08 Mats Erik Andersson + + * src/inetd.c (prepenv): New prototype: + `prepenv(int, struct sockaddr *, socklen_t)'. + (prepenv): Change type of IP to `char []' of fixed length. + New integer variable RET. Make type of SA_SERVER depend on + macro IPV6: `struct sockaddr_storage' or `struct sockaddr_in'. + (prepenv): Eliminate uses of `inet_ntoa', `gethostbyaddr' by + new calls to `getnameinfo', with and without demand on numeric + results. Debugging output on three select environment variables. + (main): Make type of SA_CLIENT depend on macro IPV6: + `struct sockaddr_storage' or `struct sockaddr_in'. + Adaption to new prototype for `prepenv'. + 2010-10-31 Mats Erik Andersson * ifconfig/if_index.c (if_nametoindex, if_freenameindex) diff --git a/src/inetd.c b/src/inetd.c index f5f7d32..e711095 100644 --- a/src/inetd.c +++ b/src/inetd.c @@ -1690,15 +1690,18 @@ tcpmux (int s, struct servtab *sep) /* Set TCP environment variables, modelled after djb's ucspi-tcp tools: http://cr.yp.to/ucspi-tcp/environment.html - FIXME: This needs support for IPv6. */ void -prepenv (int ctrl, struct sockaddr_in sa_client) +prepenv (int ctrl, struct sockaddr *sa_client, socklen_t sa_len) { char str[16]; - char *ip; - struct hostent *host; + char ip[4 * INET6_ADDRSTRLEN]; + int ret; +#ifdef IPV6 + struct sockaddr_storage sa_server; +#else struct sockaddr_in sa_server; +#endif socklen_t len = sizeof (sa_server); setenv ("PROTO", "TCP", 1); @@ -1713,47 +1716,58 @@ prepenv (int ctrl, struct sockaddr_in sa_client) syslog (LOG_WARNING, "getsockname(): %m"); else { - ip = inet_ntoa (sa_server.sin_addr); - if (ip) + ret = getnameinfo ((struct sockaddr *) &sa_server, len, + ip, sizeof (ip), str, sizeof (str), + NI_NUMERICHOST | NI_NUMERICSERV); + if (ret == 0) { if (setenv ("TCPLOCALIP", ip, 1) < 0) syslog (LOG_WARNING, "setenv (TCPLOCALIP): %m"); - } + else if (debug) + fprintf (stderr, "Assigned TCPLOCALIP = %s\n", ip); - snprintf (str, sizeof (str), "%d", ntohs (sa_server.sin_port)); - setenv ("TCPLOCALPORT", str, 1); + if (setenv ("TCPLOCALPORT", str, 1) < 0) + syslog (LOG_WARNING, "setenv (TCPLOCALPORT): %m"); + } + else + syslog (LOG_WARNING, "getnameinfo: %s", gai_strerror (ret)); if (resolve_option) { - if ((host = gethostbyaddr ((char *) &sa_server.sin_addr, - sizeof (sa_server.sin_addr), - AF_INET)) == NULL) - syslog (LOG_WARNING, "gethostbyaddr: %m"); - else if (setenv ("TCPLOCALHOST", host->h_name, 1) < 0) + ret = getnameinfo ((struct sockaddr *) &sa_server, len, + ip, sizeof (ip), NULL, 0, 0); + if (ret != 0) + syslog (LOG_WARNING, "getnameinfo: %s", gai_strerror (ret)); + else if (setenv ("TCPLOCALHOST", ip, 1) < 0) syslog (LOG_WARNING, "setenv(TCPLOCALHOST): %m"); } } - ip = inet_ntoa (sa_client.sin_addr); - if (ip) + ret = getnameinfo (sa_client, sa_len, ip, sizeof (ip), str, sizeof (str), + NI_NUMERICHOST | NI_NUMERICSERV); + if (ret == 0) { if (setenv ("TCPREMOTEIP", ip, 1) < 0) syslog (LOG_WARNING, "setenv(TCPREMOTEIP): %m"); - } + else if (debug) + fprintf (stderr, "Assigned TCPREMOTEIP = %s\n", ip); - snprintf (str, sizeof (str), "%d", ntohs (sa_client.sin_port)); - if (setenv ("TCPREMOTEPORT", str, 1) < 0) - syslog (LOG_WARNING, "setenv(TCPREMOTEPORT): %m"); + if (setenv ("TCPREMOTEPORT", str, 1) < 0) + syslog (LOG_WARNING, "setenv(TCPREMOTEPORT): %m"); - if (resolve_option) - { - if ((host = gethostbyaddr ((char *) &sa_client.sin_addr, - sizeof (sa_client.sin_addr), - AF_INET)) == NULL) - syslog (LOG_WARNING, "gethostbyaddr: %m"); - else if (setenv ("TCPREMOTEHOST", host->h_name, 1) < 0) - syslog (LOG_WARNING, "setenv(TCPREMOTEHOST): %m"); + if (resolve_option) + { + ret = getnameinfo (sa_client, sa_len, ip, sizeof (ip), NULL, 0, 0); + if (ret != 0) + syslog (LOG_WARNING, "getnameinfo: %s", gai_strerror (ret)); + else if (setenv ("TCPREMOTEHOST", ip, 1) < 0) + syslog (LOG_WARNING, "setenv(TCPREMOTEHOST): %m"); + else if (debug) + fprintf (stderr, "Assigned TCPREMOTEHOST = %s\n", ip); + } } + else + syslog (LOG_WARNING, "getnameinfo: %s", gai_strerror (ret)); } @@ -1864,7 +1878,11 @@ main (int argc, char *argv[], char *envp[]) fprintf (stderr, "someone wants %s\n", sep->se_service); if (!sep->se_wait && sep->se_socktype == SOCK_STREAM) { +#ifdef IPV6 + struct sockaddr_storage sa_client; +#else struct sockaddr_in sa_client; +#endif socklen_t len = sizeof (sa_client); ctrl = accept (sep->se_fd, (struct sockaddr *) &sa_client, @@ -1879,7 +1897,7 @@ main (int argc, char *argv[], char *envp[]) continue; } if (env_option) - prepenv (ctrl, sa_client); + prepenv (ctrl, (struct sockaddr *) &sa_client, len); } else ctrl = sep->se_fd; -- 1.7.1