Blob Blame History Raw
#ifndef _NT_SOCKET_H_
#define _NT_SOCKET_H_

/**
 *  socket api:
 *  -----------
 *  here we provide native libraries and applications
 *  with a minimal socket abstraction layer;
 *  if you are interested in posix socket semantics
 *  then this header is REALLY NOT what you
 *  are looking for, as the most portable scenario
 *  (psxscl+libc) neither requires nor allows for
 *  direct interaction with the below interfaces.
 *
 *  (additional information for the yet curious...)
 *
 *  client libraries and applications are responsible
 *  for the entire bookkeeping, which should be
 *  easy using the nt_socket structure.
 *
 *  kernel sockets are created using ZwCreateFile,
 *  and are then manipulated (bind, connect, send,
 *  recv, listen, accept, getsockname, etc.) using
 *  ZwDeviceIoControlFile.  accordingly, the main
 *  objective of the below interfaces is to provide
 *  thin wrappers around the above NT system calls,
 *  thereby releasing you from the tedious task
 *  of formatting control messages according to
 *  individual IOCTL codes, protocol types, or
 *  different versions of the operating system.
 *
 *  another noteworthy objective is the direct
 *  translation between posix socket semantics on the
 *  one hand, and the interfaces that this module
 *  provides on the other.  functions in this module
 *  normally take the same arguments as their
 *  posix equivalents, yet require a pointer
 *  to an nt_socket structure in place of an integer
 *  file descriptor (in the posix library, the task
 *  of converting an integer file descriptor to the
 *  above pointer is a trivial one).  for functions
 *  such as send() and recv(), the return value is
 *  the system's native NTSTATUS; the number of bytes
 *  sent or received is then returned in a separate
 *  argument, and can also be obtained, along with
 *  extended status, from the info member of the iosb
 *  argument.  last but not least, each function in
 *  this module accepts one or more optional arguments
 *  of questionable relevance:-)
**/

#include "nt_abi.h"
#include "nt_status.h"
#include "nt_object.h"
#include "nt_tty.h"

/* afd tcp state */
typedef enum _nt_afd_tcp_state {
	NT_AFD_TCP_STATE_CLOSED,
	NT_AFD_TCP_STATE_LISTEN,
	NT_AFD_TCP_STATE_SYN_SENT,
	NT_AFD_TCP_STATE_SYN_RCVD,
	NT_AFD_TCP_STATE_ESTABLISHED,
	NT_AFD_TCP_STATE_FIN_WAIT_1,
	NT_AFD_TCP_STATE_FIN_WAIT_2,
	NT_AFD_TCP_STATE_CLOSE_WAIT,
	NT_AFD_TCP_STATE_CLOSING,
	NT_AFD_TCP_STATE_LAST_ACK,
	NT_AFD_TCP_STATE_TIME_WAIT,
	NT_AFD_TCP_STATE_MAX,
} nt_afd_tcp_state;

/* afd socket domains */
#define NT_AF_UNSPEC		(0x0000u)
#define NT_AF_UNIX		(0x0001u)
#define NT_AF_INET		(0x0002u)
#define NT_AF_IMPLINK		(0x0003u)
#define NT_AF_PUP		(0x0004u)
#define NT_AF_CHAOS		(0x0005u)
#define NT_AF_NS		(0x0006u)
#define NT_AF_IPX		(0x0006u) /* synonym */
#define NT_AF_ISO		(0x0007u)
#define NT_AF_OSI		(0x0007u) /* synonym */
#define NT_AF_ECMA		(0x0008u)
#define NT_AF_DATAKIT		(0x0009u)
#define NT_AF_CCITT		(0x000Au)
#define NT_AF_SNA		(0x000Bu)
#define NT_AF_DECNET		(0x000Cu)
#define NT_AF_DLI		(0x000Du)
#define NT_AF_LAT		(0x000Eu)
#define NT_AF_HYLINK		(0x000Fu)
#define NT_AF_APPLETALK		(0x0010u)
#define NT_AF_NETBIOS		(0x0011u)
#define NT_AF_VOICEVIEW		(0x0012u)
#define NT_AF_FIREFOX		(0x0013u)
#define NT_AF_UNKNOWN_1ST	(0x0014u)
#define NT_AF_BAN		(0x0015u)
#define NT_AF_ATM		(0x0016u)
#define NT_AF_INET6		(0x0017u)
#define NT_AF_CLUSTER		(0x0018u)
#define NT_AF_12844		(0x0019u)
#define NT_AF_IRDA		(0x001Au)
#define NT_AF_NETDES		(0x001Cu)
#define NT_AF_TCNPROCESS	(0x001Du)
#define NT_AF_TCNMESSAGE	(0x001Eu)
#define NT_AF_ICLFXBM		(0x001Fu)
#define NT_AF_BTH		(0x0020u)
#define NT_AF_LINK		(0x0021u)


