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