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