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