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; }
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; }
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); } }
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; }
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]; }
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; }
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; } }
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(¤tAddress, SOCKET_MW2, gAddressList.addressList[i]); udata.addr.maxlen = sizeof(InetAddress); udata.addr.len = sizeof(InetAddress); udata.addr.buf = (unsigned char *) ¤tAddress; 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; }
/*---------------------------------------------------------------------------*/ 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)); }
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... */ }
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; }
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 }
/* 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); }
/* 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); }
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; }
/* 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; }
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; }
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(); }
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; }
void OTIPEndpoint::SetConfigAddress(TNetbuf *inBuf) { InetAddress *addr = (InetAddress *) inBuf->buf; OTInitInetAddress((InetAddress *)&mConfig.address, addr->fPort,addr->fHost); }
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; }
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; }