1 | #include "jnet.hpp" |
---|
2 | #include "macs.hpp" |
---|
3 | #include "dprint.hpp" |
---|
4 | #include "system.h" |
---|
5 | #include <i86.h> |
---|
6 | #include <sys/types.h> |
---|
7 | #include <fcntl.h> |
---|
8 | #include <unistd.h> |
---|
9 | #include <stdlib.h> |
---|
10 | #include <string.h> |
---|
11 | #include <dos.h> |
---|
12 | #include "jmalloc.hpp" |
---|
13 | #include "doscall.hpp" |
---|
14 | #include "bwtcp.hpp" |
---|
15 | |
---|
16 | static rminfo rm; |
---|
17 | |
---|
18 | void set_sock_err(int x); |
---|
19 | int net_ok=0; |
---|
20 | ushort low_sock_mem_seg,low_sock_mem_off; |
---|
21 | uchar *low_sock_mem; |
---|
22 | |
---|
23 | |
---|
24 | int bwt_socket(); |
---|
25 | void bwt_close(int fd); |
---|
26 | |
---|
27 | |
---|
28 | int bwt_ioctl_read(int fd); |
---|
29 | int bwt_read(int fd, uchar *buffer, long size) |
---|
30 | { |
---|
31 | memset(&rm,0,sizeof(rm)); |
---|
32 | int t=0; // counter for bytes read |
---|
33 | int breakup; // set if low buffer is not big enought o read everything |
---|
34 | do |
---|
35 | { |
---|
36 | rm.eax = 0x3f00; |
---|
37 | rm.ebx = fd; |
---|
38 | int rs; |
---|
39 | if (size>1024) |
---|
40 | { |
---|
41 | rs=1024; |
---|
42 | breakup=1; |
---|
43 | } else |
---|
44 | { |
---|
45 | rs=size; |
---|
46 | breakup=0; |
---|
47 | } |
---|
48 | |
---|
49 | rm.ecx=rs; |
---|
50 | rm.edx=low_sock_mem_off; |
---|
51 | rm.ds=low_sock_mem_seg; |
---|
52 | RM_intr(0x21,&rm); |
---|
53 | |
---|
54 | if (rm.flags & 1) |
---|
55 | { |
---|
56 | printf("socket : read error\n"); |
---|
57 | } |
---|
58 | int ret=rm.eax&0xffff; |
---|
59 | t+=ret; |
---|
60 | memcpy(buffer,low_sock_mem,ret); |
---|
61 | if (ret!=rs) return t; |
---|
62 | size-=ret; |
---|
63 | buffer+=ret; |
---|
64 | } while (breakup && size); |
---|
65 | return t; |
---|
66 | } |
---|
67 | |
---|
68 | int bwt_write(int fd, uchar *buffer, long size) |
---|
69 | { |
---|
70 | memset(&rm,0,sizeof(rm)); |
---|
71 | int t=0,breakup; |
---|
72 | do |
---|
73 | { |
---|
74 | rm.eax = 0x4000; |
---|
75 | rm.ebx = fd; |
---|
76 | int rs; |
---|
77 | if (size>1024) |
---|
78 | { |
---|
79 | rs=1024; |
---|
80 | breakup=1; |
---|
81 | } else |
---|
82 | { |
---|
83 | rs=size; |
---|
84 | breakup=0; |
---|
85 | } |
---|
86 | |
---|
87 | rm.ecx=rs; |
---|
88 | rm.edx=low_sock_mem_off; |
---|
89 | rm.ds=low_sock_mem_seg; |
---|
90 | memcpy(low_sock_mem,buffer,rs); |
---|
91 | RM_intr(0x21,&rm); |
---|
92 | if (rm.flags & 1) |
---|
93 | { |
---|
94 | printf("socket : write error\n"); |
---|
95 | } |
---|
96 | int ret=rm.eax&0xffff; |
---|
97 | t+=ret; |
---|
98 | if (ret!=rs) return t; |
---|
99 | size-=ret; |
---|
100 | buffer+=ret; |
---|
101 | } while (breakup && size); |
---|
102 | return t; |
---|
103 | } |
---|
104 | |
---|
105 | |
---|
106 | int bwt_init() |
---|
107 | { |
---|
108 | low_sock_mem=(uchar *)alloc_low_memory(3520); |
---|
109 | if (!low_sock_mem) |
---|
110 | { |
---|
111 | printf("failed to allocate memory for network driver\n"); |
---|
112 | exit(0); |
---|
113 | } |
---|
114 | low_sock_mem_seg=((long)low_sock_mem)>>4; |
---|
115 | low_sock_mem_off=((long)low_sock_mem)&0x0f; |
---|
116 | |
---|
117 | int fd=bwt_socket(); // test to see if we can open a socket |
---|
118 | |
---|
119 | if (current_sock_err || fd==-1) |
---|
120 | { |
---|
121 | free_low_memory(low_sock_mem); |
---|
122 | return 0; |
---|
123 | } else |
---|
124 | { |
---|
125 | bwt_close(fd); |
---|
126 | return 1; |
---|
127 | } |
---|
128 | return 0; |
---|
129 | } |
---|
130 | |
---|
131 | void bwt_uninit() |
---|
132 | { |
---|
133 | free_low_memory(low_sock_mem); |
---|
134 | } |
---|
135 | |
---|
136 | |
---|
137 | |
---|
138 | int bwt_ioctl_write(int fd, int size) |
---|
139 | { |
---|
140 | memset(&rm,0,sizeof(rm)); |
---|
141 | rm.eax = 0x4403; |
---|
142 | rm.ebx = fd; |
---|
143 | rm.ecx = size; |
---|
144 | rm.edx = low_sock_mem_off; |
---|
145 | rm.ds = low_sock_mem_seg; |
---|
146 | |
---|
147 | |
---|
148 | RM_intr(0x21,&rm); |
---|
149 | if (rm.flags & 1) |
---|
150 | { |
---|
151 | current_sock_err=SOCK_WRITE_FAIL; |
---|
152 | sprintf(last_sock_err,"Error writing ioctl command\n"); |
---|
153 | return -1; |
---|
154 | } |
---|
155 | return 0; |
---|
156 | } |
---|
157 | |
---|
158 | |
---|
159 | int bwt_ioctl_read(int fd) |
---|
160 | { |
---|
161 | memset(&rm,0,sizeof(rm)); |
---|
162 | rm.eax = 0x4402; |
---|
163 | rm.ebx = fd; |
---|
164 | rm.ecx = 21; |
---|
165 | rm.edx = low_sock_mem_off; |
---|
166 | rm.ds = low_sock_mem_seg; |
---|
167 | |
---|
168 | |
---|
169 | |
---|
170 | RM_intr(0x21,&rm); |
---|
171 | |
---|
172 | if (rm.flags & 1) |
---|
173 | { |
---|
174 | current_sock_err=SOCK_WRITE_FAIL; |
---|
175 | sprintf(last_sock_err,"Error reading ioctl status, flags=%d\n",rm.flags); |
---|
176 | return -1; |
---|
177 | } |
---|
178 | return 0; |
---|
179 | } |
---|
180 | |
---|
181 | int bwt_out_socket::ready_to_write() |
---|
182 | { |
---|
183 | memset(&rm,0,sizeof(rm)); |
---|
184 | rm.eax=0x4407; |
---|
185 | rm.ebx=fd; |
---|
186 | RM_intr(0x21,&rm); |
---|
187 | return (rm.eax&0xff)==0xff; |
---|
188 | } |
---|
189 | |
---|
190 | |
---|
191 | int bwt_out_socket::ready_to_read() |
---|
192 | { |
---|
193 | if (pk_buffer_last>pk_buffer_ro) return 1; |
---|
194 | memset(&rm,0,sizeof(rm)); |
---|
195 | rm.eax=0x4406; |
---|
196 | rm.ebx=fd; |
---|
197 | RM_intr(0x21,&rm); |
---|
198 | return (rm.eax&0xff)==0xff; |
---|
199 | // bwt_ioctl_read(fd); |
---|
200 | // return *((ushort *)(low_sock_mem+9)); |
---|
201 | } |
---|
202 | |
---|
203 | |
---|
204 | int bwt_socket() |
---|
205 | { |
---|
206 | memset(&rm,0,sizeof(rm)); |
---|
207 | |
---|
208 | strcpy((char *)low_sock_mem, "TCP-IP10"); |
---|
209 | rm.eax = 0x3d42; |
---|
210 | rm.ds = low_sock_mem_seg; |
---|
211 | rm.edx = low_sock_mem_off; |
---|
212 | RM_intr(0x21,&rm); |
---|
213 | if (rm.flags & 1) |
---|
214 | { |
---|
215 | current_sock_err=SOCK_CREATE_FAIL; |
---|
216 | sprintf(last_sock_err,"Unable to create socket"); |
---|
217 | return -1; |
---|
218 | } |
---|
219 | int fd = (rm.eax&0xffff); |
---|
220 | |
---|
221 | |
---|
222 | rm.eax=0x4401; |
---|
223 | rm.edx=0x60; |
---|
224 | rm.ebx=fd; |
---|
225 | RM_intr(0x21,&rm); |
---|
226 | |
---|
227 | |
---|
228 | // internal layer must be told to reclaim internal buffers |
---|
229 | low_sock_mem[0]=6; |
---|
230 | low_sock_mem[1]=0x80; |
---|
231 | bwt_ioctl_write(fd, 2); |
---|
232 | return fd; |
---|
233 | |
---|
234 | } |
---|
235 | |
---|
236 | bwt_out_socket::bwt_out_socket() |
---|
237 | { |
---|
238 | pk_buffer_last=pk_buffer_ro=0; |
---|
239 | fd=bwt_socket(); |
---|
240 | } |
---|
241 | |
---|
242 | |
---|
243 | int bwt_get_my_ip() |
---|
244 | { |
---|
245 | int s; |
---|
246 | s = bwt_socket(); |
---|
247 | if (bwt_ioctl_read(s)) return 0; |
---|
248 | close(s); |
---|
249 | return *(int*)(&low_sock_mem[3]); |
---|
250 | } |
---|
251 | |
---|
252 | int bwt_out_socket::try_connect(char *rhost, int port) |
---|
253 | { |
---|
254 | int ip[4]; |
---|
255 | if (sscanf(rhost, "%d.%d.%d.%d", ip, ip+1, ip+2, ip+3) != 4) |
---|
256 | { |
---|
257 | set_sock_err(SOCK_NAMELOOKUP_FAIL); |
---|
258 | sprintf(last_sock_err,"Connect failed, bad ip address '%s'",rhost); |
---|
259 | return 0; |
---|
260 | } else |
---|
261 | { |
---|
262 | low_sock_mem[0]=6; |
---|
263 | low_sock_mem[1]=0x10; |
---|
264 | bwt_ioctl_write(fd, 2); |
---|
265 | |
---|
266 | low_sock_mem[0]=1; |
---|
267 | ulong mip=(ip[0]<<24)+(ip[1]<<16)+(ip[2]<<8)+(ip[3]); |
---|
268 | ulong net_order_ip=long_swap(mip); |
---|
269 | memcpy(low_sock_mem+1,&net_order_ip,4); |
---|
270 | |
---|
271 | ushort host_order_port=port; |
---|
272 | memcpy(&low_sock_mem[5],&host_order_port,2); |
---|
273 | |
---|
274 | bwt_ioctl_write(fd, 7); |
---|
275 | int last_stat=-1; |
---|
276 | low_sock_mem[0]=1; |
---|
277 | low_sock_mem[7]=0; |
---|
278 | do |
---|
279 | { |
---|
280 | bwt_ioctl_read(fd); |
---|
281 | if (low_sock_mem[0]==0 || low_sock_mem[0]==8) |
---|
282 | { |
---|
283 | current_sock_err=SOCK_CONNECT_FAIL; |
---|
284 | sprintf(last_sock_err,"Connect to %s failed",rhost); |
---|
285 | return 0; |
---|
286 | } else if (low_sock_mem[7]==5) |
---|
287 | { |
---|
288 | current_sock_err=SOCK_CONNECT_FAIL; |
---|
289 | sprintf(last_sock_err,"Connect to %s refused",rhost); |
---|
290 | return 0; |
---|
291 | } |
---|
292 | } while (low_sock_mem[0]!=4); |
---|
293 | } |
---|
294 | return 1; |
---|
295 | } |
---|
296 | |
---|
297 | |
---|
298 | |
---|
299 | static int bwt_bind(int fd, ushort port) |
---|
300 | { |
---|
301 | low_sock_mem[0] = 0; |
---|
302 | memcpy(low_sock_mem+1, &port, 2); |
---|
303 | return bwt_ioctl_write(fd, 3); |
---|
304 | } |
---|
305 | |
---|
306 | static int bwt_listen(int fd) |
---|
307 | { |
---|
308 | low_sock_mem[0] = 2; |
---|
309 | return bwt_ioctl_write(fd, 1); |
---|
310 | } |
---|
311 | |
---|
312 | bwt_in_socket::bwt_in_socket(int Port) |
---|
313 | { |
---|
314 | port=Port; |
---|
315 | for (int i=0;i<5;i++) |
---|
316 | { |
---|
317 | listeners[i]=new bwt_out_socket(bwt_socket()); |
---|
318 | bwt_bind(listeners[i]->get_fd(),port); |
---|
319 | bwt_listen(listeners[i]->get_fd()); |
---|
320 | } |
---|
321 | } |
---|
322 | |
---|
323 | |
---|
324 | static int bwt_accept(int fd, ulong &ip, ulong &port) |
---|
325 | { |
---|
326 | bwt_ioctl_read(fd); |
---|
327 | if (low_sock_mem[0] < 4) return -1; |
---|
328 | ip=big_long_to_local(*(int*)(&low_sock_mem[11])); |
---|
329 | port=(int)*(short*)(&low_sock_mem[15]); |
---|
330 | low_sock_mem[0]=6; |
---|
331 | low_sock_mem[1]=4; |
---|
332 | bwt_ioctl_write(fd, 2); |
---|
333 | return 0; |
---|
334 | } |
---|
335 | |
---|
336 | out_socket *bwt_in_socket::check_for_connect() |
---|
337 | { |
---|
338 | for (int i=0;i<5;i++) |
---|
339 | { |
---|
340 | if (listeners[i]->ready_to_read()) |
---|
341 | { |
---|
342 | ulong Ip,Port; |
---|
343 | |
---|
344 | if (bwt_accept(listeners[i]->get_fd(),Ip,Port)<0) |
---|
345 | { |
---|
346 | set_sock_err(SOCK_ACCEPT_FAIL); |
---|
347 | sprintf(last_sock_err,"Accept failed!"); |
---|
348 | return NULL; |
---|
349 | } else |
---|
350 | dprintf("connection from IP %d.%d.%d.%d, on port %d\n",(Ip>>24)&0xff,(Ip>>16)&0xff, |
---|
351 | (Ip>>8)&0xff, Ip&0xff,Port); |
---|
352 | bwt_out_socket *ret=listeners[i]; |
---|
353 | |
---|
354 | int nl=bwt_socket(); |
---|
355 | listeners[i]=new bwt_out_socket(nl); |
---|
356 | bwt_bind(listeners[i]->get_fd(),port); |
---|
357 | bwt_listen(listeners[i]->get_fd()); |
---|
358 | |
---|
359 | return ret; |
---|
360 | } |
---|
361 | } |
---|
362 | return NULL; |
---|
363 | |
---|
364 | } |
---|
365 | |
---|
366 | void bwt_close(int fd) |
---|
367 | { |
---|
368 | memset(&rm,0,sizeof(rm)); |
---|
369 | rm.eax=0x3e00; |
---|
370 | rm.ebx=fd; |
---|
371 | RM_intr(0x21,&rm); |
---|
372 | } |
---|
373 | |
---|
374 | bwt_out_socket::~bwt_out_socket() |
---|
375 | { |
---|
376 | bwt_close(fd); |
---|
377 | } |
---|
378 | |
---|
379 | bwt_in_socket::~bwt_in_socket() |
---|
380 | { |
---|
381 | for (int i=0;i<5;i++) |
---|
382 | delete listeners[i]; |
---|
383 | } |
---|
384 | |
---|
385 | |
---|
386 | |
---|
387 | void bwt_out_socket::bwt_fill_buffer() |
---|
388 | { |
---|
389 | while (!ready_to_read()) ; |
---|
390 | pk_buffer_last=bwt_read(get_fd(),pk_buffer,PK_BUFFER_SIZE); |
---|
391 | pk_buffer_ro=0; |
---|
392 | } |
---|
393 | |
---|
394 | int bwt_out_socket::get(packet &pk) |
---|
395 | { |
---|
396 | pk.ro=pk.wo=2; |
---|
397 | |
---|
398 | ushort size=0; |
---|
399 | if (pk_buffer_last==pk_buffer_ro) |
---|
400 | bwt_fill_buffer(); |
---|
401 | |
---|
402 | if (pk_buffer_last-pk_buffer_ro<2) // make sure the two byte for the size are in the same packet |
---|
403 | { |
---|
404 | uchar two[2]; |
---|
405 | two[0]=pk_buffer[pk_buffer_ro]; |
---|
406 | bwt_fill_buffer(); |
---|
407 | if (pk_buffer_last-pk_buffer_ro<2) // if still not enough info, something is screwy |
---|
408 | { |
---|
409 | printf("Incomplete packet\n"); |
---|
410 | return 0; |
---|
411 | } |
---|
412 | |
---|
413 | two[1]=pk_buffer[pk_buffer_ro]; |
---|
414 | pk_buffer_ro++; |
---|
415 | size=lstl((*((ushort *)two))); |
---|
416 | } else |
---|
417 | { |
---|
418 | memcpy(&size,pk_buffer+pk_buffer_ro,2); pk_buffer_ro+=2; |
---|
419 | size=lstl(size); |
---|
420 | } |
---|
421 | pk.rend=size+2; |
---|
422 | pk.make_bigger(pk.rend); |
---|
423 | uchar *pk_off=pk.buf+2; |
---|
424 | int rs; |
---|
425 | while (size) |
---|
426 | { |
---|
427 | if (pk_buffer_last==pk_buffer_ro) |
---|
428 | bwt_fill_buffer(); |
---|
429 | if (pk_buffer_last-pk_buffer_ro>size) |
---|
430 | rs=size; |
---|
431 | else |
---|
432 | rs=pk_buffer_last-pk_buffer_ro; |
---|
433 | |
---|
434 | memcpy(pk_off,pk_buffer+pk_buffer_ro,rs); |
---|
435 | pk_buffer_ro+=rs; |
---|
436 | size-=rs; |
---|
437 | pk_off+=rs; |
---|
438 | } |
---|
439 | |
---|
440 | return 1; |
---|
441 | } |
---|
442 | |
---|
443 | int bwt_out_socket::send(packet &pk) |
---|
444 | { |
---|
445 | int ret; |
---|
446 | // pk.make_bigger(pk.wo-2+2047-((pk.wo-2)%2048)); |
---|
447 | ushort size=lstl(pk.wo-2); |
---|
448 | memcpy(pk.buf,&size,2); |
---|
449 | ret=bwt_write(fd,pk.buf,pk.wo)==pk.wo; |
---|
450 | return ret; |
---|
451 | } |
---|