1 /*
2 * Copyright (C) 2005 Roy Keene
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 */
19
20 /*
21 * Network related functions
22 */
23 #include "compat.h"
24 #include "net.h"
25
26 #ifdef HAVE_SYS_TYPES_H
27 #include <sys/types.h>
28 #endif
29 #ifdef HAVE_SYS_STAT_H
30 #include <sys/stat.h>
31 #endif
32 #include <stdarg.h>
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 #include <fcntl.h>
37
38 #ifdef HAVE_SYS_SOCKET_H
39 #include <sys/socket.h>
40 #endif
41 #ifdef HAVE_NETINET_IN_H
42 #include <netinet/in.h>
43 #endif
44 #ifdef HAVE_ARPA_INET_H
45 #include <arpa/inet.h>
46 #endif
47 #ifdef HAVE_STDLIB_H
48 #include <stdlib.h>
49 #endif
50 #ifdef HAVE_STRING_H
51 #include <string.h>
52 #endif
53 #ifdef HAVE_NETDB_H
54 #include <netdb.h>
55 #endif
56 #ifdef HAVE_ERRNO_H
57 #include <errno.h>
58 #endif
59 #ifdef HAVE_STDIO_H
60 #include <stdio.h>
61 #endif
62
63 #ifndef SHUT_RDWR
64 #define SHUT_RDWR 2
65 #endif
66
67 /* Do things required for network access. */
net_init(void)68 static int net_init(void) {
69 #ifdef _USE_WIN32_
70 static int net_init_called = 0;
71 WSADATA wsaData;
72
73 if (net_init_called) {
74 return(0);
75 }
76
77 if (WSAStartup(MAKEWORD(2, 0), &wsaData)!=0) {
78 return(-1);
79 }
80 if (wsaData.wVersion!=MAKEWORD(2, 0)) {
81 /* Cleanup Winsock stuff */
82 WSACleanup();
83 return(-1);
84 }
85
86 net_init_called = 1;
87 #endif
88 return(0);
89 }
90
91
92 /*
93 * Create a listening port on tcp port PORT
94 */
net_listen(const int port)95 int net_listen(const int port) {
96 struct sockaddr_in localname;
97 int sockFd;
98
99 net_init();
100
101 sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
102 localname.sin_family = AF_INET;
103 localname.sin_port = htons(port);
104 localname.sin_addr.s_addr = INADDR_ANY;
105
106 if (sockFd < 0) {
107 return(-1);
108 }
109
110 if (bind(sockFd, (struct sockaddr *) &localname, sizeof(localname)) < 0) {
111 return(-1);
112 }
113
114 if (listen(sockFd, 1024) < 0) {
115 return(-1);
116 }
117
118 return(sockFd);
119 }
120
121
net_connect_tcp(const char * host,const int port)122 int net_connect_tcp(const char *host, const int port) {
123 int sockid;
124 struct hostent *hostinfo;
125 struct sockaddr_in sock;
126
127 net_init();
128
129 #ifdef HAVE_INET_ATON
130 if (!inet_aton(host,&sock.sin_addr)) {
131 #else
132 #ifdef HAVE_INET_ADDR
133 if ( (sock.sin_addr.s_addr=inet_addr(host) )==-1) {
134 #else
135 {
136 #endif
137 #endif
138 if ((hostinfo=gethostbyname(host))==NULL) return(-EPERM);
139 memcpy(&sock.sin_addr.s_addr,hostinfo->h_addr_list[0],hostinfo->h_length);
140 }
141
142 sock.sin_family=AF_INET;
143 sock.sin_port=htons(port);
144 if ((sockid=socket(AF_INET, SOCK_STREAM, 0))<0) {
145 return(-EIO);
146 }
147 if (connect(sockid, (struct sockaddr *) &sock, sizeof(sock))<0) {
148 close(sockid);
149 return(-EIO);
150 }
151 return(sockid);
152 }
153
154 int net_close(const int sockid) {
155 shutdown(sockid, SHUT_RDWR);
156 return(close(sockid));
157 }
158