*/
#include <config.h>
+
#include <glib.h>
+#include <string.h>
+#include <stdlib.h>
#include <mono/metadata/object.h>
#include <mono/io-layer/io-layer.h>
#include <mono/metadata/exception.h>
#include <mono/metadata/appdomain.h>
-#ifdef HAVE_SYS_FILIO_H
-#include <sys/filio.h> /* defines FIONBIO and FIONREAD */
-#endif
-#ifdef HAVE_SYS_SOCKIO_H
-#include <sys/sockio.h> /* defines SIOCATMARK */
+#include <sys/time.h>
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
#endif
#undef DEBUG
int *system_level,
int *system_name)
{
- switch(mono_level) {
+ switch (mono_level) {
case SocketOptionLevel_Socket:
- *system_level=SOL_SOCKET;
-
+ *system_level = SOL_SOCKET;
+
switch(mono_name) {
case SocketOptionName_DontLinger:
/* This is SO_LINGER, because the setsockopt
* internal call maps DontLinger to SO_LINGER
* with l_onoff=0
*/
- *system_name=SO_LINGER;
+ *system_name = SO_LINGER;
break;
case SocketOptionName_Debug:
- *system_name=SO_DEBUG;
+ *system_name = SO_DEBUG;
break;
+#ifdef SO_ACCEPTCONN
case SocketOptionName_AcceptConnection:
- *system_name=SO_ACCEPTCONN;
+ *system_name = SO_ACCEPTCONN;
break;
+#endif
case SocketOptionName_ReuseAddress:
- *system_name=SO_REUSEADDR;
+ *system_name = SO_REUSEADDR;
break;
case SocketOptionName_KeepAlive:
- *system_name=SO_KEEPALIVE;
+ *system_name = SO_KEEPALIVE;
break;
case SocketOptionName_DontRoute:
- *system_name=SO_DONTROUTE;
+ *system_name = SO_DONTROUTE;
break;
case SocketOptionName_Broadcast:
- *system_name=SO_BROADCAST;
+ *system_name = SO_BROADCAST;
break;
case SocketOptionName_Linger:
- *system_name=SO_LINGER;
+ *system_name = SO_LINGER;
break;
case SocketOptionName_OutOfBandInline:
- *system_name=SO_OOBINLINE;
+ *system_name = SO_OOBINLINE;
break;
case SocketOptionName_SendBuffer:
- *system_name=SO_SNDBUF;
+ *system_name = SO_SNDBUF;
break;
case SocketOptionName_ReceiveBuffer:
- *system_name=SO_RCVBUF;
+ *system_name = SO_RCVBUF;
break;
case SocketOptionName_SendLowWater:
- *system_name=SO_SNDLOWAT;
+ *system_name = SO_SNDLOWAT;
break;
case SocketOptionName_ReceiveLowWater:
- *system_name=SO_RCVLOWAT;
+ *system_name = SO_RCVLOWAT;
break;
case SocketOptionName_SendTimeout:
- *system_name=SO_SNDTIMEO;
+ *system_name = SO_SNDTIMEO;
break;
case SocketOptionName_ReceiveTimeout:
- *system_name=SO_RCVTIMEO;
+ *system_name = SO_RCVTIMEO;
break;
case SocketOptionName_Error:
- *system_name=SO_ERROR;
+ *system_name = SO_ERROR;
break;
case SocketOptionName_Type:
- *system_name=SO_TYPE;
+ *system_name = SO_TYPE;
break;
case SocketOptionName_ExclusiveAddressUse:
case SocketOptionName_UseLoopback:
break;
case SocketOptionLevel_IP:
- *system_level=SOL_IP;
-
+#ifdef HAVE_SOL_IP
+ *system_level = SOL_IP;
+#else
+ if (1) {
+ static int cached = 0;
+ static int proto;
+
+ if (!cached) {
+ struct protoent *pent;
+
+ pent = getprotobyname ("IP");
+ proto = pent ? pent->p_proto : 0 /* 0 a good default value?? */;
+ cached = 1;
+ }
+
+ *system_level = proto;
+ }
+#endif /* HAVE_SOL_IP */
+
switch(mono_name) {
case SocketOptionName_IPOptions:
- *system_name=IP_OPTIONS;
+ *system_name = IP_OPTIONS;
break;
+#ifdef IP_HDRINCL
case SocketOptionName_HeaderIncluded:
- *system_name=IP_HDRINCL;
+ *system_name = IP_HDRINCL;
break;
+#endif
+#ifdef IP_TOS
case SocketOptionName_TypeOfService:
- *system_name=IP_TOS;
+ *system_name = IP_TOS;
break;
+#endif
+#ifdef IP_TTL
case SocketOptionName_IpTimeToLive:
- *system_name=IP_TTL;
+ *system_name = IP_TTL;
break;
+#endif
case SocketOptionName_MulticastInterface:
- *system_name=IP_MULTICAST_IF;
+ *system_name = IP_MULTICAST_IF;
break;
case SocketOptionName_MulticastTimeToLive:
- *system_name=IP_MULTICAST_TTL;
+ *system_name = IP_MULTICAST_TTL;
break;
case SocketOptionName_MulticastLoopback:
- *system_name=IP_MULTICAST_LOOP;
+ *system_name = IP_MULTICAST_LOOP;
break;
case SocketOptionName_AddMembership:
- *system_name=IP_ADD_MEMBERSHIP;
+ *system_name = IP_ADD_MEMBERSHIP;
break;
case SocketOptionName_DropMembership:
- *system_name=IP_DROP_MEMBERSHIP;
+ *system_name = IP_DROP_MEMBERSHIP;
break;
+#ifdef HAVE_IP_PKTINFO
case SocketOptionName_PacketInformation:
- *system_name=IP_PKTINFO;
+ *system_name = IP_PKTINFO;
break;
+#endif /* HAVE_IP_PKTINFO */
case SocketOptionName_DontFragment:
case SocketOptionName_AddSourceMembership:
case SocketOptionName_DropSourceMembership:
break;
case SocketOptionLevel_Tcp:
- *system_level=SOL_TCP;
-
+#ifdef HAVE_SOL_TCP
+ *system_level = SOL_TCP;
+#else
+ if (1) {
+ static int cached = 0;
+ static int proto;
+
+ if (!cached) {
+ struct protoent *pent;
+
+ pent = getprotobyname ("TCP");
+ proto = pent ? pent->p_proto : 6 /* is 6 a good default value?? */;
+ cached = 1;
+ }
+
+ *system_level = proto;
+ }
+#endif /* HAVE_SOL_TCP */
+
switch(mono_name) {
case SocketOptionName_NoDelay:
- *system_name=TCP_NODELAY;
+ *system_name = TCP_NODELAY;
break;
#if 0
/* The documentation is talking complete
}
#define STASH_SYS_ASS(this) \
- if(system_assembly==NULL) { \
+ if(system_assembly == NULL) { \
system_assembly=this->vtable->klass->image; \
}
return(ret);
}
-static SOCKET Socket_to_SOCKET(MonoObject *socket)
+static SOCKET Socket_to_SOCKET(MonoObject *sockobj)
{
SOCKET sock;
MonoClassField *field;
- field=mono_class_get_field_from_name(socket->vtable->klass, "socket");
- sock=*(SOCKET *)(((char *)socket)+field->offset);
+ field=mono_class_get_field_from_name(sockobj->vtable->klass, "socket");
+ sock=*(SOCKET *)(((char *)sockobj)+field->offset);
return(sock);
}
/* Only one of obj_val, byte_val or int_val has data */
if(obj_val!=NULL) {
+ MonoClassField *field;
struct linger linger;
- struct ip_mreqn mreq;
int valsize;
- MonoClassField *field;
switch(name) {
case SocketOptionName_DontLinger:
ret=setsockopt(sock, system_level, system_name,
&linger, valsize);
break;
-
case SocketOptionName_AddMembership:
case SocketOptionName_DropMembership:
+ {
+#ifdef HAVE_STRUCT_IP_MREQN
+ struct ip_mreqn mreq;
+#else
+ struct ip_mreq mreq;
+#endif /* HAVE_STRUCT_IP_MREQN */
+
/* pain! MulticastOption holds two IPAddress
* members, so I have to dig the value out of
* those :-(
*/
- field=mono_class_get_field_from_name(obj_val->vtable->klass, "group");
- mreq.imr_multiaddr=ipaddress_to_struct_in_addr(*(gpointer *)(((char *)obj_val)+field->offset));
- field=mono_class_get_field_from_name(obj_val->vtable->klass, "local");
- mreq.imr_address=ipaddress_to_struct_in_addr(*(gpointer *)(((char *)obj_val)+field->offset))
-;
- valsize=sizeof(mreq);
- ret=setsockopt(sock, system_level, system_name,
- &mreq, valsize);
+ field = mono_class_get_field_from_name (obj_val->vtable->klass, "group");
+ mreq.imr_multiaddr = ipaddress_to_struct_in_addr (*(gpointer *)(((char *)obj_val) +
+ field->offset));
+ field = mono_class_get_field_from_name (obj_val->vtable->klass, "local");
+#ifdef HAVE_STRUCT_IP_MREQN
+ mreq.imr_address = ipaddress_to_struct_in_addr (*(gpointer *)(((char *)obj_val) +
+ field->offset));
+#else
+ mreq.imr_interface = ipaddress_to_struct_in_addr (*(gpointer *)(((char *)obj_val) +
+ field->offset));
+#endif /* HAVE_STRUCT_IP_MREQN */
+
+ ret = setsockopt (sock, system_level, system_name,
+ &mreq, sizeof (mreq));
break;
-
+ }
default:
/* Throw an exception */
mono_raise_exception(get_socket_exception(WSAEINVAL));
MonoString *addr_string;
char addr[16];
- snprintf(addr, 16, "%u.%u.%u.%u",
+ g_snprintf(addr, 16, "%u.%u.%u.%u",
(unsigned char)he->h_addr_list[i][0],
(unsigned char)he->h_addr_list[i][1],
(unsigned char)he->h_addr_list[i][2],
inet_pton (int family, const char *address, void *inaddrp)
{
if (family == AF_INET) {
+#ifdef HAVE_INET_ATON
struct in_addr inaddr;
if (!inet_aton (address, &inaddr))
memcpy (inaddrp, &inaddr, sizeof (struct in_addr));
return 1;
+#else
+ /* assume the system has inet_addr(), if it doesn't
+ have that we're pretty much screwed... */
+ guint32 inaddr;
+
+ if (!strcmp (address, "255.255.255.255")) {
+ /* special-case hack */
+ inaddr = 0xffffffff;
+ } else {
+ inaddr = inet_addr (address);
+#ifndef INADDR_NONE
+#define INADDR_NONE ((in_addr_t) -1)
+#endif
+ if (inaddr == INADDR_NONE)
+ return 0;
+ }
+
+ memcpy (inaddrp, &inaddr, sizeof (guint32));
+ return 1;
+#endif /* HAVE_INET_ATON */
}
- errno = EAFNOSUPPRT;
return -1;
}
#endif /* !HAVE_INET_PTON */