@@ -70,6 +70,8 @@ distribution.
7070
7171#define NET_UNKNOWN_ERROR_OFFSET -10000
7272
73+ #define IOCTLV_SO_GETINTERFACEOPT_LEVEL 0x0000FFFE;
74+
7375enum {
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+
111121struct 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...
157186static 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