Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <windows.h>
2
#include <ws2tcpip.h>
3
#include "u.h"
4
#include "lib.h"
5
#include "dat.h"
6
#include "fns.h"
7
#include "error.h"
8
#include "ip.h"
9
 
10
#include "devip.h"
11
 
12
#ifdef MSVC
13
#pragma comment(lib, "wsock32.lib")
14
#endif
15
 
16
#undef listen
17
#undef accept
18
#undef bind
19
 
20
static int
21
family(unsigned char *addr)
22
{
23
	if(isv4(addr))
24
		return AF_INET;
25
	return AF_INET6;
26
}
27
 
28
static int
29
addrlen(struct sockaddr_storage *ss)
30
{
31
	switch(ss->ss_family){
32
	case AF_INET:
33
		return sizeof(struct sockaddr_in);
34
	case AF_INET6:
35
		return sizeof(struct sockaddr_in6);
36
	}
37
	return 0;
38
}
39
 
40
void
41
osipinit(void)
42
{
43
	WSADATA wasdat;
44
	char buf[1024];
45
 
46
	if(WSAStartup(MAKEWORD(1, 1), &wasdat) != 0)
47
		panic("no winsock.dll");
48
 
49
	gethostname(buf, sizeof(buf));
50
	kstrdup(&sysname, buf);
51
}
52
 
53
int
54
so_socket(int type, unsigned char *addr)
55
{
56
	int fd, one;
57
 
58
	switch(type) {
59
	default:
60
		error("bad protocol type");
61
	case S_TCP:
62
		type = SOCK_STREAM;
63
		break;
64
	case S_UDP:
65
		type = SOCK_DGRAM;
66
		break;
67
	}
68
 
69
	fd = socket(family(addr), type, 0);
70
	if(fd < 0)
71
		oserror();
72
 
73
	one = 1;
74
	if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0){
75
		oserrstr();
76
		print("setsockopt: %s\n", up->errstr);
77
	}
78
 
79
	return fd;
80
}
81
 
82
 
