Skip to content

Commit 37953bf

Browse files
Pavel Šimerdaokias
Pavel Šimerda
authored andcommitted
make getaddrinfo() and getnameinfo() usage consistent
Use modern name resolution functions and use them in a consistent manner. * Avoid obsolete `gethostbyname()`, `gethostbyname2()` and `gethostbyaddr()` * Maintain consistency in variable names and error messages * Leave IDN handling up to name resolution functions Note: This patch provides a primitive translation of calls to obsolete functions to calls to modern functions but more changes are needed to process the whole result lists instead of using just the first result. Note: This patch skips functions that use jumps to avoid making more damage than benefits.
1 parent 8d6b07f commit 37953bf

11 files changed

+142
-204
lines changed

Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ LIB_clockdiff = $(LIB_CAP)
148148

149149
# ping / ping6
150150
DEF_ping_common = $(DEF_CAP) $(DEF_IDN)
151+
DEF_ping6_common = $(DEF_CAP) $(DEF_IDN)
151152
DEF_ping = $(DEF_CAP) $(DEF_IDN) $(DEF_WITHOUT_IFADDRS)
152-
LIB_ping = $(LIB_CAP) $(LIB_IDN)
153+
LIB_ping = $(LIB_CAP) $(LIB_IDN) $(LIB_RESOLV)
153154
DEF_ping6 = $(DEF_CAP) $(DEF_IDN) $(DEF_WITHOUT_IFADDRS) $(DEF_ENABLE_PING6_RTHDR) $(DEF_CRYPTO)
154155
LIB_ping6 = $(LIB_CAP) $(LIB_IDN) $(LIB_RESOLV) $(LIB_CRYPTO)
155156

arping.c

+12-18
Original file line numberDiff line numberDiff line change
@@ -1091,30 +1091,24 @@ main(int argc, char **argv)
10911091
}
10921092

