source: abuse/tags/pd/abuse/src/net/mac/ottcp.c @ 49

Last change on this file since 49 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: 9.4 KB
Line 
1#include "ottcp.hpp"
2#include <ctype.h>
3
4ot_tcpip_protocol ot_tcpip;
5
6/*
7FILE *log_file=NULL;
8extern int net_start();
9void net_log(char *st, void *buf, long size)
10{
11   
12  if (!log_file)
13  {
14    if (net_start())
15      log_file=fopen("client.log","wb");
16    else
17      log_file=fopen("server.log","wb");
18  }
19
20
21    fprintf(log_file,"%s%d - ",st,size);
22    int i;
23    for (i=0;i<size;i++)
24      if (isprint(*((unsigned char *)buf+i)))
25        fprintf(log_file,"%c",*((unsigned char *)buf+i));
26      else fprintf(log_file,"~");
27
28    fprintf(log_file," : ");
29
30    for (i=0;i<size;i++)
31    fprintf(log_file,"%02x, ",*((unsigned char *)buf+i),*((unsigned char *)buf+i));
32    fprintf(log_file,"\n");
33    fflush(log_file);
34
35} */
36
37pascal void ot_tcp_EventHandler(void*, OTEventCode event, OTResult result, void* cookie)
38{
39        OTEventCode tempevent = 0;
40        ot_tcp_socket *sckt = (ot_tcp_socket*)cookie;
41
42        switch(event)
43        {
44        case T_OPENCOMPLETE:
45                sckt->err = (OSStatus)result;
46                sckt->code = event;
47                break;
48        case T_DATA:
49                sckt->ready = 1;
50                break;
51        case T_BINDCOMPLETE:
52//              gBindCompleted = 1;
53                break;
54        case T_ORDREL:
55//              gCallRcvOrdDiscon = 1;
56                break;
57        default:
58                // OTDebugBreak("EventHandler got unexpected event");
59//              tempevent = event;
60                break;
61        }
62        return;
63}
64
65ot_tcp_socket::ot_tcp_socket()
66{
67        TEndpointInfo   info;
68        OSStatus err;
69
70        // create TCP endpoint structure for MAC
71        ep = OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, &info, &err);
72        if ( ep == NULL || err != kOTNoError )
73        {
74                ep = NULL;
75                fprintf(stderr,"ERROR: OpenEndpoint(\"TCP\") failed with %d\n", err);
76                return;
77        }
78
79        // required by mac?
80        err = ep->SetSynchronous();
81        if ( err != kOTNoError )
82        {
83                fprintf(stderr,"ERROR: SetSynchronous() failed with %d\n", err);
84                return;
85        }
86
87        // Install notifier of communication events
88        err = ep->InstallNotifier(ot_tcp_EventHandler, this);
89        if ( err != kOTNoError )
90        {
91                fprintf(stderr, "ERROR: InstallNotifier() failed with %d\n", err);
92                return;
93        }
94        listening = 0;
95}
96
97int ot_tcp_socket::read(void *buf, int size, net_address **addr)
98{
99  int result;
100 
101  result = ep->Rcv(buf, size, 0);
102  if (addr) *addr=NULL;
103 
104  if (result>=0)
105        return result;
106  else
107  {
108        // save error code for next select
109        return 0;
110  }
111}
112
113int ot_tcp_socket::write(void *buf, int size, net_address *addr)
114{
115  if (addr) fprintf(stderr,"Cannot change address for this socket type\n");
116 
117        result = ep->Snd(buf, len, 0);
118        if (result >= 0)
119                return result;
120        else if (result != kOTFlowErr)
121        {
122                // store error for next select
123                return 0;
124        }
125}
126
127int ot_tcp_socket::listen(int port)
128{
129  sockaddr_in host;
130  memset( (char*) &host,0, sizeof(host));
131  host.sin_family = AF_INET;
132  host.sin_port = htons(port);
133  host.sin_addr.s_addr = htonl(INADDR_ANY);
134  if (ep->Bind(ep, (struct sockaddr *) &host, sizeof(sockaddr_in))==-1)
135  {
136    fprintf(stderr,"net driver : could not bind socket to port %d\n",port);
137    return 0;
138  }
139  if (::listen(fd,5)==-1)
140  {
141    fprintf(stderr,"net driver : could not listen to socket on port %d\n",port);   
142    return 0;
143  }
144  listening=1;
145  return 1;
146}
147
148net_socket *ot_tcp_socket::accept(net_address *&addr);
149{
150  if (listening)
151  {
152    struct sockaddr_in from;
153    int addr_len=sizeof(from);
154    int new_fd=::accept(fd,(sockaddr *)&from,&addr_len);
155    if (new_fd>=0)
156    {
157                        addr=new ip_address(&from);
158                        return new tcp_socket(new_fd);
159    }
160    else
161    { addr=NULL; return 0; }
162  }
163}
164
165int ot_tcp_socket::connect(ot_ip_address addr);
166{
167        TBind ret;
168        InetAddr retsin;
169
170        ret.addr.maxlen = sizeof(struct InetAddress);
171        ret.addr.buf = (unsigned char *) &retsin;
172
173        // bind TCP to current address and port
174        err = fd->Bind(nil, &ret);
175        if ( err != kOTNoError )
176        {
177                printf("ERROR: Bind() failed with %d\n", err);
178                break;
179        }
180        err = ep->SetSynchronous();
181        if ( err != kOTNoError )
182        {
183                printf("ERROR: SetSynchronous() failed with %d\n", err);
184                break;
185        }
186
187        def_addr.addr.len = sizeof(struct InetAddress);
188        def_addr.addr.buf = (unsigned char *) &sndsin;
189
190        err = ep->Connect(&sndcall, nil);
191        if ( err != kOTNoError )
192        {
193                printf("ERROR: Connect() failed with %d\n", err);
194                break;
195        }
196}
197
198pascal void ot_udp_EventHandler(void*, OTEventCode event, OTResult, void*)
199{
200        if (event == T_DATA)
201        {
202                gDataToRead = 1;
203                return;
204        }
205        if (event == T_BINDCOMPLETE)
206        {
207                gBindCompleted = 1;
208                return;
209        }
210        return;
211}
212
213ot_udp_socket::ot_udp_socket()
214{
215        TEndpointInfo   info;
216        OSStatus err;
217
218        fd = OTOpenEndpoint(OTCreateConfiguration(kUDPName), 0, &info, &err);
219        if ( ep == NULL || err != kOTNoError )
220        {
221                ep = NULL;
222                fprintf(stderr,"ERROR: OpenEndpoint(\"UDP\") failed with %d\n", err);
223                break;
224        }
225       
226        // Install notifier
227        err = ep->InstallNotifier(ot_udp_EventHandler, this);
228        if ( err != kOTNoError )
229        {
230                fprintf(stderr, "ERROR: InstallNotifier() failed with %d\n", err);
231                break;
232        }
233
234}
235
236int ot_udp_socket::read(void *buf, int size, net_address **addr);
237{
238  int tr;
239  if (addr)
240  {
241    *addr=new ip_address;
242    int addr_size=sizeof(ip_address::addr);
243    tr=recvfrom(fd,buf,size,0, (sockaddr *) &((ip_address *)(*addr))->addr,&addr_size);
244  } else
245    tr=recv(fd,buf,size,0);
246  return tr;
247}
248
249int ot_udp_socket::write(void *buf, int size, net_address *addr);
250{
251        OSStatus        err = kOTNoError;
252        TUnitData       unitdata;
253        char            mystr[255];
254
255        unitdata.addr.len = sizeof (struct InetAddress);
256  if (addr)
257                unitdata.addr.buf = (UInt8*) &((ot_ip_address *)addr->addr);
258  else
259                unitdata.addr.buf = (UInt8*) &def_addr;
260        unitdata.opt.len = 0;
261        unitdata.opt.buf = 0;
262        unitdata.udata.len = size;
263        unitdata.udata.buf = (UInt8*) buf;
264
265        err = ep->SndUData( &unitdata);
266
267        if ( err != kOTNoError )
268        {
269                fprintf(stderr, "SndUData() returns %d\n", err);
270        }
271        else
272                return size;
273}
274
275int ot_udp_socket::listen(int port);
276{
277        sockaddr_in host;
278        memset( (char*) &host,0, sizeof(host));
279        host.sin_family = AF_INET;
280        host.sin_port = htons(port);
281        host.sin_addr.s_addr = htonl(INADDR_ANY);
282        if (bind(fd, (struct sockaddr *) &host, sizeof(sockaddr_in))==-1)
283        {
284          fprintf(stderr,"net driver : could not bind socket to port %d\n",port);
285          return 0;
286        }
287        return 1;
288}
289
290net_address *tcpip_protocol::get_local_address()
291{
292  char my_name[100];                              // now check to see if this address is 'hostname'
293  gethostname(my_name,100);
294  struct hostent *l_hn=gethostbyname(my_name); 
295  ip_address *a=new ip_address();
296  memset(&a->addr,0,sizeof(a->addr));
297  memcpy(&a->addr.sin_addr,*l_hn->h_addr_list,4); 
298}
299
300net_address *tcpip_protocol::get_node_address(char *&server_name, int def_port, int force_port)
301{
302  char name[256],*np;
303  np=name;
304  while (*server_name && *server_name!=':' && *server_name!='/')
305    *(np++)=*(server_name)++;
306  *np=0;
307  if (*server_name==':')
308  {
309    server_name++;
310    char port[256],*p;
311    p=port;
312    while (*server_name && *server_name!='/')
313      *(p++)=*(server_name++);
314    *p=0;
315    int x;
316    if (!force_port)
317    {
318      if (sscanf(port,"%d",&x)==1) def_port=x;
319      else return 0;
320    }
321  }
322
323  if (*server_name=='/') server_name++;
324
325  hostent *hp=gethostbyname(name);
326  if (!hp)
327  {
328    fprintf(stderr,"unable to locate server named '%s'\n",name);
329    return 0;
330  }
331 
332
333  sockaddr_in host;
334  memset( (char*) &host,0, sizeof(host));
335  host.sin_family = AF_INET;
336  host.sin_port = htons(def_port);
337  host.sin_addr.s_addr = htonl(INADDR_ANY);
338  memcpy(&host.sin_addr,hp->h_addr,hp->h_length);
339  return new ip_address(&host);
340}
341
342net_socket *tcpip_protocol::connect_to_server(net_address *addr, net_socket::socket_type sock_type)
343{
344  if (addr->protocol_type()!=net_address::IP)
345  {
346    fprintf(stderr,"Procotol type not supported in the executable\n");
347    return NULL;
348  }
349
350  int socket_fd=socket(AF_INET,sock_type==net_socket::SOCKET_SECURE ? SOCK_STREAM : SOCK_DGRAM,0);
351  if (socket_fd<0)
352  {
353    fprintf(stderr,"unable to create socket (too many open files?)\n");
354    return 0;
355  }
356
357  int zz;
358  if (setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz))<0)
359  {
360    fprintf(stderr,"could not set socket option reuseaddr");
361    return 0;
362  }
363
364   
365  if (connect(socket_fd, (struct sockaddr *) &((ip_address *)addr)->addr, sizeof( ((ip_address *)addr)->addr ))==-1)
366  {
367    fprintf(stderr,"unable to connect\n");
368    close(socket_fd);
369    return 0;
370  }
371
372  if (sock_type==net_socket::SOCKET_SECURE)
373    return new tcp_socket(socket_fd);
374  else
375    return new udp_socket(socket_fd);
376}
377
378
379net_socket *tcpip_protocol::create_listen_socket(int port, net_socket::socket_type sock_type, char *name)
380{
381  int socket_fd=socket(AF_INET,sock_type==net_socket::SOCKET_SECURE ? SOCK_STREAM : SOCK_DGRAM,0);
382  if (socket_fd<0)
383  {
384    fprintf(stderr,"unable to create socket (too many open files?)\n");
385    return 0;
386  }
387/*  int zz;
388  if (setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz))<0)
389  {
390    fprintf(stderr,"could not set socket option reuseaddr");
391    return 0;
392  } */
393
394
395  net_socket *s;
396  if (sock_type==net_socket::SOCKET_SECURE)
397    s=new tcp_socket(socket_fd);
398  else s=new udp_socket(socket_fd);
399  if (s->listen(port)==0)
400  {   
401    delete s;
402    return 0;
403  }
404
405  return s;
406}
407
408
409tcpip_protocol::tcpip_protocol()
410{
411  FD_ZERO(&master_set); 
412  FD_ZERO(&master_write_set); 
413  FD_ZERO(&read_set);
414  FD_ZERO(&exception_set);
415  FD_ZERO(&write_set);
416}
417
418
419int tcpip_protocol::select(int block)
420{
421  memcpy(&read_set,&master_set,sizeof(master_set));
422  memcpy(&exception_set,&master_set,sizeof(master_set));
423  memcpy(&write_set,&master_write_set,sizeof(master_set));
424  if (block)
425    return ::select(FD_SETSIZE,&read_set,&write_set,&exception_set,NULL);
426  else
427  {
428    timeval tv={0,0};
429    return ::select(FD_SETSIZE,&read_set,&write_set,&exception_set,&tv);
430  }
431}
432
433
Note: See TracBrowser for help on using the repository browser.