Ejemplo n.º 1
0
unsigned tcpabi_udp_open( unsigned long ip_dst, unsigned dst_port,
                          unsigned src_port,
                          unsigned char flags, unsigned *local_port ) {
    unsigned long		i;

    //	save all of the paramaters in our array and return the index
    //	that we just used

    if (gDests == nil) {
        gDests = (DestStruct*) NewPtrClear(sizeof(DestStruct) * MAX_DESTS);		//	space for dest records
        if (gDests == nil) {
            return trump_HDL_NONE;
        }
    }

    for (i = 0; i < MAX_DESTS; i++) {
        if (!gDests[i].inUse) {
            break;
        }
    }

    OTInitInetAddress(&gDests[i].dest_addr, dst_port, ip_dst);

    gDests[i].inUse = true;
    gDests[i].ipDest = ip_dst;
    gDests[i].portDest = dst_port;
    gDests[i].portSource = src_port;
    gDests[i].flags = flags;

    *local_port = 0;			//	never used

    return i;
}
Ejemplo n.º 2
0
static pascal OSStatus DoIncomingBind(OTMPEndpointRef ep, InetPort portNum, OTQLen qlen)
{
	OSStatus err;
	TBind req;
	TBind ret;
	InetAddress reqAddr;
	InetAddress retAddr;

	OTInitInetAddress(&reqAddr, portNum, kOTAnyInetAddress);
	OTMemzero(&req, sizeof(req));
	req.addr.len    = sizeof(reqAddr);
	req.addr.buf    = (UInt8 *) &reqAddr;
	req.qlen        = qlen;
		
	OTMemzero(&ret, sizeof(ret));
	ret.addr.maxlen = sizeof(retAddr);
	ret.addr.buf    = (UInt8 *) &retAddr;
	
	err = OTMPXBind(ep, &req, &ret);
	if (err == noErr) {
		char addrAsStr[32];
		
		OTInetHostToString(retAddr.fHost, addrAsStr);
		MPLogPrintf("\n");
		MPLogPrintf("Bound to = %s:%d with qlen of %d\n", addrAsStr, retAddr.fPort, ret.qlen);
	}
	return err;
}
Ejemplo n.º 3
0
void do_write(OTUDP *x, long length, void *bytes) {
	/* This should never be called at interrupt level */
	OSStatus err;
	InetAddress dest_addr;
	TUnitData udata;

			
	OTInitInetAddress(&dest_addr, x->o_inetPort, x->o_inetHost);
	udata.addr.len = sizeof(dest_addr);
	udata.addr.buf = (unsigned char *) &dest_addr;
	udata.opt.len = 0;
	udata.opt.buf = nil;
	
	udata.udata.len = length;
	udata.udata.buf = bytes;
	
	err = OTSndUData(x->o_udp_ep, &udata);
	
	if (err == kOTBadSyncErr) {
		error("¥ OTUDP: failed to send data at interrupt level.  Try turning off overdrive.");
	} else if (err == kEHOSTUNREACHErr) {
		error("OTUDP: Host address is unreachable; couldn't send packet");
		post("Make sure you're really on a network.");
	} else if (err != noErr) {
		error("¥ OTUDP: OTSndUData returned error code %ld.", err);
	}
}
Ejemplo n.º 4
0
int TCPLow_PutPacket(TCPINSTANCE* tcp, TCPPEER* pPeer,void* bufptr,ULONG len)
{
	TUnitData	udata;
	OSStatus	err;
	OTResult	theResult;
	InetAddress	destAddr;
	unsigned char *pt;
	
	OTInitInetAddress(&destAddr,pPeer->port,pPeer->addr);
	
	udata.addr.maxlen = sizeof(InetAddress);
	udata.addr.len = sizeof(InetAddress);
	udata.addr.buf = (unsigned char *) &destAddr;
	
	udata.opt.maxlen = 0;
	udata.opt.len = 0;
	udata.opt.buf = nil;
	
	udata.udata.maxlen = len;
	udata.udata.len = len;
	udata.udata.buf = (unsigned char *)bufptr;
	
	do {
		err = OTSndUData(tcp->udpEndpoint, &udata);
		if (err == kOTLookErr) {
			theResult = OTLook(tcp->udpEndpoint);
			if (theResult == T_UDERR) {
				HandleErrorUDERR();
				err = 666;
			}
		}
	} while (err == 666);

	return err;
}
Ejemplo n.º 5
0
OTIPEndpoint::OTIPEndpoint(
	NMEndpointRef	inRef,
	NMUInt32			inMode)
		: OTEndpoint(inRef, inMode)
{	
NMBoolean	success;

//%% TO DO: What happens if the config doesn't cause one or both of these to be setup?
//				Is this OK, or should the process have stopped before we reach this routine?

	//    Each endpoint stores its local and its remote address
    if( mMode & kNMStreamMode && mStreamEndpoint)		//LR make sure we don't crash
    {
		success = AllocAddressBuffer(&mStreamEndpoint->mLocalAddress);
		op_assert(success);
	        OTInitInetAddress((InetAddress*)mStreamEndpoint->mLocalAddress.buf,0,0);
		
		success = AllocAddressBuffer(&mStreamEndpoint->mRemoteAddress);
		op_assert(success);
        OTInitInetAddress((InetAddress*)mStreamEndpoint->mRemoteAddress.buf,0,0);
    }

    if( mMode & kNMDatagramMode && mDatagramEndpoint)		//LR make sure we don't crash
    {
		success = AllocAddressBuffer(&mDatagramEndpoint->mLocalAddress);
		op_assert(success);
	        OTInitInetAddress((InetAddress*)mDatagramEndpoint->mLocalAddress.buf,0,0);
		
		success = AllocAddressBuffer(&mDatagramEndpoint->mRemoteAddress);
		op_assert(success);
        OTInitInetAddress((InetAddress*)mDatagramEndpoint->mRemoteAddress.buf,0,0);
    }
	
	//	Alloc the address buffer for the TCall structure
	success = AllocAddressBuffer(&mCall.addr);
	op_assert(success);
		
	success = AllocAddressBuffer(&mRcvUData.addr);
	op_assert(success);

	mEnumerationResponseData = NULL;
	mEnumerationResponseLen = 0;

	mPreprocessBuffer = new NMUInt8[kQuerySize];
}
Ejemplo n.º 6
0
Archivo: gsocket.c Proyecto: EdgarTx/wx
GSocketError _GAddress_translate_to(GAddress *address,
                                    InetAddress *addr)
{
 if ( GSocket_Verify_Inited() == FALSE )
    return GSOCK_IOERR ;
  memset(addr, 0 , sizeof(struct InetAddress));
  OTInitInetAddress( addr , address->m_port , address->m_host ) ;
  return GSOCK_NOERROR;
}
Ejemplo n.º 7
0
void
OTIPEndpoint::SetConfig(NMIPConfigPriv *inConfig)
{
	if (inConfig == NULL)
	{
		mConfig.type = kModuleID;
		mConfig.version = kVersion;
		mConfig.customEnumDataLen = 0;
		OTInitInetAddress((InetAddress *) &mConfig.address, 0, 0);
	}
	else
	{
		mConfig = *inConfig;
	}
}
Ejemplo n.º 8
0
int tcpabi_udp_broadcast(void *buf, unsigned len) {
    OSStatus			err = noErr;
    TUnitData			udata;
    OTResult			theResult;
    short				i;
    InetAddress			currentAddress;

    //	this method sends the specified packet to our list of
    //	IP addreses. We return noErr if they were all sent
    //	without any trouble (we should ignore errors which
    //	indicate that the other end is not there since we
    //	really don't care if all of these packets are delivered)

    //	we don't broadcast to the first address because it's our own

    for (i = 1; i < gAddressList.addressCount; i++) {

        OTInitInetAddress(&currentAddress, SOCKET_MW2, gAddressList.addressList[i]);

        udata.addr.maxlen = sizeof(InetAddress);
        udata.addr.len = sizeof(InetAddress);
        udata.addr.buf = (unsigned char *) &currentAddress;

        udata.opt.maxlen = 0;
        udata.opt.len = 0;
        udata.opt.buf = nil;

        udata.udata.maxlen = len;
        udata.udata.len = len;
        udata.udata.buf = (unsigned char *)buf;

        do {
            err = OTSndUData(gUDPEndpoint, &udata);
            if (err == kOTLookErr) {
                theResult = OTLook(gUDPEndpoint);
                if (theResult == T_UDERR) {
                    HandleErrorUDERR();
                    err = 666;
                }
            }
        } while (err == 666);

    }

    return err;
}
Ejemplo n.º 9
0
/*---------------------------------------------------------------------------*/
static sword AGNetConnect(AGNetCtx *ctx, AGSocket *soc, uint32 laddr,
                          int16 port, AGBool _block)
{
    InetAddress hostInetAddress;
    TCall sndCall;
    
    if (NULL == ctx || NULL == soc)
        return AG_NET_ERROR;

    sndCall.addr.buf = (uint8*)&hostInetAddress;
    sndCall.addr.len = sizeof(InetAddress);
    OTInitInetAddress(&hostInetAddress, port, (InetHost)laddr);
    sndCall.opt.buf = NULL;
    sndCall.opt.len = 0;
    sndCall.udata.buf = NULL;
    sndCall.udata.len = 0;
    sndCall.sequence = 0;

    return AGNetMacMapError(OTConnect(soc->ep, &sndCall, NULL));
}
Ejemplo n.º 10
0
void BindTheEndpoint(OTUDP *x) {
	// This will be called from within our notifier function after the endpoint is created,
	// or, when changing hosts, to re-bind the endpoint after unbinding it.
	OSStatus err;

	
	/* Set up the data structure OTBind will use to say what port number we got */
	x->o_bindAddrWeActuallyGot.addr.maxlen = sizeof(struct InetAddress);
	x->o_bindAddrWeActuallyGot.addr.buf = (unsigned char *) &(x->o_addrWeActuallyGot);
	
	if (x->o_writer) {
		/* Let OTBind pick a return address port number for us */
  	    err = OTBind(x->o_udp_ep, nil, &(x->o_bindAddrWeActuallyGot));
		if (err != kOTNoError) {
			error("¥ otudp: Error %d from OTBind.  You may not be able to write.", err);
			return;
		}
	} else {
		/* Tell OTBind what port number we want to use */
		struct InetAddress desiredAddress;
		TBind bindDesiredAddress;

		OTInitInetAddress(&desiredAddress, x->o_receiveInetPort, (InetHost) 0);
		
		bindDesiredAddress.addr.maxlen = sizeof(struct InetAddress);
		bindDesiredAddress.addr.len = sizeof(struct InetAddress);
		bindDesiredAddress.addr.buf = (unsigned char *) &desiredAddress;

		err = OTBind(x->o_udp_ep, &bindDesiredAddress, &(x->o_bindAddrWeActuallyGot));

		if (err != kOTNoError) {
			error("¥ otudp: Error %d from OTBind.  You may not be able to read.", err);
			return;
		}
		
	}
	
	/* Could output something to let the Max programmer know that we're now re-bound... */

}
Ejemplo n.º 11
0
NMErr
OTIPEnumerator::SendQuery(void)
{
	DEBUG_ENTRY_EXIT("IPEnumerator::SendQuery");

TUnitData	udata;
OTResult	result;
InetAddress	broadcastAddr;
	
	//	Set up the unit data structure
	//	fBroadcastAddr doesn't seem to get set right, so construct it
	OTInitInetAddress(&broadcastAddr, mConfig.address.fPort, mInterfaceInfo.fAddress | ~mInterfaceInfo.fNetmask);

	udata.addr.buf = (NMUInt8 *) &broadcastAddr;
	udata.addr.len = sizeof (InetAddress);
	udata.opt.len = 0;
	udata.udata.len = kQuerySize;
	udata.udata.buf = mPacketData;
	
	do
	{
		result = OTSndUData(mEP, &udata);

		if (result < 0)
		{
			DEBUG_PRINT("OTSndUData returned an error: %ld", result);

			if (result == kOTLookErr)
				HandleLookErr();
		}
	} while (result != kNMNoError && result == kOTLookErr);
	
	//	Set the timestamp so that we'll know when to ping again
	OTGetTimeStamp(&mLastQueryTimeStamp);
	
	return result;
}
Ejemplo n.º 12
0
int connect_chuukei_server(char *prf_name)
{
#ifndef MACINTOSH

#ifdef WINDOWS
	WSADATA wsaData;
	WORD wVersionRequested = (WORD) (( 1) |  ( 1 << 8));
#endif

	struct sockaddr_in ask;
	struct hostent *hp;

	if (read_chuukei_prf(prf_name) < 0)
	{
		printf("Wrong prf file\n");
		return (-1);
	}

	if (init_buffer() < 0)
	{
		printf("Malloc error\n");
		return (-1);
	}

#ifdef WINDOWS
	if (WSAStartup(wVersionRequested, &wsaData))
	{
		msg_print("Report: WSAStartup failed.");
		return (-1);
	}
#endif

	printf("server = %s\nport = %d\n", server_name, server_port);

	if ((hp = gethostbyname(server_name)) != NULL)
	{
		memset(&ask, 0, sizeof(ask));
		memcpy(&ask.sin_addr, hp->h_addr_list[0], hp->h_length);
	}
	else
	{
		if ((ask.sin_addr.s_addr=inet_addr(server_name)) == 0)
		{
			printf("Bad hostname\n");
			return (-1);
		}
	}

	ask.sin_family = AF_INET;
	ask.sin_port = htons((unsigned short)server_port);

#ifndef WINDOWS
	if ((sd=socket(PF_INET,SOCK_STREAM, 0)) < 0)
#else
	if ((sd=socket(PF_INET,SOCK_STREAM, 0)) == INVALID_SOCKET)
#endif
	{
		printf("Can't create socket\n");
		return (-1);
	}

	if (connect(sd, (struct sockaddr *)&ask, sizeof(ask)) < 0)
	{
		close(sd);
		printf("Can't connect %s port %d\n", server_name, server_port);
		return (-1);
	}

	return (0);
#else	/* MACINTOSH */
	OSStatus err;
	InetHostInfo 	response;
	InetHost 		host_addr;
	InetAddress 	inAddr;
	TCall 			sndCall;
	Boolean			bind	= false;
	OSStatus 	junk;

	if (read_chuukei_prf(prf_name) < 0){
		printf("Wrong prf file\n");
		return (-1);
	}
	
	init_buffer();
	
	printf("server = %s\nport = %d\n", server_name, server_port);


#if TARGET_API_MAC_CARBON
	err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL);