83
void
84
so_connect(int fd, unsigned char *raddr, unsigned short rport)
85
{
86
	struct sockaddr_storage ss;
87
 
88
	memset(&ss, 0, sizeof(ss));
89
 
90
	ss.ss_family = family(raddr);
91
 
92
	switch(ss.ss_family){
93
	case AF_INET:
94
		hnputs(&((struct sockaddr_in*)&ss)->sin_port, rport);
95
		v6tov4((unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr, raddr);
96
		break;
97
	case AF_INET6:
98
		hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, rport);
99
		memcpy(&((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, raddr, sizeof(struct in6_addr));
100
		break;
101
	}
102
 
103
	if(connect(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0)
104
		oserror();
105
}
106
 
107
void
108
so_getsockname(int fd, unsigned char *laddr, unsigned short *lport)
109
{
110
	int len;
111
	struct sockaddr_storage ss;
112
 
113
	len = sizeof(ss);
114
	if(getsockname(fd, (struct sockaddr*)&ss, &len) < 0)
115
		oserror();
116
 
117
	switch(ss.ss_family){
118
	case AF_INET:
119
		v4tov6(laddr, (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr);
120
		*lport = nhgets(&((struct sockaddr_in*)&ss)->sin_port);
121
		break;
122
	case AF_INET6:
123
		memcpy(laddr, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, sizeof(struct in6_addr));
124
		*lport = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port);
125
		break;
126
	default:
127
		error("not AF_INET or AF_INET6");
128
	}
129
}
130
 
131
void
132
so_listen(int fd)
133
{
134
	if(listen(fd, 5) < 0)
135
		oserror();
136
}
137
 
138
int
139
so_accept(int fd, unsigned char *raddr, unsigned short *rport)
140
{
141
	int nfd;
142
	int len;
143
	struct sockaddr_storage ss;
144
 
145
	len = sizeof(ss);
146
	nfd = accept(fd, (struct sockaddr*)&ss, &len);
147
	if(nfd < 0)
148
		oserror();
149
 
150
	switch(ss.ss_family){
151
	case AF_INET:
152
		v4tov6(raddr, (unsigned char*)&((struct sockaddr_in*)&ss)->sin_addr.s_addr);
153
		*rport = nhgets(&((struct sockaddr_in*)&ss)->sin_port);
154
		break;
155
	case AF_INET6:
156
		memcpy(raddr, &((struct sockaddr_in6*)&ss)->sin6_addr.s6_addr, sizeof(struct in6_addr));
157
		*rport = nhgets(&((struct sockaddr_in6*)&ss)->sin6_port);
158
		break;
159
	default:
160
		error("not AF_INET or AF_INET6");
161
	}
162
	return nfd;
163
}
164
 
165
void
166
so_bind(int fd, int su, unsigned short port, unsigned char *addr)
167
{
168
	int i, one;
169
	struct sockaddr_storage ss;
170
 
171
	one = 1;
172
	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){
173
		oserrstr();
174
		print("setsockopt: %r");
175
	}
176
 
177
	if(su) {
178
		for(i = 600; i < 1024; i++) {
179
			memset(&ss, 0, sizeof(ss));
180
			ss.ss_family = family(addr);
181
 
182
			switch(ss.ss_family){
183
			case AF_INET:
184
				((struct sockaddr_in*)&ss)->sin_port = i;
185
				break;
186
			case AF_INET6:
187
				((struct sockaddr_in6*)&ss)->sin6_port = i;
188
				break;
189
			}
190
 
191
			if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) >= 0)	
192
				return;
193
		}
194
		oserror();
195
	}
196
 
197
	memset(&ss, 0, sizeof(ss));
198
	ss.ss_family = family(addr);
199
 
200
	switch(ss.ss_family){
201
	case AF_INET:
202
		hnputs(&((struct sockaddr_in*)&ss)->sin_port, port);
203
		break;
204
	case AF_INET6:
205
		hnputs(&((struct sockaddr_in6*)&ss)->sin6_port, port);
206
		break;
207
	}
208
 
209
	if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0)
210
		oserror();
211
}
212
 
213
int
214
so_gethostbyname(char *host, char**hostv, int n)
215
{
216
	int i;
217
	char buf[32];
218
	unsigned char *p;
219
	struct hostent *hp;
220
 
221
	hp = gethostbyname(host);
222
	if(hp == 0)
223
		return 0;
224
 
225
	for(i = 0; hp->h_addr_list[i] && i < n; i++) {
226
		p = (unsigned char*)hp->h_addr_list[i];
227
		sprint(buf, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
228
		hostv[i] = strdup(buf);
229
		if(hostv[i] == 0)
230
			break;
231
	}
232
	return i;
233
}
234
 
235
char*
236
hostlookup(char *host)
237
{
238
	char buf[100];
239
	uchar *p;
240
	struct hostent *he;
241
 
242
	he = gethostbyname(host);
243
	if(he != 0 && he->h_addr_list[0]) {
244
		p = (uchar*)he->h_addr_list[0];
245
		sprint(buf, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3]);
246
	} else
247
		strcpy(buf, host);
248
 
249
	return strdup(buf);
250
}
251
 
252
int
253
so_getservbyname(char *service, char *net, char *port)
254
{
255
	struct servent *s;
256
 
257
	s = getservbyname(service, net);
258
	if(s == 0)
259
		return -1;
260
 
261
	sprint(port, "%d", nhgets(&s->s_port));
262
	return 0;
263
}
264
 
265
int
266
so_send(int fd, void *d, int n, int f)
267
{
268
	return send(fd, d, n, f);
269
}
270
 
271
int
272
so_recv(int fd, void *d, int n, int f)
273
{
274
	return recv(fd, d, n, f);
275
}