*
*****************************************************************************/
#include <netdb.h>
+#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h> /* C standard library */
/*
* 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 = PF_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 = PF_INET;
+ break;
+ }
+ if (j == 6) {
+ hint.ai_family = PF_INET6;
+ break;
+ }
+ printf("Wrong IP protocol version, use 4 o 6\n\n");
+ usage();
break;
case '?': /* unrecognized options */
printf("Unrecognized options -%c\n",optopt);
* 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 == PF_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 == PF_INET6) { /* if IPv6 */
printf("IPv6 address: \n");
- addr6 = (struct sockaddr_in *) ptr->ai_addr;
- port = ntohs(addr6->sin6_port);
+ addr6 = (struct sockaddr_in *) 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);
}
/*
void usage(void) {
printf("Program mygethost: do an hostname resolution \n");
printf("Usage:\n");
- printf(" mygethost [-h] hostname service\n");
- printf(" -h print this help\n");
+ printf("mygethost [-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);
}