From: Paul Gofman pgofman@codeweavers.com
--- dlls/iphlpapi/tests/iphlpapi.c | 6 ++++++ dlls/nsiproxy.sys/device.c | 1 + dlls/nsiproxy.sys/icmp_echo.c | 26 ++++++++++++++++++++------ dlls/nsiproxy.sys/nsiproxy_private.h | 1 + 4 files changed, 28 insertions(+), 6 deletions(-)
diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c index e189fd795f8..ea7ec0e5e70 100644 --- a/dlls/iphlpapi/tests/iphlpapi.c +++ b/dlls/iphlpapi/tests/iphlpapi.c @@ -1240,6 +1240,12 @@ static void testIcmpSendEcho(void) ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, ICMP_MINLEN, NULL, replydata2, replysz, 1000); ok(ret, "IcmpSendEcho2 failed unexpectedly with error %ld\n", GetLastError());
+ SetLastError(0xdeadbeef); + ret = IcmpSendEcho2Ex(icmp, NULL, NULL, NULL, 0x01010101, address, senddata, ICMP_MINLEN, NULL, replydata2, replysz, 1000); + ok(!ret, "IcmpSendEcho2 succeded unexpectedly\n"); + error = GetLastError(); + ok(error == ERROR_INVALID_NETNAME, "got %ld\n", error); + SetLastError(0xdeadbeef); replysz = sizeof(replydata2); ret = IcmpSendEcho2(icmp, NULL, NULL, NULL, address, senddata, sizeof(senddata), NULL, replydata2, replysz, 1000); diff --git a/dlls/nsiproxy.sys/device.c b/dlls/nsiproxy.sys/device.c index 9db77f73c89..b3d00fd5187 100644 --- a/dlls/nsiproxy.sys/device.c +++ b/dlls/nsiproxy.sys/device.c @@ -275,6 +275,7 @@ static NTSTATUS handle_send_echo( IRP *irp ) params.bits = in->bits; params.ttl = in->ttl; params.tos = in->tos; + params.src = &in->src; params.dst = &in->dst; params.handle = &handle;
diff --git a/dlls/nsiproxy.sys/icmp_echo.c b/dlls/nsiproxy.sys/icmp_echo.c index e92fa4394c1..8fc97a858db 100644 --- a/dlls/nsiproxy.sys/icmp_echo.c +++ b/dlls/nsiproxy.sys/icmp_echo.c @@ -113,6 +113,10 @@ struct icmp_data unsigned short id; unsigned short seq; const struct family_ops *ops; + struct sockaddr_storage src_storage; + struct sockaddr_storage dst_storage; + int src_len; + int dst_len; };
#define MAX_HANDLES 256 /* Max number of simultaneous pings - could become dynamic if need be */ @@ -625,14 +629,26 @@ NTSTATUS icmp_send_echo( void *args ) { struct icmp_send_echo_params *params = args; struct icmp_hdr *icmp_hdr; /* this is the same for both ipv4 and ipv6 */ - struct sockaddr_storage dst_storage; - struct sockaddr *dst = (struct sockaddr *)&dst_storage; struct icmp_data *data; - int dst_len, ret; + int ret; + struct sockaddr *src, *dst; + NTSTATUS status;
status = icmp_data_create( params->dst->si_family, &data ); if (status) return status; + + src = (struct sockaddr *)&data->src_storage; + dst = (struct sockaddr *)&data->dst_storage; + data->src_len = SOCKADDR_INET_to_sockaddr( params->src, src, sizeof(data->src_storage) ); + data->dst_len = SOCKADDR_INET_to_sockaddr( params->dst, dst, sizeof(data->dst_storage) ); + + if (bind( data->socket, src, data->src_len )) + { + icmp_data_free( data ); + return STATUS_INVALID_ADDRESS_COMPONENT; + } + data->ops->set_socket_opts( data, params );
icmp_hdr = malloc( sizeof(*icmp_hdr) + params->request_size ); @@ -645,10 +661,8 @@ NTSTATUS icmp_send_echo( void *args ) memcpy( icmp_hdr + 1, params->request, params->request_size ); icmp_hdr->checksum = data->ops->chksum( (BYTE *)icmp_hdr, sizeof(*icmp_hdr) + params->request_size );
- dst_len = SOCKADDR_INET_to_sockaddr( params->dst, dst, sizeof(dst_storage) ); - NtQueryPerformanceCounter( &data->send_time, NULL ); - ret = sendto( data->socket, icmp_hdr, sizeof(*icmp_hdr) + params->request_size, 0, dst, dst_len ); + ret = sendto( data->socket, icmp_hdr, sizeof(*icmp_hdr) + params->request_size, 0, dst, data->dst_len ); free( icmp_hdr );
if (ret < 0) diff --git a/dlls/nsiproxy.sys/nsiproxy_private.h b/dlls/nsiproxy.sys/nsiproxy_private.h index 1b6eacf7d08..e7cc707f729 100644 --- a/dlls/nsiproxy.sys/nsiproxy_private.h +++ b/dlls/nsiproxy.sys/nsiproxy_private.h @@ -41,6 +41,7 @@ struct icmp_listen_params
struct icmp_send_echo_params { + SOCKADDR_INET *src; SOCKADDR_INET *dst; void *request, *reply; UINT request_size, reply_len;