/* GNet - Networking library
* Copyright (C) 2000 David Helder
* Copyright (C) 2000-2003 Andrew Lanoix
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _GNET_PRIVATE_H
#define _GNET_PRIVATE_H
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_LIBPTHREAD
#include <pthread.h>
#endif
#include <glib.h>
#include "gnet.h"
#include "gnetconfig.h"
#ifndef GNET_WIN32 /*********** Unix specific ***********/
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/utsname.h>
#include <sys/wait.h>
#include <netinet/in_systm.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* Need for TOS */
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <netdb.h>
#ifndef HAVE_SOCKADDR_STORAGE
struct sockaddr_storage {
#ifdef HAVE_SOCKADDR_LEN
unsigned char ss_len;
unsigned char ss_family;
#else
unsigned short ss_family;
#endif
char info[126];
};
#endif
#ifndef SOCKET
#define SOCKET gint
#endif
#ifndef socklen_t
# ifdef GNET_APPLE_DARWIN
# define socklen_t int /* socklen_t is int in Darwin */
# else
# define socklen_t size_t /* it's size_t on all other Unixes */
# endif
#endif
#define GNET_CLOSE_SOCKET(SOCKFD) close(SOCKFD)
/* Use gnet_private_io_channel_new() to create iochannels */
#define GNET_SOCKET_IO_CHANNEL_NEW(SOCKFD) g_io_channel_unix_new(SOCKFD)
#define GNET_IS_SOCKET_VALID(S) ((S) >= 0)
#else /*********** Windows specific ***********/
#include <windows.h>
#include <winbase.h>
#include <winuser.h>
#include <ws2tcpip.h>
#define socklen_t gint32
#define in_addr_t guint32
#define GNET_IS_SOCKET_VALID(S) ((S) != INVALID_SOCKET)
#define GNET_CLOSE_SOCKET(SOCKFD) closesocket(SOCKFD)
/* Use gnet_private_io_channel_new() to create iochannels */
#define GNET_SOCKET_IO_CHANNEL_NEW(SOCKFD) g_io_channel_win32_new_socket(SOCKFD)
#endif /*********** End Windows specific ***********/
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
#ifndef IN_LOOPBACKNET /* not defined in Win32 */
#define IN_LOOPBACKNET 127
#endif
#define GNET_SOCKADDR_IN(s) (*((struct sockaddr_in*) &s))
#define GNET_SOCKADDR_SA(s) (*((struct sockaddr*) &s))
#define GNET_SOCKADDR_SA4(s) (*((struct sockaddr_in*) &s))
#define GNET_SOCKADDR_FAMILY(s) ((s).ss_family)
#ifdef HAVE_IPV6
#ifndef IN6_ARE_ADDR_EQUAL
#define IN6_ARE_ADDR_EQUAL(a,b) \
((((unsigned int *) (a))[0] == ((unsigned int *) (b))[0]) && \
(((unsigned int *) (a))[1] == ((unsigned int *) (b))[1]) && \
(((unsigned int *) (a))[2] == ((unsigned int *) (b))[2]) && \
(((unsigned int *) (a))[3] == ((unsigned int *) (b))[3]))
#endif
#define GNET_SOCKADDR_SA6(s) (*((struct sockaddr_in6*) &s))
#define GNET_SOCKADDR_ADDRP(s) (((s).ss_family == AF_INET)?\
(void*)&((struct sockaddr_in*)&s)->sin_addr:\
(void*)&((struct sockaddr_in6*)&s)->sin6_addr)
#define GNET_SOCKADDR_ADDR32(s,n)(((s).ss_family == AF_INET)?\
((struct sockaddr_in*)&s)->sin_addr.s_addr:\
*(guint32*)&((struct sockaddr_in6*)&s)->sin6_addr.s6_addr[(n)*4])
#define GNET_SOCKADDR_ADDR32_SET(s,n,a) if ((s).ss_family == AF_INET) \
((struct sockaddr_in*)&s)->sin_addr.s_addr = a; \
else \
*(guint32*)&((struct sockaddr_in6*)&s)->sin6_addr.s6_addr[(n)*4] = a;
#define GNET_SOCKADDR_ADDRLEN(s) (((s).ss_family == AF_INET)?\
sizeof(struct in_addr):\
sizeof(struct in6_addr))
#define GNET_SOCKADDR_PORT(s) (((s).ss_family == AF_INET)?\
((struct sockaddr_in*)&s)->sin_port:\
((struct sockaddr_in6*)&s)->sin6_port)
#define GNET_SOCKADDR_PORT_SET(s, p) if ((s).ss_family == AF_INET)\
((struct sockaddr_in*)&(s))->sin_port = p;\
else \
((struct sockaddr_in6*)&(s))->sin6_port = p;
#define GNET_SOCKADDR_LEN(s) (((s).ss_family == AF_INET)?\
sizeof(struct sockaddr_in):\
sizeof(struct sockaddr_in6))
#else /* NO IPV6 */
#define GNET_SOCKADDR_ADDRP(s) (void*)&((struct sockaddr_in*)&s)->sin_addr
#define GNET_SOCKADDR_ADDR32(s,n)((struct sockaddr_in*)&s)->sin_addr.s_addr
#define GNET_SOCKADDR_ADDRLEN(s) sizeof(struct in_addr)
#define GNET_SOCKADDR_PORT(s) ((struct sockaddr_in*)&s)->sin_port
#define GNET_SOCKADDR_LEN(s) sizeof(struct sockaddr_in)
#define GNET_SOCKADDR_PORT_SET(s, p) ((struct sockaddr_in*)&(s))->sin_port = p;
#endif
#ifdef HAVE_SOCKADDR_SA_LEN
#define GNET_SOCKADDR_SET_SS_LEN(s) do{(s).ss_len = GNET_SOCKADDR_LEN(s);}while(0)
#else
#define GNET_SOCKADDR_SET_SS_LEN(s) while(0){} /* do nothing */
#endif
#define GNET_INETADDR_SA(i) GNET_SOCKADDR_SA((i)->sa)
#define GNET_INETADDR_SA4(i) GNET_SOCKADDR_SA4((i)->sa)
#define GNET_INETADDR_SA6(i) GNET_SOCKADDR_SA6((i)->sa)
#define GNET_INETADDR_FAMILY(i) GNET_SOCKADDR_FAMILY((i)->sa)
#define GNET_INETADDR_ADDRP(i) GNET_SOCKADDR_ADDRP((i)->sa)
#define GNET_INETADDR_ADDR32(i,n) GNET_SOCKADDR_ADDR32((i)->sa,(n))
#define GNET_INETADDR_ADDRLEN(i) GNET_SOCKADDR_ADDRLEN((i)->sa)
#define GNET_INETADDR_PORT(i) GNET_SOCKADDR_PORT((i)->sa)
#define GNET_INETADDR_PORT_SET(i, p) GNET_SOCKADDR_PORT_SET((i)->sa, p)
#define GNET_INETADDR_LEN(i) GNET_SOCKADDR_LEN((i)->sa)
#define GNET_INETADDR_SET_SS_LEN(i) GNET_SOCKADDR_SET_SS_LEN((i)->sa)
#define GNET_ANY_IO_CONDITION (G_IO_IN|G_IO_OUT|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL)
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*
This is the private declaration and definition file. The things in
here are to be used by GNet ONLY. Use at your own risk. If this
file includes something that you absolutely must have, write the
GNet developers.
*/
struct _GUdpSocket
{
SOCKET sockfd;
guint ref_count;
GIOChannel* iochannel;
struct sockaddr_storage sa;
};
struct _GMcastSocket
{
SOCKET sockfd;
guint ref_count;
GIOChannel* iochannel;
struct sockaddr_storage sa;
};
struct _GTcpSocket
{
SOCKET sockfd;
guint ref_count;
GIOChannel* iochannel;
struct sockaddr_storage sa;
/* sa is remote host for clients, local host for servers */
GTcpSocketAcceptFunc accept_func;
gpointer accept_data;
guint accept_watch;
};
struct _GInetAddr
{
gchar* name;
guint ref_count;
struct sockaddr_storage sa;
};
#ifndef GNET_WIN32 /*********** Unix specific ***********/
struct _GUnixSocket
{
gint sockfd;
guint ref_count;
GIOChannel *iochannel;
struct sockaddr_un sa;
gboolean server;
};
#endif /*********** End Unix specific ***********/
/* **************************************** */
/* Async functions */
gboolean gnet_inetaddr_new_list_async_cb (GIOChannel* iochannel,
GIOCondition condition,
gpointer data);
typedef struct _GInetAddrNewListState
{
GList* ias;
gint port;
GInetAddrNewListAsyncFunc func;
gpointer data;
#ifndef GNET_WIN32 /* UNIX */
gboolean in_callback;
#ifdef HAVE_LIBPTHREAD /* UNIX pthread */
pthread_mutex_t mutex;
gboolean is_cancelled;
gboolean lookup_failed;
guint source;
#else /* UNIX process */
int fd;
pid_t pid;
GIOChannel* iochannel;
guint watch;
int len;
guchar buffer[256];
#endif
#else /* Windows */
gboolean in_callback;
CRITICAL_SECTION mutex;
gboolean is_cancelled;
gboolean lookup_failed;
guint source;
#endif
} GInetAddrNewListState;
typedef struct _GInetAddrNewState
{
GInetAddrNewListAsyncID list_id;
GInetAddrNewAsyncFunc func;
gpointer data;
gboolean in_callback;
} GInetAddrNewState;
gboolean gnet_inetaddr_get_name_async_cb (GIOChannel* iochannel,
GIOCondition condition,
gpointer data);
typedef struct _GInetAddrReverseAsyncState
{
GInetAddr* ia;
GInetAddrGetNameAsyncFunc func;
gpointer data;
gboolean in_callback;
#ifndef GNET_WIN32 /* UNIX */
#ifdef HAVE_LIBPTHREAD /* UNIX pthread */
pthread_mutex_t mutex;
gboolean is_cancelled;
gchar* name;
guint source;
#else /* UNIX process */
int fd;
pid_t pid;
guint watch;
GIOChannel* iochannel;
#endif
guchar buffer[256 + 1];/* Names can only be 256 characters? */
int len;
#else /* WINDOWS */
int WSAhandle;
char hostentBuffer[MAXGETHOSTSTRUCT];
int errorcode;
CRITICAL_SECTION mutex;
gboolean is_cancelled;
gchar* name;
guint source;
#endif
} GInetAddrReverseAsyncState;
gboolean gnet_tcp_socket_new_async_cb (GIOChannel* iochannel,
GIOCondition condition,
gpointer data);
typedef struct _GTcpSocketAsyncState
{
GTcpSocket* socket;
GTcpSocketNewAsyncFunc func;
gpointer data;
gint flags;
GIOChannel* iochannel;
guint connect_watch;
#ifdef GNET_WIN32
gint errorcode;
#endif
} GTcpSocketAsyncState;
void gnet_tcp_socket_connect_inetaddr_cb (GList* ia_list, gpointer data);
void gnet_tcp_socket_connect_tcp_cb(GTcpSocket* socket, gpointer data);
typedef struct _GTcpSocketConnectState
{
GList* ia_list;
GList* ia_next;
gpointer inetaddr_id;
gpointer tcp_id;
gboolean in_callback;
GTcpSocketConnectAsyncFunc func;
gpointer data;
} GTcpSocketConnectState;
/* **************************************** */
/* More Windows specific stuff */
#ifdef GNET_WIN32
extern HWND gnet_hWnd;
extern GHashTable *gnet_hash;
#define IA_NEW_MSG 100 /* gnet_inetaddr_new_async */
#define GET_NAME_MSG 101 /* gnet_inetaddr_get_name_async */
/* Name-mangled IPv6 structures for primarily Mingw and a few VC .NET 2002 */
#ifndef MAX_ADAPTER_ADDRESS_LENGTH
#define MAX_ADAPTER_ADDRESS_LENGTH 8
#endif
#ifndef GAA_FLAG_SKIP_UNICAST
#define GAA_FLAG_SKIP_UNICAST 0x0001
#endif
#ifndef GAA_FLAG_SKIP_ANYCAST
#define GAA_FLAG_SKIP_ANYCAST 0x0002
#endif
#ifndef GAA_FLAG_SKIP_MULTICAST
#define GAA_FLAG_SKIP_MULTICAST 0x0004
#endif
#ifndef GAA_FLAG_SKIP_DNS_SERVER
#define GAA_FLAG_SKIP_DNS_SERVER 0x0008
#endif
/* VC .NET 2002 is missing this too. */
#ifndef GAA_FLAG_INCLUDE_PREFIX
#define GAA_FLAG_INCLUDE_PREFIX 0x0010
#endif
/* VC .NET 2002 is missing this too. */
#ifndef GAA_FLAG_SKIP_FRIENDLY_NAME
#define GAA_FLAG_SKIP_FRIENDLY_NAME 0x0020
#endif
#ifndef IPV6_UNICAST_HOPS
#define IPV6_UNICAST_HOPS 4
#endif
#ifndef IPV6_MULTICAST_LOOP
#define IPV6_MULTICAST_LOOP 11
#endif
#ifndef IPV6_ADD_MEMBERSHIP
#define IPV6_ADD_MEMBERSHIP 12
#endif
#ifndef IPV6_DROP_MEMBERSHIP
#define IPV6_DROP_MEMBERSHIP 13
#endif
#ifndef IPV6_JOIN_GROUP
#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
#endif
#ifndef IPV6_LEAVE_GROUP
#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
#endif
#ifndef IPV6_MULTICAST_HOPS
#define IPV6_MULTICAST_HOPS 10
#endif
typedef enum
{
IpDadStateInvalid_GNET = 0,
IpDadStateTentative_GNET,
IpDadStateDuplicate_GNET,
IpDadStateDeprecated_GNET,
IpDadStatePreferred_GNET
} IP_DAD_STATE_GNET;
typedef enum
{
IpPrefixOriginOther_GNET = 0,
IpPrefixOriginManual_GNET,
IpPrefixOriginWellKnown_GNET,
IpPrefixOriginDhcp_GNET,
IpPrefixOriginRouterAdvertisement_GNET
} IP_PREFIX_ORIGIN_GNET;
typedef enum
{
IpSuffixOriginOther_GNET = 0,
IpSuffixOriginManual_GNET,
IpSuffixOriginWellKnown_GNET,
IpSuffixOriginDhcp_GNET,
IpSuffixOriginLinkLayerAddress_GNET,
IpSuffixOriginRandom_GNET
} IP_SUFFIX_ORIGIN_GNET;
typedef enum
{
IfOperStatusUp_GNET = 1,
IfOperStatusDown_GNET,
IfOperStatusTesting_GNET,
IfOperStatusUnknown_GNET,
IfOperStatusDormant_GNET,
IfOperStatusNotPresent_GNET,
IfOperStatusLowerLayerDown_GNET
} IF_OPER_STATUS_GNET;
typedef struct _IP_ADAPTER_UNICAST_ADDRESS_GNET
{
union
{
struct
{
ULONG Length;
DWORD Flags;
};
};
struct _IP_ADAPTER_UNICAST_ADDRESS_GNET* Next;
SOCKET_ADDRESS Address;
IP_PREFIX_ORIGIN_GNET PrefixOrigin;
IP_SUFFIX_ORIGIN_GNET SuffixOrigin;
IP_DAD_STATE_GNET DadState;
ULONG ValidLifetime;
ULONG PreferredLifetime;
ULONG LeaseLifetime;
} IP_ADAPTER_UNICAST_ADDRESS_GNET, *PIP_ADAPTER_UNICAST_ADDRESS_GNET;
typedef struct _IP_ADAPTER_ANYCAST_ADDRESS_GNET
{
union
{
ULONGLONG Alignment;
struct
{
ULONG Length;
DWORD Flags;
};
};
struct _IP_ADAPTER_ANYCAST_ADDRESS_GNET* Next;
SOCKET_ADDRESS Address;
} IP_ADAPTER_ANYCAST_ADDRESS_GNET, *PIP_ADAPTER_ANYCAST_ADDRESS_GNET;
typedef struct _IP_ADAPTER_DNS_SERVER_ADDRESS_GNET
{
union
{
ULONGLONG Alignment;
struct
{
ULONG Length;
DWORD Reserved;
};
};
struct _IP_ADAPTER_DNS_SERVER_ADDRESS_GNET* Next;
SOCKET_ADDRESS Address;
} IP_ADAPTER_DNS_SERVER_ADDRESS_GNET, *PIP_ADAPTER_DNS_SERVER_ADDRESS_GNET;
typedef struct _IP_ADAPTER_PREFIX_GNET
{
union
{
ULONGLONG Alignment;
struct
{
ULONG Length;
DWORD Flags;
};
};
struct _IP_ADAPTER_PREFIX_GNET* Next;
SOCKET_ADDRESS Address; ULONG PrefixLength;
} IP_ADAPTER_PREFIX_GNET, *PIP_ADAPTER_PREFIX_GNET;
typedef struct _IP_ADAPTER_MULTICAST_ADDRESS_GNET {
union {
ULONGLONG _temp;
struct {
ULONG Length;
DWORD Flags;
};
};
struct _IP_ADAPTER_MULTICAST_ADDRESS_GNET* Next;
SOCKET_ADDRESS Address;
} IP_ADAPTER_MULTICAST_ADDRESS_GNET, *PIP_ADAPTER_MULTICAST_ADDRESS_GNET;
typedef struct _IP_ADAPTER_ADDRESSES_GNET
{
union
{
ULONGLONG Alignment;
struct
{
ULONG Length;
DWORD IfIndex;
};
};
struct _IP_ADAPTER_ADDRESSES_GNET* Next;
PCHAR AdapterName;
PIP_ADAPTER_UNICAST_ADDRESS_GNET FirstUnicastAddress;
PIP_ADAPTER_ANYCAST_ADDRESS_GNET FirstAnycastAddress;
PIP_ADAPTER_MULTICAST_ADDRESS_GNET FirstMulticastAddress;
PIP_ADAPTER_DNS_SERVER_ADDRESS_GNET FirstDnsServerAddress;
PWCHAR DnsSuffix;
PWCHAR Description;
PWCHAR FriendlyName;
BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD PhysicalAddressLength;
DWORD Flags;
DWORD Mtu;
DWORD IfType;
IF_OPER_STATUS_GNET OperStatus;
DWORD Ipv6IfIndex;
DWORD ZoneIndices[16];
PIP_ADAPTER_PREFIX_GNET FirstPrefix;
} IP_ADAPTER_ADDRESSES_GNET, *PIP_ADAPTER_ADDRESSES_GNET;
/* Name-mangled IPv6 structures */
/* Function Pointers to the new IPv6 functions */
HANDLE hLibrary_ws2_32; /* WinSock 2 dll */
HANDLE hLibrary_Iphlpapi; /* for GetAdaptersAddresses() */
typedef int (WINAPI * PFN_GETADDRINFO) (const char*, const char*,
const struct addrinfo FAR *,
struct addrinfo FAR *FAR *);
PFN_GETADDRINFO pfn_getaddrinfo;
typedef int (WINAPI * PFN_GETNAMEINFO) (const struct sockaddr FAR *,
socklen_t, char FAR *, DWORD,
char FAR *, DWORD, int);
PFN_GETNAMEINFO pfn_getnameinfo;
typedef void (WINAPI * PFN_FREEADDRINFO) (struct addrinfo FAR *);
PFN_FREEADDRINFO pfn_freeaddrinfo;
typedef DWORD (WINAPI * PFN_GETADAPTERSADDRESSES) (ULONG, DWORD, PVOID,
PIP_ADAPTER_ADDRESSES_GNET,
PULONG);
PFN_GETADAPTERSADDRESSES pfn_getaddaptersaddresses;
#endif
/* ************************************************************ */
/* Private/Experimental functions */
GIOChannel* gnet_private_io_channel_new (SOCKET sockfd);
SOCKET gnet_private_create_listen_socket (int type, const GInetAddr* iface, int port, struct sockaddr_storage* sa);
int gnet_initialize_windows_sockets(void);
void gnet_uninitialize_windows_sockets(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _GNET_PRIVATE_H */
syntax highlighted by Code2HTML, v. 0.9.1