1 /*
2     SDL_net:  An example cross-platform network library for use with SDL
3     Copyright (C) 1997-2004 Sam Lantinga
4 
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9 
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14 
15     You should have received a copy of the GNU Library General Public
16     License along with this library; if not, write to the Free
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 
19     Sam Lantinga
20     slouken@libsdl.org
21 */
22 
23 /* $Id: SDL_net.h 3281 2007-07-15 05:58:56Z slouken $ */
24 
25 #ifndef _SDL_NET_H
26 #define _SDL_NET_H
27 
28 #include "SDL.h"
29 #include "SDL_endian.h"
30 #include "SDL_version.h"
31 #include "begin_code.h"
32 
33 
34 
35 /* Set up for C function definitions, even when using C++ */
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 /* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
41 */
42 #define SDL_NET_MAJOR_VERSION	1
43 #define SDL_NET_MINOR_VERSION	2
44 #define SDL_NET_PATCHLEVEL	7
45 
46 /* This macro can be used to fill a version structure with the compile-time
47  * version of the SDL_net library.
48  */
49 #define SDL_NET_VERSION(X)						\
50 {									\
51 	(X)->major = SDL_NET_MAJOR_VERSION;				\
52 	(X)->minor = SDL_NET_MINOR_VERSION;				\
53 	(X)->patch = SDL_NET_PATCHLEVEL;				\
54 }
55 
56 /* This function gets the version of the dynamically linked SDL_net library.
57    it should NOT be used to fill a version structure, instead you should
58    use the SDL_NET_VERSION() macro.
59  */
60 extern DECLSPEC const SDL_version * SDLCALL SDLNet_Linked_Version(void);
61 
62 /* Initialize/Cleanup the network API
63    SDL must be initialized before calls to functions in this library,
64    because this library uses utility functions from the SDL library.
65 */
66 extern DECLSPEC int  SDLCALL SDLNet_Init(void);
67 extern DECLSPEC void SDLCALL SDLNet_Quit(void);
68 
69 /***********************************************************************/
70 /* IPv4 hostname resolution API                                        */
71 /***********************************************************************/
72 
73 typedef struct {
74 	Uint32 host;			/* 32-bit IPv4 host address */
75 	Uint16 port;			/* 16-bit protocol port */
76 } IPaddress;
77 
78 /* Resolve a host name and port to an IP address in network form.
79    If the function succeeds, it will return 0.
80    If the host couldn't be resolved, the host portion of the returned
81    address will be INADDR_NONE, and the function will return -1.
82    If 'host' is NULL, the resolved host will be set to INADDR_ANY.
83  */
84 #ifndef INADDR_ANY
85 #define INADDR_ANY		0x00000000
86 #endif
87 #ifndef INADDR_NONE
88 #define INADDR_NONE		0xFFFFFFFF
89 #endif
90 #ifndef INADDR_BROADCAST
91 #define INADDR_BROADCAST	0xFFFFFFFF
92 #endif
93 extern DECLSPEC int SDLCALL SDLNet_ResolveHost(IPaddress *address, const char *host, Uint16 port);
94 
95 /* Resolve an ip address to a host name in canonical form.
96    If the ip couldn't be resolved, this function returns NULL,
97    otherwise a pointer to a static buffer containing the hostname
98    is returned.  Note that this function is not thread-safe.
99 */
100 extern DECLSPEC const char * SDLCALL SDLNet_ResolveIP(IPaddress *ip);
101 
102 
103 /***********************************************************************/
104 /* TCP network API                                                     */
105 /***********************************************************************/
106 
107 typedef struct _TCPsocket *TCPsocket;
108 
109 /* Open a TCP network socket
110    If ip.host is INADDR_NONE or INADDR_ANY, this creates a local server
111    socket on the given port, otherwise a TCP connection to the remote
112    host and port is attempted. The address passed in should already be
113    swapped to network byte order (addresses returned from
114    SDLNet_ResolveHost() are already in the correct form).
115    The newly created socket is returned, or NULL if there was an error.
116 */
117 extern DECLSPEC TCPsocket SDLCALL SDLNet_TCP_Open(IPaddress *ip);
118 
119 /* Accept an incoming connection on the given server socket.
120    The newly created socket is returned, or NULL if there was an error.
121 */
122 extern DECLSPEC TCPsocket SDLCALL SDLNet_TCP_Accept(TCPsocket server);
123 
124 /* Get the IP address of the remote system associated with the socket.
125    If the socket is a server socket, this function returns NULL.
126 */
127 extern DECLSPEC IPaddress * SDLCALL SDLNet_TCP_GetPeerAddress(TCPsocket sock);
128 
129 /* Send 'len' bytes of 'data' over the non-server socket 'sock'
130    This function returns the actual amount of data sent.  If the return value
131    is less than the amount of data sent, then either the remote connection was
132    closed, or an unknown socket error occurred.
133 */
134 extern DECLSPEC int SDLCALL SDLNet_TCP_Send(TCPsocket sock, const void *data,
135 		int len);
136 
137 /* Receive up to 'maxlen' bytes of data over the non-server socket 'sock',
138    and store them in the buffer pointed to by 'data'.
139    This function returns the actual amount of data received.  If the return
140    value is less than or equal to zero, then either the remote connection was
141    closed, or an unknown socket error occurred.
142 */
143 extern DECLSPEC int SDLCALL SDLNet_TCP_Recv(TCPsocket sock, void *data, int maxlen);
144 
145 /* Close a TCP network socket */
146 extern DECLSPEC void SDLCALL SDLNet_TCP_Close(TCPsocket sock);
147 
148 
149 /***********************************************************************/
150 /* UDP network API                                                     */
151 /***********************************************************************/
152 
153 /* The maximum channels on a a UDP socket */
154 #define SDLNET_MAX_UDPCHANNELS	32
155 /* The maximum addresses bound to a single UDP socket channel */
156 #define SDLNET_MAX_UDPADDRESSES	4
157 
158 typedef struct _UDPsocket *UDPsocket;
159 typedef struct {
160 	int channel;		/* The src/dst channel of the packet */
161 	Uint8 *data;		/* The packet data */
162 	int len;		/* The length of the packet data */
163 	int maxlen;		/* The size of the data buffer */
164 	int status;		/* packet status after sending */
165 	IPaddress address;		/* The source/dest address of an incoming/outgoing packet */
166 } UDPpacket;
167 
168 /* Allocate/resize/free a single UDP packet 'size' bytes long.
169    The new packet is returned, or NULL if the function ran out of memory.
170  */
171 extern DECLSPEC UDPpacket * SDLCALL SDLNet_AllocPacket(int size);
172 extern DECLSPEC int SDLCALL SDLNet_ResizePacket(UDPpacket *packet, int newsize);
173 extern DECLSPEC void SDLCALL SDLNet_FreePacket(UDPpacket *packet);
174 
175 /* Allocate/Free a UDP packet vector (array of packets) of 'howmany' packets,
176    each 'size' bytes long.
177    A pointer to the first packet in the array is returned, or NULL if the
178    function ran out of memory.
179  */
180 extern DECLSPEC UDPpacket ** SDLCALL SDLNet_AllocPacketV(int howmany, int size);
181 extern DECLSPEC void SDLCALL SDLNet_FreePacketV(UDPpacket **packetV);
182 
183 
184 /* Open a UDP network socket
185    If 'port' is non-zero, the UDP socket is bound to a local port.
186    The 'port' should be given in native byte order, but is used
187    internally in network (big endian) byte order, in addresses, etc.
188    This allows other systems to send to this socket via a known port.
189 */
190 extern DECLSPEC UDPsocket SDLCALL SDLNet_UDP_Open(Uint16 port);
191 
192 /* Bind the address 'address' to the requested channel on the UDP socket.
193    If the channel is -1, then the first unbound channel will be bound with
194    the given address as it's primary address.
195    If the channel is already bound, this new address will be added to the
196    list of valid source addresses for packets arriving on the channel.
197    If the channel is not already bound, then the address becomes the primary
198    address, to which all outbound packets on the channel are sent.
199    This function returns the channel which was bound, or -1 on error.
200 */
201 extern DECLSPEC int SDLCALL SDLNet_UDP_Bind(UDPsocket sock, int channel, IPaddress *address);
202 
203 /* Unbind all addresses from the given channel */
204 extern DECLSPEC void SDLCALL SDLNet_UDP_Unbind(UDPsocket sock, int channel);
205 
206 /* Get the primary IP address of the remote system associated with the
207    socket and channel.  If the channel is -1, then the primary IP port
208    of the UDP socket is returned -- this is only meaningful for sockets
209    opened with a specific port.
210    If the channel is not bound and not -1, this function returns NULL.
211  */
212 extern DECLSPEC IPaddress * SDLCALL SDLNet_UDP_GetPeerAddress(UDPsocket sock, int channel);
213 
214 /* Send a vector of packets to the the channels specified within the packet.
215    If the channel specified in the packet is -1, the packet will be sent to
216    the address in the 'src' member of the packet.
217    Each packet will be updated with the status of the packet after it has
218    been sent, -1 if the packet send failed.
219    This function returns the number of packets sent.
220 */
221 extern DECLSPEC int SDLCALL SDLNet_UDP_SendV(UDPsocket sock, UDPpacket **packets, int npackets);
222 
223 /* Send a single packet to the specified channel.
224    If the channel specified in the packet is -1, the packet will be sent to
225    the address in the 'src' member of the packet.
226    The packet will be updated with the status of the packet after it has
227    been sent.
228    This function returns 1 if the packet was sent, or 0 on error.
229 
230    NOTE:
231    The maximum size of the packet is limited by the MTU (Maximum Transfer Unit)
232    of the transport medium.  It can be as low as 250 bytes for some PPP links,
233    and as high as 1500 bytes for ethernet.
234 */
235 extern DECLSPEC int SDLCALL SDLNet_UDP_Send(UDPsocket sock, int channel, UDPpacket *packet);
236 
237 /* Receive a vector of pending packets from the UDP socket.
238    The returned packets contain the source address and the channel they arrived
239    on.  If they did not arrive on a bound channel, the the channel will be set
240    to -1.
241    The channels are checked in highest to lowest order, so if an address is
242    bound to multiple channels, the highest channel with the source address
243    bound will be returned.
244    This function returns the number of packets read from the network, or -1
245    on error.  This function does not block, so can return 0 packets pending.
246 */
247 extern DECLSPEC int SDLCALL SDLNet_UDP_RecvV(UDPsocket sock, UDPpacket **packets);
248 
249 /* Receive a single packet from the UDP socket.
250    The returned packet contains the source address and the channel it arrived
251    on.  If it did not arrive on a bound channel, the the channel will be set
252    to -1.
253    The channels are checked in highest to lowest order, so if an address is
254    bound to multiple channels, the highest channel with the source address
255    bound will be returned.
256    This function returns the number of packets read from the network, or -1
257    on error.  This function does not block, so can return 0 packets pending.
258 */
259 extern DECLSPEC int SDLCALL SDLNet_UDP_Recv(UDPsocket sock, UDPpacket *packet);
260 
261 /* Close a UDP network socket */
262 extern DECLSPEC void SDLCALL SDLNet_UDP_Close(UDPsocket sock);
263 
264 
265 /***********************************************************************/
266 /* Hooks for checking sockets for available data                       */
267 /***********************************************************************/
268 
269 typedef struct _SDLNet_SocketSet *SDLNet_SocketSet;
270 
271 /* Any network socket can be safely cast to this socket type */
272 typedef struct {
273 	int ready;
274 } *SDLNet_GenericSocket;
275 
276 /* Allocate a socket set for use with SDLNet_CheckSockets()
277    This returns a socket set for up to 'maxsockets' sockets, or NULL if
278    the function ran out of memory.
279  */
280 extern DECLSPEC SDLNet_SocketSet SDLCALL SDLNet_AllocSocketSet(int maxsockets);
281 
282 /* Add a socket to a set of sockets to be checked for available data */
283 #define SDLNet_TCP_AddSocket(set, sock) \
284 			SDLNet_AddSocket(set, (SDLNet_GenericSocket)sock)
285 #define SDLNet_UDP_AddSocket(set, sock) \
286 			SDLNet_AddSocket(set, (SDLNet_GenericSocket)sock)
287 extern DECLSPEC int SDLCALL SDLNet_AddSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock);
288 
289 /* Remove a socket from a set of sockets to be checked for available data */
290 #define SDLNet_TCP_DelSocket(set, sock) \
291 			SDLNet_DelSocket(set, (SDLNet_GenericSocket)sock)
292 #define SDLNet_UDP_DelSocket(set, sock) \
293 			SDLNet_DelSocket(set, (SDLNet_GenericSocket)sock)
294 extern DECLSPEC int SDLCALL SDLNet_DelSocket(SDLNet_SocketSet set, SDLNet_GenericSocket sock);
295 
296 /* This function checks to see if data is available for reading on the
297    given set of sockets.  If 'timeout' is 0, it performs a quick poll,
298    otherwise the function returns when either data is available for
299    reading, or the timeout in milliseconds has elapsed, which ever occurs
300    first.  This function returns the number of sockets ready for reading,
301    or -1 if there was an error with the select() system call.
302 */
303 extern DECLSPEC int SDLCALL SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout);
304 
305 /* After calling SDLNet_CheckSockets(), you can use this function on a
306    socket that was in the socket set, to find out if data is available
307    for reading.
308 */
309 #define SDLNet_SocketReady(sock) \
310 		((sock != NULL) && ((SDLNet_GenericSocket)sock)->ready)
311 
312 /* Free a set of sockets allocated by SDL_NetAllocSocketSet() */
313 extern DECLSPEC void SDLCALL SDLNet_FreeSocketSet(SDLNet_SocketSet set);
314 
315 
316 /***********************************************************************/
317 /* Platform-independent data conversion functions                      */
318 /***********************************************************************/
319 
320 /* Write a 16/32 bit value to network packet buffer */
321 extern DECLSPEC void SDLCALL SDLNet_Write16(Uint16 value, void *area);
322 extern DECLSPEC void SDLCALL SDLNet_Write32(Uint32 value, void *area);
323 
324 /* Read a 16/32 bit value from network packet buffer */
325 extern DECLSPEC Uint16 SDLCALL SDLNet_Read16(void *area);
326 extern DECLSPEC Uint32 SDLCALL SDLNet_Read32(void *area);
327 
328 /***********************************************************************/
329 /* Error reporting functions                                           */
330 /***********************************************************************/
331 
332 /* We'll use SDL's functions for error reporting */
333 #define SDLNet_SetError	SDL_SetError
334 #define SDLNet_GetError	SDL_GetError
335 
336 /* I'm eventually going to try to disentangle SDL_net from SDL, thus making
337    SDL_net an independent X-platform networking toolkit.  Not today though....
338 
339 extern no_parse_DECLSPEC void SDLCALL SDLNet_SetError(const char *fmt, ...);
340 extern no_parse_DECLSPEC char * SDLCALL SDLNet_GetError(void);
341 */
342 
343 
344 /* Inline macro functions to read/write network data */
345 
346 /* Warning, some systems have data access alignment restrictions */
347 #if defined(sparc) || defined(mips)
348 #define SDL_DATA_ALIGNED	1
349 #endif
350 #ifndef SDL_DATA_ALIGNED
351 #define SDL_DATA_ALIGNED	0
352 #endif
353 
354 /* Write a 16 bit value to network packet buffer */
355 #if !SDL_DATA_ALIGNED
356 #define SDLNet_Write16(value, areap)	\
357 	(*(Uint16 *)(areap) = SDL_SwapBE16(value))
358 #else
359 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
360 #define SDLNet_Write16(value, areap)	\
361 do 					\
362 {					\
363 	Uint8 *area = (Uint8 *)(areap);	\
364 	area[0] = (value >>  8) & 0xFF;	\
365 	area[1] =  value        & 0xFF;	\
366 } while ( 0 )
367 #else
368 #define SDLNet_Write16(value, areap)	\
369 do 					\
370 {					\
371 	Uint8 *area = (Uint8 *)(areap);	\
372 	area[1] = (value >>  8) & 0xFF;	\
373 	area[0] =  value        & 0xFF;	\
374 } while ( 0 )
375 #endif
376 #endif /* !SDL_DATA_ALIGNED */
377 
378 /* Write a 32 bit value to network packet buffer */
379 #if !SDL_DATA_ALIGNED
380 #define SDLNet_Write32(value, areap) 	\
381 	*(Uint32 *)(areap) = SDL_SwapBE32(value);
382 #else
383 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
384 #define SDLNet_Write32(value, areap) 	\
385 do					\
386 {					\
387 	Uint8 *area = (Uint8 *)(areap);	\
388 	area[0] = (value >> 24) & 0xFF;	\
389 	area[1] = (value >> 16) & 0xFF;	\
390 	area[2] = (value >>  8) & 0xFF;	\
391 	area[3] =  value       & 0xFF;	\
392 } while ( 0 )
393 #else
394 #define SDLNet_Write32(value, areap) 	\
395 do					\
396 {					\
397 	Uint8 *area = (Uint8 *)(areap);	\
398 	area[3] = (value >> 24) & 0xFF;	\
399 	area[2] = (value >> 16) & 0xFF;	\
400 	area[1] = (value >>  8) & 0xFF;	\
401 	area[0] =  value       & 0xFF;	\
402 } while ( 0 )
403 #endif
404 #endif /* !SDL_DATA_ALIGNED */
405 
406 /* Read a 16 bit value from network packet buffer */
407 #if !SDL_DATA_ALIGNED
408 #define SDLNet_Read16(areap) 		\
409 	(SDL_SwapBE16(*(Uint16 *)(areap)))
410 #else
411 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
412 #define SDLNet_Read16(areap) 		\
413 	((((Uint8 *)areap)[0] <<  8) | ((Uint8 *)areap)[1] <<  0)
414 #else
415 #define SDLNet_Read16(areap) 		\
416 	((((Uint8 *)areap)[1] <<  8) | ((Uint8 *)areap)[0] <<  0)
417 #endif
418 #endif /* !SDL_DATA_ALIGNED */
419 
420 /* Read a 32 bit value from network packet buffer */
421 #if !SDL_DATA_ALIGNED
422 #define SDLNet_Read32(areap) 		\
423 	(SDL_SwapBE32(*(Uint32 *)(areap)))
424 #else
425 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
426 #define SDLNet_Read32(areap) 		\
427 	((((Uint8 *)areap)[0] << 24) | (((Uint8 *)areap)[1] << 16) | \
428 	 (((Uint8 *)areap)[2] <<  8) |  ((Uint8 *)areap)[3] <<  0)
429 #else
430 #define SDLNet_Read32(areap) 		\
431 	((((Uint8 *)areap)[3] << 24) | (((Uint8 *)areap)[2] << 16) | \
432 	 (((Uint8 *)areap)[1] <<  8) |  ((Uint8 *)areap)[0] <<  0)
433 #endif
434 #endif /* !SDL_DATA_ALIGNED */
435 
436 #ifdef MACOS_OPENTRANSPORT
437 #endif
438 /* Ends C function definitions when using C++ */
439 #ifdef __cplusplus
440 }
441 #endif
442 #include "close_code.h"
443 
444 #endif /* _SDL_NET_H */
445