source: abuse/tags/pd/macabuse/imlib/port/dos4gw/bwtcp.c

Last change on this file was 49, checked in by Sam Hocevar, 11 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 8.4 KB
Line 
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
16static rminfo rm;
17
18void set_sock_err(int x);
19int net_ok=0;
20ushort low_sock_mem_seg,low_sock_mem_off;
21uchar *low_sock_mem;
22
23
24int bwt_socket();
25void bwt_close(int fd);
26
27
28int bwt_ioctl_read(int fd);
29int 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
68int 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
106int 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
131void bwt_uninit()
132{
133  free_low_memory(low_sock_mem);
134}
135
136
137
138int 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
159int 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
181int 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
191int 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
204int 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
236bwt_out_socket::bwt_out_socket()
237{
238  pk_buffer_last=pk_buffer_ro=0;
239  fd=bwt_socket();
240}
241
242
243int 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
252int 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
299static 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
306static int bwt_listen(int fd)
307{
308  low_sock_mem[0] = 2;
309  return bwt_ioctl_write(fd, 1);
310}
311
312bwt_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
324static 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
336out_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
366void 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
374bwt_out_socket::~bwt_out_socket()
375{
376  bwt_close(fd);
377}
378
379bwt_in_socket::~bwt_in_socket()
380{
381  for (int i=0;i<5;i++)
382    delete listeners[i];
383}
384
385
386
387void 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
394int 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
443int 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}
Note: See TracBrowser for help on using the repository browser.