/* afd socket types */
#define NT_SOCK_STREAM		(0x0001u)
#define NT_SOCK_DGRAM		(0x0002u)
#define NT_SOCK_RAW		(0x0003u)
#define NT_SOCK_RDM		(0x0004u)
#define NT_SOCK_SEQPACKET	(0x0005u)


/* afd socket protocols */
#define NT_IPPROTO_IP				0
#define NT_IPPROTO_HOPOPTS			0
#define NT_IPPROTO_ICMP				1
#define NT_IPPROTO_IGMP				2
#define NT_IPPROTO_GGP				3
#define NT_IPPROTO_IPV4				4
#define NT_IPPROTO_ST				5
#define NT_IPPROTO_TCP				6
#define NT_IPPROTO_CBT				7
#define NT_IPPROTO_EGP				8
#define NT_IPPROTO_IGP				9
#define NT_IPPROTO_PUP				12
#define NT_IPPROTO_UDP				17
#define NT_IPPROTO_IDP				22
#define NT_IPPROTO_RDP				27
#define NT_IPPROTO_IPV6				41
#define NT_IPPROTO_ROUTING			43
#define NT_IPPROTO_FRAGMENT			44
#define NT_IPPROTO_ESP				50
#define NT_IPPROTO_AH				51
#define NT_IPPROTO_ICMPV6			58
#define NT_IPPROTO_NONE				59
#define NT_IPPROTO_DSTOPTS			60
#define NT_IPPROTO_ND				77
#define NT_IPPROTO_ICLFXBM			78
#define NT_IPPROTO_PIM				103
#define NT_IPPROTO_PGM				113
#define NT_IPPROTO_L2TP				115
#define NT_IPPROTO_SCTP				132
#define NT_IPPROTO_RAW				255
#define NT_IPPROTO_MAX				256
#define NT_IPPROTO_RESERVED_RAW			257
#define NT_IPPROTO_RESERVED_IPSEC		258
#define NT_IPPROTO_RESERVED_IPSECOFFLOAD	259
#define NT_IPPROTO_RESERVED_WNV			260
#define NT_IPPROTO_RESERVED_MAX			261



/* afd socket option levels */
#define NT_SOL_IPV6				41
#define NT_SOL_SOCKET				0xffff


/* afd socket ioctl primitives */
#define NT_SO_IOCTL_IN				(1 << 31)
#define NT_SO_IOCTL_OUT				(1 << 30)
#define NT_SO_IOCTL_VOID			(1 << 29)

#define NT_SO_IOCTL_TYPE_UNIX			((0 << 28) | (0 << 27))
#define NT_SO_IOCTL_TYPE_WS2			((0 << 28) | (1 << 27))
#define NT_SO_IOCTL_TYPE_PROTOCOL		((1 << 28) | (0 << 27))
#define NT_SO_IOCTL_TYPE_VENDOR			((1 << 28) | (1 << 27))

#define NT_SO_IOCTL_UNIX_VOID(x)		(x | NT_SO_IOCTL_TYPE_UNIX | NT_SO_IOCTL_VOID)
#define NT_SO_IOCTL_UNIX_GET(x)			(x | NT_SO_IOCTL_TYPE_UNIX | NT_SO_IOCTL_OUT)
#define NT_SO_IOCTL_UNIX_SET(x)			(x | NT_SO_IOCTL_TYPE_UNIX | NT_SO_IOCTL_IN)
#define NT_SO_IOCTL_UNIX_EX(x)			(x | NT_SO_IOCTL_TYPE_UNIX | NT_SO_IOCTL_IN|NT_SO_IOCTL_OUT)

