diff --git a/sysmodules/rosalina/include/minisoc.h b/sysmodules/rosalina/include/minisoc.h index 6836b5e..efa564a 100644 --- a/sysmodules/rosalina/include/minisoc.h +++ b/sysmodules/rosalina/include/minisoc.h @@ -37,10 +37,17 @@ int socConnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); int socPoll(struct pollfd *fds, nfds_t nfds, int timeout); int socSetsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); int socClose(int sockfd); +long socGethostid(void); -ssize_t soc_recv(int sockfd, void *buf, size_t len, int flags); -ssize_t soc_send(int sockfd, const void *buf, size_t len, int flags); +ssize_t socRecvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); +ssize_t socSendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); -// actually provided by ctrulib -ssize_t soc_recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); -ssize_t soc_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); +static inline ssize_t socRecv(int sockfd, void *buf, size_t len, int flags) +{ + return socRecvfrom(sockfd, buf, len, flags, NULL, 0); +} + +static inline ssize_t socSend(int sockfd, const void *buf, size_t len, int flags) +{ + return socSendto(sockfd, buf, len, flags, NULL, 0); +} diff --git a/sysmodules/rosalina/source/gdb/net.c b/sysmodules/rosalina/source/gdb/net.c index 34c3312..85ff466 100644 --- a/sysmodules/rosalina/source/gdb/net.c +++ b/sysmodules/rosalina/source/gdb/net.c @@ -177,7 +177,7 @@ int GDB_ReceivePacket(GDBContext *ctx) memcpy(backupbuf, ctx->buffer, ctx->latestSentPacketSize); memset(ctx->buffer, 0, sizeof(ctx->buffer)); - int r = soc_recv(ctx->super.sockfd, ctx->buffer, sizeof(ctx->buffer), MSG_PEEK); + int r = socRecv(ctx->super.sockfd, ctx->buffer, sizeof(ctx->buffer), MSG_PEEK); if(r < 1) return -1; if(ctx->buffer[0] == '+') // GDB sometimes acknowleges TCP acknowledgment packets (yes...). IDA does it properly @@ -186,20 +186,20 @@ int GDB_ReceivePacket(GDBContext *ctx) return -1; // Consume it - r = soc_recv(ctx->super.sockfd, ctx->buffer, 1, 0); + r = socRecv(ctx->super.sockfd, ctx->buffer, 1, 0); if(r != 1) return -1; ctx->buffer[0] = 0; - r = soc_recv(ctx->super.sockfd, ctx->buffer, sizeof(ctx->buffer), MSG_PEEK); + r = socRecv(ctx->super.sockfd, ctx->buffer, sizeof(ctx->buffer), MSG_PEEK); if(r == -1) goto packet_error; } else if(ctx->buffer[0] == '-') { - soc_send(ctx->super.sockfd, backupbuf, ctx->latestSentPacketSize, 0); + socSend(ctx->super.sockfd, backupbuf, ctx->latestSentPacketSize, 0); return 0; } int maxlen = r > (int)sizeof(ctx->buffer) ? (int)sizeof(ctx->buffer) : r; @@ -215,7 +215,7 @@ int GDB_ReceivePacket(GDBContext *ctx) else { u8 checksum; - r = soc_recv(ctx->super.sockfd, ctx->buffer, 3 + pos - ctx->buffer, 0); + r = socRecv(ctx->super.sockfd, ctx->buffer, 3 + pos - ctx->buffer, 0); if(r != 3 + pos - ctx->buffer || GDB_DecodeHex(&checksum, pos + 1, 1) != 1) goto packet_error; else if(GDB_ComputeChecksum(ctx->buffer + 1, pos - ctx->buffer - 1) != checksum) @@ -227,7 +227,7 @@ int GDB_ReceivePacket(GDBContext *ctx) } else if(ctx->buffer[0] == '\x03') { - r = soc_recv(ctx->super.sockfd, ctx->buffer, 1, 0); + r = socRecv(ctx->super.sockfd, ctx->buffer, 1, 0); if(r != 1) goto packet_error; @@ -236,7 +236,7 @@ int GDB_ReceivePacket(GDBContext *ctx) if(!(ctx->flags & GDB_FLAG_NOACK)) { - int r2 = soc_send(ctx->super.sockfd, "+", 1, 0); + int r2 = socSend(ctx->super.sockfd, "+", 1, 0); if(r2 != 1) return -1; } @@ -252,7 +252,7 @@ int GDB_ReceivePacket(GDBContext *ctx) packet_error: if(!(ctx->flags & GDB_FLAG_NOACK)) { - r = soc_send(ctx->super.sockfd, "-", 1, 0); + r = socSend(ctx->super.sockfd, "-", 1, 0); if(r != 1) return -1; else @@ -264,7 +264,7 @@ packet_error: static int GDB_DoSendPacket(GDBContext *ctx, u32 len) { - int r = soc_send(ctx->super.sockfd, ctx->buffer, len, 0); + int r = socSend(ctx->super.sockfd, ctx->buffer, len, 0); if(r > 0) ctx->latestSentPacketSize = r; diff --git a/sysmodules/rosalina/source/input_redirection.c b/sysmodules/rosalina/source/input_redirection.c index 058162e..7dc941e 100644 --- a/sysmodules/rosalina/source/input_redirection.c +++ b/sysmodules/rosalina/source/input_redirection.c @@ -69,7 +69,7 @@ void inputRedirectionThreadMain(void) struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(4950); - saddr.sin_addr.s_addr = gethostid(); + saddr.sin_addr.s_addr = socGethostid(); res = socBind(sock, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in)); if(res != 0) { @@ -99,7 +99,7 @@ void inputRedirectionThreadMain(void) int pollres = socPoll(&pfd, 1, 10); if(pollres > 0 && (pfd.revents & POLLIN)) { - int n = soc_recvfrom(sock, buf, 20, 0, NULL, 0); + int n = socRecvfrom(sock, buf, 20, 0, NULL, 0); if(n < 0) break; else if(n < 12) diff --git a/sysmodules/rosalina/source/menu.c b/sysmodules/rosalina/source/menu.c index a4809de..7f1267e 100644 --- a/sysmodules/rosalina/source/menu.c +++ b/sysmodules/rosalina/source/menu.c @@ -245,7 +245,7 @@ static void menuDraw(Menu *menu, u32 selected) if(miniSocEnabled) { char ipBuffer[17]; - u32 ip = gethostid(); + u32 ip = socGethostid(); u8 *addr = (u8 *)&ip; int n = sprintf(ipBuffer, "%hhu.%hhu.%hhu.%hhu", addr[0], addr[1], addr[2], addr[3]); Draw_DrawString(SCREEN_BOT_WIDTH - 10 - SPACING_X * n, 10, COLOR_WHITE, ipBuffer); diff --git a/sysmodules/rosalina/source/menus/process_list.c b/sysmodules/rosalina/source/menus/process_list.c index 8ff0364..47b0bdc 100644 --- a/sysmodules/rosalina/source/menus/process_list.c +++ b/sysmodules/rosalina/source/menus/process_list.c @@ -666,7 +666,7 @@ void RosalinaMenu_ProcessList(void) if(gdbServer.super.running) { char ipBuffer[17]; - u32 ip = gethostid(); + u32 ip = socGethostid(); u8 *addr = (u8 *)&ip; int n = sprintf(ipBuffer, "%hhu.%hhu.%hhu.%hhu", addr[0], addr[1], addr[2], addr[3]); Draw_DrawString(SCREEN_BOT_WIDTH - 10 - SPACING_X * n, 10, COLOR_WHITE, ipBuffer); diff --git a/sysmodules/rosalina/source/minisoc.c b/sysmodules/rosalina/source/minisoc.c index e77913f..52953ca 100644 --- a/sysmodules/rosalina/source/minisoc.c +++ b/sysmodules/rosalina/source/minisoc.c @@ -457,12 +457,262 @@ int socSetsockopt(int sockfd, int level, int optname, const void *optval, sockle return ret; } -ssize_t soc_recv(int sockfd, void *buf, size_t len, int flags) +long socGethostid(void) { - return soc_recvfrom(sockfd, buf, len, flags, NULL, 0); + int ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x16,0,0); // 0x160000 + + ret = svcSendSyncRequest(SOCU_handle); + if(ret != 0) { + //errno = SYNC_ERROR; + return -1; + } + + ret = (int)cmdbuf[1]; + if(ret == 0) + ret = cmdbuf[2]; + + return ret; } -ssize_t soc_send(int sockfd, const void *buf, size_t len, int flags) +static ssize_t _socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { - return soc_sendto(sockfd, buf, len, flags, NULL, 0); + int ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + u32 tmp_addrlen = 0; + u8 tmpaddr[0x1c]; + u32 saved_threadstorage[2]; + + memset(tmpaddr, 0, 0x1c); + + if(src_addr) + tmp_addrlen = 0x1c; + + cmdbuf[0] = IPC_MakeHeader(0x7,4,4); // 0x70104 + cmdbuf[1] = (u32)sockfd; + cmdbuf[2] = (u32)len; + cmdbuf[3] = (u32)flags; + cmdbuf[4] = (u32)tmp_addrlen; + cmdbuf[5] = IPC_Desc_CurProcessId(); + cmdbuf[7] = IPC_Desc_Buffer(len,IPC_BUFFER_W); + cmdbuf[8] = (u32)buf; + + u32 * staticbufs = getThreadStaticBuffers(); + saved_threadstorage[0] = staticbufs[0]; + saved_threadstorage[1] = staticbufs[1]; + + staticbufs[0] = IPC_Desc_StaticBuffer(tmp_addrlen,0); + staticbufs[1] = (u32)tmpaddr; + + ret = svcSendSyncRequest(SOCU_handle); + + staticbufs[0] = saved_threadstorage[0]; + staticbufs[1] = saved_threadstorage[1]; + + if(ret != 0) { + //errno = SYNC_ERROR; + return -1; + } + + ret = (int)cmdbuf[1]; + if(ret == 0) + ret = _net_convert_error(cmdbuf[2]); + + if(ret < 0) { + //errno = -ret; + return -1; + } + + if(src_addr != NULL) { + src_addr->sa_family = tmpaddr[1]; + if(*addrlen > tmpaddr[0]) + *addrlen = tmpaddr[0]; + memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2); + } + + return ret; +} + +static ssize_t _socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) +{ + int ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + u32 tmp_addrlen = 0; + u8 tmpaddr[0x1c]; + u32 saved_threadstorage[4]; + + if(src_addr) + tmp_addrlen = 0x1c; + + memset(tmpaddr, 0, 0x1c); + + cmdbuf[0] = 0x00080102; + cmdbuf[1] = (u32)sockfd; + cmdbuf[2] = (u32)len; + cmdbuf[3] = (u32)flags; + cmdbuf[4] = (u32)tmp_addrlen; + cmdbuf[5] = 0x20; + + saved_threadstorage[0] = cmdbuf[0x100>>2]; + saved_threadstorage[1] = cmdbuf[0x104>>2]; + saved_threadstorage[2] = cmdbuf[0x108>>2]; + saved_threadstorage[3] = cmdbuf[0x10c>>2]; + + cmdbuf[0x100>>2] = (((u32)len)<<14) | 2; + cmdbuf[0x104>>2] = (u32)buf; + cmdbuf[0x108>>2] = (tmp_addrlen<<14) | 2; + cmdbuf[0x10c>>2] = (u32)tmpaddr; + + ret = svcSendSyncRequest(SOCU_handle); + if(ret != 0) { + //errno = SYNC_ERROR; + return ret; + } + + cmdbuf[0x100>>2] = saved_threadstorage[0]; + cmdbuf[0x104>>2] = saved_threadstorage[1]; + cmdbuf[0x108>>2] = saved_threadstorage[2]; + cmdbuf[0x10c>>2] = saved_threadstorage[3]; + + ret = (int)cmdbuf[1]; + if(ret == 0) + ret = _net_convert_error(cmdbuf[2]); + + if(ret < 0) { + //errno = -ret; + return -1; + } + + if(src_addr != NULL) { + src_addr->sa_family = tmpaddr[1]; + if(*addrlen > tmpaddr[0]) + *addrlen = tmpaddr[0]; + memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2); + } + + return ret; +} + +static ssize_t _socuipc_cmd9(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) +{ + int ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + u32 tmp_addrlen = 0; + u8 tmpaddr[0x1c]; + + memset(tmpaddr, 0, 0x1c); + + if(dest_addr) { + if(dest_addr->sa_family == AF_INET) + tmp_addrlen = 8; + else + tmp_addrlen = 0x1c; + + if(addrlen < tmp_addrlen) { + //errno = EINVAL; + return -1; + } + + tmpaddr[0] = tmp_addrlen; + tmpaddr[1] = dest_addr->sa_family; + memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2); + } + + cmdbuf[0] = IPC_MakeHeader(0x9,4,6); // 0x90106 + cmdbuf[1] = (u32)sockfd; + cmdbuf[2] = (u32)len; + cmdbuf[3] = (u32)flags; + cmdbuf[4] = (u32)tmp_addrlen; + cmdbuf[5] = IPC_Desc_CurProcessId(); + cmdbuf[7] = IPC_Desc_StaticBuffer(tmp_addrlen,1); + cmdbuf[8] = (u32)tmpaddr; + cmdbuf[9] = IPC_Desc_Buffer(len,IPC_BUFFER_R); + cmdbuf[10] = (u32)buf; + + ret = svcSendSyncRequest(SOCU_handle); + if(ret != 0) { + //errno = SYNC_ERROR; + return ret; + } + + ret = (int)cmdbuf[1]; + if(ret == 0) + ret = _net_convert_error(cmdbuf[2]); + + if(ret < 0) { + //errno = -ret; + return -1; + } + + return ret; +} + +static ssize_t _socuipc_cmda(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) +{ + int ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + u32 tmp_addrlen = 0; + u8 tmpaddr[0x1c]; + + memset(tmpaddr, 0, 0x1c); + + if(dest_addr) { + if(dest_addr->sa_family == AF_INET) + tmp_addrlen = 8; + else + tmp_addrlen = 0x1c; + + if(addrlen < tmp_addrlen) { + //errno = EINVAL; + return -1; + } + + tmpaddr[0] = tmp_addrlen; + tmpaddr[1] = dest_addr->sa_family; + memcpy(&tmpaddr[2], &dest_addr->sa_data, tmp_addrlen-2); + } + + cmdbuf[0] = IPC_MakeHeader(0xA,4,6); // 0xA0106 + cmdbuf[1] = (u32)sockfd; + cmdbuf[2] = (u32)len; + cmdbuf[3] = (u32)flags; + cmdbuf[4] = (u32)tmp_addrlen; + cmdbuf[5] = IPC_Desc_CurProcessId(); + cmdbuf[7] = IPC_Desc_StaticBuffer(len,2); + cmdbuf[8] = (u32)buf; + cmdbuf[9] = IPC_Desc_StaticBuffer(tmp_addrlen,1); + cmdbuf[10] = (u32)tmpaddr; + + ret = svcSendSyncRequest(SOCU_handle); + if(ret != 0) { + //errno = SYNC_ERROR; + return ret; + } + + ret = (int)cmdbuf[1]; + if(ret == 0) + ret = _net_convert_error(cmdbuf[2]); + + if(ret < 0) { + //errno = -ret; + return -1; + } + + return ret; +} + +ssize_t socRecvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) +{ + if(len < 0x2000) + return _socuipc_cmd8(sockfd, buf, len, flags, src_addr, addrlen); + return _socuipc_cmd7(sockfd, buf, len, flags, src_addr, addrlen); +} + +ssize_t socSendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) +{ + if(len < 0x2000) + return _socuipc_cmda(sockfd, buf, len, flags, dest_addr, addrlen); + return _socuipc_cmd9(sockfd, buf, len, flags, dest_addr, addrlen); } diff --git a/sysmodules/rosalina/source/ntp.c b/sysmodules/rosalina/source/ntp.c index 567d0a1..30040c9 100644 --- a/sysmodules/rosalina/source/ntp.c +++ b/sysmodules/rosalina/source/ntp.c @@ -125,10 +125,10 @@ Result ntpGetTimeStamp(time_t *outTimestamp) if(socConnect(sock, (struct sockaddr *)&servAddr, sizeof(struct sockaddr_in)) < 0) goto cleanup; - if(soc_send(sock, &packet, sizeof(NtpPacket), 0) < 0) + if(socSend(sock, &packet, sizeof(NtpPacket), 0) < 0) goto cleanup; - if(soc_recv(sock, &packet, sizeof(NtpPacket), 0) < 0) + if(socRecv(sock, &packet, sizeof(NtpPacket), 0) < 0) goto cleanup; res = 0; diff --git a/sysmodules/rosalina/source/sock_util.c b/sysmodules/rosalina/source/sock_util.c index 6421ae9..561084a 100644 --- a/sysmodules/rosalina/source/sock_util.c +++ b/sysmodules/rosalina/source/sock_util.c @@ -120,7 +120,7 @@ void server_bind(struct sock_server *serv, u16 port) struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons(port); - saddr.sin_addr.s_addr = gethostid(); + saddr.sin_addr.s_addr = socGethostid(); res = socBind(server_sockfd, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in));