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
27 *****************************************************************************/
30 #include <sys/types.h>
32 #include <stdlib.h> /* C standard library */
33 #include <stdio.h> /* I/O standard library */
35 #include <arpa/inet.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
43 * Use getaddrinfo and print results
45 /* Help printing routine */
48 int main(int argc, char *argv[])
51 * Variables definition
55 struct addrinfo *res, *ptr;
57 struct sockaddr_in *addr;
58 struct sockaddr_in6 *addr6;
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 };
69 memset(&hint, 0, sizeof(hint));
70 hint.ai_family = PF_UNSPEC;
72 * Input section: decode command line parameters
75 opterr = 0; /* don't want writing to stderr */
76 while ( (i = getopt(argc, argv, "hdcp:t:v:")) != -1) {
81 case 'h': /* help option */
82 printf("Wrong -h option use\n");
85 case 'c': /* set canonical host name resolution */
86 hint.ai_flags = hint.ai_flags | AI_CANONNAME;
88 case 'd': /* set canonical host name resolution */
91 case 'p': /* set protocol value */
93 while ( (string = protocols[j]) != NULL ) {
94 if ( (strncmp(string, optarg, strlen(string)) == 0) ) {
95 hint.ai_protocol = protval[j];
101 printf("Wrong protocol, use 'tcp' or 'udp'\n\n");
105 case 't': /* set socket type value */
107 while ( (string = socktype[j]) != NULL ) {
108 if ( (strncmp(string, optarg, strlen(string)) == 0) ) {
109 hint.ai_socktype = sockval[j];
115 printf("Wrong socket type, use 'dgram' or 'stream'\n\n");
119 case 'v': /* set address type */
120 j = strtol(optarg, NULL, 10);
122 hint.ai_family = PF_INET;
126 hint.ai_family = PF_INET6;
129 printf("Wrong IP protocol version, use 4 o 6\n\n");
132 case '?': /* unrecognized options */
133 printf("Unrecognized options -%c\n",optopt);
135 default: /* should not reached */
139 /* ***********************************************************
141 * Options processing completed
143 * Main code beginning
145 * ***********************************************************/
146 /* if debug actived printout hint values*/
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]);
155 /* remaining argument check */
156 if ((argc - optind) != 2) {
157 printf("Wrong number of arguments %d\n", argc - optind);
161 ret = getaddrinfo(argv[optind], argv[optind+1], &hint, &res);
163 printf("Resolution error %s\n", gai_strerror(ret));
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");
185 printf("\tIndirizzo %s\n", string);
186 printf("\tProtocollo %i\n", ptr->ai_protocol);
187 printf("\tPorta %i\n", port);
193 * routine to print usage info and exit
196 printf("Program mygethost: do an hostname resolution \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");