Correzione della stampa per la struttura IPv6 per mygetaddr, rimosse le
[gapil.git] / sources / mygetaddr.c
1 /* mygetaddr.c
2  * 
3  * Copyright (C) 2004 Simone Piccardi
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /*****************************************************************************
20  *
21  * File mygetaddr.c: An example for getaddrinfo program
22  *
23  * Author: S. Piccardi Nov. 2004
24  *
25  * $Id$
26  *
27  *****************************************************************************/
28 #include <netdb.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <stdlib.h>        /* C standard library */
33 #include <stdio.h>         /* I/O standard library */
34 #include <unistd.h>
35 #include <arpa/inet.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
38
39 #include "Gapil.h"
40 /*
41  * Program myhost
42  *
43  * Use gethostbyname and print results
44  */
45 /* Help printing routine */
46 void usage(void);
47
48 int main(int argc, char *argv[]) 
49 {
50 /* 
51  * Variables definition
52  */
53     int i,j;
54     struct addrinfo hint;
55     struct addrinfo *res, *ptr;
56     int ret, port;
57     struct sockaddr_in *addr;
58     struct sockaddr_in6 *addr6;
59     char *string;
60     char buffer[INET6_ADDRSTRLEN];
61     char *protocols[] = { "tcp","udp", NULL };
62     int protval[] = { 6, 17 };
63     char *socktype[] = { "dgram","stream", NULL };
64     int sockval[] = { SOCK_DGRAM, SOCK_STREAM };
65     int debug = 0;
66     /*
67      * Init variables
68      */
69     memset(&hint, 0, sizeof(hint));
70     hint.ai_family = PF_UNSPEC;
71     /*
72      * Input section: decode command line parameters 
73      * Use getopt function
74      */
75     opterr = 0;  /* don't want writing to stderr */
76     while ( (i = getopt(argc, argv, "hdcp:t:v:")) != -1) {
77         switch (i) {
78         /* 
79          * Handling options 
80          */ 
81         case 'h':                                             /* help option */
82             printf("Wrong -h option use\n");
83             usage();
84             break;
85         case 'c':                      /* set canonical host name resolution */
86             hint.ai_flags = hint.ai_flags | AI_CANONNAME;
87             break;
88         case 'd':                      /* set canonical host name resolution */
89             debug = 1;
90             break;
91         case 'p':                                      /* set protocol value */
92             j = 0;
93             while ( (string = protocols[j]) != NULL ) {
94                 if ( (strncmp(string, optarg, strlen(string)) == 0) ) {
95                     hint.ai_protocol = protval[j];
96                     break;
97                 }
98                 j++;
99             }
100             if (j>=2) {
101                 printf("Wrong protocol, use 'tcp' or 'udp'\n\n");
102                 usage();
103             }
104             break;
105         case 't':                                   /* set socket type value */
106             j = 0;
107             while ( (string = socktype[j]) != NULL ) {
108                 if ( (strncmp(string, optarg, strlen(string)) == 0) ) {
109                     hint.ai_socktype = sockval[j];
110                     break;
111                 }
112                 j++;
113             }           
114             if (j>=2) {
115                 printf("Wrong socket type, use 'dgram' or 'stream'\n\n");
116                 usage();
117             }
118             break;
119         case 'v':                                        /* set address type */
120             j = strtol(optarg, NULL, 10);
121             if (j == 4) {
122                 hint.ai_family = PF_INET;
123                 break;
124             } 
125             if (j == 6) {
126                 hint.ai_family = PF_INET6;
127                 break;
128             }
129             printf("Wrong IP protocol version, use 4 o 6\n\n");
130             usage();
131             break;
132         case '?':                                    /* unrecognized options */
133             printf("Unrecognized options -%c\n",optopt);
134             usage();
135         default:                                       /* should not reached */
136             usage();
137         }
138     }
139     /* ***********************************************************
140      * 
141      *           Options processing completed
142      *
143      *                Main code beginning
144      * 
145      * ***********************************************************/
146     /* if debug actived printout hint values*/
147     if (debug) {
148         printf("hint.ai_flag     = %d\n", hint.ai_flags);
149         printf("hint.ai_family   = %d\n", hint.ai_family);
150         printf("hint.ai_socktype = %d\n", hint.ai_socktype);
151         printf("hint.ai_protocol = %d\n", hint.ai_protocol);
152         printf("address = %s\n", argv[optind]);
153         printf("port    = %s\n", argv[optind+1]);
154     }
155     /* remaining argument check */
156     if ((argc - optind) != 2) {
157         printf("Wrong number of arguments %d\n", argc - optind);
158         usage();
159     }
160     /* main body */    
161     ret = getaddrinfo(argv[optind], argv[optind+1], &hint, &res); 
162     if (ret != 0) {
163         printf("Resolution error %s\n", gai_strerror(ret));
164         exit(1);
165     }
166     ptr = res;                                        /* init list pointer */
167     printf("Canonical name %s\n", ptr->ai_canonname); /* print cname */
168     while (ptr != NULL) {                             /* loop on list */
169         if (ptr->ai_family == PF_INET) {              /* if IPv4 */
170             printf("IPv4 address: \n");
171             addr = (struct sockaddr_in *) ptr->ai_addr;          /* address */
172             port = ntohs(addr->sin_port);                        /* port */
173             string = inet_ntop(addr->sin_family, &addr->sin_addr, 
174                                buffer, sizeof(buffer));
175         } else if (ptr->ai_family == PF_INET6) {      /* if IPv6 */
176             printf("IPv6 address: \n");
177             addr6 = (struct sockaddr_in6 *) ptr->ai_addr;        /* address */
178             port = ntohs(addr6->sin6_port);                      /* port */
179             string = inet_ntop(addr6->sin6_family, &addr6->sin6_addr, 
180                                buffer, sizeof(buffer));
181         } else {                                      /* else is an error */
182             printf("Address family error\n");
183             exit(1);
184         }       
185         printf("\tIndirizzo %s\n", string);
186         printf("\tProtocollo %i\n", ptr->ai_protocol);
187         printf("\tPorta %i\n", port);
188         ptr = ptr->ai_next;
189     }
190     exit(0);
191 }
192 /*
193  * routine to print usage info and exit
194  */
195 void usage(void) {
196     printf("Program mygethost: do an hostname resolution \n");
197     printf("Usage:\n");
198     printf("mygethost [-h] [-p protocol] [-t socktype] hostname service\n");
199     printf("  -h              print this help\n");
200     printf("  -p udp,tcp      select a protocol\n");
201     printf("  -t dgram,stream select a socket type\n");
202     printf("  -v 4,6          select IPv4 or IPv6 \n");
203     printf("  -c              require canonical name resolution\n");
204     exit(1);
205 }