mirror of
git://source.winehq.org/git/wine.git
synced 2024-07-21 09:24:10 +00:00
nsiproxy.sys: Implement ipv6_forward_enumerate_all.
This commit is contained in:
parent
512f8b17ae
commit
5a7d75cd34
|
@ -1482,13 +1482,145 @@ static NTSTATUS ipv4_forward_enumerate_all( void *key_data, UINT key_size, void
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ipv6_route_data
|
||||||
|
{
|
||||||
|
NET_LUID luid;
|
||||||
|
UINT if_index;
|
||||||
|
struct in6_addr prefix;
|
||||||
|
UINT prefix_len;
|
||||||
|
struct in6_addr next_hop;
|
||||||
|
UINT metric;
|
||||||
|
UINT protocol;
|
||||||
|
BYTE loopback;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ipv6_forward_fill_entry( struct ipv6_route_data *entry, struct nsi_ipv6_forward_key *key,
|
||||||
|
struct nsi_ip_forward_rw *rw, struct nsi_ipv6_forward_dynamic *dyn,
|
||||||
|
struct nsi_ip_forward_static *stat )
|
||||||
|
{
|
||||||
|
if (key)
|
||||||
|
{
|
||||||
|
key->unk = 0;
|
||||||
|
memcpy( key->prefix.u.Byte, entry->prefix.s6_addr, sizeof(entry->prefix.s6_addr) );
|
||||||
|
key->prefix_len = entry->prefix_len;
|
||||||
|
memset( key->unk2, 0, sizeof(key->unk2) );
|
||||||
|
memset( key->unk3, 0, sizeof(key->unk3) );
|
||||||
|
key->luid = entry->luid;
|
||||||
|
key->luid2 = entry->luid;
|
||||||
|
memcpy( key->next_hop.u.Byte, entry->next_hop.s6_addr, sizeof(entry->next_hop.s6_addr) );
|
||||||
|
key->pad = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rw)
|
||||||
|
{
|
||||||
|
rw->site_prefix_len = 0;
|
||||||
|
rw->valid_lifetime = ~0u;
|
||||||
|
rw->preferred_lifetime = ~0u;
|
||||||
|
rw->metric = entry->metric;
|
||||||
|
rw->protocol = entry->protocol;
|
||||||
|
rw->loopback = entry->loopback;
|
||||||
|
rw->autoconf = 1;
|
||||||
|
rw->publish = 0;
|
||||||
|
rw->immortal = 1;
|
||||||
|
memset( rw->unk, 0, sizeof(rw->unk) );
|
||||||
|
rw->unk2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dyn)
|
||||||
|
{
|
||||||
|
memset( dyn, 0, sizeof(*dyn) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat)
|
||||||
|
{
|
||||||
|
stat->origin = NlroManual;
|
||||||
|
stat->if_index = entry->if_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct in6_addr str_to_in6_addr(char *nptr, char **endptr)
|
||||||
|
{
|
||||||
|
struct in6_addr ret;
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeof(ret); i++)
|
||||||
|
{
|
||||||
|
if (!isxdigit( *nptr ) || !isxdigit( *nptr + 1 ))
|
||||||
|
{
|
||||||
|
/* invalid hex string */
|
||||||
|
if (endptr) *endptr = nptr;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
sscanf( nptr, "%2hhx", &ret.s6_addr[i] );
|
||||||
|
nptr += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endptr) *endptr = nptr;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS ipv6_forward_enumerate_all( void *key_data, UINT key_size, void *rw_data, UINT rw_size,
|
static NTSTATUS ipv6_forward_enumerate_all( void *key_data, UINT key_size, void *rw_data, UINT rw_size,
|
||||||
void *dynamic_data, UINT dynamic_size,
|
void *dynamic_data, UINT dynamic_size,
|
||||||
void *static_data, UINT static_size, UINT_PTR *count )
|
void *static_data, UINT static_size, UINT_PTR *count )
|
||||||
{
|
{
|
||||||
|
UINT num = 0;
|
||||||
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
|
BOOL want_data = key_size || rw_size || dynamic_size || static_size;
|
||||||
|
struct ipv6_route_data entry;
|
||||||
|
|
||||||
|
TRACE( "%p %d %p %d %p %d %p %d %p" , key_data, key_size, rw_data, rw_size,
|
||||||
|
dynamic_data, dynamic_size, static_data, static_size, count );
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
{
|
||||||
|
char buf[512], *ptr;
|
||||||
|
UINT rtf_flags;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
if (!(fp = fopen( "/proc/net/ipv6_route", "r" ))) return STATUS_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
while ((ptr = fgets( buf, sizeof(buf), fp )))
|
||||||
|
{
|
||||||
|
while (!isspace( *ptr )) ptr++;
|
||||||
|
*ptr++ = '\0';
|
||||||
|
|
||||||
|
entry.prefix = str_to_in6_addr( ptr, &ptr );
|
||||||
|
entry.prefix_len = strtoul( ptr + 1, &ptr, 16 );
|
||||||
|
str_to_in6_addr( ptr + 1, &ptr ); /* source network, skip */
|
||||||
|
strtoul( ptr + 1, &ptr, 16 ); /* source prefix length, skip */
|
||||||
|
entry.next_hop = str_to_in6_addr( ptr + 1, &ptr );
|
||||||
|
entry.metric = strtoul( ptr + 1, &ptr, 16 );
|
||||||
|
strtoul( ptr + 1, &ptr, 16 ); /* refcount, skip */
|
||||||
|
strtoul( ptr + 1, &ptr, 16 ); /* use, skip */
|
||||||
|
rtf_flags = strtoul( ptr + 1, &ptr, 16);
|
||||||
|
entry.protocol = (rtf_flags & RTF_GATEWAY) ? MIB_IPPROTO_NETMGMT : MIB_IPPROTO_LOCAL;
|
||||||
|
entry.loopback = entry.protocol == MIB_IPPROTO_LOCAL && entry.prefix_len == 32;
|
||||||
|
|
||||||
|
if (!convert_unix_name_to_luid( ptr, &entry.luid )) continue;
|
||||||
|
if (!convert_luid_to_index( &entry.luid, &entry.if_index )) continue;
|
||||||
|
|
||||||
|
if (num < *count)
|
||||||
|
{
|
||||||
|
ipv6_forward_fill_entry( &entry, key_data, rw_data, dynamic_data, static_data );
|
||||||
|
key_data = (BYTE *)key_data + key_size;
|
||||||
|
rw_data = (BYTE *)rw_data + rw_size;
|
||||||
|
dynamic_data = (BYTE *)dynamic_data + dynamic_size;
|
||||||
|
static_data = (BYTE *)static_data + static_size;
|
||||||
|
}
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
#else
|
||||||
FIXME( "not implemented\n" );
|
FIXME( "not implemented\n" );
|
||||||
*count = 0;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
return STATUS_SUCCESS;
|
#endif
|
||||||
|
|
||||||
|
if (!want_data || num <= *count) *count = num;
|
||||||
|
else status = STATUS_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct module_table ipv4_tables[] =
|
static struct module_table ipv4_tables[] =
|
||||||
|
|
Loading…
Reference in a new issue