static void cmd_PASV_func(ClientInfo *client) { int ret; UNUSED(ret); char cmd[512]; unsigned int namelen; SceNetSockaddrIn picked; /* Create data mode socket name */ char data_socket_name[64]; sprintf(data_socket_name, "FTPVita_client_%i_data_socket", client->num); /* Create the data socket */ client->data_sockfd = sceNetSocket(data_socket_name, PSP2_NET_AF_INET, PSP2_NET_SOCK_STREAM, 0); DEBUG("PASV data socket fd: %d\n", client->data_sockfd); /* Fill the data socket address */ client->data_sockaddr.sin_family = PSP2_NET_AF_INET; client->data_sockaddr.sin_addr.s_addr = sceNetHtonl(PSP2_NET_INADDR_ANY); /* Let the PSVita choose a port */ client->data_sockaddr.sin_port = sceNetHtons(0); /* Bind the data socket address to the data socket */ ret = sceNetBind(client->data_sockfd, (SceNetSockaddr *)&client->data_sockaddr, sizeof(client->data_sockaddr)); DEBUG("sceNetBind(): 0x%08X\n", ret); /* Start listening */ ret = sceNetListen(client->data_sockfd, 128); DEBUG("sceNetListen(): 0x%08X\n", ret); /* Get the port that the PSVita has chosen */ namelen = sizeof(picked); sceNetGetsockname(client->data_sockfd, (SceNetSockaddr *)&picked, &namelen); DEBUG("PASV mode port: 0x%04X\n", picked.sin_port); /* Build the command */ sprintf(cmd, "227 Entering Passive Mode (%hhu,%hhu,%hhu,%hhu,%hhu,%hhu)\n", (vita_addr.s_addr >> 0) & 0xFF, (vita_addr.s_addr >> 8) & 0xFF, (vita_addr.s_addr >> 16) & 0xFF, (vita_addr.s_addr >> 24) & 0xFF, (picked.sin_port >> 0) & 0xFF, (picked.sin_port >> 8) & 0xFF); client_send_ctrl_msg(client, cmd); /* Set the data connection type to passive! */ client->data_con_type = FTP_DATA_CONNECTION_PASSIVE; }
void _start(void) { // Pass address of a syscall gadget in rcx register f rcx asm("rcx"); directSyscall = rcx; // Load modules int libNet = 14; // Resolve functions int (*sceNetSocket)(const char *, int, int, int); int (*sceNetSocketClose)(int); int (*sceNetBind)(int, struct sockaddr_in *, int); int (*sceNetListen)(int, int); int (*sceNetAccept)(int, struct sockaddr_in *, int *); int (*sceNetRecv)(int, void *, size_t, int); STACK_RESOLVE(libNet, sceNetSocket); STACK_RESOLVE(libNet, sceNetSocketClose); STACK_RESOLVE(libNet, sceNetBind); STACK_RESOLVE(libNet, sceNetListen); STACK_RESOLVE(libNet, sceNetAccept); STACK_RESOLVE(libNet, sceNetRecv); // Fetch code char socketName[] = "loader"; struct sockaddr_in serverAddress; serverAddress.sin_family = htons(AF_INET); serverAddress.sin_addr.s_addr = IN_ADDR_ANY; serverAddress.sin_port = htons(9023); serverAddress.sin_zero[0] = 0; serverAddress.sin_zero[1] = 0; serverAddress.sin_zero[2] = 0; serverAddress.sin_zero[3] = 0; serverAddress.sin_zero[4] = 0; serverAddress.sin_zero[5] = 0; serverAddress.sin_zero[6] = 0; serverAddress.sin_zero[7] = 0; int server = sceNetSocket(socketName, AF_INET, SOCK_STREAM, 0); sceNetBind(server, &serverAddress, sizeof(serverAddress)); sceNetListen(server, 10); int client = sceNetAccept(server, NULL, NULL); void *write = DATA; int length; while((length = sceNetRecv(client, write, 4096, 0)) > 0) { write += length; } sceNetSocketClose(server); sceNetSocketClose(client); }
void *ps4link_requests_thread(void * args) { int ret; struct sockaddr_in serveraddr; ps4link_requests_connected=0; /* Create server socket */ configuration->ps4link_requests_sock = sceNetSocket("requests_server_sock",AF_INET,SOCK_STREAM,0); if(ps4LinkGetValue(REQUESTS_SOCK)>=0) { debugNetPrintf(DEBUG,"[PS4LINK] Created ps4link_requests_sock: %d\n", ps4LinkGetValue(REQUESTS_SOCK)); } /* Fill the server's address */ serveraddr.sin_len = 16; serveraddr.sin_family = 2; serveraddr.sin_addr.s_addr = sceNetHtonl(INADDR_ANY); serveraddr.sin_port = sceNetHtons(ps4LinkGetValue(REQUESTS_PORT)); memset(serveraddr.sin_zero, 0, sizeof(serveraddr.sin_zero)); /* Bind the server's address to the socket */ ret = sceNetBind(ps4LinkGetValue(REQUESTS_SOCK), (struct sockaddr *)&serveraddr, sizeof(serveraddr)); if(ret<0) { debugNetPrintf(DEBUG,"[PS4LINK] sceNetBind error: 0x%08X\n", ret); sceNetSocketClose(ps4LinkGetValue(REQUESTS_SOCK)); return NULL; } debugNetPrintf(DEBUG,"[PS4LINK] bind to ps4link_requests_sock done\n"); /* Start listening */ ret = sceNetListen(ps4LinkGetValue(REQUESTS_SOCK), 5); if(ret<0) { debugNetPrintf(DEBUG,"[PS4LINK] sceNetListen error: 0x%08X\n", ret); sceNetSocketClose(ps4LinkGetValue(REQUESTS_SOCK)); return NULL; } debugNetPrintf(DEBUG,"[PS4LINK] Ready for connection %d\n", ps4LinkGetValue(FILEIO_ACTIVE)); while(ps4LinkGetValue(FILEIO_ACTIVE)) { debugNetPrintf(DEBUG,"[PS4LINK] Waiting for connection\n", ret); /* Accept clients */ struct sockaddr_in clientaddr; int client_sock; unsigned int addrlen = sizeof(clientaddr); client_sock = sceNetAccept(ps4LinkGetValue(REQUESTS_SOCK), (struct sockaddr *)&clientaddr, &addrlen); if (client_sock < 0) { debugNetPrintf(DEBUG,"[PS4LINK] sceNetAccept error (0x%08X)\n", client_sock); continue; } /* Get the client's IP address */ remote_pc_addr = clientaddr.sin_addr.s_addr; char remote_ip[16]; sceNetInetNtop(AF_INET,&clientaddr.sin_addr.s_addr,remote_ip,sizeof(remote_ip)); debugNetPrintf(DEBUG,"[PS4LINK] Client connected from %s port: %i\n ",remote_ip, clientaddr.sin_port); if (ps4LinkGetValue(FILEIO_SOCK) > 0) { debugNetPrintf(DEBUG,"[PS4LINK] Client reconnected\n"); // sceNetSocketClose(ps4LinkGetValue(FILEIO_SOCK)); } configuration->ps4link_fileio_sock = client_sock; ps4link_requests_connected=1; debugNetPrintf(DEBUG,"[PS4LINK] sock ps4link_fileio set %d connected %d\n",ps4LinkGetValue(FILEIO_SOCK),ps4link_requests_connected); } debugNetPrintf(DEBUG,"[PS4LINK] exit thread requests\n"); if(ps4LinkGetValue(FILEIO_SOCK)) { debugNetPrintf(DEBUG,"[PS4LINK] closing fileio_sock\n"); sceNetSocketClose(ps4LinkGetValue(FILEIO_SOCK)); configuration->ps4link_fileio_sock=-1; } if(ps4LinkGetValue(REQUESTS_SOCK)) { debugNetPrintf(DEBUG,"[PS4LINK] closing server_request_sock\n"); sceNetSocketClose(ps4LinkGetValue(REQUESTS_SOCK)); configuration->ps4link_requests_sock=-1; } ps4link_requests_connected=0; //sceKernelExitDeleteThread(0); return NULL; }
static int server_thread(SceSize args, void *argp) { int ret; UNUSED(ret); SceNetSockaddrIn serveraddr; DEBUG("Server thread started!\n"); /* Create server socket */ server_sockfd = sceNetSocket("FTPVita_server_sock", PSP2_NET_AF_INET, PSP2_NET_SOCK_STREAM, 0); DEBUG("Server socket fd: %d\n", server_sockfd); /* Fill the server's address */ serveraddr.sin_family = PSP2_NET_AF_INET; serveraddr.sin_addr.s_addr = sceNetHtonl(PSP2_NET_INADDR_ANY); serveraddr.sin_port = sceNetHtons(FTP_PORT); /* Bind the server's address to the socket */ ret = sceNetBind(server_sockfd, (SceNetSockaddr *)&serveraddr, sizeof(serveraddr)); DEBUG("sceNetBind(): 0x%08X\n", ret); /* Start listening */ ret = sceNetListen(server_sockfd, 128); DEBUG("sceNetListen(): 0x%08X\n", ret); while (1) { /* Accept clients */ SceNetSockaddrIn clientaddr; int client_sockfd; unsigned int addrlen = sizeof(clientaddr); DEBUG("Waiting for incoming connections...\n"); client_sockfd = sceNetAccept(server_sockfd, (SceNetSockaddr *)&clientaddr, &addrlen); if (client_sockfd >= 0) { DEBUG("New connection, client fd: 0x%08X\n", client_sockfd); /* Get the client's IP address */ char remote_ip[16]; sceNetInetNtop(PSP2_NET_AF_INET, &clientaddr.sin_addr.s_addr, remote_ip, sizeof(remote_ip)); INFO("Client %i connected, IP: %s port: %i\n", number_clients, remote_ip, clientaddr.sin_port); /* Create a new thread for the client */ char client_thread_name[64]; sprintf(client_thread_name, "FTPVita_client_%i_thread", number_clients); SceUID client_thid = sceKernelCreateThread( client_thread_name, client_thread, 0x10000100, 0x10000, 0, 0, NULL); DEBUG("Client %i thread UID: 0x%08X\n", number_clients, client_thid); /* Allocate the ClientInfo struct for the new client */ ClientInfo *client = malloc(sizeof(*client)); client->num = number_clients; client->thid = client_thid; client->ctrl_sockfd = client_sockfd; client->data_con_type = FTP_DATA_CONNECTION_NONE; sprintf(client->cur_path, "%s%s", FTP_DEFAULT_PREFIX, FTP_DEFAULT_PATH); memcpy(&client->addr, &clientaddr, sizeof(client->addr)); /* Add the new client to the client list */ client_list_add(client); /* Start the client thread */ sceKernelStartThread(client_thid, sizeof(*client), client); number_clients++; } else { /* if sceNetAccept returns < 0, it means that the listening * socket has been closed, this means that we want to * finish the server thread */ DEBUG("Server socket closed, 0x%08X\n", client_sockfd); break; } } DEBUG("Server thread exiting!\n"); sceKernelExitDeleteThread(0); return 0; }