2 * Copyright 2001, 2002, 2003 David Mansfield and Cobite, Inc.
3 * See COPYING file for license information
14 #else /* not windows */
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
23 #include <netinet/tcp.h>
26 #endif /* if windows */
28 #include "tcpsocket.h"
35 RCSID("$Id: tcpsocket.c,v 1.6 1999/12/27 20:35:34 david Exp $");
38 tcp_create_socket(int reuse_addr
)
43 if ((retval
= socket(AF_INET
, SOCK_STREAM
, 0)) < 0)
45 debug(DEBUG_ERROR
, "tcp: can't create socket");
50 setsockopt( retval
, SOL_SOCKET
, SO_REUSEADDR
, (char *)&yes
, sizeof(int));
53 debug(DEBUG_TCP
, "tcp: socket created");
55 return get_fd(retval
, WIN32_SOCKET
);
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
);
72 sockfd
= win32_file_table
[sockfd
].win32id
;
75 if (bind(sockfd
, (struct sockaddr
*)&addr
, sizeof(addr
)) < 0)
77 debug(DEBUG_ERROR
, "tcp: can't bind to socket");
82 if (listen(sockfd
, LISTEN_QUEUE_SIZE
) < 0)
84 debug(DEBUG_ERROR
, "tcp: can't listen on socket");
88 debug(DEBUG_TCP
, "tcp: socket bound and listening");
94 tcp_accept_connection(int sockfd
)
96 struct sockaddr_in remaddr
;
101 sockfd
= win32_file_table
[sockfd
].win32id
;
104 addrlen
= sizeof(struct sockaddr_in
);
107 if ((retval
= accept(sockfd
, (struct sockaddr
*) &remaddr
, &addrlen
)) == INVALID_SOCKET
)
109 debug(DEBUG_APPERROR
, "tcp: error accepting connection");
113 if ((retval
= accept(sockfd
, (struct sockaddr
*) &remaddr
, &addrlen
)) < 0)
116 debug(DEBUG_ERROR
, "tcp: error accepting connection");
122 debug(DEBUG_TCP
, "tcp: got connection (fd=%d)", retval
);
128 tcp_get_client_ip(int fd
)
130 struct sockaddr_in remaddr
;
136 fd
= win32_file_table
[fd
].win32id
;
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");
147 saddr
= ntohl(remaddr
.sin_addr
.s_addr
);
153 tcp_connect(int sockfd
, const char *rem_addr
, unsigned short port
)
155 struct sockaddr_in addr
;
160 sockfd
= win32_file_table
[sockfd
].win32id
;
163 if ( convert_address(&ipno
, rem_addr
) < 0 )
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");
181 debug(DEBUG_STATUS
, "tcp: connection established on port %d", port
);
186 convert_address(long *dest
, const char *addr_str
)
194 /* first try converting "numbers and dots" notation */
196 if ( inet_aton(addr_str
, &ip
) )
198 memcpy(dest
, &ip
.s_addr
, sizeof(ip
.s_addr
));
201 if ( (*dest
= inet_addr(addr_str
)) != INADDR_NONE
)
206 else /* if it fails, do a gethostbyname() */
208 struct hostent
*host
;
209 if ((host
= gethostbyname(addr_str
)) == NULL
)
214 strcpy(errstr
, "HOST_NOT_FOUND");
218 strcpy(errstr
, "NO_ADDRESS");
222 strcpy(errstr
, "NO_RECOVERY");
226 strcpy(errstr
, "TRY_AGAIN");
230 debug(DEBUG_ERROR
, "gethostbyname failed for %s: ", addr_str
, errstr
);
235 memcpy(dest
, host
->h_addr_list
[0], sizeof(unsigned long));
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" );
253 *ip
= ntohl( addr
.sin_addr
.s_addr
);
254 *port
= ntohs( addr
.sin_port
);