Correzione della stampa per la struttura IPv6 per mygetaddr, rimosse le
[gapil.git] / sources / SockUtil.c
1 /* Sockutils.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 SockUtils.c 
22  * Routines for socket operations. 
23  *
24  * Define routines for socket handling 
25  *
26  * Author: S. Piccardi
27  *
28  * $Id$
29  *
30  ***************************************************************/
31 #include <sys/types.h>
32 #include <stdio.h>                                 /* standard I/O functions */
33 #include <unistd.h>
34 #include <string.h>
35 #include <errno.h>
36 #include <arpa/inet.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <netdb.h>
41
42 #include "macros.h"
43 /**************************************************************************
44  *
45  * Routine ip_ntop
46  *
47  * Return a string with the numeric address translation of the content
48  * of an addrinfo stucture
49  *
50  * Author: Simone Piccardi
51  * Dec. 2004
52  *
53  * $Id$ 
54  *
55  **************************************************************************/
56 char *ip_ntop(struct addrinfo *addr, char *dst, socklen_t cnt)
57 {
58 //    char buffer[INET6_ADDRSTRLEN];
59     char * ret;
60     struct sockaddr_in *ip4;
61     struct sockaddr_in6 *ip6;
62     if (addr->ai_family == PF_INET) {
63         ip4 = (struct sockaddr_in *) addr->ai_addr;
64         ret = inet_ntop(ip4->sin_family, &ip4->sin_addr, dst, cnt);
65     } else {
66         ip6 = (struct sockaddr_in6 *) addr->ai_addr;
67         ret = inet_ntop(ip6->sin6_family, &ip6->sin6_addr, dst, cnt);
68     }
69     return ret;
70 }
71 /****************************************************************
72  *
73  * Routine sockconn
74  * Return a connected socket given hostname, service, and socket type
75  *
76  * Author: Simone Piccardi
77  * Dec. 2004
78  *
79  * $Id$ 
80  *
81  ****************************************************************/
82 int sockconn(char *host, char *serv, int prot, int type) 
83 {
84     struct addrinfo hint, *addr, *save;
85     int res;
86     int sock;
87     /* initialize hint structure */
88     memset(&hint, 0, sizeof(struct addrinfo)); 
89     hint.ai_family = PF_UNSPEC;          /* generic address (IPv4 or IPv6) */
90     hint.ai_protocol = prot;             /* protocol */
91     hint.ai_socktype = type;             /* socket type */
92     res = getaddrinfo(host, serv, &hint, &addr);    /* calling getaddrinfo */
93     if (res != 0) {                                 /* on error exit */
94         fprintf(stderr, "sockconn: resolution failed:");
95 //      fprintf(stderr, "host %s, service %s, protocol %d", host, serv, prot);
96         fprintf(stderr, " %s\n", gai_strerror(res));
97         errno = 0;                                 /* clear errno */
98         return -1;
99     }
100     /* loop on possible addresses */
101     save = addr;
102     while (addr != NULL) {
103         /* get a socket */
104         sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
105         if (sock < 0) {
106             if (addr->ai_next != NULL) {
107                 addr=addr->ai_next;
108                 continue;
109             } else {
110                 perror("sockconn: cannot create socket");
111                 return sock;
112             }
113         }
114         /* connect the socket */
115         if ( (res = connect(sock, addr->ai_addr, addr->ai_addrlen) < 0)) {
116             if (addr->ai_next != NULL) {
117                 addr=addr->ai_next;
118                 close(sock);
119                 continue;
120             } else {
121                 perror("sockconn: cannot connect");
122                 close(sock);
123                 return res;
124             }
125         } else break;
126     }
127     freeaddrinfo(save);         /* done, release memory */
128     return sock;
129 }
130 /****************************************************************
131  *
132  * Routine sockbind
133  * Return a binded socket given hostname, service, and socket type
134  *
135  * Author: Simone Piccardi
136  * Dec. 2004
137  *
138  * $Id$ 
139  *
140  ****************************************************************/
141 int sockbind(char *host, char *serv, int prot, int type) 
142 {
143     struct addrinfo hint, *addr, *save;
144     int res;
145     int sock;
146     char buf[INET6_ADDRSTRLEN];
147     /* initialize hint structure */
148     memset(&hint, 0, sizeof(struct addrinfo)); 
149     hint.ai_flags = AI_PASSIVE;          /* address for binding */
150     hint.ai_family = PF_UNSPEC;          /* generic address (IPv4 or IPv6) */
151     hint.ai_protocol = prot;             /* protocol */
152     hint.ai_socktype = type;             /* socket type */
153     res = getaddrinfo(host, serv, &hint, &addr);   /* calling getaddrinfo */
154     if (res != 0) {                                /* on error exit */
155         fprintf(stderr, "sockbind: resolution failed:");
156 //      fprintf(stderr, "host %s, service %s, protocol %d", host, serv, prot);
157         fprintf(stderr, " %s\n", gai_strerror(res));
158         errno = 0;                                 /* clear errno */
159         return -1;
160     }
161     /* loop on possible addresses */
162     save = addr;
163     while (addr != NULL) {
164         /* get a socket */
165         sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
166         if (sock < 0) {
167             if (addr->ai_next != NULL) {
168                 addr=addr->ai_next;
169                 continue;
170             } else {
171                 perror("sockconn: cannot create socket");
172                 return sock;
173             }
174         }
175         /* connect the socket */
176         printf("Indirizzo %s\n", ip_ntop(addr, buf, sizeof(buf)));
177         ;
178         if ( (res = bind(sock, addr->ai_addr, addr->ai_addrlen)) < 0) {
179             if (addr->ai_next != NULL) {
180                 addr=addr->ai_next;
181                 close(sock);
182                 continue;
183             } else {
184                 perror("sockconn: cannot connect");
185                 close(sock);
186                 return res;
187             }
188         } else break;
189     }
190     freeaddrinfo(save);                            /* done, release memory */
191     return sock;
192 }