Watt-32 tcp/ip  2.2 dev-rel.10
pcbuf.c
Go to the documentation of this file.
1 
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <limits.h>
9 
10 #include "copyrigh.h"
11 #include "wattcp.h"
12 #include "language.h"
13 #include "misc.h"
14 #include "strings.h"
15 #include "pctcp.h"
16 #include "pcdbug.h"
17 #include "pcbuf.h"
18 
19 #if defined(USE_BSD_API)
20 static int num_free_raw (const _raw_Socket *raw)
21 {
22  int num;
23 
24  for (num = 0; raw; raw = raw->next)
25  if (!raw->used)
26  num++;
27  return (num);
28 }
29 #endif
30 
31 #if defined(USE_IPV6)
32 static int num_free_raw6 (const _raw6_Socket *raw)
33 {
34  int num;
35 
36  for (num = 0; raw; raw = raw->next)
37  if (!raw->used)
38  num++;
39  return (num);
40 }
41 #endif
42 
43 
44 size_t W32_CALL sock_rbsize (const sock_type *s)
45 {
46  switch (_chk_socket(s))
47  {
48  case VALID_IP4:
49  return (sizeof(s->raw.ip) + sizeof(s->raw.rx_data));
50 #if defined(USE_IPV6)
51  case VALID_IP6:
52  return (sizeof(s->raw6.ip6) + sizeof(s->raw6.rx_data));
53 #endif
54  case VALID_UDP:
55  return (s->udp.max_rx_data);
56  case VALID_TCP:
57  return (s->tcp.max_rx_data);
58  }
59  return (0);
60 }
61 
62 size_t W32_CALL sock_rbused (const sock_type *s)
63 {
64  switch (_chk_socket(s))
65  {
66 #if defined(USE_BSD_API)
67  case VALID_IP4:
68  {
69  const _raw_Socket *raw = find_oldest_raw (&s->raw);
70  return (raw ? intel16 (raw->ip.length) : 0);
71  }
72 #if defined(USE_IPV6)
73  case VALID_IP6:
74  {
75  const _raw6_Socket *raw = find_oldest_raw6 (&s->raw6);
76  return (raw ? intel16 (raw->ip6.len) : 0);
77  }
78 #endif
79 #endif
80  case VALID_UDP:
81  return (s->udp.rx_datalen);
82  case VALID_TCP:
83  return (s->tcp.rx_datalen);
84  }
85  return (0);
86 }
87 
88 size_t W32_CALL sock_rbleft (const sock_type *s)
89 {
90  switch (_chk_socket(s))
91  {
92 #if defined(USE_BSD_API)
93  case VALID_IP4:
94  return num_free_raw (&s->raw) *
95  (sizeof(s->raw.ip) + sizeof(s->raw.rx_data));
96 #if defined(USE_IPV6)
97  case VALID_IP6:
98  return num_free_raw6 (&s->raw6) *
99  (sizeof(s->raw6.ip6) + sizeof(s->raw6.rx_data));
100 #endif
101 #endif
102  case VALID_UDP:
103  return (s->tcp.max_rx_data - s->udp.rx_datalen);
104  case VALID_TCP:
105  return (s->tcp.max_rx_data - s->tcp.rx_datalen);
106  }
107  return (0);
108 }
109 
110 size_t W32_CALL sock_tbsize (const sock_type *s)
111 {
112  switch (_chk_socket(s))
113  {
114  case VALID_IP4:
115  case VALID_IP6:
116  return (_mtu);
117  case VALID_TCP:
118  return (s->tcp.max_tx_data);
119  case VALID_UDP:
120  return (_mtu - UDP_OVERHEAD);
121  }
122  return (0);
123 }
124 
125 size_t W32_CALL sock_tbleft (const sock_type *s)
126 {
127  switch (_chk_socket(s))
128  {
129  case VALID_IP4:
130  case VALID_IP6:
131  return (_mtu);
132  case VALID_TCP:
133  return (s->tcp.max_tx_data - s->tcp.tx_datalen - 1);
134  case VALID_UDP:
135  return (_mtu - UDP_OVERHEAD);
136  }
137  return (0);
138 }
139 
140 size_t W32_CALL sock_tbused (const sock_type *s)
141 {
142  if (_chk_socket(s) == VALID_TCP)
143  return (s->tcp.tx_datalen);
144  return (0);
145 }
146 
147 /*
148  * Sets new buffer for Rx-data (for udp/tcp).
149  * Set debug-marker in front and at end of buffer.
150  * \note does not copy the old content over to new buffer.
151  */
152 size_t W32_CALL sock_setbuf (sock_type *s, BYTE *rx_buf, size_t rx_len)
153 {
154  int type = _chk_socket (s);
155 
156  /* Raw-sockets use fixed buffer
157  */
158  if (!type || type == VALID_IP4 || type == VALID_IP6)
159  return (0);
160 
161  if (rx_len < 8 || !rx_buf)
162  {
163  s->tcp.rx_data = &s->tcp.rx_buf[0];
164  s->tcp.max_rx_data = sizeof(s->tcp.rx_buf) - 1;
165  }
166  else
167  {
168  size_t len = min (rx_len, USHRT_MAX-1) - 8;
169 
170  *(DWORD*)rx_buf = SAFETY_TCP;
171  *(DWORD*)(rx_buf+4+len) = SAFETY_TCP;
172  s->tcp.rx_data = rx_buf + 4;
173  s->tcp.max_rx_data = (UINT) (len - 1);
174  }
175  return (s->tcp.max_rx_data);
176 }
177 
178 #if defined(USE_DEBUG)
179 /*
180  * Check the Rx-buffer marker signatures of Rx/Tx-buffers.
181  * Rx-buffer may have been allocated in above sock_setbuf().
182  * Tx-buffer may have been allocated in tcp_SetWindow().
183  * Only usable for TCP sockets.
184  */
185 void _sock_check_tcp_buffers (const _tcp_Socket *tcp)
186 {
187  const BYTE *rx, *tx;
188 
189  if (tcp->ip_type != TCP_PROTO) /* should already be true */
190  return;
191 
192  rx = tcp->rx_data;
193  tx = tcp->tx_data;
194 
195  WATT_ASSERT (tcp->safetysig == SAFETY_TCP);
196  WATT_ASSERT (tcp->safetytcp == SAFETY_TCP);
197 
198 #if (DOSX)
199  WATT_ASSERT (valid_addr(rx, tcp->max_rx_data));
200  WATT_ASSERT (valid_addr(tx, tcp->max_tx_data));
201 #endif
202 
203  if (rx != &tcp->rx_buf[0])
204  {
205  WATT_ASSERT (*(DWORD*)(rx-4) == SAFETY_TCP);
206  WATT_ASSERT (*(DWORD*)(rx+1+tcp->max_rx_data) == SAFETY_TCP);
207  }
208  if (tx != &tcp->tx_buf[0])
209  {
210  WATT_ASSERT (*(DWORD*)(tx-4) == SAFETY_TCP);
211  WATT_ASSERT (*(DWORD*)(tx+1+tcp->max_tx_data) == SAFETY_TCP);
212  }
213 }
214 
215 void _sock_check_udp_buffers (const _udp_Socket *udp)
216 {
217  ARGSUSED (udp); /* \todo */
218 }
219 #endif
220 
221 
222 int W32_CALL sock_preread (const sock_type *s, BYTE *buf, int len)
223 {
224  int count;
225  int type = _chk_socket (s);
226 
227  /* Raw-sockets use fixed buffer
228  */
229  if (!type || type == VALID_IP4 || type == VALID_IP6)
230  return (0);
231 
232  count = s->tcp.rx_datalen;
233  if (count < 1)
234  return (count);
235 
236  if (count > len)
237  count = len;
238  if (buf)
239  memcpy (buf, s->tcp.rx_data, count);
240  return (count);
241 }
242 
243 /*
244  * chk_socket - determine whether a real socket or not
245  */
246 int W32_CALL _chk_socket (const sock_type *s)
247 {
248  if (!s)
249  return (0);
250 
251  if (s->tcp.ip_type == TCP_PROTO && s->tcp.state <= tcp_StateCLOSED)
252  return (VALID_TCP);
253 
254  if (s->udp.ip_type == UDP_PROTO)
255  return (VALID_UDP);
256 
257  if (s->raw.ip_type == IP4_TYPE)
258  return (VALID_IP4);
259 
260  if (s->raw6.ip_type == IP6_TYPE)
261  return (VALID_IP6);
262 
263  return (0);
264 }
265 
266 const char *W32_CALL sockerr (const sock_type *s)
267 {
268  if (s && s->tcp.err_msg)
269  return (s->tcp.err_msg);
270  return (NULL);
271 }
272 
273 void W32_CALL sockerr_clear (sock_type *s)
274 {
275  if (s)
276  {
277  s->tcp.err_msg = NULL;
278  s->tcp.err_buf[0] = '\0';
279  }
280 }
281 
282 const char *W32_CALL sockstate (const sock_type *s)
283 {
284  switch (_chk_socket(s))
285  {
286  case VALID_IP4:
287  return (_LANG("Raw IPv4 Socket"));
288 
289  case VALID_IP6:
290  return (_LANG("Raw IPv6 Socket"));
291 
292  case VALID_UDP:
293  return (_LANG("UDP Socket"));
294 
295  case VALID_TCP:
296  return (_LANG(tcpStateName(s->tcp.state)));
297 
298  default:
299  return (_LANG("Not an active socket"));
300  }
301 }
302 
303 #if defined(USE_BSD_API)
304 const _raw_Socket *find_oldest_raw (const _raw_Socket *raw)
305 {
306  const _raw_Socket *s;
307 
308  for (s = raw; raw; raw = raw->next)
309  {
310  if (raw->used && raw->seq_num < s->seq_num)
311  s = raw;
312  }
313  return (s->used ? s : NULL);
314 }
315 
316 #if defined(USE_IPV6)
317 const _raw6_Socket *find_oldest_raw6 (const _raw6_Socket *raw)
318 {
319  const _raw6_Socket *s;
320 
321  for (s = raw; raw; raw = raw->next)
322  {
323  if (raw->used && raw->seq_num < s->seq_num)
324  s = raw;
325  }
326  return (s->used ? s : NULL);
327 }
328 #endif
329 #endif
330 
BYTE * tx_data
Tx data buffer (default tx_buf[])
Definition: wattcp.h:682
WORD ip_type
same ofs as for udp/tcp Socket
Definition: wattcp.h:695
BOOL used
used flag; packet not read yet
Definition: wattcp.h:696
UINT max_tx_data
Last index for tx_data[].
Definition: wattcp.h:681
UINT tx_datalen
number of bytes of data to send
Definition: wattcp.h:680
Core definitions.
BYTE rx_buf[tcp_MaxBufSize+1]
received data buffer
Definition: wattcp.h:616
DWORD safetytcp
extra magic marker
Definition: wattcp.h:685
BYTE tx_buf[tcp_MaxTxBufSize+1]
data for transmission
Definition: wattcp.h:683
BYTE rx_data[MAX_FRAG_SIZE]
room for 1 jumbo IP packet
Definition: wattcp.h:699
DWORD safetysig
magic marker
Definition: wattcp.h:684
DWORD seq_num
counter for finding oldest pkt
Definition: wattcp.h:697
UINT state
tcp connection state
Definition: wattcp.h:622