--- iputils-s20101006/ping.c 2012-06-25 09:43:53.247390215 +0200 +++ iputils-s20101006-patch/ping.c 2012-06-25 09:46:01.333436372 +0200 @@ -1243,12 +1243,17 @@ pr_addr(__u32 addr) addr_cache = addr; tmp_addr.s_addr = addr; - if ((options & F_NUMERIC) || + in_pr_addr = !setjmp(pr_addr_jmp); + + if (exiting || (options & F_NUMERIC) || !(hp = gethostbyaddr((char *)&addr, 4, AF_INET))) sprintf(buf, "%s", inet_ntoa(tmp_addr)); else snprintf(buf, sizeof(buf), "%s (%s)", hp->h_name, inet_ntoa(tmp_addr)); + + in_pr_addr = 0; + return(buf); } --- iputils-s20101006/ping6.c 2012-06-25 09:43:53.233390208 +0200 +++ iputils-s20101006-patch/ping6.c 2012-06-25 09:46:52.437450591 +0200 @@ -1565,9 +1565,13 @@ char * pr_addr(struct in6_addr *addr) return hp ? hp->h_name : pr_addr_n(addr); memcpy(&addr_cache, addr, sizeof(addr_cache)); - if (!(options&F_NUMERIC)) + in_pr_addr = !setjmp(pr_addr_jmp); + + if (!(exiting || options&F_NUMERIC)) hp = gethostbyaddr((__u8*)addr, sizeof(struct in6_addr), AF_INET6); + in_pr_addr = 0; + return hp ? hp->h_name : pr_addr_n(addr); } --- iputils-s20101006/ping_common.h 2012-06-25 09:43:53.249390215 +0200 +++ iputils-s20101006-patch/ping_common.h 2012-06-25 09:47:24.002458261 +0200 @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef HAVE_CAPABILITIES #include @@ -219,3 +220,6 @@ extern int gather_statistics(__u8 *ptr, int csfailed, struct timeval *tv, char *from, void (*pr_reply)(__u8 *ptr, int cc)); extern void print_timestamp(void); + +extern int in_pr_addr; +extern jmp_buf pr_addr_jmp; --- iputils-s20101006/ping_common.c 2012-06-25 09:43:53.252390217 +0200 +++ iputils-s20101006-patch/ping_common.c 2012-06-25 09:49:04.972477402 +0200 @@ -32,6 +32,8 @@ struct timeval start_time, cur_time; volatile int exiting; volatile int status_snapshot; int confirm = 0; +int in_pr_addr = 0; /* pr_addr() is executing */ +jmp_buf pr_addr_jmp; /* Stupid workarounds for bugs/missing functionality in older linuces. * confirm_flag fixes refusing service of kernels without MSG_CONFIRM. @@ -252,6 +254,8 @@ void common_options(int ch) static void sigexit(int signo) { exiting = 1; + if (in_pr_addr) + longjmp(pr_addr_jmp, 0); } static void sigstatus(int signo)