Skip to content

Commit f43c818

Browse files
authored
implement getsockopt for GameCube (#105)
* implement getsockopt for GameCube * return 1 or 0 for getsockopt flags
1 parent 6862675 commit f43c818

2 files changed

Lines changed: 112 additions & 0 deletions

File tree

gc/network.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ s32 net_recvfrom(s32 s,void *mem,s32 len,u32 flags,struct sockaddr *from,socklen
276276
s32 net_read(s32 s,void *mem,s32 len);
277277
s32 net_close(s32 s);
278278
s32 net_select(s32 maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,struct timeval *timeout);
279+
s32 net_getsockopt(s32 s,u32 level,u32 optname,const void *optval,socklen_t optlen);
279280
s32 net_setsockopt(s32 s,u32 level,u32 optname,const void *optval,socklen_t optlen);
280281
s32 net_ioctl(s32 s, u32 cmd, void *argp);
281282
s32 net_fcntl(s32 s, u32 cmd, u32 flags);

lwip/network.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2129,6 +2129,117 @@ s32 net_select(s32 maxfdp1,fd_set *readset,fd_set *writeset,fd_set *exceptset,st
21292129
return nready;
21302130
}
21312131

2132+
s32 net_getsockopt(s32 s,u32 level,u32 optname,const void *optval,socklen_t optlen)
2133+
{
2134+
s32 err = 0;
2135+
struct netsocket *sock;
2136+
2137+
sock = get_socket(s);
2138+
if(sock==NULL) return -ENOTSOCK;
2139+
if(optval==NULL) return -EINVAL;
2140+
2141+
switch(level) {
2142+
case SOL_SOCKET:
2143+
{
2144+
switch(optname) {
2145+
case SO_ERROR:
2146+
case SO_BROADCAST:
2147+
case SO_KEEPALIVE:
2148+
case SO_REUSEADDR:
2149+
case SO_REUSEPORT:
2150+
if(optlen<sizeof(u32)) err = EINVAL;
2151+
break;
2152+
default:
2153+
LWIP_DEBUGF(SOCKETS_DEBUG, ("net_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", s, optname));
2154+
err = ENOPROTOOPT;
2155+
}
2156+
}
2157+
break;
2158+
2159+
case IPPROTO_IP:
2160+
{
2161+
switch(optname) {
2162+
case IP_TTL:
2163+
case IP_TOS:
2164+
if(optlen<sizeof(u32)) err = EINVAL;
2165+
break;
2166+
default:
2167+
LWIP_DEBUGF(SOCKETS_DEBUG, ("net_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", s, optname));
2168+
err = ENOPROTOOPT;
2169+
}
2170+
}
2171+
break;
2172+
2173+
case IPPROTO_TCP:
2174+
{
2175+
if(optlen<sizeof(u32)) {
2176+
err = EINVAL;
2177+
break;
2178+
}
2179+
if(sock->conn->type!=NETCONN_TCP) return 0;
2180+
switch(optname) {
2181+
case TCP_NODELAY:
2182+
case TCP_KEEPALIVE:
2183+
break;
2184+
default:
2185+
LWIP_DEBUGF(SOCKETS_DEBUG, ("net_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", s, optname));
2186+
err = ENOPROTOOPT;
2187+
}
2188+
}
2189+
break;
2190+
2191+
default:
2192+
LWIP_DEBUGF(SOCKETS_DEBUG, ("net_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", s, level, optname));
2193+
err = ENOPROTOOPT;
2194+
}
2195+
if(err) return -err;
2196+
2197+
switch(level) {
2198+
case SOL_SOCKET:
2199+
{
2200+
switch(optname) {
2201+
case SO_ERROR:
2202+
(*(u32*)optval) = sock->conn->err;
2203+
sock->conn->err = 0;
2204+
break;
2205+
case SO_BROADCAST:
2206+
case SO_KEEPALIVE:
2207+
case SO_REUSEADDR:
2208+
case SO_REUSEPORT:
2209+
(*(u32*)optval) = (sock->conn->pcb.tcp->so_options & optname) ? 1 : 0;
2210+
break;
2211+
}
2212+
}
2213+
break;
2214+
2215+
case IPPROTO_IP:
2216+
{
2217+
switch(optname) {
2218+
case IP_TTL:
2219+
(*(u32*)optval) = sock->conn->pcb.tcp->ttl;
2220+
break;
2221+
case IP_TOS:
2222+
(*(u32*)optval) = sock->conn->pcb.tcp->tos;
2223+
break;
2224+
}
2225+
}
2226+
break;
2227+
2228+
case IPPROTO_TCP:
2229+
{
2230+
switch(optname) {
2231+
case TCP_NODELAY:
2232+
(*(u32*)optval) = (sock->conn->pcb.tcp->flags & TF_NODELAY) ? 1 : 0;
2233+
break;
2234+
case TCP_KEEPALIVE:
2235+
(*(u32*)optval) = sock->conn->pcb.tcp->keepalive;
2236+
break;
2237+
}
2238+
}
2239+
}
2240+
return 0;
2241+
}
2242+
21322243
s32 net_setsockopt(s32 s,u32 level,u32 optname,const void *optval,socklen_t optlen)
21332244
{
21342245
s32 err = 0;

0 commit comments

Comments
 (0)