Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
Re: rpcinfo(8): get rid of inet_aton(3).
To:
tech@openbsd.org
Date:
Mon, 12 Aug 2024 00:22:13 +0200

Download raw body.

Thread
On Sun, Aug 11, 2024 at 02:11:22PM +0200, Florian Obser wrote:
> On 2024-08-11 13:58 +02, Florian Obser <florian@openbsd.org> wrote:
> > OK?
> >
> > (I don't think if (res->ai_family != AF_INET) can actually happen, happy
> > to leave that out.)

As far as I understand our implementation, setting hints.ai_family
= AF_INET forces res->ai_family == AF_INET.  POSIX demands this
behavior.

    If the ai_family field to which hints points has the value
    AF_UNSPEC, addresses are returned for use with any protocol
    family that can be used with the specified nodename and/or
    servname.  Otherwise, addresses are returned for use only with
    the specified protocol family.

> oops, this is the correct diff.

OK bluhm@

> diff --git rpcinfo.c rpcinfo.c
> index 9b48a2108ee..db6706f904e 100644
> --- rpcinfo.c
> +++ rpcinfo.c
> @@ -491,15 +491,9 @@ pmapdump(int argc, char **argv)
>  
>  	if (argc == 1)
>  		get_inet_address(&server_addr, argv[0]);
> -	else {
> -		bzero((char *)&server_addr, sizeof server_addr);
> -		server_addr.sin_family = AF_INET;
> -		if ((hp = gethostbyname("localhost")) != NULL)
> -			bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
> -			    hp->h_length);
> -		else
> -			(void) inet_aton("0.0.0.0", &server_addr.sin_addr);
> -	}
> +	else
> +		get_inet_address(&server_addr, "127.0.0.1");
> +
>  	minutetimeout.tv_sec = 60;
>  	minutetimeout.tv_usec = 0;
>  	server_addr.sin_port = htons(PMAPPORT);
> @@ -689,16 +683,25 @@ fail:
>  void
>  get_inet_address(struct sockaddr_in *addr, char *host)
>  {
> -	struct hostent *hp;
> +	struct addrinfo hints, *res;
> +	int error;
>  
> -	bzero((char *)addr, sizeof *addr);
> -	if (inet_aton(host, &addr->sin_addr) == 0) {
> -		if ((hp = gethostbyname(host)) == NULL) {
> -			fprintf(stderr, "rpcinfo: %s is unknown host\n",
> -			    host);
> -			exit(1);
> -		}
> -		bcopy(hp->h_addr, (char *)&addr->sin_addr, hp->h_length);
> +	memset(&hints, 0, sizeof(hints));
> +	hints.ai_family = AF_INET;
> +
> +	if ((error = getaddrinfo(host, NULL, &hints, &res))) {
> +		fprintf(stderr, "rpcinfo: %s is unknown host: %s\n",
> +		    host, gai_strerror(error));
> +		exit(1);
>  	}
> +
> +	if (res->ai_family != AF_INET) {
> +		fprintf(stderr, "rpcinfo: %s is unknown host\n",
> +		    host);
> +		exit(1);
> +	}
> +
>  	addr->sin_family = AF_INET;
> +	addr->sin_addr = ((struct sockaddr_in *)res->ai_addr)->sin_addr;
> +	freeaddrinfo(res);
>  }
> 
> 
> 
> -- 
> In my defence, I have been left unsupervised.