Files
HexwellandClaude Fable 5 2df9e0b2fb fix: share console IP lookup across modules
get_ip_address had three independent implementations (shellui, util, daemon)
because each module also carried its own copy of SceNetCtlInfo and its own
prototype for sceNetCtlGetInfo, with the pointer typed as SceNetCtlInfo* in
two of them and void* in the third.

The shellui and util copies stored the result in an unsigned int and tested
`ret < 0`, which is never true for an unsigned value. Their error branch was
unreachable, so a failed lookup returned success, left not_connected clear,
and copied an uninitialised SceNetCtlInfo to the caller instead of the
IP NOT FOUND placeholder. util's rest-mode network-recovery retry keys off
that return value and therefore never ran.

Declare the netctl ABI once in source/include/ps5/net_ctl.h, add
onion_net_get_ip_address to libonion_platform with an explicit buffer-size
contract, and keep util's not_connected latch in util where it belongs.
Cover the status mapping, the placeholder length and buffer validation with
host tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 19:49:50 +08:00

79 lines
2.4 KiB
C

/* Copyright (C) 2025 OnionHEN / LightningMods
*
* SceNetCtl ABI declarations.
*
* The PS5 payload SDK does not ship a netctl header, so every module used to
* carry its own copy of SceNetCtlInfo (shellui/external_symbols.hpp,
* util/common_utils.h, daemon/daemon_utils.cpp). The three copies had the same
* layout but different prototypes for sceNetCtlGetInfo (SceNetCtlInfo* vs
* void*, int vs int32_t), which is how three subtly different get_ip_address
* implementations grew. This header is the single source of truth.
*
* Declarations only — no OnionHEN behaviour lives here. For reading the
* console IP use onion_net_get_ip_address() from <onion/net.h>.
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define SCE_NET_ETHER_ADDR_LEN 6
#define SCE_NET_ETHER_ADDRSTRLEN 18
#define SCE_NET_CTL_SSID_LEN (32 + 1)
#define SCE_NET_CTL_WIFI_SECURITY_KEY_LEN (64 + 1)
#define SCE_NET_CTL_AUTH_NAME_LEN (127 + 1)
#define SCE_NET_CTL_AUTH_KEY_LEN (127 + 1)
#define SCE_NET_CTL_HOSTNAME_LEN (255 + 1)
#define SCE_NET_CTL_IPV4_ADDR_STR_LEN (16)
/* `code` argument to sceNetCtlGetInfo for the IPv4 address field. */
#define SCE_NET_CTL_INFO_IP_ADDRESS 14
/*
* Returned as a positive 0x8041xxxx bit pattern, so compare against the
* unsigned value — comparing a signed int result never matches.
*/
#define SCE_NET_CTL_ERROR_NOT_CONNECTED 0x80412108u
#define SCE_NET_CTL_ERROR_NOT_AVAIL 0x80412109u
typedef struct SceNetEtherAddr {
uint8_t data[SCE_NET_ETHER_ADDR_LEN];
} SceNetEtherAddr;
typedef void (*SceNetCtlCallback)(int eventType, void *arg);
typedef union SceNetCtlInfo {
uint32_t device;
SceNetEtherAddr ether_addr;
uint32_t mtu;
uint32_t link;
SceNetEtherAddr bssid;
char ssid[SCE_NET_CTL_SSID_LEN];
uint32_t wifi_security;
int32_t rssi_dbm;
uint8_t rssi_percentage;
uint8_t channel;
uint32_t ip_config;
char dhcp_hostname[SCE_NET_CTL_HOSTNAME_LEN];
char pppoe_auth_name[SCE_NET_CTL_AUTH_NAME_LEN];
char ip_address[SCE_NET_CTL_IPV4_ADDR_STR_LEN];
char netmask[SCE_NET_CTL_IPV4_ADDR_STR_LEN];
char default_route[SCE_NET_CTL_IPV4_ADDR_STR_LEN];
char primary_dns[SCE_NET_CTL_IPV4_ADDR_STR_LEN];
char secondary_dns[SCE_NET_CTL_IPV4_ADDR_STR_LEN];
uint32_t http_proxy_config;
char http_proxy_server[SCE_NET_CTL_HOSTNAME_LEN];
uint16_t http_proxy_port;
} SceNetCtlInfo;
int32_t sceNetCtlGetInfo(int32_t code, SceNetCtlInfo *info);
void sceNetCtlTerm(void);
#ifdef __cplusplus
}
#endif