sniped from Fedora and made to not suck http://bugs.gentoo.org/218638 --- iputils-s20070202/Makefile +++ iputils-s20070202/Makefile @@ -22,6 +22,11 @@ all: $(TARGETS) +ifeq ($(IDN),yes) +CPPFLAGS += -DIDN +ping: LDLIBS += -lidn +ping6: LDLIBS += -lidn +endif tftpd: tftpd.o tftpsubs.o ping: ping.o ping_common.o --- iputils-s20070202/ping.c +++ iputils-s20070202/ping.c @@ -58,6 +58,11 @@ * This program has to run SUID to ROOT to access the ICMP socket. */ +#ifdef IDN +#include +#include +#endif + #include "ping_common.h" #include @@ -122,6 +128,12 @@ char *target, hnamebuf[MAXHOSTNAMELEN]; char rspace[3 + 4 * NROUTES + 1]; /* record route space */ +#ifdef IDN + char *idn; + int rc = 0; + setlocale(LC_ALL, ""); +#endif + icmp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); socket_errno = errno; @@ -242,13 +254,35 @@ if (argc == 1) options |= F_NUMERIC; } else { +#ifdef IDN + rc = idna_to_ascii_lz (target, &idn, 0); + if (rc == IDNA_SUCCESS) + hp = gethostbyname (idn); + else { + fprintf(stderr, "ping: IDN encoding of '%s' failed with error code %d\n", target, rc); + exit(2); + } + free(idn); +#else hp = gethostbyname(target); +#endif if (!hp) { fprintf(stderr, "ping: unknown host %s\n", target); exit(2); } memcpy(&whereto.sin_addr, hp->h_addr, 4); +#ifdef IDN + rc = idna_to_unicode_lzlz (hp->h_name, &idn, 0); + if (rc == IDNA_SUCCESS) + strncpy(hnamebuf, idn, sizeof(hnamebuf) - 1); + else { + fprintf(stderr, "ping: IDN encoding of '%s' failed with error code %d\n", hp->h_name, rc); + exit(2); + } + free(idn); +#else strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1); +#endif hnamebuf[sizeof(hnamebuf) - 1] = 0; hostname = hnamebuf; } --- iputils-s20070202/ping6.c +++ iputils-s20070202/ping6.c @@ -66,6 +66,13 @@ * More statistics could always be gathered. * This program has to run SUID to ROOT to access the ICMP socket. */ +#ifdef IDN +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include +#endif + #include "ping_common.h" #include @@ -210,6 +216,10 @@ int err, csum_offset, sz_opt; static uint32_t scope_id = 0; +#ifdef IDN + setlocale(LC_ALL, ""); +#endif + icmp_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); socket_errno = errno; @@ -296,6 +306,9 @@ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; +#ifdef IDN + hints.ai_flags = AI_IDN; +#endif gai = getaddrinfo(target, NULL, &hints, &ai); if (gai) { fprintf(stderr, "unknown host\n"); @@ -328,6 +341,9 @@ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET6; +#ifdef IDN + hints.ai_flags = AI_IDN; +#endif gai = getaddrinfo(target, NULL, &hints, &ai); if (gai) { fprintf(stderr, "unknown host\n"); --- iputils-s20070202/ping_common.c +++ iputils-s20070202/ping_common.c @@ -1,3 +1,7 @@ +#ifdef IDN +#include +#endif + #include "ping_common.h" #include #include @@ -97,6 +102,9 @@ void common_options(int ch) { +#ifdef IDN + setlocale(LC_ALL, "C"); +#endif switch(ch) { case 'a': options |= F_AUDIBLE; @@ -222,6 +230,9 @@ default: abort(); } +#ifdef IDN + setlocale(LC_ALL, ""); +#endif }