mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 09:55:50 +00:00
wpcap: Build pcap_address structure from IP_ADAPTER_UNICAST_ADDRESS.
This commit is contained in:
parent
6d01d01455
commit
382dbe77f6
|
@ -17,18 +17,13 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
struct sockaddr_hdr
|
||||
{
|
||||
unsigned short sa_family;
|
||||
};
|
||||
|
||||
struct pcap_address
|
||||
{
|
||||
struct pcap_address *next;
|
||||
struct sockaddr_hdr *addr;
|
||||
struct sockaddr_hdr *netmask;
|
||||
struct sockaddr_hdr *broadaddr;
|
||||
struct sockaddr_hdr *dstaddr;
|
||||
struct sockaddr *addr;
|
||||
struct sockaddr *netmask;
|
||||
struct sockaddr *broadaddr;
|
||||
struct sockaddr *dstaddr;
|
||||
};
|
||||
|
||||
struct pcap_interface
|
||||
|
@ -57,7 +52,6 @@ struct pcap
|
|||
struct pcap_pkthdr_win32 hdr;
|
||||
};
|
||||
|
||||
|
||||
struct compile_params
|
||||
{
|
||||
struct pcap *pcap;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "winsock2.h"
|
||||
#include "ws2ipdef.h"
|
||||
#include "iphlpapi.h"
|
||||
#include "netioapi.h"
|
||||
|
||||
#include "wine/unixlib.h"
|
||||
#include "wine/debug.h"
|
||||
|
@ -236,59 +237,109 @@ static char *build_win32_description( const struct pcap_interface *unix_dev )
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct sockaddr_hdr *dup_sockaddr( const struct sockaddr_hdr *addr )
|
||||
static struct sockaddr *get_address( const IP_ADAPTER_UNICAST_ADDRESS *addr )
|
||||
{
|
||||
struct sockaddr_hdr *ret;
|
||||
struct sockaddr *ret;
|
||||
if (!(ret = malloc( addr->Address.iSockaddrLength ))) return NULL;
|
||||
memcpy( ret, addr->Address.lpSockaddr, addr->Address.iSockaddrLength );
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (addr->sa_family)
|
||||
static void convert_length_to_ipv6_mask( ULONG length, IN6_ADDR *mask )
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < length / 8; i++) mask->u.Byte[i] = 0xff;
|
||||
mask->u.Byte[i] = 0xff << (8 - length % 8);
|
||||
}
|
||||
|
||||
static struct sockaddr *get_netmask( const IP_ADAPTER_UNICAST_ADDRESS *addr )
|
||||
{
|
||||
struct sockaddr *ret;
|
||||
|
||||
switch (addr->Address.lpSockaddr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *dst, *src = (struct sockaddr_in *)addr;
|
||||
if (!(dst = calloc( 1, sizeof(*dst) ))) return NULL;
|
||||
dst->sin_family = src->sin_family;
|
||||
dst->sin_port = src->sin_port;
|
||||
dst->sin_addr = src->sin_addr;
|
||||
ret = (struct sockaddr_hdr *)dst;
|
||||
struct sockaddr_in *netmask_addr_in;
|
||||
|
||||
if (!(netmask_addr_in = calloc( 1, sizeof(*netmask_addr_in) ))) return NULL;
|
||||
netmask_addr_in->sin_family = AF_INET;
|
||||
ConvertLengthToIpv4Mask( addr->OnLinkPrefixLength, &netmask_addr_in->sin_addr.S_un.S_addr );
|
||||
ret = (struct sockaddr *)netmask_addr_in;
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *dst, *src = (struct sockaddr_in6 *)addr;
|
||||
if (!(dst = malloc( sizeof(*dst) ))) return NULL;
|
||||
dst->sin6_family = src->sin6_family;
|
||||
dst->sin6_port = src->sin6_port;
|
||||
dst->sin6_flowinfo = src->sin6_flowinfo;
|
||||
dst->sin6_addr = src->sin6_addr;
|
||||
dst->sin6_scope_id = src->sin6_scope_id;
|
||||
ret = (struct sockaddr_hdr *)dst;
|
||||
struct sockaddr_in6 *netmask_addr_in6;
|
||||
|
||||
if (!(netmask_addr_in6 = calloc( 1, sizeof(*netmask_addr_in6) ))) return NULL;
|
||||
netmask_addr_in6->sin6_family = AF_INET6;
|
||||
convert_length_to_ipv6_mask( addr->OnLinkPrefixLength, &netmask_addr_in6->sin6_addr );
|
||||
ret = (struct sockaddr *)netmask_addr_in6;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME( "address family %u not supported\n", addr->sa_family );
|
||||
FIXME( "address family %u not supported\n", addr->Address.lpSockaddr->sa_family );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct pcap_address *build_win32_address( struct pcap_address *src )
|
||||
static struct sockaddr *get_broadcast( const IP_ADAPTER_UNICAST_ADDRESS *addr )
|
||||
{
|
||||
struct pcap_address *dst;
|
||||
struct sockaddr *ret;
|
||||
|
||||
if (!(dst = calloc( 1, sizeof(*dst) ))) return NULL;
|
||||
if (src->addr && !(dst->addr = dup_sockaddr( src->addr ))) goto err;
|
||||
if (src->netmask && !(dst->netmask = dup_sockaddr( src->netmask ))) goto err;
|
||||
if (src->broadaddr && !(dst->broadaddr = dup_sockaddr( src->broadaddr ))) goto err;
|
||||
if (src->dstaddr && !(dst->dstaddr = dup_sockaddr( src->dstaddr ))) goto err;
|
||||
return dst;
|
||||
switch (addr->Address.lpSockaddr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in *broadcast_addr_in, *addr_in = (struct sockaddr_in *)addr->Address.lpSockaddr;
|
||||
ULONG netmask;
|
||||
|
||||
if (!(broadcast_addr_in = calloc( 1, sizeof(*broadcast_addr_in) ))) return FALSE;
|
||||
broadcast_addr_in->sin_family = AF_INET;
|
||||
ConvertLengthToIpv4Mask( addr->OnLinkPrefixLength, &netmask );
|
||||
broadcast_addr_in->sin_addr.S_un.S_addr = addr_in->sin_addr.S_un.S_addr | ~netmask;
|
||||
ret = (struct sockaddr *)broadcast_addr_in;
|
||||
break;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *broadcast_addr_in6, *addr_in6 = (struct sockaddr_in6 *)addr->Address.lpSockaddr;
|
||||
IN6_ADDR netmask, *address = (IN6_ADDR *)&addr_in6->sin6_addr;
|
||||
unsigned int i;
|
||||
|
||||
if (!(broadcast_addr_in6 = calloc( 1, sizeof(*broadcast_addr_in6) ))) return NULL;
|
||||
broadcast_addr_in6->sin6_family = AF_INET6;
|
||||
convert_length_to_ipv6_mask( addr->OnLinkPrefixLength, &netmask );
|
||||
for (i = 0; i < 8; i++) broadcast_addr_in6->sin6_addr.u.Word[i] = address->u.Word[i] | ~netmask.u.Word[i];
|
||||
ret = (struct sockaddr *)broadcast_addr_in6;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME( "address family %u not supported\n", addr->Address.lpSockaddr->sa_family );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct pcap_address *build_win32_address( const IP_ADAPTER_UNICAST_ADDRESS *addr )
|
||||
{
|
||||
struct pcap_address *ret;
|
||||
|
||||
if (!(ret = calloc( 1, sizeof(*ret) ))) return NULL;
|
||||
if (!(ret->addr = get_address( addr ))) goto err;
|
||||
if (!(ret->netmask = get_netmask( addr ))) goto err;
|
||||
if (!(ret->broadaddr = get_broadcast( addr ))) goto err;
|
||||
return ret;
|
||||
|
||||
err:
|
||||
free( dst->addr );
|
||||
free( dst->netmask );
|
||||
free( dst->broadaddr );
|
||||
free( dst->dstaddr );
|
||||
free( dst );
|
||||
free( ret->addr );
|
||||
free( ret->netmask );
|
||||
free( ret->broadaddr );
|
||||
free( ret );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -303,27 +354,27 @@ static void add_win32_address( struct pcap_address **list, struct pcap_address *
|
|||
}
|
||||
}
|
||||
|
||||
static struct pcap_address *build_win32_addresses( struct pcap_address *addrs )
|
||||
static struct pcap_address *build_win32_addresses( const IP_ADAPTER_ADDRESSES *adapter )
|
||||
{
|
||||
struct pcap_address *src, *dst, *ret = NULL;
|
||||
src = addrs;
|
||||
struct pcap_address *dst, *ret = NULL;
|
||||
IP_ADAPTER_UNICAST_ADDRESS *src = adapter->FirstUnicastAddress;
|
||||
while (src)
|
||||
{
|
||||
if ((dst = build_win32_address( src ))) add_win32_address( &ret, dst );
|
||||
src = src->next;
|
||||
src = src->Next;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct pcap_interface *build_win32_device( const struct pcap_interface *unix_dev, const char *source,
|
||||
const char *adapter_name )
|
||||
const IP_ADAPTER_ADDRESSES *adapter )
|
||||
{
|
||||
struct pcap_interface *ret;
|
||||
|
||||
if (!(ret = calloc( 1, sizeof(*ret) ))) return NULL;
|
||||
if (!(ret->name = build_win32_name( source, adapter_name ))) goto err;
|
||||
if (!(ret->name = build_win32_name( source, adapter->AdapterName ))) goto err;
|
||||
if (!(ret->description = build_win32_description( unix_dev ))) goto err;
|
||||
ret->addresses = build_win32_addresses( unix_dev->addresses );
|
||||
ret->addresses = build_win32_addresses( adapter );
|
||||
ret->flags = unix_dev->flags;
|
||||
return ret;
|
||||
|
||||
|
@ -364,7 +415,7 @@ static int find_all_devices( const char *source, struct pcap_interface **devs, c
|
|||
cur = unix_devs;
|
||||
while (cur)
|
||||
{
|
||||
if ((ptr = find_adapter( adapters, cur->name )) && (dev = build_win32_device( cur, source, ptr->AdapterName )))
|
||||
if ((ptr = find_adapter( adapters, cur->name )) && (dev = build_win32_device( cur, source, ptr )))
|
||||
{
|
||||
add_win32_device( &win32_devs, dev );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue