Skip to content

Commit 60fba8e

Browse files
authored
net: refactor if_config to also fetch gateway & network mask #179 (#180)
1 parent f4dbfca commit 60fba8e

File tree

1 file changed

+125
-34
lines changed

1 file changed

+125
-34
lines changed

libogc/network_wii.c

Lines changed: 125 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ distribution.
7070

7171
#define NET_UNKNOWN_ERROR_OFFSET -10000
7272

73+
#define IOCTLV_SO_GETINTERFACEOPT_LEVEL 0x0000FFFE;
74+
7375
enum {
7476
IOCTL_SO_ACCEPT = 1,
7577
IOCTL_SO_BIND,
@@ -98,7 +100,7 @@ enum {
98100
IOCTL_SO_SOCKATMARK, // todo
99101
IOCTLV_SO_UNK1A, // todo
100102
IOCTLV_SO_UNK1B, // todo
101-
IOCTLV_SO_GETINTERFACEOPT, // todo
103+
IOCTLV_SO_GETINTERFACEOPT,
102104
IOCTLV_SO_SETINTERFACEOPT, // todo
103105
IOCTL_SO_SETINTERFACE, // todo
104106
IOCTL_SO_STARTUP, // 0x1f
@@ -108,6 +110,14 @@ enum {
108110
IOCTL_SO_ICMPCLOSE // todo
109111
};
110112

113+
enum {
114+
SO_GETINTERFACEOPT_MAC = 0x1004,
115+
SO_GETINTERFACEOPT_LINKSTATE = 0x1005,
116+
SO_GETINTERFACEOPT_IPCONFIG = 0x4003,
117+
SO_GETINTERFACEOPT_ROUTING_SIZE = 0x4005,
118+
SO_GETINTERFACEOPT_ROUTING = 0x4006,
119+
};
120+
111121
struct init_data {
112122
u32 state;
113123
s32 fd;
@@ -152,6 +162,25 @@ struct setsockopt_params {
152162
u8 optval[20];
153163
};
154164

165+
struct getinterfaceopt_params {
166+
u32 magic;
167+
u32 option;
168+
};
169+
170+
struct getinterfaceopt_ipconfig{
171+
u32 inet;
172+
u32 subnetMask;
173+
u32 broadcastIp;
174+
};
175+
176+
struct getinterfaceopt_iproute{
177+
u32 destination;
178+
u32 netmask;
179+
u32 gateway;
180+
u32 flags;
181+
u64 ticks;
182+
};
183+
155184
// 0 means we don't know what this error code means
156185
// I sense a pattern here...
157186
static u8 _net_error_code_map[] = {
@@ -1169,11 +1198,16 @@ s32 net_poll(struct pollsd *sds,s32 nsds,s32 timeout)
11691198
return ret;
11701199
}
11711200

1172-
s32 if_config(char *local_ip, char *netmask, char *gateway,bool use_dhcp, int max_retries)
1201+
s32 if_configex(struct in_addr *local_ip, struct in_addr *netmask, struct in_addr *gateway, bool use_dhcp, int max_retries)
11731202
{
11741203
s32 i,ret;
1175-
struct in_addr hostip;
1176-
1204+
const u32 ipconfig_size = sizeof(struct getinterfaceopt_ipconfig);
1205+
STACK_ALIGN(ioctlv, vectors, sizeof(ioctlv)*3, 32);
1206+
STACK_ALIGN(struct getinterfaceopt_params, params, sizeof(struct getinterfaceopt_params), 32);
1207+
STACK_ALIGN(struct getinterfaceopt_ipconfig, ipconfig, ipconfig_size, 32);
1208+
static u32 response __attribute__((aligned(32)));
1209+
static u32 table_size __attribute__((aligned(32)));
1210+
11771211
if (!use_dhcp)
11781212
return -EINVAL;
11791213

@@ -1188,43 +1222,100 @@ s32 if_config(char *local_ip, char *netmask, char *gateway,bool use_dhcp, int ma
11881222

11891223
if (ret < 0)
11901224
return ret;
1191-
1192-
hostip.s_addr = net_gethostip();
1193-
if (local_ip && hostip.s_addr) {
1194-
strcpy(local_ip, inet_ntoa(hostip));
1225+
1226+
//setup input vectors
1227+
memset(ipconfig, 0, ipconfig_size);
1228+
params->magic = IOCTLV_SO_GETINTERFACEOPT_LEVEL;
1229+
params->option = SO_GETINTERFACEOPT_IPCONFIG;
1230+
response = ipconfig_size;
1231+
vectors[0].data = params;
1232+
vectors[0].len = sizeof(struct getinterfaceopt_params);
1233+
1234+
vectors[1].data = ipconfig;
1235+
vectors[1].len = ipconfig_size;
1236+
1237+
vectors[2].data = &response;
1238+
vectors[2].len = sizeof(u32);;
1239+
1240+
ret = IOS_Ioctlv(net_ip_top_fd, IOCTLV_SO_GETINTERFACEOPT, 1, 2, vectors);
1241+
if(ret < 0)
1242+
return _net_convert_error(ret);
1243+
1244+
if(local_ip)
1245+
local_ip->s_addr = ipconfig->inet;
1246+
1247+
if(netmask)
1248+
netmask->s_addr = ipconfig->subnetMask;
1249+
1250+
if(!gateway)
11951251
return 0;
1252+
1253+
//retrieve gateway from the ip routing table
1254+
params->option = SO_GETINTERFACEOPT_ROUTING_SIZE;
1255+
response = sizeof(u32);
1256+
1257+
vectors[1].data = &table_size;
1258+
vectors[1].len = sizeof(u32);;
1259+
1260+
ret = IOS_Ioctlv(net_ip_top_fd, IOCTLV_SO_GETINTERFACEOPT, 1, 2, vectors);
1261+
if(ret < 0)
1262+
{
1263+
debug_printf("failed to get the routing table size: %d\n", ret);
1264+
return _net_convert_error(ret);
11961265
}
1197-
1266+
1267+
params->option = SO_GETINTERFACEOPT_ROUTING;
1268+
const u32 memory_size = table_size * sizeof(struct getinterfaceopt_iproute);
1269+
response = memory_size;
1270+
struct getinterfaceopt_iproute* routing_tables = (struct getinterfaceopt_iproute*)net_malloc(memory_size);
1271+
if(routing_tables == NULL)
1272+
{
1273+
debug_printf("failed to malloc routing tables\n");
1274+
return IPC_ENOMEM;
1275+
}
1276+
1277+
memset(routing_tables, 0, memory_size);
1278+
vectors[1].data = routing_tables;
1279+
vectors[1].len = memory_size;
1280+
1281+
ret = IOS_Ioctlv(net_ip_top_fd, 28, 1, 2, vectors);
1282+
if(ret < 0)
1283+
{
1284+
debug_printf("failed to get the routing table: %d\n", ret);
1285+
net_free(routing_tables);
1286+
return _net_convert_error(ret);
1287+
}
1288+
1289+
DCFlushRange(routing_tables, memory_size);
1290+
for(i = 0; i < table_size;i++)
1291+
{
1292+
if(routing_tables[i].destination != 0 || routing_tables[i].netmask != 0 || (routing_tables[i].flags & 1) != 1)
1293+
continue;
1294+
1295+
gateway->s_addr = routing_tables[i].gateway;
1296+
net_free(routing_tables);
1297+
return 0;
1298+
}
1299+
1300+
net_free(routing_tables);
11981301
return -1;
11991302
}
12001303

1201-
s32 if_configex(struct in_addr *local_ip, struct in_addr *netmask, struct in_addr *gateway,bool use_dhcp, int max_retries)
1304+
s32 if_config(char *local_ip, char *netmask, char *gateway, bool use_dhcp, int max_retries)
12021305
{
1203-
s32 i,ret;
1204-
struct in_addr hostip;
1205-
1206-
if (!use_dhcp)
1207-
return -EINVAL;
1208-
1209-
for (i = 0; i < MAX_INIT_RETRIES; ++i) {
1210-
ret = net_init();
1211-
1212-
if ((ret != -EAGAIN) && (ret != -ETIMEDOUT))
1213-
break;
1214-
1215-
usleep(50 * 1000);
1216-
}
1217-
1218-
if (ret < 0)
1306+
struct in_addr hostip, hostnetmask, hostgateway;
1307+
s32 ret = if_configex(&hostip, &hostnetmask, gateway == NULL ? NULL : &hostgateway, use_dhcp, max_retries);
1308+
if(ret < 0)
12191309
return ret;
1220-
1221-
hostip.s_addr = net_gethostip();
1222-
if (local_ip && hostip.s_addr) {
1223-
*local_ip = hostip;
1224-
return 0;
1225-
}
1226-
1227-
return -1;
1310+
1311+
if(local_ip && hostip.s_addr)
1312+
strcpy(local_ip, inet_ntoa(hostip));
1313+
if(netmask && hostnetmask.s_addr)
1314+
strcpy(netmask, inet_ntoa(hostnetmask));
1315+
if(gateway && hostgateway.s_addr)
1316+
strcpy(gateway, inet_ntoa(hostgateway));
1317+
1318+
return ret;
12281319
}
12291320

12301321
#endif /* defined(HW_RVL) */

0 commit comments

Comments
 (0)