/* $Copyright:
 *
 * Copyright 1998-2000 by the Massachusetts Institute of Technology.
 * 
 * All rights reserved.
 * 
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of M.I.T. not be used in
 * advertising or publicity pertaining to distribution of the software
 * without specific, written prior permission.  Furthermore if you modify
 * this software you must label your software as modified software and not
 * distribute it in such a fashion that it might be confused with the
 * original MIT software. M.I.T. makes no representations about the
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 * 
 * Individual source code files are copyright MIT, Cygnus Support,
 * OpenVision, Oracle, Sun Soft, FundsXpress, and others.
 * 
 * Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira,
 * and Zephyr are trademarks of the Massachusetts Institute of Technology
 * (MIT).  No commercial use of these trademarks may be made without prior
 * written permission of MIT.
 * 
 * "Commercial use" means use of a name in a product or other for-profit
 * manner.  It does NOT prevent a commercial firm from referring to the MIT
 * trademarks in order to convey information (although in doing so,
 * recognition of their trademark status should be given).
 * $
 */

/* $Header: /cvs/src/sasl/mac/CommonKClient/mac_kclient3/Headers/KerberosSupport/Sockets.h,v 1.2 2001/12/04 02:05:57 rjs3 Exp $ */

/* 
 *
 * Sockets.h -- Main external header file for the sockets library.
 *
 */


#include <KerberosSupport/ErrorLib.h>
#include <KerberosSupport/Utilities.h>
#include <KerberosSupport/SocketErrors.h>
#include <unix.h>

#include <MacTypes.h>
#include <Events.h>
#include <OpenTptInternet.h>

#ifndef _SOCKETS_
#define _SOCKETS_