#else
	err = InitOpenTransport();
#endif

	memset(&response, 0, sizeof(response));


#if TARGET_API_MAC_CARBON
	inet_services = OTOpenInternetServicesInContext(kDefaultInternetServicesPath, 0, &err, NULL);
#else
	inet_services = OTOpenInternetServices(kDefaultInternetServicesPath, 0, &err);
#endif
	
	if (err == noErr) {
		err = OTInetStringToAddress(inet_services, (char *)server_name, &response);
		
		if (err == noErr) {
			host_addr = response.addrs[0];
		} else {
			printf("Bad hostname\n");
		}
		
#if TARGET_API_MAC_CARBON
		ep = (void *)OTOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0, nil, &err, NULL);
#else
		ep = (void *)OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err);
#endif

		if (err == noErr) {
			err = OTBind(ep, nil, nil);
			bind = (err == noErr);
	    }
	    if (err == noErr){
		OTInitInetAddress(&inAddr, server_port, host_addr);
			
			sndCall.addr.len 	= sizeof(InetAddress);				
			sndCall.addr.buf	= (unsigned char*) &inAddr;
			sndCall.opt.buf 	= nil;		/* no connection options */
			sndCall.opt.len 	= 0;
			sndCall.udata.buf 	= nil;		/* no connection data */
			sndCall.udata.len 	= 0;
			sndCall.sequence 	= 0;		/* ignored by OTConnect */
			
			err = OTConnect(ep, &sndCall, NULL);
			
			if( err != noErr ){
				printf("Can't connect %s port %d\n", server_name, server_port);
			}
		}
		
		err = OTSetSynchronous(ep);
		if (err == noErr)		
			err = OTSetBlocking(ep);
		
	}
	
	if( err != noErr ){
		if( bind ){
			OTUnbind(ep);
		}
		/* Clean up. */
		if (ep != kOTInvalidEndpointRef) {
			OTCloseProvider(ep);
			ep = nil;
		}
		if (inet_services != nil) {
			OTCloseProvider(inet_services);
			inet_services = nil;
		}
	
		return -1;
	}
	
	return 0;

