--- iputils-s20070202/ping.c.idn 2007-08-06 14:45:36.000000000 +0200 +++ iputils-s20070202/ping.c 2007-08-06 14:45:36.000000000 +0200 @@ -58,6 +58,12 @@ * This program has to run SUID to ROOT to access the ICMP socket. */ +#define LIBIDN +#ifdef LIBIDN +#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 LIBIDN + 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 LIBIDN + 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 LIBIDN + 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/Makefile.idn 2007-08-06 14:45:36.000000000 +0200 +++ iputils-s20070202/Makefile 2007-08-06 14:45:36.000000000 +0200 @@ -27,8 +27,13 @@ tftpd: tftpd.o tftpsubs.o + ping: ping.o ping_common.o + $(CC) $(CFLAGS) ping.o ping_common.o -lidn -o ping + ping6: ping6.o ping_common.o + $(CC) $(CFLAGS) ping6.o ping_common.o -o ping6 + ping.o ping6.o ping_common.o: ping_common.h tftpd.o tftpsubs.o: tftp.h --- iputils-s20070202/ping6.c.idn 2007-08-06 14:45:36.000000000 +0200 +++ iputils-s20070202/ping6.c 2007-08-06 14:45:36.000000000 +0200 @@ -66,6 +66,12 @@ * More statistics could always be gathered. * This program has to run SUID to ROOT to access the ICMP socket. */ +#define IDN +#ifdef IDN +#define _GNU_SOURCE +#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.idn 2007-08-06 14:45:36.000000000 +0200 +++ iputils-s20070202/ping_common.c 2007-08-06 14:47:41.000000000 +0200 @@ -1,3 +1,8 @@ +#define LIBIDN +#ifdef LIBIDN +#include +#endif + #include "ping_common.h" #include #include @@ -97,6 +102,9 @@ void common_options(int ch) { +#ifdef LIBIDN + setlocale(LC_ALL, "C"); +#endif switch(ch) { case 'a': options |= F_AUDIBLE; @@ -222,6 +230,9 @@ default: abort(); } +#ifdef LIBIDN + setlocale(LC_ALL, ""); +#endif }