#define NT_SO_IOCTL_WS2_VOID(x)			(x | NT_SO_IOCTL_TYPE_WS2 | NT_SO_IOCTL_VOID)
#define NT_SO_IOCTL_WS2_GET(x)			(x | NT_SO_IOCTL_TYPE_WS2 | NT_SO_IOCTL_OUT)
#define NT_SO_IOCTL_WS2_SET(x)			(x | NT_SO_IOCTL_TYPE_WS2 | NT_SO_IOCTL_IN)
#define NT_SO_IOCTL_WS2_EX(x)			(x | NT_SO_IOCTL_TYPE_WS2 | NT_SO_IOCTL_IN|NT_SO_IOCTL_OUT)

#define NT_SO_IOCTL_PROTOCOL_VOID(x)		(x | NT_SO_IOCTL_TYPE_PROTOCOL | NT_SO_IOCTL_VOID)
#define NT_SO_IOCTL_PROTOCOL_GET(x)		(x | NT_SO_IOCTL_TYPE_PROTOCOL | NT_SO_IOCTL_OUT)
#define NT_SO_IOCTL_PROTOCOL_SET(x)		(x | NT_SO_IOCTL_TYPE_PROTOCOL | NT_SO_IOCTL_IN)
#define NT_SO_IOCTL_PROTOCOL_EX(x)		(x | NT_SO_IOCTL_TYPE_PROTOCOL | NT_SO_IOCTL_IN|NT_SO_IOCTL_OUT)

#define NT_SO_IOCTL_VENDOR_VOID(x)		(x | NT_SO_IOCTL_TYPE_VENDOR | NT_SO_IOCTL_VOID)
#define NT_SO_IOCTL_VENDOR_GET(x)		(x | NT_SO_IOCTL_TYPE_VENDOR | NT_SO_IOCTL_OUT)
#define NT_SO_IOCTL_VENDOR_SET(x)		(x | NT_SO_IOCTL_TYPE_VENDOR | NT_SO_IOCTL_IN)
#define NT_SO_IOCTL_VENDOR_EX(x)		(x | NT_SO_IOCTL_TYPE_VENDOR | NT_SO_IOCTL_IN|NT_SO_IOCTL_OUT)


/* afd socket ws2 ioctl codes */
#define NT_SO_IOCTL_ASSOCIATE_HANDLE		NT_SO_IOCTL_WS2_SET(1)
#define NT_SO_IOCTL_ENABLE_CIRCULAR_QUEUEING	NT_SO_IOCTL_WS2_VOID(2)
#define NT_SO_IOCTL_FIND_ROUTE			NT_SO_IOCTL_WS2_GET(3)
#define NT_SO_IOCTL_FLUSH			NT_SO_IOCTL_WS2_VOID(4)
#define NT_SO_IOCTL_GET_BROADCAST_ADDRESS	NT_SO_IOCTL_WS2_GET(5)
#define NT_SO_IOCTL_GET_EXTENSION_FUNC_PTR	NT_SO_IOCTL_WS2_EX((6)
#define NT_SO_IOCTL_GET_QOS			NT_SO_IOCTL_WS2_EX((7)
#define NT_SO_IOCTL_GET_GROUP_QOS		NT_SO_IOCTL_WS2_EX((8)
#define NT_SO_IOCTL_MULTIPOINT_LOOPBACK		NT_SO_IOCTL_WS2_SET(9)
#define NT_SO_IOCTL_MULTICAST_SCOPE		NT_SO_IOCTL_WS2_SET(10)
#define NT_SO_IOCTL_SET_QOS			NT_SO_IOCTL_WS2_SET(11)
#define NT_SO_IOCTL_SET_GROUP_QOS		NT_SO_IOCTL_WS2_SET(12)
#define NT_SO_IOCTL_TRANSLATE_HANDLE		NT_SO_IOCTL_WS2_EX((13)
#define NT_SO_IOCTL_ROUTING_INTERFACE_QUERY	NT_SO_IOCTL_WS2_EX((20)
#define NT_SO_IOCTL_ROUTING_INTERFACE_CHANGE	NT_SO_IOCTL_WS2_SET(21)
#define NT_SO_IOCTL_ADDRESS_LIST_QUERY		NT_SO_IOCTL_WS2_GET(22)
#define NT_SO_IOCTL_ADDRESS_LIST_CHANGE		NT_SO_IOCTL_WS2_VOID(23)
#define NT_SO_IOCTL_QUERY_TARGET_PNP_HANDLE	NT_SO_IOCTL_WS2_GET(24)
#define SIO_ADDRESS_LIST_SORT			NT_SO_IOCTL_WS2_EX((25)

