3 * Copyright (C) 2004 Simone Piccardi
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.
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.
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.
19 /*****************************************************************************
21 * File mygetaddr.c: An example for getaddrinfo program
23 * Author: S. Piccardi Nov. 2004
25 *****************************************************************************/
26 #include <string.h> /* C strings library */
27 #include <sys/types.h> /* primitive system data types */
28 #include <sys/stat.h> /* file characteristics constants and functions */
29 #include <unistd.h> /* unix standard library */
30 #include <stdlib.h> /* C standard library */
31 #include <stdio.h> /* standard I/O library */
32 #include <arpa/inet.h> /* IP addresses conversion utilities */
33 #include <sys/socket.h> /* socket constants, types and functions */
34 #include <netinet/in.h> /* IPv4 and IPv6 constants and types */
35 #include <netdb.h> /* C resolver library */
41 * Use getaddrinfo and print results
43 /* Help printing routine */
46 int main(int argc, char *argv[])
49 * Variables definition
53 struct addrinfo *res, *ptr;
55 struct sockaddr_in *addr;
56 struct sockaddr_in6 *addr6;
58 char buffer[INET6_ADDRSTRLEN];
59 char *protocols[] = { "tcp","udp", NULL };
60 int protval[] = { 6, 17 };
61 char *socktype[] = { "dgram","stream", NULL };
62 int sockval[] = { SOCK_DGRAM, SOCK_STREAM };
67 memset(&hint, 0, sizeof(hint));
68 hint.ai_family = PF_UNSPEC;
70 * Input section: decode command line parameters
73 opterr = 0; /* don't want writing to stderr */
74 while ( (i = getopt(argc, argv, "hdcp:t:v:")) != -1) {
79 case 'h': /* help option */
80 printf("Wrong -h option use\n");
83 case 'c': /* set canonical host name resolution */
84 hint.ai_flags = hint.ai_flags | AI_CANONNAME;
86 case 'd': /* set canonical host name resolution */
89 case 'p': /* set protocol value */
91 while ( (string = protocols[j]) != NULL ) {
92 if ( (strncmp(string, optarg, strlen(string)) == 0) ) {
93 hint.ai_protocol = protval[j];
99 printf("Wrong protocol, use 'tcp' or 'udp'\n\n");
103 case 't': /* set socket type value */
105 while ( (string = socktype[j]) != NULL ) {
106 if ( (strncmp(string, optarg, strlen(string)) == 0) ) {
107 hint.ai_socktype = sockval[j];
113 printf("Wrong socket type, use 'dgram' or 'stream'\n\n");
117 case 'v': /* set address type */
118 j = strtol(optarg, NULL, 10);
120 hint.ai_family = PF_INET;
124 hint.ai_family = PF_INET6;
127 printf("Wrong IP protocol version, use 4 o 6\n\n");
130 case '?': /* unrecognized options */
131 printf("Unrecognized options -%c\n",optopt);
133 default: /* should not reached */
137 /* ***********************************************************
139 * Options processing completed
141 * Main code beginning
143 * ***********************************************************/
144 /* if debug actived printout hint values*/
146 printf("hint.ai_flag = %d\n", hint.ai_flags);
147 printf("hint.ai_family = %d\n", hint.ai_family);
148 printf("hint.ai_socktype = %d\n", hint.ai_socktype);
149 printf("hint.ai_protocol = %d\n", hint.ai_protocol);
150 printf("address = %s\n", argv[optind]);
151 printf("port = %s\n", argv[optind+1]);
153 /* remaining argument check */
154 if ((argc - optind) != 2) {
155 printf("Wrong number of arguments %d\n", argc - optind);
159 ret = getaddrinfo(argv[optind], argv[optind+1], &hint, &res);
161 printf("Resolution error %s\n", gai_strerror(ret));
164 ptr = res; /* init list pointer */
165 printf("Canonical name %s\n", ptr->ai_canonname); /* print cname */
166 while (ptr != NULL) { /* loop on list */
167 if (ptr->ai_family == PF_INET) { /* if IPv4 */
168 printf("IPv4 address: \n");
169 addr = (struct sockaddr_in *) ptr->ai_addr; /* address */
170 port = ntohs(addr->sin_port); /* port */
171 string = inet_ntop(addr->sin_family, &addr->sin_addr,
172 buffer, sizeof(buffer));
173 } else if (ptr->ai_family == PF_INET6) { /* if IPv6 */
174 printf("IPv6 address: \n");
175 addr6 = (struct sockaddr_in6 *) ptr->ai_addr; /* address */
176 port = ntohs(addr6->sin6_port); /* port */
177 string = inet_ntop(addr6->sin6_family, &addr6->sin6_addr,
178 buffer, sizeof(buffer));
179 } else { /* else is an error */
180 printf("Address family error\n");
183 printf("\tIndirizzo %s\n", string);
184 printf("\tProtocollo %i\n", ptr->ai_protocol);
185 printf("\tPorta %i\n", port);
191 * routine to print usage info and exit
194 printf("Program mygetaddr: do an hostname resolution \n");
196 printf("mygetaddr [-h] [-p protocol] [-t socktype] hostname service\n");
197 printf(" -h print this help\n");
198 printf(" -p udp,tcp select a protocol\n");
199 printf(" -t dgram,stream select a socket type\n");
200 printf(" -v 4,6 select IPv4 or IPv6 \n");
201 printf(" -c require canonical name resolution\n");