Use INADDR_NONE instead of -1 to check inet_addr() result
[cvsps-yd.git] / cbtcommon / tcpsocket.c
blobf31060e94c42eb8d882b6ac757d4aac2c8b95934
1 /*
2 * Copyright 2001, 2002, 2003 David Mansfield and Cobite, Inc.
3 * See COPYING file for license information
4 */
6 #ifdef SOLARIS
7 #include <strings.h>
8 #else
9 #include <string.h>
10 #endif
12 #ifdef WIN32
13 #include <winsock2.h>
14 #else /* not windows */
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <netdb.h>
20 #include <errno.h>
22 #ifdef SOLARIS
23 #include <netinet/tcp.h>
24 #endif
26 #endif /* if windows */
28 #include "tcpsocket.h"
29 #include "debug.h"
30 #include "rcsid.h"
31 #ifdef WIN32
32 #include "win32fd.h"
33 #endif
35 RCSID("$Id: tcpsocket.c,v 1.6 1999/12/27 20:35:34 david Exp $");
37 int
38 tcp_create_socket(int reuse_addr)
40 int retval;
41 int yes = 1;
43 if ((retval = socket(AF_INET, SOCK_STREAM, 0)) < 0)
45 debug(DEBUG_ERROR, "tcp: can't create socket");
48 if (reuse_addr)
50 setsockopt( retval, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(int));
53 debug(DEBUG_TCP, "tcp: socket created");
54 #ifdef WIN32
55 return get_fd(retval, WIN32_SOCKET);
56 #else
57 return retval;
58 #endif
61 int
62 tcp_bind_and_listen(int sockfd, unsigned short tcp_port)
64 struct sockaddr_in addr;
66 memset((char *) &addr, 0, sizeof(struct sockaddr_in));
67 addr.sin_family = AF_INET;
68 addr.sin_addr.s_addr = htonl(INADDR_ANY);
69 addr.sin_port = htons(tcp_port);
71 #ifdef WIN32
72 sockfd = win32_file_table[sockfd].win32id;
73 #endif
75 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
77 debug(DEBUG_ERROR, "tcp: can't bind to socket");
78 return -1;
82 if (listen(sockfd, LISTEN_QUEUE_SIZE) < 0)
84 debug(DEBUG_ERROR, "tcp: can't listen on socket");
85 return -1;
88 debug(DEBUG_TCP, "tcp: socket bound and listening");
90 return 0;
93 int
94 tcp_accept_connection(int sockfd)
96 struct sockaddr_in remaddr;
97 int addrlen;
98 int retval;
100 #ifdef WIN32
101 sockfd = win32_file_table[sockfd].win32id;
102 #endif
104 addrlen = sizeof(struct sockaddr_in);
106 #ifdef WIN32
107 if ((retval = accept(sockfd, (struct sockaddr *) &remaddr, &addrlen)) == INVALID_SOCKET)
109 debug(DEBUG_APPERROR, "tcp: error accepting connection");
110 return -1;
112 #else
113 if ((retval = accept(sockfd, (struct sockaddr *) &remaddr, &addrlen)) < 0)
115 if (errno != EINTR )
116 debug(DEBUG_ERROR, "tcp: error accepting connection");
118 return -1;
120 #endif
122 debug(DEBUG_TCP, "tcp: got connection (fd=%d)", retval);
124 return retval;
127 unsigned int
128 tcp_get_client_ip(int fd)
130 struct sockaddr_in remaddr;
131 int addrlen;
132 int retval;
133 unsigned int saddr;
135 #ifdef WIN32
136 fd = win32_file_table[fd].win32id;
137 #endif
139 addrlen = sizeof(struct sockaddr_in);
141 if ((retval = getpeername(fd, (struct sockaddr *) &remaddr, &addrlen)) < 0)
143 debug(DEBUG_ERROR, "tcp: error getting remote's ip address");
144 return 0;
147 saddr = ntohl(remaddr.sin_addr.s_addr);
149 return saddr;
153 tcp_connect(int sockfd, const char *rem_addr, unsigned short port)
155 struct sockaddr_in addr;
156 int addrlen;
157 long ipno;
159 #ifdef WIN32
160 sockfd = win32_file_table[sockfd].win32id;
161 #endif
163 if ( convert_address(&ipno , rem_addr) < 0 )
165 return -1;
168 addrlen = sizeof(struct sockaddr_in);
170 memset((char *) &addr, 0, sizeof(struct sockaddr_in));
171 addr.sin_family = AF_INET;
172 addr.sin_addr.s_addr = ipno;
173 addr.sin_port = htons(port);
175 if (connect(sockfd, (struct sockaddr *)&addr, addrlen) < 0)
177 debug(DEBUG_ERROR, "connect error");
178 return -1;
181 debug(DEBUG_STATUS, "tcp: connection established on port %d", port);
182 return 0;
186 convert_address(long *dest, const char *addr_str)
188 #ifdef __linux__
189 struct in_addr ip;
190 #endif
191 int retval = 0;
192 char errstr[256];
194 /* first try converting "numbers and dots" notation */
195 #ifdef __linux__
196 if ( inet_aton(addr_str, &ip) )
198 memcpy(dest, &ip.s_addr, sizeof(ip.s_addr));
200 #else
201 if ( (*dest = inet_addr(addr_str)) != INADDR_NONE)
203 /* nothing */
205 #endif
206 else /* if it fails, do a gethostbyname() */
208 struct hostent *host;
209 if ((host = gethostbyname(addr_str)) == NULL)
211 switch(h_errno)
213 case HOST_NOT_FOUND:
214 strcpy(errstr, "HOST_NOT_FOUND");
215 break;
217 case NO_ADDRESS:
218 strcpy(errstr, "NO_ADDRESS");
219 break;
221 case NO_RECOVERY:
222 strcpy(errstr, "NO_RECOVERY");
223 break;
225 case TRY_AGAIN:
226 strcpy(errstr, "TRY_AGAIN");
227 break;
230 debug(DEBUG_ERROR, "gethostbyname failed for %s: ", addr_str, errstr);
232 retval = -1;
235 memcpy(dest, host->h_addr_list[0], sizeof(unsigned long));
239 return retval;
242 int tcp_get_local_address(int sockfd, unsigned int *ip, unsigned short *port)
244 struct sockaddr_in addr;
245 int addrlen = sizeof(struct sockaddr_in);
247 if(getsockname(sockfd, (struct sockaddr *)&addr, &addrlen) < 0)
249 debug(DEBUG_SYSERROR, "getsockname failed" );
250 return -1;
253 *ip = ntohl( addr.sin_addr.s_addr );
254 *port = ntohs( addr.sin_port );
256 return 0;