/* afd socket vendor ioctl codes */
#define NT_SO_IOCTL_RCVALL			NT_SO_IOCTL_VENDOR_GET(1)
#define NT_SO_IOCTL_RCVALL_MCAST		NT_SO_IOCTL_VENDOR_GET(2)
#define NT_SO_IOCTL_RCVALL_IGMPMCAST		NT_SO_IOCTL_VENDOR_GET(3)
#define NT_SO_IOCTL_KEEPALIVE_VALS		NT_SO_IOCTL_VENDOR_GET(4)
#define NT_SO_IOCTL_ABSORB_RTRALERT		NT_SO_IOCTL_VENDOR_GET(5)
#define NT_SO_IOCTL_UCAST_IF			NT_SO_IOCTL_VENDOR_GET(6)
#define NT_SO_IOCTL_LIMIT_BROADCASTS		NT_SO_IOCTL_VENDOR_GET(7)
#define NT_SO_IOCTL_INDEX_BIND			NT_SO_IOCTL_VENDOR_GET(8)
#define NT_SO_IOCTL_INDEX_MCASTIF		NT_SO_IOCTL_VENDOR_GET(9)
#define NT_SO_IOCTL_INDEX_ADD_MCAST		NT_SO_IOCTL_VENDOR_GET(10)
#define NT_SO_IOCTL_INDEX_DEL_MCAST		NT_SO_IOCTL_VENDOR_GET(11)
#define NT_SO_IOCTL_RCVALL_MCAST_IF		NT_SO_IOCTL_VENDOR_GET(13)
#define NT_SO_IOCTL_RCVALL_IF			NT_SO_IOCTL_VENDOR_GET(14)
#define NT_SO_IOCTL_GET_TCP_INFO		NT_SO_IOCTL_VENDOR_EX(39)

/* afd socket-level socket options */
#define NT_SO_DEBUG				(0x0001)
#define NT_SO_ACCEPTCONN			(0x0002)
#define NT_SO_REUSEADDR				(0x0004)
#define NT_SO_KEEPALIVE				(0x0008)
#define NT_SO_DONTROUTE				(0x0010)
#define NT_SO_BROADCAST				(0x0020)
#define NT_SO_USELOOPBACK			(0x0040)
#define NT_SO_LINGER				(0x0080)
#define NT_SO_OOBINLINE				(0x0100)

#define NT_SO_SNDBUF				(0x1001)
#define NT_SO_RCVBUF				(0x1002)
#define NT_SO_SNDLOWAT				(0x1003)
#define NT_SO_RCVLOWAT				(0x1004)
#define NT_SO_SNDTIMEO				(0x1005)
#define NT_SO_RCVTIMEO				(0x1006)
#define NT_SO_ERROR				(0x1007)
#define NT_SO_TYPE				(0x1008)

#define NT_SO_GROUP_ID				(0x2001)
#define NT_SO_GROUP_PRIORITY			(0x2002)
#define NT_SO_MAX_MSG_SIZE			(0x2003)



/* afd ipv6 socket options */
#define NT_IPV6_HOPOPTS				1
#define NT_IPV6_HDRINCL				2
#define NT_IPV6_UNICAST_HOPS			4
#define NT_IPV6_MULTICAST_IF			9
#define NT_IPV6_MULTICAST_HOPS			10
#define NT_IPV6_MULTICAST_LOOP			11
#define NT_IPV6_ADD_MEMBERSHIP			12
#define NT_IPV6_DROP_MEMBERSHIP			13
#define NT_IPV6_DONTFRAG			14
#define NT_IPV6_PKTINFO				19
#define NT_IPV6_HOPLIMIT			21
#define NT_IPV6_PROTECTION_LEVEL		23
#define NT_IPV6_RECVIF				24
#define NT_IPV6_RECVDSTADDR			25
#define NT_IPV6_CHECKSUM			26
#define NT_IPV6_V6ONLY				27
#define NT_IPV6_IFLIST				28
#define NT_IPV6_ADD_IFLIST			29
#define NT_IPV6_DEL_IFLIST			30
#define NT_IPV6_UNICAST_IF			31
#define NT_IPV6_RTHDR				32
#define NT_IPV6_RECVRTHDR			38
#define NT_IPV6_TCLASS				39
#define NT_IPV6_RECVTCLASS			40

