xref: /plan9/sys/src/cmd/unix/drawterm/kern/devip-win32.c (revision 58da3067adcdccaaa043d0bfde28ba83b7ced07d)
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
family(unsigned char * addr)21 family(unsigned char *addr)
22 {
23 	if(isv4(addr))
24 		return AF_INET;
25 	return AF_INET6;
26 }
27 
28 static int
addrlen(struct sockaddr_storage * ss)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
osipinit(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
so_socket(int type,unsigned char * addr)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
so_connect(int fd,unsigned char * raddr,unsigned short rport)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
so_getsockname(int fd,unsigned char * laddr,unsigned short * lport)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
so_listen(int fd)132 so_listen(int fd)
133 {
134 	if(listen(fd, 5) < 0)
135 		oserror();
136 }
137 
138 int
so_accept(int fd,unsigned char * raddr,unsigned short * rport)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
so_bind(int fd,int su,unsigned short port,unsigned char * addr)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
so_gethostbyname(char * host,char ** hostv,int n)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*
hostlookup(char * host)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
so_getservbyname(char * service,char * net,char * port)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
so_send(int fd,void * d,int n,int f)266 so_send(int fd, void *d, int n, int f)
267 {
268 	return send(fd, d, n, f);
269 }
270 
271 int
so_recv(int fd,void * d,int n,int f)272 so_recv(int fd, void *d, int n, int f)
273 {
274 	return recv(fd, d, n, f);
275 }
276