380 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			380 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 *  ws2tcpip.h : TCP/IP specific extensions in Windows Sockets 2
 | 
						|
 *
 | 
						|
 * Portions Copyright (c) 1980, 1983, 1988, 1993
 | 
						|
 * The Regents of the University of California.  All rights reserved.
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#ifndef _WS2TCPIP_H
 | 
						|
#define _WS2TCPIP_H
 | 
						|
#if __GNUC__ >=3
 | 
						|
#pragma GCC system_header
 | 
						|
#endif
 | 
						|
 | 
						|
#if (defined _WINSOCK_H && !defined _WINSOCK2_H)
 | 
						|
#error "ws2tcpip.h is not compatible with winsock.h. Include winsock2.h instead."
 | 
						|
#endif
 | 
						|
 | 
						|
#include <winsock2.h>
 | 
						|
#ifdef  __cplusplus
 | 
						|
extern "C" {
 | 
						|
#endif
 | 
						|
 | 
						|
/* 
 | 
						|
 * The IP_* macros are also defined in winsock.h, but some values are different there.
 | 
						|
 * The values defined in winsock.h for 1.1 and used in wsock32.dll are consistent
 | 
						|
 * with the original values Steve Deering defined in his document "IP Multicast Extensions
 | 
						|
 * for 4.3BSD UNIX related systems (MULTICAST 1.2 Release)." However, these conflicted with
 | 
						|
 * the definitions for some IPPROTO_IP level socket options already assigned by BSD,
 | 
						|
 * so Berkeley changed all the values by adding 7.  WinSock2 (ws2_32.dll)  uses
 | 
						|
 * the BSD 4.4 compatible values defined here.
 | 
						|
 *
 | 
						|
 * See also: msdn kb article Q257460
 | 
						|
 * http://support.microsoft.com/support/kb/articles/Q257/4/60.asp
 | 
						|
 */
 | 
						|
 | 
						|
/* This is also defined in winsock.h; value hasn't changed */
 | 
						|
#define	IP_OPTIONS  1
 | 
						|
 | 
						|
#define	IP_HDRINCL  2
 | 
						|
/*
 | 
						|
 * These are also be defined in winsock.h,
 | 
						|
 * but values have changed for WinSock2 interface
 | 
						|
 */
 | 
						|
#define IP_TOS			3   /* old (winsock 1.1) value 8 */
 | 
						|
#define IP_TTL			4   /* old value 7 */
 | 
						|
#define IP_MULTICAST_IF		9   /* old value 2 */
 | 
						|
#define IP_MULTICAST_TTL	10  /* old value 3 */
 | 
						|
#define IP_MULTICAST_LOOP	11  /* old value 4 */
 | 
						|
#define IP_ADD_MEMBERSHIP	12  /* old value 5 */
 | 
						|
#define IP_DROP_MEMBERSHIP	13  /* old value 6 */
 | 
						|
#define IP_DONTFRAGMENT		14  /* old value 9 */
 | 
						|
#define IP_ADD_SOURCE_MEMBERSHIP	15
 | 
						|
#define IP_DROP_SOURCE_MEMBERSHIP	16
 | 
						|
#define IP_BLOCK_SOURCE			17
 | 
						|
#define IP_UNBLOCK_SOURCE		18
 | 
						|
#define IP_PKTINFO			19
 | 
						|
 | 
						|
/*
 | 
						|
 * As with BSD implementation, IPPROTO_IPV6 level socket options have
 | 
						|
 * same values as IPv4 counterparts.
 | 
						|
 */
 | 
						|
#define IPV6_UNICAST_HOPS	4
 | 
						|
#define IPV6_MULTICAST_IF	9
 | 
						|
#define IPV6_MULTICAST_HOPS	10
 | 
						|
#define IPV6_MULTICAST_LOOP	11
 | 
						|
#define IPV6_ADD_MEMBERSHIP	12
 | 
						|
#define IPV6_DROP_MEMBERSHIP	13
 | 
						|
#define IPV6_JOIN_GROUP		IPV6_ADD_MEMBERSHIP
 | 
						|
#define IPV6_LEAVE_GROUP	IPV6_DROP_MEMBERSHIP
 | 
						|
#define IPV6_PKTINFO		19
 | 
						|
 | 
						|
#define IP_DEFAULT_MULTICAST_TTL 1 
 | 
						|
#define IP_DEFAULT_MULTICAST_LOOP 1 
 | 
						|
#define IP_MAX_MEMBERSHIPS 20 
 | 
						|
 | 
						|
#define TCP_EXPEDITED_1122  2
 | 
						|
 | 
						|
#define UDP_NOCHECKSUM 1
 | 
						|
 | 
						|
/* INTERFACE_INFO iiFlags */
 | 
						|
#define IFF_UP  1
 | 
						|
#define IFF_BROADCAST   2
 | 
						|
#define IFF_LOOPBACK    4
 | 
						|
#define IFF_POINTTOPOINT    8
 | 
						|
#define IFF_MULTICAST   16
 | 
						|
 | 
						|
#define SIO_GET_INTERFACE_LIST  _IOR('t', 127, u_long)
 | 
						|
 | 
						|
#define INET_ADDRSTRLEN  16
 | 
						|
#define INET6_ADDRSTRLEN 46
 | 
						|
 | 
						|
/* getnameinfo constants */ 
 | 
						|
#define NI_MAXHOST	1025
 | 
						|
#define NI_MAXSERV	32
 | 
						|
 | 
						|
#define NI_NOFQDN 	0x01
 | 
						|
#define NI_NUMERICHOST	0x02
 | 
						|
#define NI_NAMEREQD	0x04
 | 
						|
#define NI_NUMERICSERV	0x08
 | 
						|
#define NI_DGRAM	0x10
 | 
						|
 | 
						|
/* getaddrinfo constants */
 | 
						|
#define AI_PASSIVE	1
 | 
						|
#define AI_CANONNAME	2
 | 
						|
#define AI_NUMERICHOST	4
 | 
						|
 | 
						|
/* getaddrinfo error codes */
 | 
						|
#define EAI_AGAIN	WSATRY_AGAIN
 | 
						|
#define EAI_BADFLAGS	WSAEINVAL
 | 
						|
#define EAI_FAIL	WSANO_RECOVERY
 | 
						|
#define EAI_FAMILY	WSAEAFNOSUPPORT
 | 
						|
#define EAI_MEMORY	WSA_NOT_ENOUGH_MEMORY
 | 
						|
#define EAI_NODATA	WSANO_DATA
 | 
						|
#define EAI_NONAME	WSAHOST_NOT_FOUND
 | 
						|
#define EAI_SERVICE	WSATYPE_NOT_FOUND
 | 
						|
#define EAI_SOCKTYPE	WSAESOCKTNOSUPPORT
 | 
						|
 | 
						|
/*
 | 
						|
 *   ip_mreq also in winsock.h for WinSock1.1,
 | 
						|
 *   but online msdn docs say it is defined here for WinSock2.
 | 
						|
 */ 
 | 
						|
 | 
						|
struct ip_mreq {
 | 
						|
	struct in_addr	imr_multiaddr;
 | 
						|
	struct in_addr	imr_interface;
 | 
						|
};
 | 
						|
 | 
						|
struct ip_mreq_source {
 | 
						|
	struct in_addr	imr_multiaddr;
 | 
						|
	struct in_addr	imr_sourceaddr;
 | 
						|
	struct in_addr	imr_interface;
 | 
						|
};
 | 
						|
 | 
						|
struct ip_msfilter {
 | 
						|
	struct in_addr	imsf_multiaddr;
 | 
						|
	struct in_addr	imsf_interface;
 | 
						|
	u_long		imsf_fmode;
 | 
						|
	u_long		imsf_numsrc;
 | 
						|
	struct in_addr	imsf_slist[1];
 | 
						|
};
 | 
						|
 | 
						|
#define IP_MSFILTER_SIZE(numsrc) \
 | 
						|
   (sizeof(struct ip_msfilter) - sizeof(struct in_addr) \
 | 
						|
   + (numsrc) * sizeof(struct in_addr))
 | 
						|
 | 
						|
struct in_pktinfo {
 | 
						|
	IN_ADDR ipi_addr;
 | 
						|
	UINT    ipi_ifindex;
 | 
						|
};
 | 
						|
typedef struct in_pktinfo IN_PKTINFO;
 | 
						|
 | 
						|
 | 
						|
/* ipv6 */ 
 | 
						|
/* These require XP or .NET Server or use of add-on IPv6 stacks on NT 4
 | 
						|
  or higher */
 | 
						|
 | 
						|
/* This is based on the example given in RFC 2553 with stdint types
 | 
						|
   changed to BSD types.  For now, use these  field names until there
 | 
						|
   is some consistency in MS docs. In this file, we only use the
 | 
						|
   in6_addr structure start address, with casts to get the right offsets
 | 
						|
   when testing addresses */
 | 
						|
  
 | 
						|
struct in6_addr {
 | 
						|
    union {
 | 
						|
        u_char	_S6_u8[16];
 | 
						|
        u_short	_S6_u16[8];
 | 
						|
        u_long	_S6_u32[4];
 | 
						|
        } _S6_un;
 | 
						|
};
 | 
						|
/* s6_addr is the standard name */
 | 
						|
#define s6_addr		_S6_un._S6_u8
 | 
						|
 | 
						|
/* These are GLIBC names */ 
 | 
						|
#define s6_addr16	_S6_un._S6_u16
 | 
						|
#define s6_addr32	_S6_un._S6_u32
 | 
						|
 | 
						|
/* These are used in some MS code */
 | 
						|
#define in_addr6	in6_addr
 | 
						|
#define _s6_bytes	_S6_un._S6_u8
 | 
						|
#define _s6_words	_S6_un._S6_u16
 | 
						|
 | 
						|
typedef struct in6_addr IN6_ADDR,  *PIN6_ADDR, *LPIN6_ADDR;
 | 
						|
 | 
						|
struct sockaddr_in6 {
 | 
						|
	short sin6_family;	/* AF_INET6 */
 | 
						|
	u_short sin6_port; 	/* transport layer port # */
 | 
						|
	u_long sin6_flowinfo;	/* IPv6 traffic class & flow info */
 | 
						|
	struct in6_addr sin6_addr;  /* IPv6 address */
 | 
						|
	u_long sin6_scope_id;	/* set of interfaces for a scope */
 | 
						|
};
 | 
						|
typedef struct sockaddr_in6 SOCKADDR_IN6, *PSOCKADDR_IN6, *LPSOCKADDR_IN6;
 | 
						|
 | 
						|
extern const struct in6_addr in6addr_any;
 | 
						|
extern const struct in6_addr in6addr_loopback;
 | 
						|
/* the above can get initialised using: */ 
 | 
						|
#define IN6ADDR_ANY_INIT        { 0 }
 | 
						|
#define IN6ADDR_LOOPBACK_INIT   { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
 | 
						|
 | 
						|
/* Described in RFC 2292, but not in 2553 */
 | 
						|
/* int IN6_ARE_ADDR_EQUAL(const struct in6_addr * a, const struct in6_addr * b) */
 | 
						|
#define IN6_ARE_ADDR_EQUAL(a, b)	\
 | 
						|
    (memcmp ((void*)(a), (void*)(b), sizeof (struct in6_addr)) == 0)
 | 
						|
 | 
						|
 | 
						|
/* Address Testing Macros 
 | 
						|
 | 
						|
 These macro functions all take const struct in6_addr* as arg.
 | 
						|
 Static inlines would allow type checking, but RFC 2553 says they
 | 
						|
 macros.	 
 | 
						|
 NB: These are written specifically for little endian host */
 | 
						|
 | 
						|
#define IN6_IS_ADDR_UNSPECIFIED(_addr) \
 | 
						|
	(   (((const u_long *)(_addr))[0] == 0)	\
 | 
						|
	 && (((const u_long *)(_addr))[1] == 0)	\
 | 
						|
	 && (((const u_long *)(_addr))[2] == 0)	\
 | 
						|
	 && (((const u_long *)(_addr))[3] == 0))
 | 
						|
 | 
						|
#define IN6_IS_ADDR_LOOPBACK(_addr) \
 | 
						|
	(   (((const u_long *)(_addr))[0] == 0)	\
 | 
						|
	 && (((const u_long *)(_addr))[1] == 0)	\
 | 
						|
	 && (((const u_long *)(_addr))[2] == 0)	\
 | 
						|
	 && (((const u_long *)(_addr))[3] == 0x01000000)) /* Note byte order reversed */
 | 
						|
/*	    (((const u_long *)(_addr))[3] == ntohl(1))  */
 | 
						|
 | 
						|
#define IN6_IS_ADDR_MULTICAST(_addr) (((const u_char *) (_addr))[0] == 0xff)
 | 
						|
 | 
						|
#define IN6_IS_ADDR_LINKLOCAL(_addr) \
 | 
						|
	(   (((const u_char *)(_addr))[0] == 0xfe)	\
 | 
						|
	 && ((((const u_char *)(_addr))[1] & 0xc0) == 0x80))
 | 
						|
 | 
						|
#define IN6_IS_ADDR_SITELOCAL(_addr) \
 | 
						|
	(   (((const u_char *)(_addr))[0] == 0xfe)	\
 | 
						|
	 && ((((const u_char *)(_addr))[1] & 0xc0) == 0xc0))
 | 
						|
 | 
						|
#define IN6_IS_ADDR_V4MAPPED(_addr) \
 | 
						|
	(   (((const u_long *)(_addr))[0] == 0)		\
 | 
						|
	 && (((const u_long *)(_addr))[1] == 0)		\
 | 
						|
	 && (((const u_long *)(_addr))[2] == 0xffff0000)) /* Note byte order reversed */
 | 
						|
/* 	    (((const u_long *)(_addr))[2] == ntohl(0x0000ffff))) */
 | 
						|
 | 
						|
#define IN6_IS_ADDR_V4COMPAT(_addr) \
 | 
						|
	(   (((const u_long *)(_addr))[0] == 0)		\
 | 
						|
	 && (((const u_long *)(_addr))[1] == 0)		\
 | 
						|
	 && (((const u_long *)(_addr))[2] == 0)		\
 | 
						|
	 && (((const u_long *)(_addr))[3] != 0)		\
 | 
						|
	 && (((const u_long *)(_addr))[3] != 0x01000000)) /* Note byte order reversed */
 | 
						|
/*           (ntohl (((const u_long *)(_addr))[3]) > 1 ) */
 | 
						|
 | 
						|
 | 
						|
#define IN6_IS_ADDR_MC_NODELOCAL(_addr)	\
 | 
						|
	(   IN6_IS_ADDR_MULTICAST(_addr)		\
 | 
						|
	 && ((((const u_char *)(_addr))[1] & 0xf) == 0x1)) 
 | 
						|
 | 
						|
#define IN6_IS_ADDR_MC_LINKLOCAL(_addr)	\
 | 
						|
	(   IN6_IS_ADDR_MULTICAST (_addr)		\
 | 
						|
	 && ((((const u_char *)(_addr))[1] & 0xf) == 0x2))
 | 
						|
 | 
						|
#define IN6_IS_ADDR_MC_SITELOCAL(_addr)	\
 | 
						|
	(   IN6_IS_ADDR_MULTICAST(_addr)		\
 | 
						|
	 && ((((const u_char *)(_addr))[1] & 0xf) == 0x5))
 | 
						|
 | 
						|
#define IN6_IS_ADDR_MC_ORGLOCAL(_addr)	\
 | 
						|
	(   IN6_IS_ADDR_MULTICAST(_addr)		\
 | 
						|
	 && ((((const u_char *)(_addr))[1] & 0xf) == 0x8))
 | 
						|
 | 
						|
#define IN6_IS_ADDR_MC_GLOBAL(_addr)	\
 | 
						|
	(   IN6_IS_ADDR_MULTICAST(_addr)	\
 | 
						|
	 && ((((const u_char *)(_addr))[1] & 0xf) == 0xe))
 | 
						|
 | 
						|
 | 
						|
typedef int socklen_t;
 | 
						|
 | 
						|
struct ipv6_mreq {
 | 
						|
	struct in6_addr ipv6mr_multiaddr;
 | 
						|
	unsigned int    ipv6mr_interface;
 | 
						|
};
 | 
						|
typedef struct ipv6_mreq IPV6_MREQ;
 | 
						|
 | 
						|
struct in6_pktinfo {
 | 
						|
	IN6_ADDR ipi6_addr;
 | 
						|
	UINT     ipi6_ifindex;
 | 
						|
};
 | 
						|
typedef struct  in6_pktinfo IN6_PKTINFO;
 | 
						|
 | 
						|
struct addrinfo {
 | 
						|
	int     ai_flags;
 | 
						|
	int     ai_family;
 | 
						|
	int     ai_socktype;
 | 
						|
	int     ai_protocol;
 | 
						|
	size_t  ai_addrlen;
 | 
						|
	char   *ai_canonname;
 | 
						|
	struct sockaddr  *ai_addr;
 | 
						|
	struct addrinfo  *ai_next;
 | 
						|
};
 | 
						|
 | 
						|
#if (_WIN32_WINNT >= 0x0501)
 | 
						|
void WSAAPI freeaddrinfo (struct addrinfo*);
 | 
						|
int WSAAPI getaddrinfo (const char*,const char*,const struct addrinfo*,
 | 
						|
		        struct addrinfo**);
 | 
						|
int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
 | 
						|
		       char*,DWORD,int);
 | 
						|