#define NT_IPV6_JOIN_GROUP			IPV6_ADD_MEMBERSHIP
#define NT_IPV6_LEAVE_GROUP			IPV6_DROP_MEMBERSHIP



/* afd tcp socket options */
#define NT_TCP_OFFLOAD_NO_PREFERENCE            (0)
#define NT_TCP_OFFLOAD_NOT_PREFERRED            (1)
#define NT_TCP_OFFLOAD_PREFERRED                (2)

#define NT_TCP_NODELAY                          (1)
#define NT_TCP_EXPEDITED_1122                   (2)
#define NT_TCP_KEEPALIVE                        (3)
#define NT_TCP_MAXSEG                           (4)
#define NT_TCP_MAXRT                            (5)
#define NT_TCP_STDURG                           (6)
#define NT_TCP_NOURG                            (7)
#define NT_TCP_ATMARK                           (8)
#define NT_TCP_NOSYNRETRIES                     (9)
#define NT_TCP_TIMESTAMPS                       (10)
#define NT_TCP_OFFLOAD_PREFERENCE               (11)
#define NT_TCP_CONGESTION_ALGORITHM             (12)
#define NT_TCP_DELAY_FIN_ACK                    (13)
#define NT_TCP_MAXRTMS                          (14)
#define NT_TCP_FASTOPEN                         (15)
#define NT_TCP_KEEPCNT                          (16)
#define NT_TCP_KEEPINTVL                        (17)
#define NT_TCP_FAIL_CONNECT_ON_ICMP_ERROR       (18)
#define NT_TCP_ICMP_ERROR_INFO                  (19)

#define NT_TCP_KEEPIDLE                         NT_TCP_KEEPALIVE



/* tdi receive modes */
#define NT_TDI_RECEIVE_BROADCAST		(0x0004u)
#define NT_TDI_RECEIVE_MULTICAST		(0x0008u)
#define NT_TDI_RECEIVE_PARTIAL			(0x0010u)
#define NT_TDI_RECEIVE_NORMAL			(0x0020u)
#define NT_TDI_RECEIVE_EXPEDITED		(0x0040u)
#define NT_TDI_RECEIVE_PEEK			(0x0080u)
#define NT_TDI_RECEIVE_NO_RESPONSE_EXP		(0x0100u)
#define NT_TDI_RECEIVE_COPY_LOOKAHEAD		(0x0200u)
#define NT_TDI_RECEIVE_ENTIRE_MESSAGE		(0x0400u)
#define NT_TDI_RECEIVE_AT_DISPATCH_LEVEL	(0x0800u)
#define NT_TDI_RECEIVE_CONTROL_INFO		(0x1000u)
#define NT_TDI_RECEIVE_FORCE_INDICATION		(0x2000u)
#define NT_TDI_RECEIVE_NO_PUSH			(0x4000u)

/* tdi send modes */
#define NT_TDI_SEND_EXPEDITED			(0x0020u)
#define NT_TDI_SEND_PARTIAL			(0x0040u)
#define NT_TDI_SEND_NO_RESPONSE_EXPECTED	(0x0080u)
#define NT_TDI_SEND_NON_BLOCKING		(0x0100u)
#define NT_TDI_SEND_AND_DISCONNECT		(0x0200u)

/* tdi listen modes */
#define NT_TDI_QUERY_ACCEPT			(0x0001u)

/* tdi disconnect modes */
#define NT_TDI_DISCONNECT_WAIT			(0x0001u)
#define NT_TDI_DISCONNECT_ABORT			(0x0002u)
#define NT_TDI_DISCONNECT_RELEASE		(0x0004u)

