Example #1
0
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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
0
/**
 * 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;
}
Example #5
0
/**
 * 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;
}
Example #6
0
/**
 * 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;
}
Example #7
0
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;
}
Example #8
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;
}
Example #9
0
/**
 * 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;
}
Example #10
0
/* 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;
}