Skip to content

Commit 4057aa2

Browse files
TornadoCookiePaul Gofman
authored andcommitted
nsiproxy.sys: Implement ipv6_forward_enumerate_all.
(cherry picked from commit 5a7d75c) CW-Bug-Id: #23460
1 parent 04c387c commit 4057aa2

File tree

1 file changed

+134
-2
lines changed
  • dlls/nsiproxy.sys

1 file changed

+134
-2
lines changed

dlls/nsiproxy.sys/ip.c

Lines changed: 134 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
14851563
static 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

14941626
static struct module_table ipv4_tables[] =

0 commit comments

Comments
 (0)