/* afd ioctl codes */
#define NT_AFD_IOCTL_BIND			(0x12003u)
#define NT_AFD_IOCTL_CONNECT			(0x12007u)
#define NT_AFD_IOCTL_LISTEN			(0x1200Bu)
#define NT_AFD_IOCTL_ACCEPT			(0x1200Cu)
#define NT_AFD_IOCTL_DUPLICATE			(0x12010u)
#define NT_AFD_IOCTL_SEND			(0x1201Fu)
#define NT_AFD_IOCTL_UDP_SEND			(0x12023u)
#define NT_AFD_IOCTL_RECV			(0x12017u)
#define NT_AFD_IOCTL_UDP_RECV			(0x1201bu)
#define NT_AFD_IOCTL_DISCONNECT			(0x1202Bu)
#define NT_AFD_IOCTL_SELECT			(0x12024u)
#define NT_AFD_IOCTL_GET_SOCK_NAME		(0x1202Fu)
#define NT_AFD_IOCTL_GET_PEER_NAME		(0x12033u)
#define NT_AFD_IOCTL_SET_CONTEXT		(0x12047u)
#define NT_AFD_IOCTL_GET_CONTEXT		(0x12043u)
#define NT_AFD_IOCTL_SET_INFO			(0x1203bu)
#define NT_AFD_IOCTL_GET_INFO			(0x1207bu)
#define NT_AFD_IOCTL_SOCKOPT			(0x120bfu)

/* afd listen/accept bits */
#define NT_AFD_DEFER_ACCEPT			(0x01u)

/* afd sockopt mode bits */
#define NT_AFD_SOCKOPT_SET			(0x01u)
#define NT_AFD_SOCKOPT_GET			(0x02u)

/* afd poll socket info bits */
#define NT_AFD_POLL_RECEIVE			(0x01u)
#define NT_AFD_POLL_RECEIVE_EXPEDITED		(0x02u)
#define NT_AFD_POLL_SEND			(0x04u)
#define NT_AFD_POLL_DISCONNECT			(0x08u)
#define NT_AFD_POLL_ABORT			(0x10u)
#define NT_AFD_POLL_LOCAL_CLOSE			(0x20u)
#define NT_AFD_POLL_CONNECT			(0x40u)
#define NT_AFD_POLL_ACCEPT			(0x80u)
#define NT_AFD_POLL_CONNECT_FAIL		(0x100u)

/* afd socket shutdown bits */
#define NT_AFD_DISCONNECT_WR	(0x01u)
#define NT_AFD_DISCONNECT_RD	(0x02u)

/* afd socket share bits */
#define NT_AFD_SHARE_UNIQUE	(0x00u)
#define NT_AFD_SHARE_REUSE	(0x01u)
#define NT_AFD_SHARE_WILDCARD	(0x02u)
#define NT_AFD_SHARE_EXCLUSIVE	(0x03u)

/* socket structures */
typedef struct _nt_socket {
	union {
		void *		hsocket;
		void *		hfile;
		void *		hpipe;
		void *		hdir;
		void *		hobj;
		nt_pty *	hpty;
	};

	void *			hevent;
	int32_t			refcnt;		/* reserved for client */
	uint16_t		fdtype;		/* reserved for client */
	uint16_t		sctype;		/* reserved for client */
	uint16_t		state;		/* reserved for client */
	uint16_t		iomode;		/* reserved for client */
	uint32_t		ctxid;		/* reserved for client */
	uint32_t		psxflags;	/* reserved for client */
	uint32_t		ntflags;	/* sc_wait alert flags */
	nt_large_integer	timeout;
	int32_t			iostatus;
	int32_t			waitstatus;

	union {
		struct {
			uint16_t	domain;
			uint16_t	type;
			uint32_t	protocol;
		};

		struct {
			uint16_t	vfdtype;
			uint16_t	vfdflags;
			uint32_t	vfdpid;
		};

		void *	hipc;
		void *	hkey;
		void *	hpair;
		void *	hasync;
		void *	hobject;
		void *	hsection;
		void *	dirctx;
		void *	dbgctx;
	};
} nt_socket;


