added SOCU_GetNetworkOpt
This commit is contained in:
parent
3a3ee64b64
commit
2b9dc3c82a
@ -6,6 +6,94 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
|
||||||
|
/// The config level to be used with @ref SOCU_GetNetworkOpt
|
||||||
|
#define SOL_CONFIG 0xfffe
|
||||||
|
|
||||||
|
/// Options to be used with @ref SOCU_GetNetworkOpt
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
NETOPT_MAC_ADDRESS = 0x1004, ///< The mac address of the interface (u32 mac[6])
|
||||||
|
NETOPT_ARP_TABLE = 0x3002, ///< The ARP table @see SOCU_ARPTableEntry
|
||||||
|
NETOPT_IP_INFO = 0x4003, ///< The cureent IP setup @see SOCU_IPInfo
|
||||||
|
NETOPT_IP_MTU = 0x4004, ///< The value of the IP MTU (u32)
|
||||||
|
NETOPT_ROUTING_TABLE = 0x4006, ///< The routing table @see SOCU_RoutingTableEntry
|
||||||
|
NETOPT_UDP_NUMBER = 0x8002, ///< The number of sockets in the UDP table (u32)
|
||||||
|
NETOPT_UDP_TABLE = 0x8003, ///< The table of opened UDP sockets @see SOCU_UDPTableEntry
|
||||||
|
NETOPT_TCP_NUMBER = 0x9002, ///< The number of sockets in the TCP table (u32)
|
||||||
|
NETOPT_TCP_TABLE = 0x9003, ///< The table of opened TCP sockets @see SOCU_TCPTableEntry
|
||||||
|
NETOPT_DNS_TABLE = 0xB003, ///< The table of the DNS servers @see SOCU_DNSTableEntry -- Returns a buffer of size 336 but only 2 entries are set ?
|
||||||
|
} NetworkOpt;
|
||||||
|
|
||||||
|
/// One entry of the ARP table retrieved by using @ref SOCU_GetNetworkOpt and @ref NETOPT_ARP_TABLE
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 unk0; // often 2 ? state ?
|
||||||
|
struct in_addr ip; ///< The IPv4 address associated to the entry
|
||||||
|
u8 mac[6]; ///< The MAC address of associated to the entry
|
||||||
|
u8 padding[2];
|
||||||
|
} SOCU_ARPTableEntry;
|
||||||
|
|
||||||
|
/// Structure returned by @ref SOCU_GetNetworkOpt when using @ref NETOPT_IP_INFO
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct in_addr ip; ///< Current IPv4 address
|
||||||
|
struct in_addr netmask; ///< Current network mask
|
||||||
|
struct in_addr broadcast; ///< Current network broadcast address
|
||||||
|
} SOCU_IPInfo;
|
||||||
|
|
||||||
|
// Linux netstat flags
|
||||||
|
// NOTE : there are probably other flags supported, if you can forge ICMP requests please check for D and M flags
|
||||||
|
|
||||||
|
/** The route uses a gateway */
|
||||||
|
#define ROUTING_FLAG_G 0x01
|
||||||
|
|
||||||
|
/// One entry of the routing table retrieved by using @ref SOCU_GetNetworkOpt and @ref NETOPT_ROUTING_TABLE
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct in_addr dest_ip; ///< Destination IP address of the route
|
||||||
|
struct in_addr netmask; ///< Mask used for this route
|
||||||
|
struct in_addr gateway; ///< Gateway address to reach the network
|
||||||
|
u32 flags; ///< Linux netstat flags @see ROUTING_FLAG_G
|
||||||
|
u64 time; ///< number of milliseconds since 1st Jan 1900 00:00.
|
||||||
|
} SOCU_RoutingTableEntry;
|
||||||
|
|
||||||
|
/// One entry of the UDP sockets table retrieved by using @ref SOCU_GetNetworkOpt and @ref NETOPT_UDP_TABLE
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct sockaddr_storage local; ///< Local address information
|
||||||
|
struct sockaddr_storage remote; ///< Remote address information
|
||||||
|
} SOCU_UDPTableEntry;
|
||||||
|
|
||||||
|
///@name TCP states
|
||||||
|
///@{
|
||||||
|
#define TCP_STATE_CLOSED 1
|
||||||
|
#define TCP_STATE_LISTEN 2
|
||||||
|
#define TCP_STATE_ESTABLISHED 5
|
||||||
|
#define TCP_STATE_FINWAIT1 6
|
||||||
|
#define TCP_STATE_FINWAIT2 7
|
||||||
|
#define TCP_STATE_CLOSE_WAIT 8
|
||||||
|
#define TCP_STATE_LAST_ACK 9
|
||||||
|
#define TCP_STATE_TIME_WAIT 11
|
||||||
|
///@}
|
||||||
|
|
||||||
|
/// One entry of the TCP sockets table retrieved by using @ref SOCU_GetNetworkOpt and @ref NETOPT_TCP_TABLE
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 state; ///< @see TCP states defines
|
||||||
|
struct sockaddr_storage local; ///< Local address information
|
||||||
|
struct sockaddr_storage remote; ///< Remote address information
|
||||||
|
} SOCU_TCPTableEntry;
|
||||||
|
|
||||||
|
/// One entry of the DNS servers table retrieved by using @ref SOCU_GetNetworkOpt and @ref NETOPT_DNS_TABLE
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 family; /// Family of the address of the DNS server
|
||||||
|
struct in_addr ip; /// IP of the DNS server
|
||||||
|
u8 padding[12]; // matches the length required for IPv6 addresses
|
||||||
|
} SOCU_DNSTableEntry;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializes the SOC service.
|
* @brief Initializes the SOC service.
|
||||||
@ -35,6 +123,16 @@ int SOCU_ShutdownSockets();
|
|||||||
|
|
||||||
int SOCU_CloseSockets();
|
int SOCU_CloseSockets();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Retrieves information from the network configuration. Similar to getsockopt().
|
||||||
|
* @param level Only value allowed seems to be @ref SOL_CONFIG
|
||||||
|
* @param optname The option to be retrieved
|
||||||
|
* @param optval Will contain the output of the command
|
||||||
|
* @param optlen Size of the optval buffer, will be updated to hold the size of the output
|
||||||
|
* @return 0 if successful. -1 if failed, and errno will be set accordingly. Can also return a system error code.
|
||||||
|
*/
|
||||||
|
int SOCU_GetNetworkOpt(int level, NetworkOpt optname, void * optval, socklen_t * optlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the system's IP address, netmask, and subnet broadcast
|
* @brief Gets the system's IP address, netmask, and subnet broadcast
|
||||||
* @return error
|
* @return error
|
||||||
|
@ -1,54 +1,14 @@
|
|||||||
#include "soc_common.h"
|
#include "soc_common.h"
|
||||||
#include <3ds/ipc.h>
|
#include <3ds/ipc.h>
|
||||||
#include <3ds/result.h>
|
#include <3ds/result.h>
|
||||||
|
#include <3ds/services/soc.h>
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
struct in_addr ip;
|
|
||||||
struct in_addr netmask;
|
|
||||||
struct in_addr broadcast;
|
|
||||||
} SOCU_IPInfo_t;
|
|
||||||
|
|
||||||
int SOCU_GetIPInfo(struct in_addr *ip, struct in_addr *netmask, struct in_addr *broadcast)
|
int SOCU_GetIPInfo(struct in_addr *ip, struct in_addr *netmask, struct in_addr *broadcast)
|
||||||
{
|
{
|
||||||
int i, ret;
|
SOCU_IPInfo info;
|
||||||
u32 *cmdbuf = getThreadCommandBuffer();
|
socklen_t infolen = sizeof info;
|
||||||
u32 *staticbufs = getThreadStaticBuffers();
|
int ret = SOCU_GetNetworkOpt(SOL_CONFIG,NETOPT_IP_INFO,&info,&infolen);
|
||||||
u32 saved_threadstorage[2];
|
if(ret != 0) return ret;
|
||||||
SOCU_IPInfo_t info;
|
|
||||||
|
|
||||||
cmdbuf[0] = IPC_MakeHeader(0x1A,3,0); //0x1A00C0
|
|
||||||
cmdbuf[1] = 0xFFFE;
|
|
||||||
cmdbuf[2] = 0x4003;
|
|
||||||
cmdbuf[3] = sizeof(info);
|
|
||||||
|
|
||||||
// Save the thread storage values
|
|
||||||
for(i = 0 ; i < 2 ; ++i)
|
|
||||||
saved_threadstorage[i] = staticbufs[i];
|
|
||||||
|
|
||||||
staticbufs[0] = IPC_Desc_StaticBuffer(sizeof(info), 0);
|
|
||||||
staticbufs[1] = (u32)&info;
|
|
||||||
|
|
||||||
ret = svcSendSyncRequest(SOCU_handle);
|
|
||||||
|
|
||||||
// Restore the thread storage values
|
|
||||||
for(i = 0 ; i < 2 ; ++i)
|
|
||||||
staticbufs[i] = saved_threadstorage[i];
|
|
||||||
|
|
||||||
if(R_FAILED(ret)) {
|
|
||||||
errno = SYNC_ERROR;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = cmdbuf[1];
|
|
||||||
if(R_FAILED(ret)) {
|
|
||||||
errno = SYNC_ERROR;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
if(cmdbuf[2] != 0)
|
|
||||||
{
|
|
||||||
return cmdbuf[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ip != NULL)
|
if(ip != NULL)
|
||||||
*ip = info.ip;
|
*ip = info.ip;
|
||||||
|
54
libctru/source/services/soc/soc_getnetworkopt.c
Normal file
54
libctru/source/services/soc/soc_getnetworkopt.c
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "soc_common.h"
|
||||||
|
#include <3ds/ipc.h>
|
||||||
|
#include <3ds/result.h>
|
||||||
|
#include <3ds/services/soc.h>
|
||||||
|
|
||||||
|
int SOCU_GetNetworkOpt(int level, NetworkOpt optname, void * optval, socklen_t * optlen)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
u32 *cmdbuf = getThreadCommandBuffer();
|
||||||
|
u32 *staticbufs = getThreadStaticBuffers();
|
||||||
|
u32 saved_threadstorage[2];
|
||||||
|
|
||||||
|
cmdbuf[0] = IPC_MakeHeader(0x1A,3,0); //0x1A00C0
|
||||||
|
cmdbuf[1] = level;
|
||||||
|
cmdbuf[2] = optname;
|
||||||
|
cmdbuf[3] = *optlen;
|
||||||
|
|
||||||
|
// Save the thread storage values
|
||||||
|
for(i = 0 ; i < 2 ; ++i)
|
||||||
|
saved_threadstorage[i] = staticbufs[i];
|
||||||
|
|
||||||
|
staticbufs[0] = IPC_Desc_StaticBuffer(*optlen, 0);
|
||||||
|
staticbufs[1] = (u32)optval;
|
||||||
|
|
||||||
|
ret = svcSendSyncRequest(SOCU_handle);
|
||||||
|
|
||||||
|
// Restore the thread storage values
|
||||||
|
for(i = 0 ; i < 2 ; ++i)
|
||||||
|
staticbufs[i] = saved_threadstorage[i];
|
||||||
|
|
||||||
|
if(R_FAILED(ret)) {
|
||||||
|
errno = SYNC_ERROR;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (int)cmdbuf[1];
|
||||||
|
if(R_FAILED(ret))
|
||||||
|
{
|
||||||
|
errno = SYNC_ERROR;
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _net_convert_error(cmdbuf[2]);
|
||||||
|
|
||||||
|
if(ret < 0) {
|
||||||
|
errno = -ret;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*optlen = cmdbuf[3];
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user