#endif
}
Ejemplo n.º 13
0
/* Send a vector of packets to the the channels specified within the packet.
   If the channel specified in the packet is -1, the packet will be sent to
   the address in the 'src' member of the packet.
   Each packet will be updated with the status of the packet after it has 
   been sent, -1 if the packet send failed.
   This function returns the number of packets sent.
*/
int SDLNet_UDP_SendV(UDPsocket sock, UDPpacket **packets, int npackets)
{
	int numsent, i, j;
	struct UDP_channel *binding;
	int status;
#ifndef MACOS_OPENTRANSPORT
	int sock_len;
	struct sockaddr_in sock_addr;

	/* Set up the variables to send packets */
	sock_len = sizeof(sock_addr);
#endif

	numsent = 0;
	for ( i=0; i<npackets; ++i ) 
	{
		/* if channel is < 0, then use channel specified in sock */
		
		if ( packets[i]->channel < 0 ) 
		{
#ifdef MACOS_OPENTRANSPORT
		TUnitData OTpacket;
		InetAddress address;

			memset(&OTpacket, 0, sizeof(OTpacket));
			OTpacket.addr.buf = (Uint8 *)&address;
			OTpacket.addr.len = (sizeof address);
			OTpacket.udata.buf = packets[i]->data;
			OTpacket.udata.len = packets[i]->len;
			OTInitInetAddress(&address, packets[i]->address.port, packets[i]->address.host);
#ifdef DEBUG_NET
			printf("Packet send address: 0x%8.8x:%d, length = %d\n", packets[i]->address.host, packets[i]->address.port, packets[i]->len);
#endif
			
			status = OTSndUData(sock->channel, &OTpacket);
#ifdef DEBUG_NET
			printf("SDLNet_UDP_SendV   OTSndUData return value is ;%d\n", status );
#endif

			AsyncUDPPopEvent( sock );
			packets[i]->status = status;
			
			if (status == noErr)
			{
				++numsent;
			}
#else
			sock_addr.sin_addr.s_addr = packets[i]->address.host;
			sock_addr.sin_port = packets[i]->address.port;
			sock_addr.sin_family = AF_INET;
			status = sendto(sock->channel, 
					packets[i]->data, packets[i]->len, 0,
					(struct sockaddr *)&sock_addr,sock_len);
			if ( status >= 0 )
			{
				packets[i]->status = status;
				++numsent;
			}
#endif /* MACOS_OPENTRANSPORT */
		}
		else 
		{
			/* Send to each of the bound addresses on the channel */
#ifdef DEBUG_NET
			printf("SDLNet_UDP_SendV sending packet to channel = %d\n", packets[i]->channel );
#endif
			
			binding = &sock->binding[packets[i]->channel];
			
			for ( j=binding->numbound-1; j>=0; --j ) 
			{
#ifdef MACOS_OPENTRANSPORT
			TUnitData OTpacket;
			InetAddress address;

				OTInitInetAddress(&address, binding->address[j].port,binding->address[j].host);
#ifdef DEBUG_NET
				printf("Packet send address: 0x%8.8x:%d, length = %d\n", binding->address[j].host, binding->address[j].port, packets[i]->len);
#endif
				memset(&OTpacket, 0, sizeof(OTpacket));
				OTpacket.addr.buf = (Uint8 *)&address;
				OTpacket.addr.len = (sizeof address);
				OTpacket.udata.buf = packets[i]->data;
				OTpacket.udata.len = packets[i]->len;
			                              
				status = OTSndUData(sock->channel, &OTpacket);
#ifdef DEBUG_NET
				printf("SDLNet_UDP_SendV   OTSndUData returne value is;%d\n", status );
#endif
				AsyncUDPPopEvent(sock);
				packets[i]->status = status;
				
				if (status == noErr)
				{
					++numsent;
				}

#else
				sock_addr.sin_addr.s_addr = binding->address[j].host;
				sock_addr.sin_port = binding->address[j].port;
				sock_addr.sin_family = AF_INET;
				status = sendto(sock->channel, 
						packets[i]->data, packets[i]->len, 0,
						(struct sockaddr *)&sock_addr,sock_len);
				if ( status >= 0 )
				{
					packets[i]->status = status;
					++numsent;
				}
#endif /* MACOS_OPENTRANSPORT */
			}
		}
	}
	
	return(numsent);
}
Ejemplo n.º 14
0
/* Open a UDP network socket
   If 'port' is non-zero, the UDP socket is bound to a fixed local port.
*/
extern UDPsocket SDLNet_UDP_Open(Uint16 port)
{
	UDPsocket sock;
#ifdef MACOS_OPENTRANSPORT
	EndpointRef dummy = NULL;
#endif

	/* Allocate a UDP socket structure */
	sock = (UDPsocket)malloc(sizeof(*sock));
	if ( sock == NULL ) {
		SDLNet_SetError("Out of memory");
		goto error_return;
	}
	memset(sock, 0, sizeof(*sock));
	
	/* Open the socket */
#ifdef MACOS_OPENTRANSPORT
	{
		sock->error = OTAsyncOpenEndpoint(
			OTCreateConfiguration(kUDPName),0, &(sock->info),
			(OTNotifyProcPtr)AsyncUDPNotifier, sock );
		AsyncUDPPopEvent( sock );
		while( !sock->error && !( sock->completion & CompleteMask(T_OPENCOMPLETE)))
		{
			AsyncUDPPopEvent( sock );
		}
		if( sock->error )
		{
			SDLNet_SetError("Could not open UDP socket");
			goto error_return;
		}
		// Should we ??
		// (01/05/03 minami<*****@*****.**>
		OTSetBlocking( sock->channel );
	}
#else
	sock->channel = socket(AF_INET, SOCK_DGRAM, 0);
#endif /* MACOS_OPENTRANSPORT */

	if ( sock->channel == INVALID_SOCKET ) 
	{
		SDLNet_SetError("Couldn't create socket");
		goto error_return;
	}

#ifdef MACOS_OPENTRANSPORT
	{
	InetAddress required, assigned;
	TBind req_addr, assigned_addr;
	OSStatus status;
	InetInterfaceInfo info;
		
		memset(&assigned_addr, 0, sizeof(assigned_addr));
		assigned_addr.addr.maxlen = sizeof(assigned);
		assigned_addr.addr.len = sizeof(assigned);
		assigned_addr.addr.buf = (UInt8 *) &assigned;
		
		if ( port ) {
			status = OTInetGetInterfaceInfo( &info, kDefaultInetInterface );
			if( status != kOTNoError )
				goto error_return;
			OTInitInetAddress(&required, port, info.fAddress );
			req_addr.addr.maxlen = sizeof( required );
			req_addr.addr.len = sizeof( required );
			req_addr.addr.buf = (UInt8 *) &required;
		
			sock->error = OTBind(sock->channel, &req_addr, &assigned_addr);
		} else {
			sock->error = OTBind(sock->channel, nil, &assigned_addr );
		}
		AsyncUDPPopEvent(sock);

		while( !sock->error && !(sock->completion & CompleteMask(T_BINDCOMPLETE)))
		{
			AsyncUDPPopEvent(sock);
		}	
		if (sock->error != noErr)
		{
			SDLNet_SetError("Couldn't bind to local port, OTBind() = %d",(int) status);
			goto error_return;
		}

		sock->address.host = assigned.fHost;
		sock->address.port = assigned.fPort;
		
#ifdef DEBUG_NET
		printf("UDP open host = %d, port = %d\n", assigned.fHost, assigned.fPort );
#endif
	}
#else
	/* Bind locally, if appropriate */
	if ( port )
	{
		struct sockaddr_in sock_addr;
		memset(&sock_addr, 0, sizeof(sock_addr));
		sock_addr.sin_family = AF_INET;
		sock_addr.sin_addr.s_addr = INADDR_ANY;
		sock_addr.sin_port = SDL_SwapBE16(port);

		/* Bind the socket for listening */
		if ( bind(sock->channel, (struct sockaddr *)&sock_addr,
				sizeof(sock_addr)) == SOCKET_ERROR ) {
			SDLNet_SetError("Couldn't bind to local port");
			goto error_return;
		}
		/* Fill in the channel host address */
		sock->address.host = sock_addr.sin_addr.s_addr;
		sock->address.port = sock_addr.sin_port;
	}

	/* Allow LAN broadcasts with the socket */
	{ int yes = 1;
		setsockopt(sock->channel, SOL_SOCKET, SO_BROADCAST, (char*)&yes, sizeof(yes));
	}
#endif /* MACOS_OPENTRANSPORT */

	/* The socket is ready */
	
	return(sock);

error_return:
#ifdef MACOS_OPENTRANSPORT
	if( dummy )
		OTCloseProvider( dummy );
#endif
	SDLNet_UDP_Close(sock);
	
	return(NULL);
}
Ejemplo n.º 15
0
static NMErr
ParseConfigString(
    const char		*inConfigStr,
    NMType			inGameID,
    const char		*inGameName,
    const void		*inEnumData,
    NMUInt32			inDataLen,
    NMIPConfigPriv	*outConfig)
{
    NMErr	status = kNMNoError;
    NMInetPort	port = GenerateDefaultPort(inGameID);
    InetHost	host = 0x7f000001;		// loopback address
    NMBoolean	gotToken;
    NMSInt32	tokenLen;
    char		workString[kMaxHostNameLen + 1];
    NMUInt32		p;

    outConfig->type = kModuleID;
    outConfig->version = kVersion;

    outConfig->gameID = inGameID;
    outConfig->connectionMode = kNMNormalMode;

    if (inGameName)
    {
        strncpy(outConfig->name, inGameName, kMaxGameNameLen);
        outConfig->name[kMaxGameNameLen]= 0;
    }
    else
    {
        strcpy(outConfig->name, "unknown");
    }

    if (inDataLen)
    {
        if (inDataLen > kNMEnumDataLen)
            return kNMInvalidConfigErr;

        op_assert(inDataLen <= kNMEnumDataLen);
        machine_move_data(inEnumData, outConfig->customEnumData, inDataLen);
        outConfig->customEnumDataLen = inDataLen;
    }
    else
    {
        outConfig->customEnumDataLen = 0;
    }

    if (OTUtils::OTInitialized())
    {
        OTInitInetAddress((InetAddress *)&outConfig->address, port, host);
    }
    else
    {
        op_vpause("Classic not supported!");
    }

    //  default netSprocketMode
    outConfig->netSprocketMode = kDefaultNetSprocketMode;

    //	If we got a null string, just create a default config
    if (inConfigStr == NULL)
        return kNMNoError;

    //Try_
    {
        //	Generic module information

        //	Read the type
        tokenLen = sizeof (NMType);
        gotToken = get_token(inConfigStr, kConfigModuleType, LONG_DATA, &outConfig->type, &tokenLen);
        if (!gotToken)
            outConfig->type = kModuleID;

        //	Read the version
        tokenLen = sizeof (NMUInt32);
        gotToken = get_token(inConfigStr, kConfigModuleVersion, LONG_DATA, &outConfig->version, &tokenLen);

        if (!gotToken)
            outConfig->version = kVersion;

        //	Read the game id
        tokenLen = sizeof (NMUInt32);
        gotToken = get_token(inConfigStr, kConfigGameID, LONG_DATA, &outConfig->gameID, &tokenLen);

        if (!gotToken)
            outConfig->gameID = 0;

        //	Read the game name
        if (inGameName == NULL || inGameName[0] == 0)
        {
            tokenLen = kMaxGameNameLen;
            gotToken = get_token(inConfigStr, kConfigGameName, STRING_DATA, &outConfig->name, &tokenLen);

            if (!gotToken)
                strcpy(outConfig->name, "unknown");
        }

        //	Read the connection mode
        tokenLen = sizeof (NMUInt32);
        gotToken = get_token(inConfigStr, kConfigEndpointMode, LONG_DATA, &outConfig->connectionMode, &tokenLen);

        if (! gotToken)
            outConfig->connectionMode = kNMNormalMode;

        //	Read the netSprocketMode mode
        tokenLen = sizeof (NMBoolean);
        gotToken = get_token(inConfigStr, kConfigNetSprocketMode, BOOLEAN_DATA, &outConfig->netSprocketMode, &tokenLen);

        if (!gotToken)
            outConfig->netSprocketMode = kDefaultNetSprocketMode;

        //	read the custom data, if any
        if (inDataLen == 0)
        {
            tokenLen = kNMEnumDataLen;
            gotToken = get_token(inConfigStr, kConfigCustomData, BINARY_DATA, &outConfig->customEnumData, &tokenLen);

            if (gotToken)
                outConfig->customEnumDataLen = tokenLen;
        }

        //	IP Module-specific information

        //	Read the dotted quad IP address
        tokenLen = kMaxHostNameLen;
        gotToken = get_token(inConfigStr, kIPConfigAddress, STRING_DATA, workString, &tokenLen);

        if (! gotToken)
        {
            outConfig->address.fHost = host;
        }
        else
        {
            //	This is OT-dependent, and could cause the PPP module to dial-in.
            //	It will also fail if DNS is not available
            status = OTUtils::MakeInetAddressFromString(workString, &outConfig->address);
        }

        if (outConfig->address.fPort == 0)
            outConfig->address.fPort = port;

        //	Read the port.  We don't care if it's not present.  It might have been in the address
        tokenLen = sizeof (NMUInt32);
        gotToken = get_token(inConfigStr, kIPConfigPort, LONG_DATA, &p, &tokenLen);

        if (gotToken)
            outConfig->address.fPort = p;

        return kNMNoError;
    }
    //Catch_(code)
error:
    if (status)
    {
        NMErr code = status;
        return code;
    }
    return status;
}
Ejemplo n.º 16
0
/* Open a TCP network socket
   If 'remote' is NULL, this creates a local server socket on the given port,
   otherwise a TCP connection to the remote host and port is attempted.
   The newly created socket is returned, or NULL if there was an error.

   ( re-written by masahiro minami<*****@*****.**>
     Now endpoint is created in Async mode.
     01/02/20 )
*/
TCPsocket SDLNet_TCP_Open(IPaddress *ip)
{
	EndpointRef dummy = NULL;

	TCPsocket sock = AsyncTCPNewSocket();
	if( ! sock)
		return NULL;

	// Determin whether bind locally, or connect to remote
	if ( (ip->host != INADDR_NONE) && (ip->host != INADDR_ANY) )
	{
		// ######## Connect to remote
		OTResult stat;
		InetAddress inAddr;
		TBind bindReq;

		// Open endpoint
		sock->error = OTAsyncOpenEndpoint(
			OTCreateConfiguration(kTCPName), NULL, &(sock->info),
			(OTNotifyProcPtr)(AsyncTCPNotifier),
			sock );

		AsyncTCPPopEvent( sock );
		while( !sock->error && !( sock->completion & CompleteMask(T_OPENCOMPLETE)))
		{
			//SetThreadState( kCurrentThreadID, kReadyThreadState, kNoThreadID );
			//YieldToAnyThread();
			//WaitNextEvent(everyEvent, &macEvent, 1, NULL);
			AsyncTCPPopEvent( sock );
		}

		if( !sock->channel )
		{
			SDLNet_SetError("OTAsyncOpenEndpoint failed --- client socket could not be opened");
			goto error_return;
		}

		// Set blocking mode
		// I'm not sure if this is a good solution....
		// Check out Apple's sample code, OT Virtual Server
		// ( 010314 masahiro minami<*****@*****.**>)

		sock->error = OTSetBlocking( sock->channel );
		if( sock->error != kOTNoError )
		{
			SDLNet_SetError("OTSetBlocking() returned an error");
			goto error_return;
		}

		// Bind the socket
		OTInitInetAddress(&inAddr, 0, 0 );
		bindReq.addr.len = sizeof( InetAddress );
		bindReq.addr.buf = (unsigned char*)&inAddr;
		bindReq.qlen = 0;

		sock->error = OTBind( sock->channel, &bindReq, NULL );
		AsyncTCPPopEvent(sock);
		while( !sock->error && !( sock->completion & CompleteMask(T_BINDCOMPLETE)))
		{
			//YieldToAnyThread();
			//WaitNextEvent(everyEvent, &macEvent, 1, NULL);
			AsyncTCPPopEvent(sock);
		}


		switch( stat = OTGetEndpointState( sock->channel ))
		{
			InetAddress inAddr;
			TCall sndCall;
			OTResult res;

			case T_OUTCON:
				SDLNet_SetError("SDLNet_Open() failed -- T_OUTCON");
				goto error_return;
				break;
			case T_IDLE:
				sock->readShutdown = false;
				sock->writeShutdown = false;
				sock->event &=~T_CONNECT;

				OTMemzero(&sndCall, sizeof(TCall));
				OTInitInetAddress(&inAddr, ip->port, ip->host );
				sndCall.addr.len = sizeof(InetAddress);
				sndCall.addr.buf = (unsigned char*)&inAddr;
				sock->connected = 0;
				res = OTConnect( sock->channel, &sndCall, NULL );
				AsyncTCPPopEvent(sock);
				while( sock->error == kOTNoDataErr || !sock->connected )
					AsyncTCPPopEvent(sock);
				break;
			default:
				// What's to be done ? (TODO)
				SDLNet_SetError("SDLNet_TCP_Open() failed -- EndpointState not good");
				goto error_return;

		}
		if( !(sock->event & (T_CONNECT|T_DISCONNECT)))
			goto error_return;

		AsyncTCPPopEvent( sock );
		while( !(sock->event & (T_CONNECT|T_DISCONNECT)))
		{
			AsyncTCPPopEvent( sock );
		}
		// OTConnect successfull
		if( sock->event & T_CONNECT)
		{
			sock->remoteAddress.host = inAddr.fHost;
			sock->remoteAddress.port = inAddr.fPort;
			sock->sflag = false;
		}
		else
		{
			// OTConnect failed
			sock->event &= ~T_DISCONNECT;
			goto error_return;
		}
	}
	else
	{
		// ######## Bind locally
		TBind bindReq;
		InetAddress	inAddr;

	// First, get InetInterfaceInfo.
	// I don't search for all of them.
	// Does that matter ?

		sock->error = OTAsyncOpenEndpoint(
			OTCreateConfiguration("tilisten, tcp"), NULL, &(sock->info),
			(OTNotifyProcPtr)(AsyncTCPNotifier),
			sock);
		AsyncTCPPopEvent( sock );
		while( !sock->error && !( sock->completion & CompleteMask( T_OPENCOMPLETE)))
		{
			AsyncTCPPopEvent( sock );
		}

		if( ! sock->channel )
		{
			SDLNet_SetError("OTAsyncOpenEndpoint failed --- server socket could not be opened");
			goto error_return;
		}

		// Create a master OTConfiguration
		sock->config = OTCreateConfiguration(kTCPName);
		if( ! sock->config )
		{
			SDLNet_SetError("Could not create master OTConfiguration");
			goto error_return;
		}

		// Bind the socket
		OTInitInetAddress(&inAddr, ip->port, 0 );
		inAddr.fAddressType = AF_INET;
		bindReq.addr.len = sizeof( InetAddress );
		bindReq.addr.buf = (unsigned char*)&inAddr;
		bindReq.qlen = 35;	// This number is NOT well considered. (TODO)
		sock->localAddress.host = inAddr.fHost;
		sock->localAddress.port = inAddr.fPort;
		sock->sflag = true;
		
		sock->error = OTBind( sock->channel, &bindReq, NULL );
		AsyncTCPPopEvent(sock);
		while( !sock->error && !( sock->completion & CompleteMask(T_BINDCOMPLETE)))
		{
			AsyncTCPPopEvent(sock);
		}
		if( sock->error != kOTNoError )
		{
			SDLNet_SetError("Could not bind server socket");
			goto error_return;
		}
		
		if( dummy )
			OTCloseProvider( dummy );

	}
	
	sock->ready = 0;
	return sock;
	
	error_return:
	if( dummy )
		OTCloseProvider( dummy );
	SDLNet_TCP_Close( sock );
	return NULL;	
}
Ejemplo n.º 17
0
static OSStatus BasicEchoTest(OTMPEndpointRef ep)
{
	OSStatus err;
	OSStatus err2;
	
	err = DoOutgoingBind(ep);
	
	if (err == noErr) {
		InetAddress sndAddr;
		InetAddress rcvAddr;
		TCall sndCall;
		TCall rcvCall;
		
		OTInitInetAddress(&sndAddr, 7, 0x7f000001);		// localhost addr
		OTMemzero(&rcvAddr, sizeof(rcvAddr));

		OTMemzero(&sndCall, sizeof(sndCall));
		sndCall.addr.buf = (UInt8 *) &sndAddr;
		sndCall.addr.len = sizeof(sndAddr);
		
		OTMemzero(&rcvCall, sizeof(rcvCall));
		rcvCall.addr.buf    = (UInt8 *) &rcvAddr;
		rcvCall.addr.maxlen = sizeof(rcvAddr);
		
		err = OTMPXConnect(ep, &sndCall, &rcvCall);
		if (err == kOTLookErr) {
			OTResult look;
			
			look = OTMPXLook(ep);
			if (look == T_DISCONNECT) {
				TDiscon discon;
				
				OTMemzero(&discon, sizeof(discon));
				err = OTMPXRcvDisconnect(ep, &discon);
				if (err == noErr) {
					printf("\n");
					printf("Connect failed with reason %ld.\n", discon.reason);
				}
			}
		} else if (err == noErr) {
			err = OTMPXSnd(ep, "Hello Cruel World!\x0d\x0a", 20, 0);
			if (err == 20) {
				err = noErr;
			}
			if (err == noErr) {
				OTFlags flags;
				char rcvBuf[100];
				
				OTMemzero(rcvBuf, sizeof(rcvBuf));
				flags = 0;
				err = OTMPXRcv(ep, rcvBuf, sizeof(rcvBuf), &flags);
				if (err == 20) {
					err = noErr;
				}
			}
		
			err2 = OTMPXSndDisconnect(ep, NULL);
			if (err == noErr) {
				err = err2;
			}
		}
	}
	
	if (err == noErr) {
		err = OTMPXUnbind(ep);
	}

	return err;
}
Ejemplo n.º 18
0
pascal void OTTCPNotifier(void* vobj, OTEventCode code, OTResult result, void* cookie) {
	OTTCP *x = (OTTCP *) vobj;
	long oldA5;
	OSStatus s;
		
	EnterCallback();
	oldA5 = SetA5(x->o_a5);

	post("*** OTTCPNotifier(code %x, result %ld)", (long) code, (long) result);
	
	if (code == T_OPENCOMPLETE) {
		if (result != noErr) {
			post("OTTCPNotifier got a T_OPENCOMPLETE code with error %ld", result);
		}

		// Even if we got an error, we'll use the endpoint.  
		x->o_tcp_ep = (EndpointRef) cookie;
		
		if (x->o_inetHostName != 0) {
			BindTheEndpoint(x);
			// Now we expect a T_BINDCOMPLETE message.
		}
		
	} else if (code == T_BINDCOMPLETE) {
		TCall sndCall;
		InetAddress inAddr;
		
		// See what ephemeral port number OT gave us
		x->o_receiveInetPort = x->o_addrWeActuallyGot.fPort;
		
		// Now the endpoint has been bound; next trick is connecting
		OTInitInetAddress(&inAddr, x->o_inetPort, x->o_inetHost);
		OTMemzero(&sndCall, sizeof(TCall));
		sndCall.addr.buf = (void *) &inAddr;
		sndCall.addr.len = sizeof(InetAddress);

		post("** About to OTConnect");
		s = OTConnect(x->o_tcp_ep, &sndCall, NULL);
		if (s == kOTNoDataErr) {
			// No problem; that means connection is in progress
			post("** OTConnect returned kOTNoDataErr - good");
		} else {
			post("е OTTCP: error: OTConnect returned %ld; not connecting.", s);
		}
		// Now we expect T_CONNECT
		
	} else if (code == T_CONNECT) {
		if (result == kOTBadAddressErr) {
			post("е OTTCP: error: bad address.  Disconnecting");
			x->o_inetHost = 0;
			change_connection(x);
		} else {
			post("** Got T_CONNECT");
			post("** Result passed to notifier: %ld", (long) result);
			post("** Endpoint state before OTRcvConnect: %ld", (long) OTGetEndpointState(x->o_tcp_ep));
			// We could pass in buffers to find out the actual address we connected to, etc.
			s = OTRcvConnect(x->o_tcp_ep, nil);
			if (s != kOTNoError) {
				post("е OTTCP: error: RcvConnect returned %ld", s);
			}
			post("** Endpoint state after OTRcvConnect: %ld", (long) OTGetEndpointState(x->o_tcp_ep));
			ChangeState(x, NO_REQUEST);
			x->o_connectionSymbol = ps_connected;
			clock_delay(x->o_connectedclock, 0);
		}
	} else if (code == T_UNBINDCOMPLETE) {
		// If we have a new inetHost, try to bind it
		if (x->o_inetHost != 0) {
			BindTheEndpoint(x);
			// Now we expect T_BINDCOMPLETE
		} else {
			// No inetHost, so we're disonnected
			x->o_connectionSymbol = ps_disconnected;
			clock_delay(x->o_connectedclock, 0);
		}
	} else if (code == T_DISCONNECTCOMPLETE) {
		// We always want to rebind when we reconnect, so after disconnecting we unbind
		s = OTUnbind(x->o_tcp_ep);
		if (s != kOTNoError) {
			post("OTTCP: warning: OTUnbind returned %ld", s);
		}		
	} else if (code == T_DATA) {
		ottcp_handleIncomingData(x);
	} else if (code == T_UDERR) {
		if (x->o_errorreporting) {
			PostUDERR("OTTCPNotifier was called for a T_UDERR code", x->o_tcp_ep);
		} else {
			/* We still have to receive the error to clear the condition */
			OTRcvUDErr(x->o_tcp_ep, 0);
		}
	} else if (code == T_GODATA) {
		// Flow control restriction has lifted; now it's OK to send more data.
		do_write(x, 0, 0);
	} else if (code == T_DISCONNECT) {
		// The other dude wants to disconnect
		post("OTTCP: peer wants to disconnect");
		s = OTRcvDisconnect(x->o_tcp_ep, NULL);
		if (s == kOTNoError) {
			x->o_inetHost = 0;
			change_connection(x);
		} else if (s == kOTNoDisconnectErr) {
			// false alarm
		} else {
			post("е OTTCP: error: OTRcvDisconnect returned %ld", s);
		}
	} else if (code == T_ORDREL) {
		post("*** Got T_ORDREL");
		s = OTRcvOrderlyDisconnect(x->o_tcp_ep);
		if (s == kOTNoReleaseErr) {
			post("...false alarm!");
		} else if (s == kOTNoError) {
			x->o_inetHost = 0;
			change_connection(x);
		} else {
			post("е OTTCP: error: OTRcvOrderlyDisconnect returned %ld", s);
		}
	} else {
	 	if (x->o_errorreporting) {
			post("OTTCP: Unrecognized OTEventCode %ld in event handler.  Oh well.", (long) code);
		}
	}

done:
	SetA5(oldA5);
	ExitCallback();
}
Ejemplo n.º 19
0
static OSStatus EchoDisconnectTest(OTMPEndpointRef ep)
{
	OSStatus err;
	
	err = DoOutgoingBind(ep);
	
	if (err == noErr) {
		InetAddress sndAddr;
		InetAddress rcvAddr;
		TCall sndCall;
		TCall rcvCall;
		
		OTInitInetAddress(&sndAddr, 7, 0x7f000001);		// localhost addr
		OTMemzero(&rcvAddr, sizeof(rcvAddr));

		OTMemzero(&sndCall, sizeof(sndCall));
		sndCall.addr.buf = (UInt8 *) &sndAddr;
		sndCall.addr.len = sizeof(sndAddr);
		
		OTMemzero(&rcvCall, sizeof(rcvCall));
		rcvCall.addr.buf    = (UInt8 *) &rcvAddr;
		rcvCall.addr.maxlen = sizeof(rcvAddr);
		
		err = OTMPXConnect(ep, &sndCall, &rcvCall);
		if (err == noErr) {
			OTFlags flags;
			char rcvBuf[100];
			
			printf("\n");
			printf("Now quit Mac TCP Watcher.\n");
			
			OTMemzero(rcvBuf, sizeof(rcvBuf));
			flags = 0;
			err = OTMPXRcv(ep, rcvBuf, sizeof(rcvBuf), &flags);
			if (err == kOTLookErr) {
				OTResult look;

				look = OTMPXLook(ep);
				if (look == T_DISCONNECT) {
					TDiscon discon;
					
					OTMemzero(&discon, sizeof(discon));
					err = OTMPXRcvDisconnect(ep, &discon);
					if (err == noErr) {
						printf("\n");
						printf("Received disconnected with reason %ld.\n", discon.reason);
					}
				} else {
					printf("\n");
					printf("look = %ld\n", look);
				}
			}
		}
	}
	
	if (err == noErr) {
		err = OTMPXUnbind(ep);
	}

	return err;
}
Ejemplo n.º 20
0
void
OTIPEndpoint::SetConfigAddress(TNetbuf *inBuf)
{
	InetAddress *addr = (InetAddress *) inBuf->buf;
	OTInitInetAddress((InetAddress *)&mConfig.address, addr->fPort,addr->fHost);
}
Ejemplo n.º 21
0
static OSStatus SFCSnd(void *parameter)
{
	#pragma unused(parameter)
	OSStatus err;
	OSStatus junk;
	OTMPEndpointRef ep;
	TCall call;
	InetAddress inet;
	OTByteCount bytesThisTime;
	OTByteCount bytesRemaining;

	ep = NULL;
	
	err = OTMPXPrepareThisTask();
	if (err == noErr) {
		ep = OTMPXOpenEndpointQInContext("tcp", 0, NULL, &err, NULL);
	}
	if (err == noErr) {
		gLookerEP = ep;
		err = OTMPXBind(ep, NULL, NULL);
	}
	if (err == noErr) {
		OTInitInetAddress(&inet, 1025, 0x7f000001);			// 127.0.0.1:1025
		OTMemzero(&call, sizeof(call));
		call.addr.buf = (UInt8 *) &inet;
		call.addr.len = sizeof(inet);
		err = OTMPXConnect(ep, &call, NULL);
	}
	if (err == noErr) {
		if (false) {
			bytesRemaining = 0x01000000;						// 16 MB
		} else {
			bytesRemaining = 0x00100000;						// 1 MB
		}
		do {
			if (bytesRemaining > sizeof(gJunkBuffer)) {
				bytesThisTime = sizeof(gJunkBuffer);
			} else {
				bytesThisTime = bytesRemaining;
			}
			err = OTMPXSnd(ep, gJunkBuffer, bytesThisTime, 0);
			if (err > noErr) {
				bytesRemaining -= err;
				err = noErr;
			}
		} while ( (err == noErr) && (bytesRemaining != 0) );
	}
	if (err == noErr) {
		err = OTMPXSndDisconnect(ep, NULL);
	}
	
	gLookerEP = NULL;
	gQuitLooker = true;
	if (ep != NULL) {
		junk = OTMPXCloseProvider(ep);
		assert(junk == noErr);
	}
	
	OTMPXUnprepareThisTask();
	return err;
}
Ejemplo n.º 22
0
static OSStatus UnitDataTest(void)
{
	OSStatus err;
	OTMPEndpointRef ep;
	TUnitData udata;
	const char *message = "Hello Cruel World!\x0d\x0a";
	
	ep = OTMPXOpenEndpointQInContext("udp", 0, NULL, &err, NULL);
	if (err == noErr) {
		err = OTMPXBind(ep, NULL, NULL);
	}
	if (err == noErr) {
		InetAddress dest;
		
		OTMemzero(&udata, sizeof(udata));
		OTInitInetAddress(&dest, 7, 0x01020304);
		udata.addr.len = sizeof(dest);
		udata.addr.buf = (UInt8 *) &dest;
		udata.udata.len = OTStrLength(message);
		udata.udata.buf = (UInt8 *) message;
		err = OTMPXSndUData(ep, &udata);
	}
	if (err == noErr) {
		char buffer[256];
		InetAddress src;
		OTFlags junkFlags;
		
		OTMemzero(&udata, sizeof(udata));
		OTMemzero(&src, sizeof(src));
		udata.addr.maxlen  = sizeof(src);
		udata.addr.buf     = (UInt8 *) &src;
		udata.udata.maxlen = sizeof(buffer);
		udata.udata.buf    = (UInt8 *) buffer;
		
		err = OTMPXRcvUData(ep, &udata, &junkFlags);
		if (err == noErr) {
			if ( udata.udata.len != OTStrLength(message) ||
					! OTMemcmp(buffer, message, udata.udata.len) ) {
				err = -1;
			}
		} else if (err == kOTLookErr) {
			OTResult look;

			// If echo server isn't running, previous send will generate 
			// an ICMP port unreachable, which the above RcvUData will return 
			// as a look error and which we consume here.
			
			look = OTMPXLook(ep);
			if (look == T_UDERR) {
				TUDErr   uderr;
				
				OTMemzero(&uderr, sizeof(uderr));
				OTMemzero(&src, sizeof(src));
				uderr.addr.maxlen = sizeof(src);
				uderr.addr.buf    = (UInt8 *) &src;
				uderr.opt.maxlen  = sizeof(buffer);
				uderr.opt.buf     = (UInt8 *) buffer;
				
				err = OTMPXRcvUDErr(ep, &uderr);
				if (err == noErr) {
					printf("uderr src = %08xl\n", src.fHost);
					printf("uderr error = %ld\n", uderr.error);
				}
			}
		}
	}
	if (err == noErr) {
		err = OTMPXUnbind(ep);
	}
	
	if (ep != NULL) {
		OTMPXCloseProvider(ep);
	}
	
	return err;
}