Completata la parte su getaddrinfo e rifatto il programma di esempio per
[gapil.git] / sources / mygetaddr.c
index aa830064f3ba95112044e78a233b459c2a6b2eed..ca01d74d6a9d951d6ea5c55e44e491d687ae94a6 100644 (file)
@@ -26,6 +26,7 @@
  *
  *****************************************************************************/
 #include <netdb.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <stdlib.h>        /* C standard library */
@@ -49,28 +50,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 = 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);
@@ -86,42 +143,50 @@ 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 == 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);
 }
 /*
@@ -130,7 +195,11 @@ int main(int argc, char *argv[])
 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);
 }