#else
 | 
						|
/* FIXME: Need WS protocol-independent API helpers.  */
 | 
						|
#endif
 | 
						|
 | 
						|
static __inline char*
 | 
						|
gai_strerrorA(int ecode)
 | 
						|
{
 | 
						|
	static char message[1024+1];
 | 
						|
	DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM
 | 
						|
	              | FORMAT_MESSAGE_IGNORE_INSERTS
 | 
						|
		      | FORMAT_MESSAGE_MAX_WIDTH_MASK;
 | 
						|
	DWORD dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
 | 
						|
  	FormatMessageA(dwFlags, NULL, ecode, dwLanguageId, (LPSTR)message, 1024, NULL);
 | 
						|
	return message;
 | 
						|
}
 | 
						|
static __inline WCHAR*
 | 
						|
gai_strerrorW(int ecode)
 | 
						|
{
 | 
						|
	static WCHAR message[1024+1];
 | 
						|
	DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM
 | 
						|
	              | FORMAT_MESSAGE_IGNORE_INSERTS
 | 
						|
		      | FORMAT_MESSAGE_MAX_WIDTH_MASK;
 | 
						|
	DWORD dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
 | 
						|
  	FormatMessageW(dwFlags, NULL, ecode, dwLanguageId, (LPWSTR)message, 1024, NULL);
 | 
						|
	return message;
 | 
						|
}
 | 
						|
