@@ -70,6 +70,8 @@ distribution.
70
70
71
71
#define NET_UNKNOWN_ERROR_OFFSET -10000
72
72
73
+ #define IOCTLV_SO_GETINTERFACEOPT_LEVEL 0x0000FFFE;
74
+
73
75
enum {
74
76
IOCTL_SO_ACCEPT = 1 ,
75
77
IOCTL_SO_BIND ,
@@ -98,7 +100,7 @@ enum {
98
100
IOCTL_SO_SOCKATMARK , // todo
99
101
IOCTLV_SO_UNK1A , // todo
100
102
IOCTLV_SO_UNK1B , // todo
101
- IOCTLV_SO_GETINTERFACEOPT , // todo
103
+ IOCTLV_SO_GETINTERFACEOPT ,
102
104
IOCTLV_SO_SETINTERFACEOPT , // todo
103
105
IOCTL_SO_SETINTERFACE , // todo
104
106
IOCTL_SO_STARTUP , // 0x1f
@@ -108,6 +110,14 @@ enum {
108
110
IOCTL_SO_ICMPCLOSE // todo
109
111
};
110
112
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
+
111
121
struct init_data {
112
122
u32 state ;
113
123
s32 fd ;
@@ -152,6 +162,25 @@ struct setsockopt_params {
152
162
u8 optval [20 ];
153
163
};
154
164
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
+
155
184
// 0 means we don't know what this error code means
156
185
// I sense a pattern here...
157
186
static u8 _net_error_code_map [] = {
@@ -1169,11 +1198,16 @@ s32 net_poll(struct pollsd *sds,s32 nsds,s32 timeout)
1169
1198
return ret ;
1170
1199
}
1171
1200
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 )
1173
1202
{
1174
1203
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
+
1177
1211
if (!use_dhcp )
1178
1212
return - EINVAL ;
1179
1213
@@ -1188,43 +1222,100 @@ s32 if_config(char *local_ip, char *netmask, char *gateway,bool use_dhcp, int ma
1188
1222
1189
1223
if (ret < 0 )
1190
1224
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 )
1195
1251
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 );
1196
1265
}
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 );
1198
1301
return -1 ;
1199
1302
}
1200
1303
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 )
1202
1305
{
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 )
1219
1309
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 ;
1228
1319
}
1229
1320
1230
1321
#endif /* defined(HW_RVL) */
0 commit comments