source: abuse/tags/pd/macabuse/src/net/mac/tcpip.hpp @ 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.
File size: 6.3 KB
Line 
1#include "sock.hpp"
2
3#include <stdlib.h>
4#include <fcntl.h>
5#include <sys/ioctl.h>
6#include <sys/stat.h>
7#include <sys/types.h>
8#include <signal.h>
9#include <sys/types.h>
10#include "isllist.hpp"
11#include "dprint.hpp"
12
13#ifdef __MAC__
14#include "GUSI.h"
15#else
16#include <netdb.h>
17#include <netinet/in.h>
18#include <stdio.h>
19#include <string.h>
20#include <sys/time.h>
21#include <sys/ipc.h>
22#include <sys/shm.h>
23#include <sys/socket.h>
24#include <unistd.h>
25#include <bstring.h>
26#endif
27
28extern fd_set master_set,master_write_set,read_set,exception_set,write_set;
29
30class ip_address : public net_address
31{
32public:
33  sockaddr_in addr;
34
35  virtual protocol protocol_type() const { return net_address::IP; }
36  virtual int equal(const net_address *who) const
37  //{{{
38  {
39    if (who->protocol_type()==IP &&
40        !memcmp(&addr.sin_addr,& ((ip_address *)who)->addr.sin_addr,sizeof(addr.sin_addr)))
41      return 1;
42    else return 0;
43  }
44        //}}}
45  virtual int set_port(int port)  { addr.sin_port=htons(port); return 1; }
46  ip_address(sockaddr_in *Addr) { memcpy(&addr,Addr,sizeof(addr)); }
47  virtual void print()
48  //{{{
49  {
50    unsigned char *c=(unsigned char *) (&addr.sin_addr.s_addr);
51    dprintf("%d.%d.%d.%d",c[0],c[1],c[2],c[3]);
52  }
53        //}}}
54  int get_port() { return htons(addr.sin_port); }
55  net_address *copy()  { return new ip_address(&addr); }
56  ip_address() {} ;
57  void store_string(char *st, int st_length)
58  //{{{
59  {
60    char buf[100];
61    unsigned char *c=(unsigned char *) (&addr.sin_addr.s_addr);
62    sprintf(buf,"%d.%d.%d.%d:%d",c[0],c[1],c[2],c[3],htons(addr.sin_port));
63    strncpy(st,buf,st_length);
64    st[st_length-1]=0;   
65  }
66  //}}}
67} ;
68
69class tcpip_protocol : public net_protocol
70{
71protected:
72  // Request Data
73  struct RequestItem
74  {
75        ip_address *addr;
76        char name[256];   //name
77  };
78  typedef isllist<RequestItem *>::iterator p_request;
79  isllist<RequestItem*> servers,returned;
80  net_socket *responder;
81  ip_address *bcast;
82
83  // Notification Data
84  net_socket *notifier;
85  char notify_data[512];
86  int notify_len;
87
88  int handle_notification();
89  int handle_responder();
90public :
91  fd_set master_set,master_write_set,read_set,exception_set,write_set;
92
93  tcpip_protocol();
94  net_address *get_local_address();
95  net_address *get_node_address(char *&server_name, int def_port, int force_port);
96  net_socket *connect_to_server(net_address *addr,
97        net_socket::socket_type sock_type=net_socket::SOCKET_SECURE);
98  net_socket *create_listen_socket(int &port, net_socket::socket_type sock_type);
99  int installed() { return 1; }  // always part of unix
100  char *name() { return "UNIX generic TCPIP"; }
101  void cleanup();
102  int select(int block);          // return # of sockets available for read & writing
103 
104  // Notification methods
105  virtual net_socket *start_notify(int port, void *data, int len);
106  virtual void end_notify();
107
108  // Find notifiers methods
109  virtual net_address *find_address(int port, char *name);   // name should be a 256 byte buffer
110  virtual void reset_find_list();
111  virtual ~tcpip_protocol() { cleanup(); }
112} ;
113
114extern tcpip_protocol tcpip;
115
116class unix_fd : public net_socket
117{
118  protected :
119  int fd;
120  public :
121  unix_fd(int fd) : fd(fd) { };
122  virtual int error()                             { return FD_ISSET(fd,&tcpip.exception_set); }
123  virtual int ready_to_read()                     { return FD_ISSET(fd,&tcpip.read_set); }
124  virtual int ready_to_write()                   
125  {
126    struct timeval tv={0,0};     // don't wait
127    fd_set write_check; 
128    FD_ZERO(&write_check); 
129    FD_SET(fd,&write_check);     
130    select(FD_SETSIZE,NULL,&write_check,NULL,&tv);
131    return FD_ISSET(fd,&write_check);
132  }
133  virtual int write(void *buf, int size, net_address *addr=NULL);
134  virtual int read(void *buf, int size, net_address **addr);
135
136  virtual ~unix_fd()                            { read_unselectable();  write_unselectable(); close(fd); }
137  virtual void read_selectable()                   { FD_SET(fd,&tcpip.master_set); }
138  virtual void read_unselectable()                 { FD_CLR(fd,&tcpip.master_set); }
139  virtual void write_selectable()                  { FD_SET(fd,&tcpip.master_write_set); }
140  virtual void write_unselectable()                { FD_CLR(fd,&tcpip.master_write_set); }
141  int get_fd() { return fd; }
142 
143  void broadcastable();
144} ;
145
146class tcp_socket : public unix_fd
147{
148  int listening;
149  public :
150  tcp_socket(int fd) : unix_fd(fd) { listening=0; };
151  virtual int listen(int port)
152  {
153    sockaddr_in host;
154    memset( (char*) &host,0, sizeof(host));
155    host.sin_family = AF_INET;
156    host.sin_port = htons(port);
157    host.sin_addr.s_addr = htonl(INADDR_ANY);
158    if (bind(fd, (struct sockaddr *) &host, sizeof(sockaddr_in))==-1)
159    {
160      dprintf("net driver : could not bind socket to port %d\n",port);
161      return 0;
162    }
163    if (::listen(fd,5)==-1)
164    {
165      dprintf("net driver : could not listen to socket on port %d\n",port);   
166      return 0;
167    }
168    listening=1;
169    return 1;
170  }
171  virtual net_socket *accept(net_address *&addr)
172  {
173    if (listening)
174    {
175      struct sockaddr_in from;
176      int addr_len=sizeof(from);
177      int new_fd=::accept(fd,(sockaddr *)&from,&addr_len);
178      if (new_fd>=0)
179      {
180        addr=new ip_address(&from);
181        return new tcp_socket(new_fd);
182      }
183      else
184      { addr=NULL; return 0; }
185    }
186    return 0;
187  }
188} ;
189
190class udp_socket : public unix_fd
191{
192  public :
193  udp_socket(int fd) : unix_fd(fd) { };
194  virtual int read(void *buf, int size, net_address **addr)
195  {
196    int tr;
197    if (addr)
198    {
199      *addr=new ip_address;
200      int addr_size=sizeof(sockaddr_in);
201      tr=recvfrom(fd,buf,size,0, (sockaddr *) &((ip_address *)(*addr))->addr,&addr_size);
202    } else
203      tr=recv(fd,buf,size,0);
204    return tr;
205  }
206  virtual int write(void *buf, int size, net_address *addr=NULL)
207  {
208    if (addr)
209      return sendto(fd,buf,size,0,(sockaddr *)(&((ip_address *)addr)->addr),sizeof(((ip_address *)addr)->addr));
210    else
211      return ::write(fd,(char*)buf,size);     
212  }
213  virtual int listen(int port)
214  {
215    sockaddr_in host;
216    memset( (char*) &host,0, sizeof(host));
217    host.sin_family = AF_INET;
218    host.sin_port = htons(port);
219    host.sin_addr.s_addr = htonl(INADDR_ANY);
220    if (bind(fd, (struct sockaddr *) &host, sizeof(sockaddr_in))==-1)
221    {
222      dprintf("net driver : could not bind socket to port %d\n",port);
223      return 0;
224    }
225    return 1;
226  }
227
228} ;
229
Note: See TracBrowser for help on using the repository browser.