#ifdef __cplusplus
extern "C" {
#endif

#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
#	pragma import on
#endif

/*******************/
/* API Definitions */
/*******************/

#define FD_SETSIZE		256    	/*	The maximum # of sockets -- cannot be changed	*/

/* socket types */
#define SOCK_STREAM		0		/*	stream socket -- connection oriented 			*/
#define SOCK_DGRAM		1		/*	datagram socket -- connectionless				*/
#define SOCK_RAW		2		/*	raw socket 										*/
#define SOCK_SEQPACKET	3		/*	sequenced packet socket							*/
#define SOCK_RDM		4		/*	reliably delivered message socket				*/

/* address families  -- get AF_INET from OpenTptInternet.h */
#define AF_UNSPEC		0		/*	Unspecified										*/
#define AF_UNIX			1		/*	Unix internal protocols							*/

/* protocol families */
#define PF_UNSPEC	AF_UNSPEC	/*	Unspecified										*/
#define PF_UNIX		AF_UNIX		/*	Unix internal protocols							*/
#define PF_INET		AF_INET		/*	Internet protocols								*/

/* IP Address Wildcard */
#define INADDR_ANY      kOTAnyInetAddress
#define INADDR_NONE		0xffffffff

/* recv and send flags */
#define MSG_DONTROUTE	1
#define MSG_DONTWAIT	2
#define MSG_OOB			4
#define MSG_PEEK		8
#define MSG_WAITALL		16

#define NUMBITSPERBYTE	8		/* 	Number of bits per byte							*/

/* socket_fnctl() requests */
#define F_GETFL			3		/* Get file flags 									*/
#define F_SETFL			4		/* Set file flags 									*/

/* shutdown() flags */
#define SHUT_RD			0		/* Shutdown read side of the connection				*/
#define SHUT_WR			1		/* Shutdown write side of the connection			*/
#define SHUT_RDWR		2		/* Shutdown read and write sides of the connection	*/

/* IP address sizes */
#define INET_ADDRSTRLEN		16	/* for IPv4 dotted decimal							*/
#define INET6_ADDRSTRLEN	46	/* for IPv6 dhex string								*/
#define INADDRSZ			4	/* size of IPv4 addr in bytes 						*/
#define IN6ADDRSZ			16	/* size of IPv6 addr in bytes						*/

/* host name size */
#define MAXHOSTNAMESIZE		kMaxHostNameLen
#define MAXHOSTNAMELEN		kMaxHostNameLen

#ifdef USE_STREAMS
/* Constants for poll() */
#define POLLIN          0x001   /* A non-priority message is available */
#define POLLPRI         0x002   /* A high priority message is available */
#define POLLOUT         0x004   /* The stream is writable for non-priority messages */
#define POLLERR         0x008   /* A error message has arrived */
#define POLLHUP         0x010   /* A hangup has occurred */
#define POLLNVAL        0x020   /* This fd is bogus */
#define POLLRDNORM      0x040   /* A non-priority message is available */
#define POLLRDBAND      0x080   /* A priority message (band > 0) message is available */
#define POLLWRNORM      0x100   /* Same as POLLOUT */
#define POLLWRBAND      0x200   /* A priority band exists and is writable */
#define POLLMSG         0x400   /* A signal message has reached the front of the queue */
#endif /* USE_STREAMS */

/**********/
/* Macros */
/**********/

/* network byte order conversion [none since we're already big-endian] */
#define	ntohl(x) 		(x)
#define	ntohs(x) 		(x)
#define	htonl(x) 		(x)
#define	htons(x) 		(x)

/* macros for select */
#define FD_SET(fd, fdset)	((fdset)->fds_bits[(fd) / NFDBITS] |= ((unsigned)1 << ((fd) % NFDBITS)))
#define FD_CLR(fd, fdset)	((fdset)->fds_bits[(fd) / NFDBITS] &= ~((unsigned)1 << ((fd) % NFDBITS)))
#define FD_ISSET(fd, fdset)	((fdset)->fds_bits[(fd) / NFDBITS] & ((unsigned)1 << ((fd) % NFDBITS)))
#define FD_ZERO(fdset)		memset((char *)(fdset), 0, sizeof(*(fdset)))


/****************************/
/* API Structures and Types */
/****************************/

/* An internet address */
typedef UInt32  in_addr_t; 

/* size of address structures */
typedef UInt32 socklen_t;

/* structure used to store addresses */
struct sockaddr {
	u_short	sa_family;
	char	sa_data[14];
};

/* INET protocol structures */
struct in_addr {
	in_addr_t	s_addr;
};

/* A TCP address -- the same as a OT InetAddress */
struct sockaddr_in {				/* struct InetAddress {				*/
	u_short 		sin_family;		/* OTAddressType	fAddressType	*/
	u_short 		sin_port;		/* InetPort			fPort			*/
	struct in_addr 	sin_addr;		/* InetHost			fHost			*/
	char 			sin_zero[8];	/* UInt8			fUnused			*/
};									/* };								*/

/* structures for select */
typedef long fd_mask;
#define NFDBITS			(sizeof(fd_mask) * NUMBITSPERBYTE)      /* bits per mask */

typedef struct fd_set {
  fd_mask fds_bits[(FD_SETSIZE + NFDBITS - 1) / NFDBITS];
} fd_set;

/* Structure for non-contiguous data */
struct iovec {
  struct iovec *next;			/* For compatibility with Open Transport */
  void         *iov_base;		/* Starting address of buffer */
  size_t        iov_len;		/* size of buffer */
};

/* For poll() */
struct pollfd {
  int   fd;
  short events;
  short revents;
};

/***********************/
/* Function Prototypes */
/***********************/

#if !TARGET_RT_MAC_CFM
#   pragma d0_pointers on
#else
#   define SocketsLibraryIsPresent() ((Ptr) (socket) != (Ptr) (kUnresolvedCFragSymbolAddress))
#endif

/* Sockets Control API calls */
OSStatus 			   AbortSocketOperation(int sockFD);
OSStatus 			   AbortAllDNSOperations(void);
Boolean                IsValidSocket(int sockFD);

/* Sockets API calls */
int socket(int family, int type, int protocol);
int socket_bind(int sockFD, const struct sockaddr *myAddr, int addrLength);
int socket_fcntl(int sockFD, int command, int flags);
int socket_close(int sockFD);
int socket_shutdown(int sockFD, int howTo);
int socket_connect(int sockFD, struct sockaddr *servAddr, int addrLength);
int socket_select(int maxFDsExamined, fd_set *readFDs, fd_set *writeFDs, fd_set *exceptFDs,
                  struct timeval *timeOut);
#ifdef USE_STREAMS
int socket_poll (struct pollfd *fds, unsigned int nfds, int timeout);
#endif /* USE_STREAMS */
int socket_getpeername(int sockFD, struct sockaddr *peerAddr, int *addrLength);
int socket_getsockname(int sockFD, struct sockaddr *localAddr, int *addrLength);
int socket_read(int sockFD, void *buffer, UInt32 numBytes);
int socket_write(int sockFD, const void *buffer, UInt32 numBytes);
int socket_readv(int sockFD, struct iovec *iov, UInt32 iovCount);
int socket_writev(int sockFD, struct iovec *iov, UInt32 iovCount);
int socket_recv(int sockFD, void *buffer, UInt32 numBytes, int flags);
int socket_send(int sockFD, const void *buffer, UInt32 numBytes, int flags);
int socket_recvfrom(int sockFD, void *buffer, UInt32 numBytes, int flags, struct sockaddr *fromAddr, 
                    socklen_t *addrLength);
int socket_sendto(int sockFD, const void *buffer, UInt32 numBytes, int flags, struct sockaddr *toAddr, 
                  socklen_t addrLength);

/* Utilites API calls */
char 	   *inet_ntoa(struct in_addr addr);
int 	    inet_aton(const char *str, struct in_addr *addr);
in_addr_t 	inet_addr(const char *str);
int 	    inet_pton(int family, const char *str, void *addr);
const char *inet_ntop(int family, const void *addr, char *str, size_t len);

#if !TARGET_RT_MAC_CFM
#   pragma d0_pointers reset
#endif

#if defined(__CFM68K__) && !defined(__USING_STATIC_LIBS__)
#	pragma import reset
#endif

#ifdef __cplusplus
}
#endif

#endif /* _SOCKETS_ */
