X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=sources%2Fmygetaddr.c;h=67a570d79377880c5a6b457a6d179b751f3f8588;hp=aa830064f3ba95112044e78a233b459c2a6b2eed;hb=HEAD;hpb=4c6bdffb5a1a4746b241d8323faaf3a49a4633a9 diff --git a/sources/mygetaddr.c b/sources/mygetaddr.c index aa83006..67a570d 100644 --- a/sources/mygetaddr.c +++ b/sources/mygetaddr.c @@ -18,28 +18,27 @@ */ /***************************************************************************** * - * File mygetaddr.c: An example host command + * File mygetaddr.c: An example for getaddrinfo program * * Author: S. Piccardi Nov. 2004 * - * $Id$ - * *****************************************************************************/ -#include -#include -#include -#include /* C standard library */ -#include /* I/O standard library */ -#include -#include -#include -#include +#include /* C strings library */ +#include /* primitive system data types */ +#include /* file characteristics constants and functions */ +#include /* unix standard library */ +#include /* C standard library */ +#include /* standard I/O library */ +#include /* IP addresses conversion utilities */ +#include /* socket constants, types and functions */ +#include /* IPv4 and IPv6 constants and types */ +#include /* C resolver library */ #include "Gapil.h" /* - * Program myhost + * Program mygetaddr * - * Use gethostbyname and print results + * Use getaddrinfo and print results */ /* Help printing routine */ void usage(void); @@ -49,28 +48,84 @@ int main(int argc, char *argv[]) /* * Variables definition */ - int i; + int i,j; struct addrinfo hint; struct addrinfo *res, *ptr; int ret, port; struct sockaddr_in *addr; struct sockaddr_in6 *addr6; - char buffer[INET6_ADDRSTRLEN]; char *string; + char buffer[INET6_ADDRSTRLEN]; + char *protocols[] = { "tcp","udp", NULL }; + int protval[] = { 6, 17 }; + char *socktype[] = { "dgram","stream", NULL }; + int sockval[] = { SOCK_DGRAM, SOCK_STREAM }; + int debug = 0; + /* + * Init variables + */ + memset(&hint, 0, sizeof(hint)); + hint.ai_family = AF_UNSPEC; /* * Input section: decode command line parameters * Use getopt function */ opterr = 0; /* don't want writing to stderr */ - while ( (i = getopt(argc, argv, "h")) != -1) { + while ( (i = getopt(argc, argv, "hdcp:t:v:")) != -1) { switch (i) { /* * Handling options */ - case 'h': /* help option */ + case 'h': /* help option */ printf("Wrong -h option use\n"); usage(); - return -1; + break; + case 'c': /* set canonical host name resolution */ + hint.ai_flags = hint.ai_flags | AI_CANONNAME; + break; + case 'd': /* set canonical host name resolution */ + debug = 1; + break; + case 'p': /* set protocol value */ + j = 0; + while ( (string = protocols[j]) != NULL ) { + if ( (strncmp(string, optarg, strlen(string)) == 0) ) { + hint.ai_protocol = protval[j]; + break; + } + j++; + } + if (j>=2) { + printf("Wrong protocol, use 'tcp' or 'udp'\n\n"); + usage(); + } + break; + case 't': /* set socket type value */ + j = 0; + while ( (string = socktype[j]) != NULL ) { + if ( (strncmp(string, optarg, strlen(string)) == 0) ) { + hint.ai_socktype = sockval[j]; + break; + } + j++; + } + if (j>=2) { + printf("Wrong socket type, use 'dgram' or 'stream'\n\n"); + usage(); + } + break; + case 'v': /* set address type */ + j = strtol(optarg, NULL, 10); + if (j == 4) { + hint.ai_family = AF_INET; + break; + } + if (j == 6) { + hint.ai_family = AF_INET6; + break; + } + printf("Wrong IP protocol version, use 4 o 6\n\n"); + usage(); break; case '?': /* unrecognized options */ printf("Unrecognized options -%c\n",optopt); @@ -86,51 +141,63 @@ int main(int argc, char *argv[]) * Main code beginning * * ***********************************************************/ + /* if debug actived printout hint values*/ + if (debug) { + printf("hint.ai_flag = %d\n", hint.ai_flags); + printf("hint.ai_family = %d\n", hint.ai_family); + printf("hint.ai_socktype = %d\n", hint.ai_socktype); + printf("hint.ai_protocol = %d\n", hint.ai_protocol); + printf("address = %s\n", argv[optind]); + printf("port = %s\n", argv[optind+1]); + } + /* remaining argument check */ if ((argc - optind) != 2) { printf("Wrong number of arguments %d\n", argc - optind); usage(); } - - ret = getaddrinfo(argv[1], argv[2], NULL, &res); /* main call */ - if (ret != 0) { /* on error exit */ + /* main body */ + ret = getaddrinfo(argv[optind], argv[optind+1], &hint, &res); + if (ret != 0) { printf("Resolution error %s\n", gai_strerror(ret)); exit(1); } - ptr = res; /* store pointer */ + ptr = res; /* init list pointer */ printf("Canonical name %s\n", ptr->ai_canonname); /* print cname */ - do { - if (ptr->ai_family == PF_INET) { + while (ptr != NULL) { /* loop on list */ + if (ptr->ai_family == AF_INET) { /* if IPv4 */ printf("IPv4 address: \n"); - addr = (struct sockaddr_in *) ptr->ai_addr; - port = ntohs(addr->sin_port); + addr = (struct sockaddr_in *) ptr->ai_addr; /* address */ + port = ntohs(addr->sin_port); /* port */ string = inet_ntop(addr->sin_family, &addr->sin_addr, buffer, sizeof(buffer)); - } else if (ptr->ai_family == PF_INET6) { + } else if (ptr->ai_family == AF_INET6) { /* if IPv6 */ printf("IPv6 address: \n"); - addr6 = (struct sockaddr_in *) ptr->ai_addr; - port = ntohs(addr6->sin6_port); + addr6 = (struct sockaddr_in6 *) ptr->ai_addr; /* address */ + port = ntohs(addr6->sin6_port); /* port */ string = inet_ntop(addr6->sin6_family, &addr6->sin6_addr, buffer, sizeof(buffer)); - } else { + } else { /* else is an error */ printf("Address family error\n"); exit(1); } printf("\tIndirizzo %s\n", string); printf("\tProtocollo %i\n", ptr->ai_protocol); printf("\tPorta %i\n", port); - - ptr = ptr->ai_next; - } while (ptr != NULL); + } exit(0); } /* * routine to print usage info and exit */ void usage(void) { - printf("Program mygethost: do an hostname resolution \n"); + printf("Program mygetaddr: do an hostname resolution \n"); printf("Usage:\n"); - printf(" mygethost [-h] hostname service\n"); - printf(" -h print this help\n"); + printf("mygetaddr [-h] [-p protocol] [-t socktype] hostname service\n"); + printf(" -h print this help\n"); + printf(" -p udp,tcp select a protocol\n"); + printf(" -t dgram,stream select a socket type\n"); + printf(" -v 4,6 select IPv4 or IPv6 \n"); + printf(" -c require canonical name resolution\n"); exit(1); }