xref: /plan9-contrib/sys/src/cmd/unix/drawterm/kern/devip-win32.c (revision 8ccd4a6360d974db7bd7bbd4f37e7018419ea908)
1*8ccd4a63SDavid du Colombier #include <windows.h>
2*8ccd4a63SDavid du Colombier #include "u.h"
3*8ccd4a63SDavid du Colombier #include "lib.h"
4*8ccd4a63SDavid du Colombier #include "dat.h"
5*8ccd4a63SDavid du Colombier #include "fns.h"
6*8ccd4a63SDavid du Colombier #include "error.h"
7*8ccd4a63SDavid du Colombier 
8*8ccd4a63SDavid du Colombier #include "devip.h"
9*8ccd4a63SDavid du Colombier 
10*8ccd4a63SDavid du Colombier #ifdef MSVC
11*8ccd4a63SDavid du Colombier #pragma comment(lib, "wsock32.lib")
12*8ccd4a63SDavid du Colombier #endif
13*8ccd4a63SDavid du Colombier 
14*8ccd4a63SDavid du Colombier #undef listen
15*8ccd4a63SDavid du Colombier #undef accept
16*8ccd4a63SDavid du Colombier #undef bind
17*8ccd4a63SDavid du Colombier 
18*8ccd4a63SDavid du Colombier void
19*8ccd4a63SDavid du Colombier osipinit(void)
20*8ccd4a63SDavid du Colombier {
21*8ccd4a63SDavid du Colombier 	WSADATA wasdat;
22*8ccd4a63SDavid du Colombier 	char buf[1024];
23*8ccd4a63SDavid du Colombier 
24*8ccd4a63SDavid du Colombier 	if(WSAStartup(MAKEWORD(1, 1), &wasdat) != 0)
25*8ccd4a63SDavid du Colombier 		panic("no winsock.dll");
26*8ccd4a63SDavid du Colombier 
27*8ccd4a63SDavid du Colombier 	gethostname(buf, sizeof(buf));
28*8ccd4a63SDavid du Colombier 	kstrdup(&sysname, buf);
29*8ccd4a63SDavid du Colombier }
30*8ccd4a63SDavid du Colombier 
31*8ccd4a63SDavid du Colombier int
32*8ccd4a63SDavid du Colombier so_socket(int type)
33*8ccd4a63SDavid du Colombier {
34*8ccd4a63SDavid du Colombier 	int fd, one;
35*8ccd4a63SDavid du Colombier 
36*8ccd4a63SDavid du Colombier 	switch(type) {
37*8ccd4a63SDavid du Colombier 	default:
38*8ccd4a63SDavid du Colombier 		error("bad protocol type");
39*8ccd4a63SDavid du Colombier 	case S_TCP:
40*8ccd4a63SDavid du Colombier 		type = SOCK_STREAM;
41*8ccd4a63SDavid du Colombier 		break;
42*8ccd4a63SDavid du Colombier 	case S_UDP:
43*8ccd4a63SDavid du Colombier 		type = SOCK_DGRAM;
44*8ccd4a63SDavid du Colombier 		break;
45*8ccd4a63SDavid du Colombier 	}
46*8ccd4a63SDavid du Colombier 
47*8ccd4a63SDavid du Colombier 	fd = socket(AF_INET, type, 0);
48*8ccd4a63SDavid du Colombier 	if(fd < 0)
49*8ccd4a63SDavid du Colombier 		oserror();
50*8ccd4a63SDavid du Colombier 
51*8ccd4a63SDavid du Colombier 	one = 1;
52*8ccd4a63SDavid du Colombier 	if(setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char*)&one, sizeof(one)) > 0){
53*8ccd4a63SDavid du Colombier 		oserrstr();
54*8ccd4a63SDavid du Colombier 		print("setsockopt: %s\n", up->errstr);
55*8ccd4a63SDavid du Colombier 	}
56*8ccd4a63SDavid du Colombier 
57*8ccd4a63SDavid du Colombier 	return fd;
58*8ccd4a63SDavid du Colombier }
59*8ccd4a63SDavid du Colombier 
60*8ccd4a63SDavid du Colombier 
61*8ccd4a63SDavid du Colombier void
62*8ccd4a63SDavid du Colombier so_connect(int fd, unsigned long raddr, unsigned short rport)
63*8ccd4a63SDavid du Colombier {
64*8ccd4a63SDavid du Colombier 	struct sockaddr_in sin;
65*8ccd4a63SDavid du Colombier 
66*8ccd4a63SDavid du Colombier 	memset(&sin, 0, sizeof(sin));
67*8ccd4a63SDavid du Colombier 	sin.sin_family = AF_INET;
68*8ccd4a63SDavid du Colombier 	hnputs(&sin.sin_port, rport);
69*8ccd4a63SDavid du Colombier 	hnputl(&sin.sin_addr.s_addr, raddr);
70*8ccd4a63SDavid du Colombier 
71*8ccd4a63SDavid du Colombier 	if(connect(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
72*8ccd4a63SDavid du Colombier 		oserror();
73*8ccd4a63SDavid du Colombier }
74*8ccd4a63SDavid du Colombier 
75*8ccd4a63SDavid du Colombier void
76*8ccd4a63SDavid du Colombier so_getsockname(int fd, unsigned long *laddr, unsigned short *lport)
77*8ccd4a63SDavid du Colombier {
78*8ccd4a63SDavid du Colombier 	int len;
79*8ccd4a63SDavid du Colombier 	struct sockaddr_in sin;
80*8ccd4a63SDavid du Colombier 
81*8ccd4a63SDavid du Colombier 	len = sizeof(sin);
82*8ccd4a63SDavid du Colombier 	if(getsockname(fd, (struct sockaddr*)&sin, &len) < 0)
83*8ccd4a63SDavid du Colombier 		oserror();
84*8ccd4a63SDavid du Colombier 
85*8ccd4a63SDavid du Colombier 	if(sin.sin_family != AF_INET || len != sizeof(sin))
86*8ccd4a63SDavid du Colombier 		error("not AF_INET");
87*8ccd4a63SDavid du Colombier 
88*8ccd4a63SDavid du Colombier 	*laddr = nhgetl(&sin.sin_addr.s_addr);
89*8ccd4a63SDavid du Colombier 	*lport = nhgets(&sin.sin_port);
90*8ccd4a63SDavid du Colombier }
91*8ccd4a63SDavid du Colombier 
92*8ccd4a63SDavid du Colombier void
93*8ccd4a63SDavid du Colombier so_listen(int fd)
94*8ccd4a63SDavid du Colombier {
95*8ccd4a63SDavid du Colombier 	if(listen(fd, 5) < 0)
96*8ccd4a63SDavid du Colombier 		oserror();
97*8ccd4a63SDavid du Colombier }
98*8ccd4a63SDavid du Colombier 
99*8ccd4a63SDavid du Colombier int
100*8ccd4a63SDavid du Colombier so_accept(int fd, unsigned long *raddr, unsigned short *rport)
101*8ccd4a63SDavid du Colombier {
102*8ccd4a63SDavid du Colombier 	int nfd, len;
103*8ccd4a63SDavid du Colombier 	struct sockaddr_in sin;
104*8ccd4a63SDavid du Colombier 
105*8ccd4a63SDavid du Colombier 	len = sizeof(sin);
106*8ccd4a63SDavid du Colombier 	nfd = accept(fd, (struct sockaddr*)&sin, &len);
107*8ccd4a63SDavid du Colombier 	if(nfd < 0)
108*8ccd4a63SDavid du Colombier 		oserror();
109*8ccd4a63SDavid du Colombier 
110*8ccd4a63SDavid du Colombier 	if(sin.sin_family != AF_INET || len != sizeof(sin))
111*8ccd4a63SDavid du Colombier 		error("not AF_INET");
112*8ccd4a63SDavid du Colombier 
113*8ccd4a63SDavid du Colombier 	*raddr = nhgetl(&sin.sin_addr.s_addr);
114*8ccd4a63SDavid du Colombier 	*rport = nhgets(&sin.sin_port);
115*8ccd4a63SDavid du Colombier 	return nfd;
116*8ccd4a63SDavid du Colombier }
117*8ccd4a63SDavid du Colombier 
118*8ccd4a63SDavid du Colombier void
119*8ccd4a63SDavid du Colombier so_bind(int fd, int su, unsigned short port)
120*8ccd4a63SDavid du Colombier {
121*8ccd4a63SDavid du Colombier 	int i, one;
122*8ccd4a63SDavid du Colombier 	struct sockaddr_in sin;
123*8ccd4a63SDavid du Colombier 
124*8ccd4a63SDavid du Colombier 	one = 1;
125*8ccd4a63SDavid du Colombier 	if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&one, sizeof(one)) < 0){
126*8ccd4a63SDavid du Colombier 		oserrstr();
127*8ccd4a63SDavid du Colombier 		print("setsockopt: %s", up->errstr);
128*8ccd4a63SDavid du Colombier 	}
129*8ccd4a63SDavid du Colombier 
130*8ccd4a63SDavid du Colombier 	if(su) {
131*8ccd4a63SDavid du Colombier 		for(i = 600; i < 1024; i++) {
132*8ccd4a63SDavid du Colombier 			memset(&sin, 0, sizeof(sin));
133*8ccd4a63SDavid du Colombier 			sin.sin_family = AF_INET;
134*8ccd4a63SDavid du Colombier 			sin.sin_port = i;
135*8ccd4a63SDavid du Colombier 
136*8ccd4a63SDavid du Colombier 			if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) >= 0)
137*8ccd4a63SDavid du Colombier 				return;
138*8ccd4a63SDavid du Colombier 		}
139*8ccd4a63SDavid du Colombier 		oserror();
140*8ccd4a63SDavid du Colombier 	}
141*8ccd4a63SDavid du Colombier 
142*8ccd4a63SDavid du Colombier 	memset(&sin, 0, sizeof(sin));
143*8ccd4a63SDavid du Colombier 	sin.sin_family = AF_INET;
144*8ccd4a63SDavid du Colombier 	hnputs(&sin.sin_port, port);
145*8ccd4a63SDavid du Colombier 
146*8ccd4a63SDavid du Colombier 	if(bind(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0)
147*8ccd4a63SDavid du Colombier 		oserror();
148*8ccd4a63SDavid du Colombier }
149*8ccd4a63SDavid du Colombier 
150*8ccd4a63SDavid du Colombier int
151*8ccd4a63SDavid du Colombier so_gethostbyname(char *host, char**hostv, int n)
152*8ccd4a63SDavid du Colombier {
153*8ccd4a63SDavid du Colombier 	int i;
154*8ccd4a63SDavid du Colombier 	char buf[32];
155*8ccd4a63SDavid du Colombier 	unsigned char *p;
156*8ccd4a63SDavid du Colombier 	struct hostent *hp;
157*8ccd4a63SDavid du Colombier 
158*8ccd4a63SDavid du Colombier 	hp = gethostbyname(host);
159*8ccd4a63SDavid du Colombier 	if(hp == 0)
160*8ccd4a63SDavid du Colombier 		return 0;
161*8ccd4a63SDavid du Colombier 
162*8ccd4a63SDavid du Colombier 	for(i = 0; hp->h_addr_list[i] && i < n; i++) {
163*8ccd4a63SDavid du Colombier 		p = (unsigned char*)hp->h_addr_list[i];
164*8ccd4a63SDavid du Colombier 		sprint(buf, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
165*8ccd4a63SDavid du Colombier 		hostv[i] = strdup(buf);
166*8ccd4a63SDavid du Colombier 		if(hostv[i] == 0)
167*8ccd4a63SDavid du Colombier 			break;
168*8ccd4a63SDavid du Colombier 	}
169*8ccd4a63SDavid du Colombier 	return i;
170*8ccd4a63SDavid du Colombier }
171*8ccd4a63SDavid du Colombier 
172*8ccd4a63SDavid du Colombier char*
173*8ccd4a63SDavid du Colombier hostlookup(char *host)
174*8ccd4a63SDavid du Colombier {
175*8ccd4a63SDavid du Colombier 	char buf[100];
176*8ccd4a63SDavid du Colombier 	uchar *p;
177*8ccd4a63SDavid du Colombier 	HOSTENT *he;
178*8ccd4a63SDavid du Colombier 
179*8ccd4a63SDavid du Colombier 	he = gethostbyname(host);
180*8ccd4a63SDavid du Colombier 	if(he != 0 && he->h_addr_list[0]) {
181*8ccd4a63SDavid du Colombier 		p = he->h_addr_list[0];
182*8ccd4a63SDavid du Colombier 		sprint(buf, "%ud.%ud.%ud.%ud", p[0], p[1], p[2], p[3]);
183*8ccd4a63SDavid du Colombier 	} else
184*8ccd4a63SDavid du Colombier 		strcpy(buf, host);
185*8ccd4a63SDavid du Colombier 
186*8ccd4a63SDavid du Colombier 	return strdup(buf);
187*8ccd4a63SDavid du Colombier }
188*8ccd4a63SDavid du Colombier 
189*8ccd4a63SDavid du Colombier int
190*8ccd4a63SDavid du Colombier so_getservbyname(char *service, char *net, char *port)
191*8ccd4a63SDavid du Colombier {
192*8ccd4a63SDavid du Colombier 	struct servent *s;
193*8ccd4a63SDavid du Colombier 
194*8ccd4a63SDavid du Colombier 	s = getservbyname(service, net);
195*8ccd4a63SDavid du Colombier 	if(s == 0)
196*8ccd4a63SDavid du Colombier 		return -1;
197*8ccd4a63SDavid du Colombier 
198*8ccd4a63SDavid du Colombier 	sprint(port, "%d", nhgets(&s->s_port));
199*8ccd4a63SDavid du Colombier 	return 0;
200*8ccd4a63SDavid du Colombier }
201*8ccd4a63SDavid du Colombier 
202*8ccd4a63SDavid du Colombier int
203*8ccd4a63SDavid du Colombier so_send(int fd, void *d, int n, int f)
204*8ccd4a63SDavid du Colombier {
205*8ccd4a63SDavid du Colombier 	return send(fd, d, n, f);
206*8ccd4a63SDavid du Colombier }
207*8ccd4a63SDavid du Colombier 
208*8ccd4a63SDavid du Colombier int
209*8ccd4a63SDavid du Colombier so_recv(int fd, void *d, int n, int f)
210*8ccd4a63SDavid du Colombier {
211*8ccd4a63SDavid du Colombier 	return recv(fd, d, n, f);
212*8ccd4a63SDavid du Colombier }
213