others
/* $Id$ */
/* Copyright (c) 2009-2016 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Unix others */
/* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#ifndef PROGNAME
# define PROGNAME "host"
#endif
/* host */
/* private */
/* prototypes */
static int _host(int family, char * hostname);
static int _host_gaierror(char const * message, int error);
static int _host_usage(void);
/* functions */
/* host */
static int _host(int family, char * hostname)
{
struct addrinfo hints;
struct addrinfo * ai;
int res;
struct addrinfo * p;
char buf[128];
struct sockaddr_in * sa;
struct sockaddr_in6 * sa6;
memset(&hints, 0, sizeof(hints));
hints.ai_family = family;
hints.ai_socktype = SOCK_STREAM;
if((res = getaddrinfo(hostname, NULL, &hints, &ai)) != 0)
return _host_gaierror(hostname, res);
for(p = ai; p != NULL; p = p->ai_next)
switch(p->ai_family)
{
case AF_INET:
sa = (struct sockaddr_in *)p->ai_addr;
if(inet_ntop(p->ai_family, &sa->sin_addr, buf,
sizeof(buf)) != NULL)
printf("%s has address %s\n",
hostname, buf);
break;
case AF_INET6:
sa6 = (struct sockaddr_in6 *)p->ai_addr;
if(inet_ntop(p->ai_family, &sa6->sin6_addr, buf,
sizeof(buf)) != NULL)
printf("%s has IPv6 address %s\n",
hostname, buf);
break;
}
freeaddrinfo(ai);
return 0;
}
/* host_gaierror */
static int _host_gaierror(char const * message, int error)
{
fprintf(stderr, "%s%s%s%s\n", PROGNAME ": ", message, ": ",
gai_strerror(error));
return -1;
}
/* host_usage */
static int _host_usage(void)
{
fputs("Usage: " PROGNAME " [-46] address\n", stderr);
return 1;
}
/* public */
/* functions */
/* main */
int main(int argc, char * argv[])
{
int o;
int family = AF_UNSPEC;
while((o = getopt(argc, argv, "46")) != -1)
switch(o)
{
case '4':
family = AF_INET;
break;
case '6':
family = AF_INET6;
break;
default:
return _host_usage();
}
if(optind != argc - 1)
return _host_usage();
return (_host(family, argv[optind]) == 0) ? 0 : 2;
}