@@ -1482,13 +1482,145 @@ static NTSTATUS ipv4_forward_enumerate_all( void *key_data, UINT key_size, void
14821482 return status ;
14831483}
14841484
1485+ struct ipv6_route_data
1486+ {
1487+ NET_LUID luid ;
1488+ UINT if_index ;
1489+ struct in6_addr prefix ;
1490+ UINT prefix_len ;
1491+ struct in6_addr next_hop ;
1492+ UINT metric ;
1493+ UINT protocol ;
1494+ BYTE loopback ;
1495+ };
1496+
1497+ static void ipv6_forward_fill_entry ( struct ipv6_route_data * entry , struct nsi_ipv6_forward_key * key ,
1498+ struct nsi_ip_forward_rw * rw , struct nsi_ipv6_forward_dynamic * dyn ,
1499+ struct nsi_ip_forward_static * stat )
1500+ {
1501+ if (key )
1502+ {
1503+ key -> unk = 0 ;
1504+ memcpy ( key -> prefix .u .Byte , entry -> prefix .s6_addr , sizeof (entry -> prefix .s6_addr ) );
1505+ key -> prefix_len = entry -> prefix_len ;
1506+ memset ( key -> unk2 , 0 , sizeof (key -> unk2 ) );
1507+ memset ( key -> unk3 , 0 , sizeof (key -> unk3 ) );
1508+ key -> luid = entry -> luid ;
1509+ key -> luid2 = entry -> luid ;
1510+ memcpy ( key -> next_hop .u .Byte , entry -> next_hop .s6_addr , sizeof (entry -> next_hop .s6_addr ) );
1511+ key -> pad = 0 ;
1512+ }
1513+
1514+ if (rw )
1515+ {
1516+ rw -> site_prefix_len = 0 ;
1517+ rw -> valid_lifetime = ~0u ;
1518+ rw -> preferred_lifetime = ~0u ;
1519+ rw -> metric = entry -> metric ;
1520+ rw -> protocol = entry -> protocol ;
1521+ rw -> loopback = entry -> loopback ;
1522+ rw -> autoconf = 1 ;
1523+ rw -> publish = 0 ;
1524+ rw -> immortal = 1 ;
1525+ memset ( rw -> unk , 0 , sizeof (rw -> unk ) );
1526+ rw -> unk2 = 0 ;
1527+ }
1528+
1529+ if (dyn )
1530+ {
1531+ memset ( dyn , 0 , sizeof (* dyn ) );
1532+ }
1533+
1534+ if (stat )
1535+ {
1536+ stat -> origin = NlroManual ;
1537+ stat -> if_index = entry -> if_index ;
1538+ }
1539+ }
1540+
1541+ struct in6_addr str_to_in6_addr (char * nptr , char * * endptr )
1542+ {
1543+ struct in6_addr ret ;
1544+
1545+ for (int i = 0 ; i < sizeof (ret ); i ++ )
1546+ {
1547+ if (!isxdigit ( * nptr ) || !isxdigit ( * nptr + 1 ))
1548+ {
1549+ /* invalid hex string */
1550+ if (endptr ) * endptr = nptr ;
1551+ return ret ;
1552+ }
1553+
1554+ sscanf ( nptr , "%2hhx" , & ret .s6_addr [i ] );
1555+ nptr += 2 ;
1556+ }
1557+
1558+ if (endptr ) * endptr = nptr ;
1559+
1560+ return ret ;
1561+ }
1562+
14851563static NTSTATUS ipv6_forward_enumerate_all ( void * key_data , UINT key_size , void * rw_data , UINT rw_size ,
14861564 void * dynamic_data , UINT dynamic_size ,
14871565 void * static_data , UINT static_size , UINT_PTR * count )
14881566{
1567+ UINT num = 0 ;
1568+ NTSTATUS status = STATUS_SUCCESS ;
1569+ BOOL want_data = key_size || rw_size || dynamic_size || static_size ;
1570+ struct ipv6_route_data entry ;
1571+
1572+ TRACE ( "%p %d %p %d %p %d %p %d %p" , key_data , key_size , rw_data , rw_size ,
1573+ dynamic_data , dynamic_size , static_data , static_size , count );
1574+
1575+ #ifdef __linux__
1576+ {
1577+ char buf [512 ], * ptr ;
1578+ UINT rtf_flags ;
1579+ FILE * fp ;
1580+
1581+ if (!(fp = fopen ( "/proc/net/ipv6_route" , "r" ))) return STATUS_NOT_SUPPORTED ;
1582+
1583+ while ((ptr = fgets ( buf , sizeof (buf ), fp )))
1584+ {
1585+ while (!isspace ( * ptr )) ptr ++ ;
1586+ * ptr ++ = '\0' ;
1587+
1588+ entry .prefix = str_to_in6_addr ( ptr , & ptr );
1589+ entry .prefix_len = strtoul ( ptr + 1 , & ptr , 16 );
1590+ str_to_in6_addr ( ptr + 1 , & ptr ); /* source network, skip */
1591+ strtoul ( ptr + 1 , & ptr , 16 ); /* source prefix length, skip */
1592+ entry .next_hop = str_to_in6_addr ( ptr + 1 , & ptr );
1593+ entry .metric = strtoul ( ptr + 1 , & ptr , 16 );
1594+ strtoul ( ptr + 1 , & ptr , 16 ); /* refcount, skip */
1595+ strtoul ( ptr + 1 , & ptr , 16 ); /* use, skip */
1596+ rtf_flags = strtoul ( ptr + 1 , & ptr , 16 );
1597+ entry .protocol = (rtf_flags & RTF_GATEWAY ) ? MIB_IPPROTO_NETMGMT : MIB_IPPROTO_LOCAL ;
1598+ entry .loopback = entry .protocol == MIB_IPPROTO_LOCAL && entry .prefix_len == 32 ;
1599+
1600+ if (!convert_unix_name_to_luid ( ptr , & entry .luid )) continue ;
1601+ if (!convert_luid_to_index ( & entry .luid , & entry .if_index )) continue ;
1602+
1603+ if (num < * count )
1604+ {
1605+ ipv6_forward_fill_entry ( & entry , key_data , rw_data , dynamic_data , static_data );
1606+ key_data = (BYTE * )key_data + key_size ;
1607+ rw_data = (BYTE * )rw_data + rw_size ;
1608+ dynamic_data = (BYTE * )dynamic_data + dynamic_size ;
1609+ static_data = (BYTE * )static_data + static_size ;
1610+ }
1611+ num ++ ;
1612+ }
1613+ fclose (fp );
1614+ }
1615+ #else
14891616 FIXME ( "not implemented\n" );
1490- * count = 0 ;
1491- return STATUS_SUCCESS ;
1617+ return STATUS_NOT_IMPLEMENTED ;
1618+ #endif
1619+
1620+ if (!want_data || num <= * count ) * count = num ;
1621+ else status = STATUS_BUFFER_OVERFLOW ;
1622+
1623+ return status ;
14921624}
14931625
14941626static struct module_table ipv4_tables [] =
0 commit comments