#ifdef UNICODE
 | 
						|
#define gai_strerror gai_strerrorW
 | 
						|
#else
 | 
						|
#define gai_strerror gai_strerrorA
 | 
						|
#endif
 | 
						|
 | 
						|
/* Some older IPv4/IPv6 compatibility stuff */
 | 
						|
 | 
						|
/* This struct lacks sin6_scope_id; retained for use in sockaddr_gen */
 | 
						|
struct sockaddr_in6_old {
 | 
						|
	short   sin6_family;
 | 
						|
	u_short sin6_port;
 | 
						|
	u_long  sin6_flowinfo;
 | 
						|
	struct in6_addr sin6_addr;
 | 
						|
};
 | 
						|
 | 
						|
typedef union sockaddr_gen{
 | 
						|
	struct sockaddr		Address;
 | 
						|
	struct sockaddr_in	AddressIn;
 | 
						|
	struct sockaddr_in6_old	AddressIn6;
 | 
						|
} sockaddr_gen;
 | 
						|
 | 
						|
 | 
						|
typedef struct _INTERFACE_INFO {
 | 
						|
	u_long		iiFlags;
 | 
						|
	sockaddr_gen	iiAddress;
 | 
						|
	sockaddr_gen	iiBroadcastAddress;
 | 
						|
	sockaddr_gen	iiNetmask;
 | 
						|
} INTERFACE_INFO, *LPINTERFACE_INFO;
 | 
						|
 | 
						|
/*
 | 
						|
   The definition above can cause problems on NT4,prior to sp4.
 | 
						|
   To workaround, include the following struct and typedef and
 | 
						|
   #define INTERFACE_INFO OLD_INTERFACE_INFO
 | 
						|
   See: FIX: WSAIoctl SIO_GET_INTERFACE_LIST Option Problem
 | 
						|
   (Q181520) in MSDN KB.
 | 
						|
 | 
						|
   The old definition causes problems on newer NT and on XP.
 | 
						|
 | 
						|
typedef struct _OLD_INTERFACE_INFO {
 | 
						|
	u_long		iiFlags;
 | 
						|
	struct sockaddr	iiAddress;
 | 
						|
 	struct sockaddr	iiBroadcastAddress;
 | 
						|
 	struct sockaddr	iiNetmask;
 | 
						|
} OLD_INTERFACE_INFO;
 | 
						|
*/
 | 
						|
 | 
						|
#ifdef  __cplusplus
 | 
						|
}
 | 
						|
#endif
 | 
						|
#endif
 |