10931093
if (inet_aton(target, &dst) != 1) {
1094-
struct hostent *hp;
1095-
char *idn = target;
1094+
struct addrinfo hints = {
1095+
.ai_family = AF_INET,
1096+
.ai_socktype = SOCK_RAW,
10961097
#ifdef USE_IDN
1097-
int rc;
1098-
1099-
rc = idna_to_ascii_lz(target, &idn, 0);
1100-
1101-
if (rc != IDNA_SUCCESS) {
1102-
fprintf(stderr, "arping: IDN encoding failed: %s\n", idna_strerror(rc));
1103-
exit(2);
1104-
}
1098+
.ai_flags = AI_IDN | AI_CANONIDN
11051099
#endif
1100+
};
1101+
struct addrinfo *result;
1102+
int status;
11061103

1107-
hp = gethostbyname2(idn, AF_INET);
1108-
if (!hp) {
1109-
fprintf(stderr, "arping: unknown host %s\n", target);
1104+
status = getaddrinfo(target, NULL, &hints, &result);
1105+
if (status) {
1106+
fprintf(stderr, "arping: %s: %s\n", target, gai_strerror(status));
11101107
exit(2);
11111108
}
11121109

1113-
#ifdef USE_IDN
1114-
free(idn);
1115-
#endif
1116-
1117-
memcpy(&dst, hp->h_addr, 4);
1110+
memcpy(&dst, &((struct sockaddr_in *) result->ai_addr)->sin_addr, sizeof dst);
1111+
freeaddrinfo(result);
11181112
}
11191113

11201114
if (source && inet_aton(source, &src) != 1) {

clockdiff.c

+15-13
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,9 @@ int
550550
main(int argc, char *argv[])
551551
{
552552
int measure_status;
553-
struct hostent * hp;
553+
struct addrinfo hints = { .ai_family = AF_INET, .ai_socktype = SOCK_RAW, .ai_flags = AI_CANONNAME };
554+
struct addrinfo *result;
555+
int status;
554556
char hostname[MAX_HOSTNAMELEN];
555557
int s_errno = 0;
556558
int n_errno = 0;
@@ -598,23 +600,23 @@ main(int argc, char *argv[])
598600
id = getpid();
599601

600602
(void)gethostname(hostname,sizeof(hostname));
601-
hp = gethostbyname(hostname);
602-
if (hp == NULL) {
603-
fprintf(stderr, "clockdiff: %s: my host not found\n", hostname);
604-
exit(1);
603+
status = getaddrinfo(hostname, NULL, &hints, &result);
604+
if (status) {
605+
fprintf(stderr, "clockdiff: %s: %s\n", hostname, gai_strerror(status));
606+
exit(2);
605607
}
606-
myname = strdup(hp->h_name);
608+
myname = strdup(result->ai_canonname);
609+
freeaddrinfo(result);
607610

608-
hp = gethostbyname(argv[1]);
609-
if (hp == NULL) {
610-
fprintf(stderr, "clockdiff: %s: host not found\n", argv[1]);
611+
status = getaddrinfo(argv[1], NULL, &hints, &result);
612+
if (status) {
613+
fprintf(stderr, "clockdiff: %s: %s\n", argv[1], gai_strerror(status));
611614
exit(1);
612615
}
613-
hisname = strdup(hp->h_name);
616+
hisname = strdup(result->ai_canonname);
614617

615-
memset(&server, 0, sizeof(server));
616-
server.sin_family = hp->h_addrtype;
617-
memcpy(&(server.sin_addr.s_addr), hp->h_addr, 4);
618+
memcpy(&server, result->ai_addr, sizeof server);
619+
freeaddrinfo(result);
618620

619621
if (connect(sock_raw, (struct sockaddr*)&server, sizeof(server)) == -1) {
620622
perror("connect");

ninfod/ninfod.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,7 @@ int main (int argc, char **argv)
705705
struct icmp6_hdr *icmph;
706706
#if ENABLE_DEBUG
707707
char saddrbuf[NI_MAXHOST];
708-
int gni;
708+
int status;
709709
#endif
710710

711711
init_core(0);
@@ -734,12 +734,12 @@ int main (int argc, char **argv)
734734
}
735735

736736
#if ENABLE_DEBUG
737-
gni = getnameinfo((struct sockaddr *)&p->addr,
737+
status = getnameinfo((struct sockaddr *)&p->addr,
738738
p->addrlen,
739739
saddrbuf, sizeof(saddrbuf),
740740
NULL, 0,
741741
NI_NUMERICHOST);
742-
if (gni)
742+
if (status)
743743
sprintf(saddrbuf, "???");
744744
#endif
745745
init_core(0);

ping.c

+18-49
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ ping_func_set_st ping4_func_set = {
8181
#define MAXICMPLEN 76
8282
#define NROUTES 9 /* number of record route slots */
8383
#define TOS_MAX 255 /* 8-bit TOS field */
84-
#define MAX_HOSTNAMELEN NI_MAXHOST
8584

8685
static const int max_ping4_packet = 0x10000;
8786

@@ -125,7 +124,9 @@ static void set_socket(socket_st *sock, int fd, int e)
125124
int
126125
main(int argc, char **argv)
127126
{
128-
struct hostent *hp;
127+
struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_protocol = IPPROTO_UDP, .ai_flags = getaddrinfo_flags };
128+
struct addrinfo *result;
129+
int status;
129130
int ch, hold, packlen;
130131
unsigned char *packet;
131132
char *target;
@@ -136,11 +137,7 @@ main(int argc, char **argv)
136137
char ipbuf[64];
137138
int orig_argc = argc;
138139
char **orig_argv = argv;
139-
#ifdef USE_IDN
140-
char *hnamebuf = NULL;
141-
#else
142-
char hnamebuf[MAX_HOSTNAMELEN];
143-
#endif
140+
char hnamebuf[NI_MAXHOST];
144141
char rspace[3 + 4 * NROUTES + 1]; /* record route space */
145142

146143
memset(&sock, 0, sizeof(sock));
@@ -289,53 +286,25 @@ main(int argc, char **argv)
289286
if (argc == 1)
290287
options |= F_NUMERIC;
291288
} else {
292-
char *idn;
293-
#ifdef USE_IDN
294-
int rc;
295-
296-
if (hnamebuf) {
297-
free(hnamebuf);
298-
hnamebuf = NULL;
299-
}
300-
301-
rc = idna_to_ascii_lz(target, &idn, 0);
302-
if (rc != IDNA_SUCCESS) {
303-
fprintf(stderr, "ping: IDN encoding failed: %s\n", idna_strerror(rc));
304-
exit(2);
305-
}
306-
#else
307-
idn = target;
308-
#endif
309-
hp = gethostbyname2(idn, AF_INET);
310-
if (!hp) {
311-
if (force_ipv4 == 0) {
312-
hp = gethostbyname2(idn, AF_INET6);
313-
}
314-
315-
if (hp) {
289+
hints.ai_family = AF_INET;
290+
status = getaddrinfo(target, NULL, &hints, &result);
291+
if (status && !force_ipv4) {
292+
hints.ai_family = AF_INET6;
293+
status = getaddrinfo(target, NULL, &hints, &result);
294+
if (!status) {
316295
set_socket(&sock, sock6, sock6_errno);
317296
return ping6_main(orig_argc, orig_argv, &sock);
318-
} else {
319-
fprintf(stderr, "ping: unknown host %s\n", target);
320-
exit(2);
321297
}
322298
}
323-
#ifdef USE_IDN
324-
free(idn);
325-
#endif
326-
memcpy(&whereto.sin_addr, hp->h_addr, 4);
327-
#ifdef USE_IDN
328-
if (idna_to_unicode_lzlz(hp->h_name, &hnamebuf, 0) != IDNA_SUCCESS) {
329-
hnamebuf = strdup(hp->h_name);
330-
if (!hnamebuf) {
331-
perror("ping: strdup");
332-
exit(-1);
333-
}
299+
if (status) {
300+
fprintf(stderr, "ping: %s: %s\n", target, gai_strerror(status));
301+
exit(2);
334302
}
335-
#else
336-
strncpy(hnamebuf, hp->h_name, sizeof(hnamebuf) - 1);
337-
hnamebuf[sizeof(hnamebuf) - 1] = 0;
338-
#endif
303+
memcpy(&whereto, result->ai_addr, sizeof whereto);
304+
memset(hnamebuf, 0, sizeof hnamebuf);
305+
if (result->ai_canonname)
306+
strncpy(hnamebuf, result->ai_canonname, sizeof hnamebuf - 1);
307+
freeaddrinfo(result);
339308
hostname = hnamebuf;
340309
}
341310
if (argc > 1)

ping6_common.c

+23-36
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@
7171
#include <ifaddrs.h>
7272
#endif
7373

74-
#ifdef USE_IDN
75-
#include <stringprep.h>
76-
#endif
77-
7874
#include "ping6_common.h"
7975
#include "ping6_niquery.h"
8076
#include "in6_flowlabel.h"
@@ -449,17 +445,16 @@ static int niquery_set_subject_type(int type)
449445

450446
static int niquery_option_subject_addr_handler(int index, const char *arg)
451447
{
452-
struct addrinfo hints, *ai0, *ai;
448+
struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_DGRAM, .ai_flags = getaddrinfo_flags };
449+
struct addrinfo *result, *ai;
450+
int status;
453451
int offset;
454-
int gai;
455452

456453
if (niquery_set_subject_type(niquery_options[index].data) < 0)
457454
return -1;
458455

459456
ni_subject_type = niquery_options[index].data;
460457

461-
memset(&hints, 0, sizeof(hints));
462-
463458
switch (niquery_options[index].data) {
464459
case NI_SUBJ_IPV6:
465460
ni_subject_len = sizeof(struct in6_addr);
@@ -476,18 +471,13 @@ static int niquery_option_subject_addr_handler(int index, const char *arg)
476471
offset = -1;
477472
}
478473

479-
hints.ai_socktype = SOCK_DGRAM;
480-
#ifdef USE_IDN
481-
hints.ai_flags = AI_IDN;
482-
#endif
483-
484-
gai = getaddrinfo(arg, 0, &hints, &ai0);
485-
if (gai) {
486-
fprintf(stderr, "Unknown host: %s\n", arg);
474+
status = getaddrinfo(arg, 0, &hints, &result);
475+
if (status) {
476+
fprintf(stderr, "ping6: %s: %s\n", arg, gai_strerror(status));
487477
return -1;
488478
}
489479

490-
for (ai = ai0; ai; ai = ai->ai_next) {
480+
for (ai = result; ai; ai = ai->ai_next) {
491481
void *p = malloc(ni_subject_len);
492482
if (!p)
493483
continue;
@@ -496,7 +486,7 @@ static int niquery_option_subject_addr_handler(int index, const char *arg)
496486
ni_subject = p;
497487
break;
498488
}
499-
freeaddrinfo(ai0);
489+
freeaddrinfo(result);
500490

501491
return 0;
502492
}
@@ -703,8 +693,8 @@ int ping6_main(int argc, char *argv[], socket_st *sock)
703693
int ch, hold, packlen;
704694
unsigned char *packet;
705695
char *target;
706-
struct addrinfo hints, *ai;
707-
int gai;
696+
struct addrinfo hints, *result;
697+
int status;
708698
struct sockaddr_in6 firsthop;
709699
struct icmp6_filter filter;
710700
int err;
@@ -850,15 +840,13 @@ int ping6_main(int argc, char *argv[], socket_st *sock)
850840

851841
memset(&hints, 0, sizeof(hints));
852842
hints.ai_family = AF_INET6;
853-
#ifdef USE_IDN
854-
hints.ai_flags = AI_IDN;
855-
#endif
856-
gai = getaddrinfo(target, NULL, &hints, &ai);
857-
if (gai) {
858-
fprintf(stderr, "unknown host\n");
843+
hints.ai_flags = getaddrinfo_flags
844+
status = getaddrinfo(target, NULL, &hints, &result);
845+
if (status) {
846+
fprintf(stderr, "ping6: %s: %s\n", target, gai_strerror(status));
859847
exit(2);
860848
}
861-
addr = &((struct sockaddr_in6 *)(ai->ai_addr))->sin6_addr;
849+
addr = &((struct sockaddr_in6 *)(result->ai_addr))->sin6_addr;
862850
#ifdef ENABLE_PING6_RTHDR_RFC3542
863851
inet6_rth_add(CMSG_DATA(srcrt), addr);
864852
#else
@@ -867,7 +855,7 @@ int ping6_main(int argc, char *argv[], socket_st *sock)
867855
if (IN6_IS_ADDR_UNSPECIFIED(&firsthop.sin6_addr)) {
868856
memcpy(&firsthop.sin6_addr, addr, 16);
869857
#ifdef HAVE_SIN6_SCOPEID
870-
firsthop.sin6_scope_id = ((struct sockaddr_in6 *)(ai->ai_addr))->sin6_scope_id;
858+
firsthop.sin6_scope_id = ((struct sockaddr_in6 *)(result->ai_addr))->sin6_scope_id;
871859
/* Verify scope_id is the same as previous nodes */
872860
if (firsthop.sin6_scope_id && scope_id && firsthop.sin6_scope_id != scope_id) {
873861
fprintf(stderr, "scope discrepancy among the nodes\n");
@@ -877,7 +865,7 @@ int ping6_main(int argc, char *argv[], socket_st *sock)
877865
}
878866
#endif
879867
}
880-
freeaddrinfo(ai);
868+
freeaddrinfo(result);
881869

882870
argv++;
883871
argc--;
@@ -910,22 +898,21 @@ int ping6_main(int argc, char *argv[], socket_st *sock)
910898
memset(&hints, 0, sizeof(hints));
911899
hints.ai_family = AF_INET6;
912900
#ifdef USE_IDN
913-
hints.ai_flags = AI_IDN;
901+
hints.ai_flags = AI_IDN | AI_CANONIDN;
914902
#endif
915-
gai = getaddrinfo(target, NULL, &hints, &ai);
916-
if (gai) {
917-
fprintf(stderr, "unknown host\n");
903+
status = getaddrinfo(target, NULL, &hints, &result);
904+
if (status) {
905+
fprintf(stderr, "ping6: %s: %s\n", target, gai_strerror(status));
918906
exit(2);
919907
}
920908

921-
memcpy(&whereto, ai->ai_addr, sizeof(whereto));
909+
memcpy(&whereto, result->ai_addr, sizeof(whereto));
922910
whereto.sin6_port = htons(IPPROTO_ICMPV6);
911+
freeaddrinfo(result);
923912

924913
if (memchr(target, ':', strlen(target)))
925914
options |= F_NUMERIC;
926915

927-
freeaddrinfo(ai);
928-
929916
if (IN6_IS_ADDR_UNSPECIFIED(&firsthop.sin6_addr)) {
930917
memcpy(&firsthop.sin6_addr, &whereto.sin6_addr, 16);
931918
#ifdef HAVE_SIN6_SCOPEID

ping_common.h

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
#ifdef USE_IDN
2828
#include <locale.h>
2929
#include <idna.h>
30+
#include <stringprep.h>
31+
#define getaddrinfo_flags (AI_CANONNAME | AI_IDN | AI_CANONIDN)
32+
#else
33+
#define getaddrinfo_flags (AI_CANONNAME)
3034
#endif
3135

3236
#include <netinet/in.h>

rdisc.c

+4-5
Original file line numberDiff line numberDiff line change
@@ -699,13 +699,12 @@ pr_type(int t)
699699
*/
700700
char *pr_name(struct in_addr addr)
701701
{
702-
struct hostent *phe;
702+
struct sockaddr_in sin = { .sin_family = AF_INET, .sin_addr = addr };
703+
char hnamebuf[NI_MAXHOST] = "";
703704
static char buf[80];
704705

705-
phe = gethostbyaddr((char *)&addr.s_addr, 4, AF_INET);
706-
if (phe == NULL)
707-
return( inet_ntoa(addr));
708-
snprintf(buf, sizeof(buf), "%s (%s)", phe->h_name, inet_ntoa(addr));
706+
getnameinfo((struct sockaddr *) &sin, sizeof sin, hnamebuf, sizeof hnamebuf, NULL, 0, 0);
707+
snprintf(buf, sizeof buf, "%s (%s)", hnamebuf, inet_ntoa(addr));
709708
return(buf);
710709
}
711710

0 commit comments

Comments
 (0)