Watt-32 tcp/ip  2.2 dev-rel.10
socket.h
Go to the documentation of this file.
1 
4 /*
5  * BSD sockets functionality for Waterloo TCP/IP.
6  *
7  * by G. Vanem 1997
8  */
9 
10 #ifndef _w32_SOCKET_H
11 #define _w32_SOCKET_H
12 
13 #if defined(__TURBOC__) && (__TURBOC__ <= 0x301)
14  /*
15  * Prevent tcc <= 2.01 from even looking at this.
16  */
17  #define BOOL int
18 #else /* rest of file */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <stddef.h>
24 #include <string.h>
25 #include <signal.h>
26 #include <setjmp.h>
27 #include <ctype.h>
28 #include <time.h>
29 #include <limits.h>
30 #include <fcntl.h>
31 #include <io.h>
32 
33 #include <sys/socket.h>
34 #include <sys/ioctl.h>
35 #include <sys/syslog.h>
36 
37 #include <net/if.h>
38 #include <net/if_dl.h>
39 #include <net/if_arp.h>
40 #include <net/if_ether.h>
41 #include <net/if_packe.h>
42 #include <net/route.h>
43 
44 #include <netinet/in.h>
45 #include <netinet/in_systm.h>
46 #include <netinet/ip.h>
47 #include <netinet/ip_var.h>
48 #include <netinet/ip_icmp.h>
49 #include <netinet/in_pcb.h>
50 #include <netinet/in_var.h>
51 #include <netinet/tcp.h>
52 #include <netinet/tcpip.h>
53 #include <netinet/ip6.h>
54 #include <netinet/tcp_time.h>
55 
56 #include <arpa/inet.h>
57 #include <arpa/nameser.h>
58 #include <arpa/tftp.h>
59 #include <netdb.h>
60 #include <resolv.h>
61 
62 #include "wattcp.h"
63 #include "chksum.h"
64 #include "wdpmi.h"
65 #include "misc.h"
66 #include "run.h"
67 #include "timer.h"
68 #include "strings.h"
69 #include "sock_ini.h"
70 #include "language.h"
71 #include "pcconfig.h"
72 #include "pcqueue.h"
73 #include "pcdbug.h"
74 #include "pcsed.h"
75 #include "pcpkt.h"
76 #include "pcstat.h"
77 #include "pcigmp.h"
78 #include "pctcp.h"
79 #include "pcbuf.h"
80 #include "pcicmp.h"
81 #include "pcarp.h"
82 #include "pcrecv.h"
83 #include "printk.h"
84 #include "netaddr.h"
85 #include "ip4_in.h"
86 #include "ip4_out.h"
87 #include "ip6_in.h"
88 #include "ip6_out.h"
89 #include "rs232.h"
90 #include "bsddbug.h"
91 #include "bsdname.h"
92 #include "gettod.h"
93 
94 
95 /*
96  * Various sizes
97  */
98 #if defined (TARGET_IS_32BIT)
99  #define MAX_DGRAMS 5 /* # of datagrams for broadcast */
100  #define MAX_RAW_BUFS 5 /* # of _raw_Socket in list */
101  #define MAX_RAW6_BUFS 5 /* # of _raw6_Socket in list */
102  #define MAX_PACKET_BUFS 10
103  #define MAX_SOCKETS 5000 /* # of sockets to handle */
104  #define MAX_TCP_RECV_BUF (1024*1024-1) /* Max size for SO_RCVBUF */
105 #else
106  #define MAX_DGRAMS 2
107  #define MAX_RAW_BUFS 2
108  #define MAX_RAW6_BUFS 2
109  #define MAX_PACKET_BUFS 5
110  #define MAX_SOCKETS 512
111  #define MAX_TCP_RECV_BUF (USHRT_MAX-1)
112 #endif
113 
114 #define MAX_TCP_SEND_BUF (USHRT_MAX-1) /* for SO_SNDLOWAT/SO_RCVLOWAT */
115 #define MAX_UDP_RECV_BUF (USHRT_MAX-1)
116 #define MAX_UDP_SEND_BUF (USHRT_MAX-1)
117 #define MAX_RAW_RECV_BUF (USHRT_MAX-1)
118 #define MAX_RAW_SEND_BUF (USHRT_MAX-1)
119 
120 #define DEFAULT_SEND_LOWAT 0
121 #define DEFAULT_RECV_LOWAT 0
122 #define DEFAULT_UDP_SIZE (8*1024)
123 
124 
125 /* Buffer types for AF_PACKET sockets
126  */
128  WORD rx_len;
129  char rx_buf [ETH_MAX+4]; /* add room for end marker */
130  };
131 
132 typedef struct sock_packet_pool {
133  struct pkt_ringbuf queue;
134  struct sock_packet_buf buf [MAX_PACKET_BUFS];
136 
137 typedef struct Socket {
138  int fd;
139  struct Socket *next;
140  struct sockaddr_in *local_addr;
141  struct sockaddr_in *remote_addr;
142 
143  int timeout;
144  int inp_flags; /* misc. IP-protocol options */
145  BYTE ip_tos;
146  BYTE ip_ttl;
147 
148  struct ip_opts *ip_opt; /* for setsockopt(s,IP_OPTION,..) */
149  unsigned ip_opt_len; /* output IP-option length */
150 
151  int so_options; /* SO_KEEPALIVE, SO_ACCEPTCONN etc. */
152  int so_proto; /* IPPROTO_UDP, IPPROTO_TCP etc. */
153  int so_type; /* SOCK_STREAM, SOCK_DGRAM etc. */
154  int so_family; /* address family AF_INET/AF_INET6 */
155  int so_state; /* internal state, ref SS_* below */
156  int so_error; /* internal socket errno */
157  time_t close_time; /* we closed at (SOCK_STREAM) */
158  BOOL linger_on; /* user specified lingering */
159  unsigned linger_time; /* linger-time (SOCK_STREAM) */
160  unsigned fd_duped; /* FSEXT reference counting */
161  DWORD keepalive; /* keepalive timeout */
162  DWORD nb_timer; /* non-block timer */
163  _udp_Socket *udp_sock; /* actual state and Rx/Tx data is in */
164  _tcp_Socket *tcp_sock; /* one of these pointers */
165  _raw_Socket *raw_sock; /* points to 1st in linked-list */
166  _raw6_Socket *raw6_sock;
167  recv_buf **bcast_pool; /* buffers for INADDR_ANY sockets */
168  unsigned pool_size; /* size of above buffer */
169 
170  /* For SOCK_PACKET sockets.
171  */
172  sock_packet_pool *packet_pool;
173  int (W32_CALL *old_eth_peek) (void *pkt);
174 
175  /* listen-queue for incoming tcp connections
176  */
177  int backlog;
178  _tcp_Socket *listen_queue [SOMAXCONN];
179  DWORD syn_timestamp[SOMAXCONN]; /* got SYN at [msec] */
180 
181  unsigned send_lowat; /* low-water Tx marks */
182  unsigned recv_lowat; /* low-water Rx marks */
183  BOOL msg_nosig; /* don't raise SIGPIPE */
184  DWORD cookie; /* memory cookie / marker */
185 
186  } Socket;
187 
188 
189 /*
190  * Let first socket start at 3 in order not to
191  * confuse sockets with stdin/stdout/stderr handles.
192  * First socket will always be >= 3 on djgpp thanks to FS-extensions.
193  */
194 #define SK_FIRST 3
195 
196 /*
197  * Number of 'fd_set' required to hold MAX_SOCKETS.
198  */
199 #define NUM_SOCK_FDSETS ((MAX_SOCKETS+sizeof(fd_set)-1) / sizeof(fd_set))
200 
201 /*
202  * Misc. defines
203  */
204 #ifndef SIGIO /* for asynchronous I/O support (not yet) */
205 #define SIGIO SIGUSR1
206 #endif
207 
208 #ifndef IPPORT_ANY
209 #define IPPORT_ANY 0
210 #endif
211 
212 /*
213  * Socket state bits (in so_state).
214  */
215 #define SS_NOFDREF 0x0001 /* no file table ref any more */
216 #define SS_UNCONNECTED SS_NOFDREF /* or just created socket */
217 #define SS_ISCONNECTED 0x0002 /* socket connected to a peer */
218 #define SS_ISCONNECTING 0x0004 /* in process of connecting */
219 #define SS_ISDISCONNECTING 0x0008 /* in process of disconnecting */
220 #define SS_CANTSENDMORE 0x0010 /* can't send more data */
221 #define SS_CANTRCVMORE 0x0020 /* can't receive more data */
222 #define SS_RCVATMARK 0x0040 /* at mark on input (no used) */
223 
224 #define SS_PRIV 0x0080 /* privileged for broadcast */
225 #define SS_NBIO 0x0100 /* non-blocking operations */
226 #define SS_ASYNC 0x0200 /* async I/O notify (not used) */
227 #define SS_ISCONFIRMING 0x0400 /* accepting connection req */
228 #define SS_ISLISTENING SS_ISCONFIRMING /* non standard */
229 
230 #define SS_LOCAL_ADDR 0x0800 /* has local address/port (not used) */
231 #define SS_REMOTE_ADDR 0x1000 /* has remote address/port (not used) */
232 #define SS_CONN_REFUSED 0x2000 /* connection refused (ICMP_UNREACH etc) */
233 
234 
235 /*
236  * Socket macros
237  */
238 #define SOCK_CALLOC(sz) _sock_calloc (sz, __FILE__, __LINE__)
239 #define SOCK_DEL_FD(fd) _sock_del_fd (fd, __FILE__, __LINE__)
240 
241 /*
242  * Prologue code starting most BSD-socket functions
243  */
244 #define SOCK_PROLOGUE(socket, fmt, fd) \
245  do { \
246  SOCK_DEBUGF ((fmt, fd)); \
247  if (!socket) { \
248  if (_sock_dos_fd(fd)) { \
249  SOCK_DEBUGF ((", ENOTSOCK")); \
250  SOCK_ERRNO (ENOTSOCK); \
251  return (-1); \
252  } \
253  SOCK_DEBUGF ((", EBADF")); \
254  SOCK_ERRNO (EBADF); \
255  return (-1); \
256  } \
257  } while (0)
258 
259 #if defined (TARGET_IS_32BIT)
260  #define VERIFY_RW(ptr,len) \
261  do { \
262  if (!valid_addr(ptr,len)) { \
263  SOCK_DEBUGF ((", EFAULT " \
264  "(buf %" ADDR_FMT ", len %d)", \
265  ADDR_CAST(ptr), (int)(len))); \
266  SOCK_ERRNO (EFAULT); \
267  return (-1); \
268  } \
269  } while (0)
270 #else
271  #define VERIFY_RW(ptr,len) ((void)0)
272 #endif
273 
274 /*
275  * Print error and exit at critical places. Should not be used
276  * in "production quality" code.
277  */
278 #if defined(USE_BSD_FATAL)
279  #define SOCK_FATAL(arg) do { \
280  (*_printf) arg; \
281  fflush (stdout); \
282  /* _watt_fatal_error = 1; */ \
283  exit (-1); \
284  /*@-unreachable@*/ \
285  } while (0)
286 #else
287  #define SOCK_FATAL(arg) ((void)0)
288 #endif
289 
290 /*
291  * Only djgpp/DMC have (some of) the <fcntl.h> F_?? commands.
292  * For others, we define some dummy values.
293  */
294 #define W32_FCNTL_BASE 100
295 
296 #ifndef F_DUPFD
297 #define F_DUPFD (W32_FCNTL_BASE+0)
298 #endif
299 
300 #ifndef F_GETFL
301 #define F_GETFL (W32_FCNTL_BASE+1)
302 #endif
303 
304 #ifndef F_SETFL
305 #define F_SETFL (W32_FCNTL_BASE+2)
306 #endif
307 
308 #ifndef F_GETFD
309 #define F_GETFD (W32_FCNTL_BASE+3)
310 #endif
311 
312 #ifndef F_SETFD
313 #define F_SETFD (W32_FCNTL_BASE+4)
314 #endif
315 
316 #ifndef F_GETLK
317 #define F_GETLK (W32_FCNTL_BASE+5)
318 #endif
319 
320 #ifndef F_SETLK
321 #define F_SETLK (W32_FCNTL_BASE+6)
322 #endif
323 
324 #ifndef F_SETLKW
325 #define F_SETLKW (W32_FCNTL_BASE+7)
326 #endif
327 
328 #ifndef F_GETOWN
329 #define F_GETOWN (W32_FCNTL_BASE+8)
330 #endif
331 
332 #ifndef F_SETOWN
333 #define F_SETOWN (W32_FCNTL_BASE+9)
334 #endif
335 
336 /*
337  * Setup trapping of signals and critical sections around loops.
338  */
339 extern int _sock_sig_setup (void);
340 extern int _sock_sig_restore (void);
341 extern int _sock_sig_pending (void);
342 extern int _sock_sig_epipe (const Socket *s);
343 
344 extern void _sock_crit_start (void);
345 extern void _sock_crit_stop (void);
346 
347 /*
348  * Timing of "kernel" times for some socket calls.
349  */
350 extern void _sock_start_timer (void);
351 extern void _sock_stop_timer (void);
352 
353 /*
354  * Things for SOCK_PACKET sockets.
355  */
356 extern unsigned sock_packet_transmit (Socket *sock, const void *buf,
357  unsigned len, const struct sockaddr *to,
358  int tolen);
359 
360 extern unsigned sock_packet_receive (Socket *sock, void *buf, unsigned len,
361  struct sockaddr *from, size_t *fromlen);
362 
363 extern unsigned sock_packet_rbused (Socket *sock);
364 
365 /*
366  * Allocation, `sk_list' stuff etc.
367  */
368 extern void *_sock_calloc (size_t size, const char *file, unsigned line);
369 extern Socket *_sock_del_fd (int sock, const char *file, unsigned line);
370 extern Socket *_socklist_find (int s);
371 extern BOOL _sock_dos_fd (int s);
372 extern int _sock_half_open (const _tcp_Socket *tcp);
373 extern int _sock_append (_tcp_Socket **tcp);
374 extern int _sock_set_rcv_buf (sock_type *s, size_t len);
375 extern void _sock_free_rcv_buf (sock_type *s);
376 extern void _sock_set_syn_hook (int (*func)(_tcp_Socket **));
377 extern BOOL _sock_set_promisc_rx_mode (void);
378 extern BOOL _sock_set_mcast_rx_mode (void);
379 extern BOOL _sock_set_normal_rx_mode (const Socket *_this);
380 
381 /*
382  * Interface naming stuff.
383  */
384 extern const sock_type *__get_sock_from_s (int s, int proto);
385 extern void __get_ifname (char *if_name);
386 extern void __set_ifname (const char *if_name);
387 extern int __scope_ascii_to_id (const char *str);
388 extern int __scope_id_to_ascii (int scope);
389 
390 
391 /*
392  * Check `sockaddr*' passed to bind()/connect().
393  */
394 extern int _sock_chk_sockaddr (Socket *socket, const struct sockaddr *sa, int len);
395 
396 /*
397  * Handle UDP/TCP connect()/listen() calls.
398  */
399 extern int _TCP_open (Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port);
400 extern int _UDP_open (Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port);
401 extern int _TCP_listen (Socket *socket, struct in_addr host, WORD loc_port);
402 extern int _UDP_listen (Socket *socket, struct in_addr host, WORD port);
403 
404 extern int _TCP6_open (Socket *socket, const void *host, WORD loc_port, WORD rem_port);
405 extern int _UDP6_open (Socket *socket, const void *host, WORD loc_port, WORD rem_port);
406 extern int _TCP6_listen(Socket *socket, const void *host, WORD loc_port);
407 extern int _UDP6_listen(Socket *socket, const void *host, WORD port);
408 
409 #endif /* old __TURBOC__ */
410 #endif /* _w32_SOCKET_H */
411 
unsigned sock_packet_receive(Socket *sock, void *buf, unsigned len, struct sockaddr *from, size_t *fromlen)
Called from receive.c for AF_PACKET sockets.
Definition: socket.c:601
int _UDP6_open(Socket *socket, const void *host, WORD loc_port, WORD rem_port)
Definition: socket.c:2211
Definition: in.h:270
int _sock_half_open(const _tcp_Socket *tcp)
_sock_half_open - Return true if peer closed his side.
Definition: socket.c:2239
const sock_type * __get_sock_from_s(int s, int proto)
Hack function if user application needs to use Wattcp core functions for BSD sockets.
Definition: socket.c:308
void _sock_crit_stop(void)
Mark the end of a critical region.
Definition: socket.c:1306
Definition: socket.h:137
int _sock_chk_sockaddr(Socket *socket, const struct sockaddr *sa, int len)
Check `sockaddr*' passed to bind/connect.
Definition: socket.c:839
int _TCP_open(Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port)
Open and listen routines for SOCK_STREAM at the socket-level.
Definition: socket.c:2067
Definition: if.h:84
void _sock_crit_start(void)
Start a critical region.
Definition: socket.c:1296
BOOL _sock_dos_fd(int s)
_sock_dos_fd - Return TRUE if `s' is a valid DOS/Win32 handle.
Definition: socket.c:222
Core definitions.
int _TCP6_open(Socket *socket, const void *host, WORD loc_port, WORD rem_port)
Definition: socket.c:2110
Socket * _socklist_find(int s)
Returns a pointer to the Socket structure associated with socket 's'.
Definition: socket.c:1534
Definition: in.h:146
int _UDP_open(Socket *socket, struct in_addr host, WORD loc_port, WORD rem_port)
Open and listen routines for SOCK_DGRAM at the socket-level.
Definition: socket.c:2003
void * _sock_calloc(size_t size, const char *file, unsigned line)
Memory allocation; print some info if allocation fails.
Definition: socket.c:99
int _TCP6_listen(Socket *socket, const void *host, WORD loc_port)
Definition: socket.c:2202
Socket * _sock_del_fd(int sock, const char *file, unsigned line)
Delete the socket from `inuse' array and all memory associated with it.
Definition: socket.c:701
int _sock_set_rcv_buf(sock_type *s, size_t len)
Setup a bigger receive buffer, the default in Wattcp is only 2k.
Definition: socket.c:252
int _sock_append(_tcp_Socket **tcp)
Called from tcp_fsm.c / tcp_listen_state() (via _bsd_socket_hook) to append a new connection to the l...
Definition: accept.c:418
void _sock_free_rcv_buf(sock_type *s)
Free receive buffer associated with udp/tcp sockets.
Definition: socket.c:267
int _UDP6_listen(Socket *socket, const void *host, WORD port)
Definition: socket.c:2222