typedef struct _nt_scope_id{
	union {
		struct {
			uint32_t	zone  : 28;
			uint32_t	level : 4;
		};

		uint32_t	value;
	};
} nt_scope_id;


typedef struct _nt_sockaddr_in4 {
	uint16_t	sa_family;
	char		sa_data[14];
} nt_sockaddr_in4;


typedef struct _nt_sockaddr_in6 {
	uint16_t	sa_family;
	uint16_t	sa_port;
	uint32_t	sa_flow;
	unsigned char	sa_data[16];
	nt_scope_id	sa_scope;
} nt_sockaddr_in6;


typedef union _nt_sockaddr {
	nt_sockaddr_in4	sa_addr_in4;
	nt_sockaddr_in6 sa_addr_in6;
} nt_sockaddr;


typedef struct _nt_sockaddr_reply {
	uint32_t	addrlen;
	nt_sockaddr	addr;
} nt_sockaddr_reply;


typedef struct _nt_afd_buffer {
	size_t		length;
	char *		buffer;
} nt_afd_buffer;


typedef struct _nt_afd_listen_info {
	uint32_t	unknown;
	uint32_t	backlog;
	uint32_t	flags;
} nt_afd_listen_info;


typedef struct _nt_afd_accept_info {
	uint32_t	sequence;
	nt_sockaddr	addr;
	uint32_t	legacy[2];
} nt_afd_accept_info;


typedef struct _nt_afd_duplicate_info {
	uint32_t	unknown;
	uint32_t	sequence;
	void *		hsocket_dedicated;
} nt_afd_duplicate_info;


typedef struct _nt_afd_send_info {
	nt_afd_buffer *		afd_buffer_array;
	uint32_t		buffer_count;
	uint32_t		afd_flags;
	uint32_t		tdi_flags;
} nt_afd_send_info;


typedef struct _nt_afd_recv_info {
	nt_afd_buffer *		afd_buffer_array;
	uint32_t		buffer_count;
	uint32_t		afd_flags;
	uint32_t		tdi_flags;
} nt_afd_recv_info;


typedef struct _nt_afd_sockopt_info {
	uint32_t		mode;
	uint32_t		level;
	uint32_t		optname;
	uint32_t		ding;
	const void *		optval;
	size_t			optlen;
} nt_afd_sockopt_info;


typedef struct _nt_afd_poll_socket_info {
	void *			hsocket;
	uint32_t		events;
	int32_t			status;
} nt_afd_poll_socket_info;


typedef struct _nt_afd_poll_info {
	nt_timeout		timeout;
	uint32_t		nfds;
	uint32_t		options;
	nt_afd_poll_socket_info	pollfds[];
} nt_afd_poll_info;


typedef struct _nt_afd_disconnect_info {
	uint32_t	shutdown_flags;
	uint32_t	unknown[3];
} nt_afd_disconnect_info;


typedef struct _nt_afd_tcp_info_v0 {
	nt_afd_tcp_state	state;
	uint32_t		mss;
	uint64_t		conn_time_ms;
	int			time_stamp_enabled;
	uint32_t		rtt_us;
	uint32_t		min_rtt_us;
	uint32_t		bytes_in_flight;
	uint32_t		c_wnd;
	uint32_t		snd_wnd;
	uint32_t		rcv_wnd;
	uint32_t		rcv_buf;
	uint64_t		bytes_out;
	uint64_t		bytes_in;
	uint32_t		bytes_reordered;
	uint32_t		bytes_retrans;
	uint32_t		dup_acks_in;
	uint32_t		timeout_episodes;
	uint8_t			syn_retrans;
	uint32_t		__pad;
} nt_afd_tcp_info_v0;


/* socket functions */
typedef int32_t __cdecl ntapi_sc_socket(
	__out	nt_socket *		hssocket,
	__in	int32_t			domain,
	__in	int32_t			type,
	__in	uint32_t		protocol,
	__in	uint32_t		desired_access	__optional,
	__in	nt_sqos *		sqos		__optional,
	__out	nt_iosb *		iosb		__optional);


