int CSocket::setOptions(int iOptions) { bool changeBlocking = false; unsigned long i; // If we change the SOCKET_OPTION_NONBLOCKING option, adjust the socket mode. if (iOptions & SOCKET_OPTION_NONBLOCKING && !(properties.options & SOCKET_OPTION_NONBLOCKING)) { changeBlocking = true; i = 1; } if (properties.options & SOCKET_OPTION_NONBLOCKING && !(iOptions & SOCKET_OPTION_NONBLOCKING)) { changeBlocking = true; i = 0; } // Do the changes. if (changeBlocking) { #if defined(WIN32) ioctlsocket(properties.handle, FIONBIO, &i); #elif defined(PSPSDK) sceNetInetSetsockopt(properties.handle, SOL_SOCKET, 0x1009, (const char*)&i, sizeof(u32)); #else if (i == 1) fcntl(properties.handle, F_SETFL, O_NONBLOCK); else fcntl(properties.handle, F_SETFL, ~O_NONBLOCK); #endif } // Set the options. properties.options = iOptions; return 0; }
int connectSocket( const char * ip_addr, unsigned short port ) { struct sockaddr_in addr; int opt = 1; addr.sin_family = AF_INET; addr.sin_port = htons( port ); addr.sin_addr.s_addr = sceNetInetInetAddr( ip_addr ); int i = 0; for( i = 0; i < 4; i ++ ) { ctrl_opts.sock[i].server = sceNetInetSocket( PF_INET, SOCK_STREAM, 0 ); if ( ctrl_opts.sock[i].server < 0 ) { log( "Error create sock connection\n" ); return -1; } int ret = sceNetInetSetsockopt( ctrl_opts.sock[i].server, SOL_TCP, TCP_NODELAY, &opt, sizeof( opt ) ); if ( ret != 0 ) { log( "Error setting sock option\n" ); return -1; } ret = sceNetInetConnect( ctrl_opts.sock[i].server, ( struct sockaddr * )&addr, sizeof( addr ) ); if ( ret < 0 ) { log( "Error connect to sock %08x\n", ctrl_opts.sock[i].server ); return -1; } ctrl_opts.sock[i].thid = sceKernelCreateThread( "sock_thread", sock_thread, 0x20, 0x2000, PSP_THREAD_ATTR_USBWLAN, NULL ); if ( ctrl_opts.sock[i].thid < 0 ) { log( "Error creating thread\n" ); return -1; } unsigned int addr = ( unsigned int )&ctrl_opts.sock[i]; sceKernelStartThread( ctrl_opts.sock[i].thid, 4, &addr ); } return 0; }
/** * Adhoc Emulator PTP Receiver * @param id Socket File Descriptor * @param buf Data Buffer * @param len IN: Buffersize OUT: Received Data (in Bytes) * @param timeout Receive Timeout (in Microseconds) * @param flag Nonblocking Flag * @return 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_SOCKET_ALERTED, ADHOC_WOULD_BLOCK, ADHOC_TIMEOUT, ADHOC_THREAD_ABORTED, ADHOC_DISCONNECTED, NET_INTERNAL */ int proNetAdhocPtpRecv(int id, void * buf, int * len, uint32_t timeout, int flag) { // Library is initialized if(_init) { // Valid Socket if(id > 0 && id <= 255 && _ptp[id - 1] != NULL && _ptp[id - 1]->state == PTP_STATE_ESTABLISHED) { // Cast Socket SceNetAdhocPtpStat * socket = _ptp[id - 1]; // Valid Arguments if(buf != NULL && len != NULL && *len > 0) { // Schedule Timeout Removal if(flag) timeout = 0; // Apply Send Timeout Settings to Socket sceNetInetSetsockopt(socket->id, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); // Acquire Network Lock _acquireNetworkLock(); // Receive Data int received = sceNetInetRecv(socket->id, buf, *len, ((flag) ? (INET_MSG_DONTWAIT) : (0))); // Free Network Lock _freeNetworkLock(); // Received Data if(received > 0) { // Save Length *len = received; // Return Success return 0; } // Non-Critical Error else if(received == -1 && sceNetInetGetErrno() == EAGAIN) { // Blocking Situation if(flag) return ADHOC_WOULD_BLOCK; // Timeout return ADHOC_TIMEOUT; } // Change Socket State socket->state = PTP_STATE_CLOSED; // Disconnected return ADHOC_DISCONNECTED; } // Invalid Arguments return ADHOC_INVALID_ARG; } // Invalid Socket return ADHOC_INVALID_SOCKET_ID; } // Library is uninitialized return ADHOC_NOT_INITIALIZED; }
/** * Initialize Networking Components for Adhocctl Emulator * @param adhoc_id Game Product Code * @param server_ip Server IP * @return 0 on success or... -1 */ int _initNetwork(const SceNetAdhocctlAdhocId * adhoc_id, const char * server_ip) { // WLAN Switch Check if(sceWlanGetSwitchState() == 1) { // Initialize Access Point Control if(sceNetApctlInit(0x1800, 0x30) == 0) { // Attempt Counter int attemptmax = 10; // Attempt Number int attempt = 0; // Attempt Connection Setup for(; attempt < attemptmax; attempt++) { // Start Connection if(sceNetApctlConnect(_hotspot) == 0) { // Wait for Connection int statebefore = 0; int state = 0; while(state != 4) { // Query State int getstate = sceNetApctlGetState(&state); // Log State Change if(statebefore != state) printk("New Connection State: %d\n", state); // Query Success if(getstate == 0 && state != 4) { // Wait for Retry sceKernelDelayThread(1000000); } // Query Error else break; // Save Before State statebefore = state; } // Connected if(state == 4) { // Create Friend Finder Socket int socket = sceNetInetSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Created Socket if(socket > 0) { // Enable Port Re-use sceNetInetSetsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &_one, sizeof(_one)); sceNetInetSetsockopt(socket, SOL_SOCKET, SO_REUSEPORT, &_one, sizeof(_one)); // Apply Receive Timeout Settings to Socket // uint32_t timeout = ADHOCCTL_RECV_TIMEOUT; // sceNetInetSetsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); // Server IP uint32_t ip = 0; // Initialize DNS Resolver if(sceNetResolverInit() == 0) { // Create DNS Resolver unsigned char rbuf[512]; int rid = 0; if(sceNetResolverCreate(&rid, rbuf, sizeof(rbuf)) == 0) { // Resolve Domain if(sceNetResolverStartNtoA(rid, server_ip, &ip, 500000, 2) != 0) { // Attempt IP Conversion sceNetInetInetAton(server_ip, &ip); } // Delete DNS Resolver sceNetResolverDelete(rid); } // Shutdown DNS Resolver sceNetResolverTerm(); } // Prepare Server Address SceNetInetSockaddrIn addr; addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_addr = ip; addr.sin_port = sceNetHtons(ADHOCCTL_METAPORT); // Connect to Server if(sceNetInetConnect(socket, (SceNetInetSockaddr *)&addr, sizeof(addr)) == 0) { // Save Meta Socket _metasocket = socket; // Save Product Code _product_code = *adhoc_id; // Clear Event Handler memset(_event_handler, 0, sizeof(_event_handler[0]) * ADHOCCTL_MAX_HANDLER); memset(_event_args, 0, sizeof(_event_args[0]) * ADHOCCTL_MAX_HANDLER); // Clear Internal Control Status memset(&_parameter, 0, sizeof(_parameter)); // Read PSP Player Name sceUtilityGetSystemParamString(PSP_SYSTEMPARAM_ID_STRING_NICKNAME, (char *)_parameter.nickname.data, ADHOCCTL_NICKNAME_LEN); // Read Adhoc Channel sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_ADHOC_CHANNEL, &_parameter.channel); // Fake Channel Number 1 on Automatic Channel if(_parameter.channel == 0) _parameter.channel = 1; // Read PSP MAC Address sceWlanGetEtherAddr((void *)&_parameter.bssid.mac_addr.data); // Prepare Login Packet SceNetAdhocctlLoginPacketC2S packet; // Set Packet Opcode packet.base.opcode = OPCODE_LOGIN; // Set MAC Address packet.mac = _parameter.bssid.mac_addr; // Set Nickname packet.name = _parameter.nickname; // Set Game Product ID memcpy(packet.game.data, adhoc_id->data, ADHOCCTL_ADHOCID_LEN); // Acquire Network Layer Lock _acquireNetworkLock(); // Send Login Packet sceNetInetSend(_metasocket, &packet, sizeof(packet), INET_MSG_DONTWAIT); // Free Network Layer Lock _freeNetworkLock(); // Load UPNP Library _upnp_uid = sceKernelLoadModule("ms0:/kd/pspnet_miniupnc.prx", 0, NULL); // Start UPNP Library int status = 0; sceKernelStartModule(_upnp_uid, 0, NULL, &status, NULL); // Return Success return 0; } // Delete Socket sceNetInetClose(socket); } // Close Hotspot Connection sceNetApctlDisconnect(); } } } // Terminate Access Point Control sceNetApctlTerm(); } } // Generic Error return -1; }
/** * Adhoc Emulator PDP Send Call * @param id Socket File Descriptor * @param daddr Target MAC Address * @param dport Target Port * @param data Data Payload * @param len Payload Length * @param timeout Send Timeout * @param flag Nonblocking Flag * @return 0 on success or... ADHOC_INVALID_ARG, ADHOC_NOT_INITIALIZED, ADHOC_INVALID_SOCKET_ID, ADHOC_SOCKET_DELETED, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT, ADHOC_INVALID_DATALEN, ADHOC_SOCKET_ALERTED, ADHOC_TIMEOUT, ADHOC_THREAD_ABORTED, ADHOC_WOULD_BLOCK, NET_NO_SPACE, NET_INTERNAL */ int proNetAdhocPdpSend(int id, const SceNetEtherAddr * daddr, uint16_t dport, const void * data, int len, uint32_t timeout, int flag) { // Library is initialized if(_init) { // Valid Port if(dport != 0) { // Valid Data Length if(len > 0) { // Valid Socket ID if(id > 0 && id <= 255 && _pdp[id - 1] != NULL) { // Cast Socket SceNetAdhocPdpStat * socket = _pdp[id - 1]; // Valid Data Buffer if(data != NULL) { // Valid Destination Address if(daddr != NULL) { // Log Destination #ifdef DEBUG printk("Attempting PDP Send to %02X:%02X:%02X:%02X:%02X:%02X on Port %u\n", daddr->data[0], daddr->data[1], daddr->data[2], daddr->data[3], daddr->data[4], daddr->data[5], dport); #endif // Schedule Timeout Removal if(flag) timeout = 0; // Apply Send Timeout Settings to Socket sceNetInetSetsockopt(socket->id, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); // Single Target if(!_isBroadcastMAC(daddr)) { // Fill in Target Structure SceNetInetSockaddrIn target; target.sin_family = AF_INET; target.sin_port = sceNetHtons(dport); // Get Peer IP if(_resolveMAC((SceNetEtherAddr *)daddr, &target.sin_addr) == 0) { // Acquire Network Lock _acquireNetworkLock(); // Send Data int sent = sceNetInetSendto(socket->id, data, len, ((flag != 0) ? (INET_MSG_DONTWAIT) : (0)), (SceNetInetSockaddr *)&target, sizeof(target)); // Free Network Lock _freeNetworkLock(); // Sent Data if(sent == len) { // Success return 0; } // Blocking Situation if(flag) return ADHOC_WOULD_BLOCK; // Timeout return ADHOC_TIMEOUT; } } // Broadcast Target else { // Acquire Network Lock _acquireNetworkLock(); #ifdef BROADCAST_TO_LOCALHOST // Get Local IP Address union SceNetApctlInfo info; if(sceNetApctlGetInfo(PSP_NET_APCTL_INFO_IP, &info) == 0) { // Fill in Target Structure SceNetInetSockaddrIn target; target.sin_family = AF_INET; sceNetInetInetAton(info.ip, &target.sin_addr); target.sin_port = sceNetHtons(dport); // Send Data sceNetInetSendto(socket->id, data, len, ((flag != 0) ? (INET_MSG_DONTWAIT) : (0)), (SceNetInetSockaddr *)&target, sizeof(target)); } #endif // Acquire Peer Lock _acquirePeerLock(); // Iterate Peers SceNetAdhocctlPeerInfo * peer = _getInternalPeerList(); for(; peer != NULL; peer = peer->next) { // Fill in Target Structure SceNetInetSockaddrIn target; target.sin_family = AF_INET; target.sin_addr = peer->ip_addr; target.sin_port = sceNetHtons(dport); // Send Data sceNetInetSendto(socket->id, data, len, ((flag != 0) ? (INET_MSG_DONTWAIT) : (0)), (SceNetInetSockaddr *)&target, sizeof(target)); } // Free Peer Lock _freePeerLock(); // Free Network Lock _freeNetworkLock(); // Broadcast never fails! return 0; } } // Invalid Destination Address return ADHOC_INVALID_ADDR; } // Invalid Argument return ADHOC_INVALID_ARG; } // Invalid Socket ID return ADHOC_INVALID_SOCKET_ID; } // Invalid Data Length return ADHOC_INVALID_DATALEN; } // Invalid Destination Port return ADHOC_INVALID_PORT; } // Library is uninitialized return ADHOC_NOT_INITIALIZED; }
/** * Adhoc Emulator PDP Socket Creator * @param saddr Local MAC (Unused) * @param sport Local Binding Port * @param bufsize Socket Buffer Size * @param flag Bitflags (Unused) * @return Socket ID > 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_SOCKET_ID_NOT_AVAIL, ADHOC_INVALID_ADDR, ADHOC_PORT_NOT_AVAIL, ADHOC_INVALID_PORT, ADHOC_PORT_IN_USE, NET_NO_SPACE */ int proNetAdhocPdpCreate(const SceNetEtherAddr * saddr, uint16_t sport, int bufsize, int flag) { // Library is initialized if(_init) { // Valid Arguments are supplied if(saddr != NULL && bufsize > 0) { // Valid MAC supplied if(_IsLocalMAC(saddr)) { // Random Port required if(sport == 0) { // Find unused Port while(sport == 0 || _IsPDPPortInUse(sport)) { // Generate Port Number sport = (uint16_t)_getRandomNumber(65535); } } // Unused Port supplied if(!_IsPDPPortInUse(sport)) { // Create Internet UDP Socket int socket = sceNetInetSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // Valid Socket produced if(socket > 0) { // Enable Port Re-use sceNetInetSetsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &_one, sizeof(_one)); sceNetInetSetsockopt(socket, SOL_SOCKET, SO_REUSEPORT, &_one, sizeof(_one)); // Binding Information for local Port SceNetInetSockaddrIn addr; addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_addr = INADDR_ANY; addr.sin_port = sceNetHtons(sport); // Bound Socket to local Port if(sceNetInetBind(socket, (SceNetInetSockaddr *)&addr, sizeof(addr)) == 0) { // Allocate Memory for Internal Data SceNetAdhocPdpStat * internal = (SceNetAdhocPdpStat *)malloc(sizeof(SceNetAdhocPdpStat)); // Allocated Memory if(internal != NULL) { // Clear Memory memset(internal, 0, sizeof(SceNetAdhocPdpStat)); // Find Free Translator Index int i = 0; for(; i < 255; i++) if(_pdp[i] == NULL) break; // Found Free Translator Index if(i < 255) { // Fill in Data internal->id = socket; internal->laddr = *saddr; internal->lport = sport; internal->rcv_sb_cc = bufsize; // Link Socket to Translator ID _pdp[i] = internal; // Forward Port on Router sceNetPortOpen("UDP", sport); // Success return i + 1; } // Free Memory for Internal Data free(internal); } } // Close Socket sceNetInetClose(socket); } // Default to No-Space Error return NET_NO_SPACE; } // Port is in use by another PDP Socket return ADHOC_PORT_IN_USE; } // Invalid MAC supplied return ADHOC_INVALID_ADDR; } // Invalid Arguments were supplied return ADHOC_INVALID_ARG; } // Library is uninitialized return ADHOC_NOT_INITIALIZED; }
int CSocket::connect() { // Make sure the socket is disconnected. if (properties.state != SOCKET_STATE_DISCONNECTED) return SOCKET_ALREADY_CONNECTED; // Flag the socket as connecting. properties.state = SOCKET_STATE_CONNECTING; // Create socket. if (properties.protocol == SOCKET_PROTOCOL_TCP) properties.handle = socket(AF_INET, SOCK_STREAM, 0); else properties.handle = socket(AF_INET, SOCK_DGRAM, 0); // Make sure the socket was created correctly. if (properties.handle == INVALID_SOCKET) { properties.state = SOCKET_STATE_DISCONNECTED; return SOCKET_INVALID; } // Bind the socket if it is a server-type socket. if (properties.type == SOCKET_TYPE_SERVER) { // Let us reuse the address. Freaking bind. int value = 1; setsockopt(properties.handle, SOL_SOCKET, SO_REUSEADDR, (char*)&value, sizeof(value)); // Bind the socket. if (::bind(properties.handle, (struct sockaddr *)&properties.address, sizeof(properties.address)) == SOCKET_ERROR) { destroy(); return SOCKET_BIND_ERROR; } } // Connect the socket. if (properties.type != SOCKET_TYPE_SERVER) { if (::connect(properties.handle, (struct sockaddr *)&properties.address, sizeof(properties.address)) == SOCKET_ERROR) { destroy(); return SOCKET_CONNECT_ERROR; } } // Socket connected! properties.state = SOCKET_STATE_CONNECTED; // Listening sockets. if (properties.type == SOCKET_TYPE_SERVER) { if (properties.protocol == SOCKET_PROTOCOL_UDP) properties.state = SOCKET_STATE_LISTENING; else if (properties.protocol == SOCKET_PROTOCOL_TCP) { if (::listen(properties.handle, SOMAXCONN) == SOCKET_ERROR) { destroy(); return SOCKET_CONNECT_ERROR; } properties.state = SOCKET_STATE_LISTENING; } } // Turn on non-blocking mode. if (properties.options & SOCKET_OPTION_NONBLOCKING) { #if defined(WIN32) unsigned long i = 1; ioctlsocket(properties.handle, FIONBIO, &i); #elif defined(PSPSDK) unsigned long i = 1; sceNetInetSetsockopt(properties.handle, SOL_SOCKET, 0x1009, (const char*)&i, sizeof(u32)); #else fcntl(properties.handle, F_SETFL, O_NONBLOCK); #endif } return 0; }
/* upnpDiscover() : * return a chained list of all devices found or NULL if * no devices was found. * It is up to the caller to free the chained list * delay is in millisecond (poll) */ struct UPNPDev * upnpDiscover(int delay, const char * multicastif, const char * minissdpdsock, int sameport, int ipv6, //unused in psp port int * error) { struct UPNPDev * tmp; struct UPNPDev * devlist = 0; int opt = 1; static const char MSearchMsgFmt[] = "M-SEARCH * HTTP/1.1\r\n" "HOST: %s:" XSTR(PORT) "\r\n" "ST: %s\r\n" "MAN: \"ssdp:discover\"\r\n" "MX: %u\r\n" "\r\n"; static const char * const deviceList[] = { #if 0 "urn:schemas-upnp-org:device:InternetGatewayDevice:2", "urn:schemas-upnp-org:service:WANIPConnection:2", #endif "urn:schemas-upnp-org:device:InternetGatewayDevice:1", "urn:schemas-upnp-org:service:WANIPConnection:1", "urn:schemas-upnp-org:service:WANPPPConnection:1", "upnp:rootdevice", 0 }; int deviceIndex = 0; char bufr[1536]; /* reception and emission buffer */ int sudp; int n; SceNetInetSockaddrIn sockudp_r; unsigned int mx; SceNetInetSockaddrIn sockudp_w; int linklocal = 1; if(error) *error = UPNPDISCOVER_UNKNOWN_ERROR; /* fallback to direct discovery */ //sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0); sudp = sceNetInetSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(sudp < 0) { if(error) *error = UPNPDISCOVER_SOCKET_ERROR; return NULL; } /* reception */ memset(&sockudp_r, 0, sizeof(SceNetInetSockaddrIn)); SceNetInetSockaddrIn * p = (SceNetInetSockaddrIn *)&sockudp_r; p->sin_family = AF_INET; if(sameport) p->sin_port = sceNetHtons(PORT); p->sin_addr = INADDR_ANY; // Enable Port Re-use sceNetInetSetsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); sceNetInetSetsockopt(sudp, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)); /* Avant d'envoyer le paquet on bind pour recevoir la reponse */ if (sceNetInetBind(sudp, (const struct SceNetInetSockaddr *)&sockudp_r, sizeof(SceNetInetSockaddrIn)) != 0) { if(error) *error = UPNPDISCOVER_SOCKET_ERROR; sceNetInetClose(sudp); return NULL; } if(error) *error = UPNPDISCOVER_SUCCESS; /* Calculating maximum response time in seconds */ mx = ((unsigned int)delay) / 1000u; /* receiving SSDP response packet */ for(n = 0; deviceList[deviceIndex]; deviceIndex++) { if(n == 0) { /* sending the SSDP M-SEARCH packet */ n = snprintf(bufr, sizeof(bufr), MSearchMsgFmt, UPNP_MCAST_ADDR, deviceList[deviceIndex], mx); /* the following code is not using getaddrinfo */ /* emission */ memset(&sockudp_w, 0, sizeof(SceNetInetSockaddrIn)); SceNetInetSockaddrIn * p = (SceNetInetSockaddrIn *)&sockudp_w; p->sin_family = AF_INET; p->sin_port = sceNetHtons(PORT); sceNetInetInetAton(UPNP_MCAST_ADDR, &p->sin_addr); n = sceNetInetSendto(sudp, bufr, n, 0, (SceNetInetSockaddr *)&sockudp_w, sizeof(SceNetInetSockaddrIn)); if (n < 0) { if(error) *error = UPNPDISCOVER_SOCKET_ERROR; break; } } /* Waiting for SSDP REPLY packet to M-SEARCH */ n = receivedata(sudp, bufr, sizeof(bufr), delay); if (n < 0) { /* error */ if(error) *error = UPNPDISCOVER_SOCKET_ERROR; break; } else if (n == 0) { /* no data or Time Out */ if (devlist) { /* no more device type to look for... */ if(error) *error = UPNPDISCOVER_SUCCESS; break; } if(ipv6) { if(linklocal) { linklocal = 0; --deviceIndex; } else { linklocal = 1; } } } else { const char * descURL=NULL; int urlsize=0; const char * st=NULL; int stsize=0; /*printf("%d byte(s) :\n%s\n", n, bufr);*/ /* affichage du message */ parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize); if(st&&descURL) { for(tmp=devlist; tmp; tmp = tmp->pNext) { if(memcmp(tmp->descURL, descURL, urlsize) == 0 && tmp->descURL[urlsize] == '\0' && memcmp(tmp->st, st, stsize) == 0 && tmp->st[stsize] == '\0') break; } /* at the exit of the loop above, tmp is null if * no duplicate device was found */ if(tmp) continue; tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize); if(!tmp) { /* memory allocation error */ if(error) *error = UPNPDISCOVER_MEMORY_ERROR; break; } tmp->pNext = devlist; tmp->descURL = tmp->buffer; tmp->st = tmp->buffer + 1 + urlsize; memcpy(tmp->buffer, descURL, urlsize); tmp->buffer[urlsize] = '\0'; memcpy(tmp->buffer + urlsize + 1, st, stsize); tmp->buffer[urlsize+1+stsize] = '\0'; devlist = tmp; } } } sceNetInetClose(sudp); return devlist; }
/** * Adhoc Emulator PTP Active Socket Creator * @param saddr Local MAC (Unused) * @param sport Local Binding Port * @param daddr Target MAC * @param dport Target Port * @param bufsize Socket Buffer Size * @param rexmt_int Retransmit Interval (in Microseconds) * @param rexmt_cnt Retransmit Count * @param flag Bitflags (Unused) * @return Socket ID > 0 on success or... ADHOC_NOT_INITIALIZED, ADHOC_INVALID_ARG, ADHOC_INVALID_ADDR, ADHOC_INVALID_PORT */ int proNetAdhocPtpOpen(const SceNetEtherAddr * saddr, uint16_t sport, const SceNetEtherAddr * daddr, uint16_t dport, uint32_t bufsize, uint32_t rexmt_int, int rexmt_cnt, int flag) { // Library is initialized if(_init) { // Valid Addresses if(saddr != NULL && _IsLocalMAC(saddr) && daddr != NULL && !_isBroadcastMAC(daddr)) { // Random Port required if(sport == 0) { // Find unused Port while(sport == 0 || _IsPTPPortInUse(sport)) { // Generate Port Number sport = (uint16_t)_getRandomNumber(65535); } } // Valid Ports if(!_IsPTPPortInUse(sport) && dport != 0) { // Valid Arguments if(bufsize > 0 && rexmt_int > 0 && rexmt_cnt > 0) { // Create Infrastructure Socket int socket = sceNetInetSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Valid Socket produced if(socket > 0) { // Enable Port Re-use sceNetInetSetsockopt(socket, SOL_SOCKET, SO_REUSEADDR, &_one, sizeof(_one)); sceNetInetSetsockopt(socket, SOL_SOCKET, SO_REUSEPORT, &_one, sizeof(_one)); // Binding Information for local Port SceNetInetSockaddrIn addr; addr.sin_len = sizeof(addr); addr.sin_family = AF_INET; addr.sin_addr = INADDR_ANY; addr.sin_port = sceNetHtons(sport); // Bound Socket to local Port if(sceNetInetBind(socket, (SceNetInetSockaddr *)&addr, sizeof(addr)) == 0) { // Allocate Memory SceNetAdhocPtpStat * internal = (SceNetAdhocPtpStat *)malloc(sizeof(SceNetAdhocPtpStat)); // Allocated Memory if(internal != NULL) { // Find Free Translator ID int i = 0; for(; i < 255; i++) if(_ptp[i] == NULL) break; // Found Free Translator ID if(i < 255) { // Clear Memory memset(internal, 0, sizeof(SceNetAdhocPtpStat)); // Copy Infrastructure Socket ID internal->id = socket; // Copy Address Information internal->laddr = *saddr; internal->paddr = *daddr; internal->lport = sport; internal->pport = dport; // Set Buffer Size internal->rcv_sb_cc = bufsize; // Link PTP Socket _ptp[i] = internal; // Add Port Forward to Router sceNetPortOpen("TCP", sport); // Return PTP Socket Pointer return i + 1; } // Free Memory free(internal); } } // Close Socket sceNetInetClose(socket); } } // Invalid Arguments return ADHOC_INVALID_ARG; } // Invalid Ports return ADHOC_INVALID_PORT; } // Invalid Addresses return ADHOC_INVALID_ADDR; } // Library is uninitialized return ADHOC_NOT_INITIALIZED; }
/* connecthostport() * return a socket connected (TCP) to the host and port * or -1 in case of error */ int connecthostport(const char * host, unsigned short port) { printk("Connect Attempt: %s:%u\n", host, port); // Target Address SceNetInetSockaddrIn in; // Clear Memory memset(&in, 0, sizeof(in)); // Set Address Family in.sin_family = AF_INET; // Set Structure Length in.sin_len = sizeof(in); // Translate Port in.sin_port = sceNetHtons(port); // Resolve Domain if(sceNetResolverStartNtoA(_rid, host, &in.sin_addr, 500000, 2) != 0) { // Attempt IP Conversion sceNetInetInetAton(host, &in.sin_addr); } // Create Socket int s = sceNetInetSocket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // Valid Socket if(s > 0) { // Enabler int one = 1; // Enable Port Re-use sceNetInetSetsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); sceNetInetSetsockopt(s, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)); // Set 3-Second Timeout uint32_t timeout = 3000000; sceNetInetSetsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); sceNetInetSetsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); // Connect to Destination if(sceNetInetConnect(s, (SceNetInetSockaddr *)&in, sizeof(in)) == 0/* || sceNetInetGetErrno() == 106*/) { printk("Connection Success\n"); // Return Socket return s; } printk("Errno: %d\n", sceNetInetGetErrno()); // Close Socket sceNetInetClose(s); logSockets(); } // Error State return -1; }