typedef int32_t __cdecl ntapi_sc_bind(
	__in	nt_socket *		hssocket,
	__in	const nt_sockaddr *	addr,
	__in	uintptr_t		addrlen,
	__in	uint32_t		afdflags	__optional,
	__in	uint32_t		srvflags	__optional,
	__out	nt_sockaddr *		sockaddr	__optional,
	__out	nt_iosb volatile *	iosb		__optional);


typedef int32_t __cdecl ntapi_sc_listen(
	__in	nt_socket *		hssocket,
	__in	uint32_t		backlog,
	__in	uint32_t		afdflags	__optional,
	__out	nt_iosb volatile *	iosb		__optional);


typedef int32_t __cdecl ntapi_sc_accept(
	__in	nt_socket *		hssock_listen,
	__in	nt_sockaddr *		addr,
	__in	uint16_t *		addrlen,
	__out	nt_socket *		hssock_dedicated,
	__in	uintptr_t		afdflags	__optional,
	__in	uintptr_t		tdiflags	__optional,
	__out	nt_iosb volatile *	iosb		__optional);


typedef int32_t __cdecl ntapi_sc_connect(
	__in	nt_socket *		hssocket,
	__in	nt_sockaddr *		addr,
	__in	uintptr_t		addrlen,
	__in	uintptr_t		service_flags	__optional,
	__out	nt_iosb volatile *	iosb		__optional);


typedef int32_t __cdecl ntapi_sc_send(
	__in	nt_socket *		hssocket,
	__in	const void *		buffer,
	__in	size_t			len,
	__out	ssize_t *		bytes_sent	__optional,
	__in	const nt_sockaddr *	addr		__optional,
	__in	size_t			addrlen		__optional,
	__in	uintptr_t		afdflags	__optional,
	__in	uintptr_t		tdiflags	__optional,
	__out	nt_iosb volatile *	iosb		__optional);


typedef int32_t __cdecl ntapi_sc_recv(
	__in	nt_socket *		hssocket,
	__in	const void *		buffer,
	__in	size_t			len,
	__out	ssize_t *		bytes_received	__optional,
	__in	nt_sockaddr_reply *	raddr		__optional,
	__in	uintptr_t		afdflags	__optional,
	__in	uintptr_t		tdiflags	__optional,
	__out	nt_iosb volatile *	iosb		__optional);


typedef int32_t __cdecl ntapi_sc_shutdown(
	__in	nt_socket *		hssocket,
	__in	uint32_t		afdhow,
	__out	nt_iosb volatile *	iosb		__optional);


typedef int32_t __cdecl ntapi_sc_getsockname(
	__in	nt_socket *		hssocket,
	__in	nt_sockaddr *		addr,
	__in	uint16_t *		addrlen,
	__out	nt_iosb volatile *	iosb		__optional);

typedef int32_t __cdecl ntapi_sc_getpeername(
	__in	nt_socket *		hssocket,
	__in	nt_sockaddr *		addr,
	__in	uint16_t *		addrlen,
	__out	nt_iosb volatile *	iosb		__optional);

typedef int32_t __cdecl ntapi_sc_server_accept_connection(
	__in	nt_socket *		hssocket,
	__out	nt_afd_accept_info *	accept_info,
	__out	nt_iosb volatile *	iosb		__optional);


typedef int32_t __cdecl ntapi_sc_server_duplicate_socket(
	__in	nt_socket *		hssock_listen,
	__in	nt_socket *		hssock_dedicated,
	__in	nt_afd_accept_info *	accept_info,
	__out	nt_iosb volatile *	iosb		__optional);


typedef int32_t __cdecl ntapi_sc_setsockopt(
	__in	nt_socket *		hssocket,
	__in	int32_t			level,
	__in	int32_t			optname,
	__in	const void *		optval,
	__in	uint32_t		optlen,
	__out	nt_iosb volatile *	iosb		__optional);


typedef int32_t __cdecl ntapi_sc_getsockopt(
	__in	nt_socket *		hssocket,
	__in	int32_t			level,
	__in	int32_t			optname,
	__out	void *			optval,
	__in	uint32_t		optlen,
	__out	nt_iosb volatile *	iosb);


typedef int32_t __cdecl ntapi_sc_wait(
	__in	nt_socket *		hssocket,
	__out	nt_iosb volatile *	iosb,
	__in	nt_timeout *		timeout);

#endif