Because iphlpapi has no opportunity to convert the reply in async mode.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/iphlpapi/iphlpapi_main.c | 44 +----- dlls/nsiproxy.sys/device.c | 36 ++++- dlls/nsiproxy.sys/icmp_echo.c | 203 ++++++++++++++++++--------- dlls/nsiproxy.sys/nsiproxy_private.h | 39 +++++ include/wine/nsi.h | 21 +-- 5 files changed, 212 insertions(+), 131 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index d9a85be..8a31241 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -4579,33 +4579,6 @@ DWORD WINAPI IcmpParseReplies( void *reply, DWORD reply_size ) return num_pkts; }
-/************************************************************************* - * icmpv4_echo_reply_fixup - * - * Convert struct nsiproxy_icmpv4_echo_reply into ICMP_ECHO_REPLY. - * - * This is necessary due to the different sizes of ICMP_ECHO_REPLY on - * 32 and 64-bits. Despite mention of ICMP_ECHO_REPLY32, 64-bit Windows - * actually does return a full 64-bit version. - */ -static void icmpv4_echo_reply_fixup( ICMP_ECHO_REPLY *dst, struct nsiproxy_icmp_echo_reply *reply ) -{ - dst->Address = reply->addr.Ipv4.sin_addr.s_addr; - dst->Status = reply->status; - dst->RoundTripTime = reply->round_trip_time; - dst->DataSize = reply->data_size; - dst->Reserved = reply->num_of_pkts; - dst->Data = (BYTE *)(dst + 1) + ((reply->opts.options_size + 3) & ~3); - dst->Options.Ttl = reply->opts.ttl; - dst->Options.Tos = reply->opts.tos; - dst->Options.Flags = reply->opts.flags; - dst->Options.OptionsSize = reply->opts.options_size; - dst->Options.OptionsData = (BYTE *)(reply + 1); - - memcpy( dst->Options.OptionsData, (BYTE *)reply + reply->opts.options_offset, reply->opts.options_size ); - memcpy( dst->Data, (BYTE *)reply + reply->data_offset, reply->data_size ); -} - /*********************************************************************** * IcmpSendEcho (IPHLPAPI.@) */ @@ -4636,9 +4609,8 @@ DWORD WINAPI IcmpSendEcho2Ex( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc_r void *reply, DWORD reply_size, DWORD timeout ) { struct icmp_handle_data *data = (struct icmp_handle_data *)handle; - DWORD opt_size, in_size, ret = 0, out_size; + DWORD opt_size, in_size, ret = 0; struct nsiproxy_icmp_echo *in; - struct nsiproxy_icmp_echo_reply *out; HANDLE request_event; IO_STATUS_BLOCK iosb; NTSTATUS status; @@ -4658,17 +4630,15 @@ DWORD WINAPI IcmpSendEcho2Ex( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc_r opt_size = opts ? (opts->OptionsSize + 3) & ~3 : 0; in_size = FIELD_OFFSET(struct nsiproxy_icmp_echo, data[opt_size + request_size]); in = heap_alloc_zero( in_size ); - out_size = reply_size - sizeof(ICMP_ECHO_REPLY) + sizeof(*out); - out = heap_alloc( out_size );
- if (!in || !out) + if (!in) { - heap_free( out ); - heap_free( in ); SetLastError( IP_NO_RESOURCES ); return 0; }
+ in->user_reply_ptr = (ULONG_PTR)reply; + in->bits = sizeof(void*) * 8; in->src.Ipv4.sin_family = AF_INET; in->src.Ipv4.sin_addr.s_addr = src; in->dst.Ipv4.sin_family = AF_INET; @@ -4689,19 +4659,15 @@ DWORD WINAPI IcmpSendEcho2Ex( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc_r
status = NtDeviceIoControlFile( data->nsi_device, request_event, NULL, NULL, &iosb, IOCTL_NSIPROXY_WINE_ICMP_ECHO, in, in_size, - out, out_size ); + reply, reply_size );
if (status == STATUS_PENDING && !WaitForSingleObject( request_event, INFINITE )) status = iosb.Status;
if (!status) - { - icmpv4_echo_reply_fixup( reply, out ); ret = IcmpParseReplies( reply, reply_size ); - }
CloseHandle( request_event ); - heap_free( out ); heap_free( in );
if (status) SetLastError( RtlNtStatusToDosError( status ) ); diff --git a/dlls/nsiproxy.sys/device.c b/dlls/nsiproxy.sys/device.c index 90a7a3d..4ace66d 100644 --- a/dlls/nsiproxy.sys/device.c +++ b/dlls/nsiproxy.sys/device.c @@ -31,6 +31,7 @@ #include "netiodef.h" #include "wine/nsi.h" #include "wine/debug.h" +#include "wine/heap.h" #include "wine/unixlib.h"
#include "nsiproxy_private.h" @@ -211,6 +212,13 @@ static void WINAPI icmp_echo_cancel( DEVICE_OBJECT *device, IRP *irp ) LeaveCriticalSection( &nsiproxy_cs ); }
+static int icmp_echo_reply_struct_len( ULONG family, ULONG bits ) +{ + if (family == AF_INET) + return (bits == 32) ? sizeof(struct icmp_echo_reply_32) : sizeof(struct icmp_echo_reply_64); + return 0; +} + static NTSTATUS nsiproxy_icmp_echo( IRP *irp ) { IO_STACK_LOCATION *irpsp = IoGetCurrentIrpStackLocation( irp ); @@ -222,7 +230,7 @@ static NTSTATUS nsiproxy_icmp_echo( IRP *irp )
if (in_len < offsetof(struct nsiproxy_icmp_echo, data[0]) || in_len < offsetof(struct nsiproxy_icmp_echo, data[((in->opt_size + 3) & ~3) + in->req_size]) || - out_len < sizeof(struct nsiproxy_icmp_echo_reply)) + out_len < icmp_echo_reply_struct_len( in->dst.si_family, in->bits )) return STATUS_INVALID_PARAMETER;
switch (in->dst.si_family) @@ -326,8 +334,10 @@ static DWORD WINAPI listen_thread_proc( void *arg )
TRACE( "\n" );
+ params.user_reply_ptr = in->user_reply_ptr; params.handle = irp_get_icmp_handle( irp ); params.timeout = in->timeout; + params.bits = in->bits; params.reply = irp->AssociatedIrp.SystemBuffer; params.reply_len = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
@@ -353,8 +363,10 @@ static DWORD WINAPI listen_thread_proc( void *arg ) static void handle_queued_send_echo( IRP *irp ) { struct nsiproxy_icmp_echo *in = (struct nsiproxy_icmp_echo *)irp->AssociatedIrp.SystemBuffer; - struct nsiproxy_icmp_echo_reply *reply = (struct nsiproxy_icmp_echo_reply *)irp->AssociatedIrp.SystemBuffer; + void *out = irp->AssociatedIrp.SystemBuffer; struct icmp_send_echo_params params; + ULONG family = in->dst.si_family; + ULONG bits = in->bits; NTSTATUS status;
TRACE( "\n" ); @@ -372,9 +384,23 @@ static void handle_queued_send_echo( IRP *irp ) irp->IoStatus.Status = status; if (status == STATUS_SUCCESS) { - memset( reply, 0, sizeof(*reply) ); - reply->status = params.ip_status; - irp->IoStatus.Information = sizeof(*reply); + if (family == AF_INET) + { + if (bits == 32) + { + struct icmp_echo_reply_32 *reply = out; + memset( reply, 0, sizeof(*reply) ); + reply->status = params.ip_status; + irp->IoStatus.Information = sizeof(*reply); + } + else + { + struct icmp_echo_reply_64 *reply = out; + memset( reply, 0, sizeof(*reply) ); + reply->status = params.ip_status; + irp->IoStatus.Information = sizeof(*reply); + } + } } IoCompleteRequest( irp, IO_NO_INCREMENT ); } diff --git a/dlls/nsiproxy.sys/icmp_echo.c b/dlls/nsiproxy.sys/icmp_echo.c index 955fdfd..1e106c6 100644 --- a/dlls/nsiproxy.sys/icmp_echo.c +++ b/dlls/nsiproxy.sys/icmp_echo.c @@ -93,6 +93,20 @@ struct icmp_hdr } un; };
+struct icmp_reply_ctx +{ + SOCKADDR_INET addr; + ULONG status; + ULONG round_trip_time; + LONG data_size; + BYTE ttl; + BYTE tos; + BYTE flags; + BYTE options_size; + void *options_data; + void *data; +}; + struct family_ops; struct icmp_data { @@ -232,20 +246,22 @@ static void ipv4_linux_ping_set_socket_opts( struct icmp_data *data, struct icmp } #endif
-static int ipv4_reply_buffer_len( int reply_len ) +static int ipv4_reply_buffer_len( struct icmp_listen_params *params ) { - return sizeof(struct ip_hdr) + sizeof(struct icmp_hdr) + reply_len - sizeof(struct nsiproxy_icmp_echo_reply); + int struct_len = (params->bits == 32) ? sizeof(struct icmp_echo_reply_32) : sizeof(struct icmp_echo_reply_64); + return sizeof(struct ip_hdr) + sizeof(struct icmp_hdr) + params->reply_len - struct_len; }
#ifdef __linux__ -static int ipv4_linux_ping_reply_buffer_len( int reply_len ) +static int ipv4_linux_ping_reply_buffer_len( struct icmp_listen_params *params ) { - return sizeof(struct icmp_hdr) + reply_len - sizeof(struct nsiproxy_icmp_echo_reply); + int struct_len = (params->bits == 32) ? sizeof(struct icmp_echo_reply_32) : sizeof(struct icmp_echo_reply_64); + return sizeof(struct icmp_hdr) + params->reply_len - struct_len; } #endif
-static BOOL ipv4_parse_ip_hdr( struct msghdr *msg, int recvd, - int *ip_hdr_len, struct nsiproxy_icmp_echo_reply *reply, void **opts ) +static BOOL ipv4_parse_ip_hdr( struct msghdr *msg, int recvd, int *ip_hdr_len, + struct icmp_reply_ctx *ctx ) { struct ip_hdr *ip_hdr;
@@ -254,27 +270,27 @@ static BOOL ipv4_parse_ip_hdr( struct msghdr *msg, int recvd, if (ip_hdr->v_hl >> 4 != 4 || ip_hdr->protocol != IPPROTO_ICMP) return FALSE; *ip_hdr_len = (ip_hdr->v_hl & 0xf) << 2; if (*ip_hdr_len < sizeof(*ip_hdr)) return FALSE; - *opts = ip_hdr + 1; - reply->opts.ttl = ip_hdr->ttl; - reply->opts.tos = ip_hdr->tos; - reply->opts.flags = ip_hdr->frag_off >> 13; - reply->opts.options_size = *ip_hdr_len - sizeof(*ip_hdr); + ctx->options_data = ip_hdr + 1; + ctx->ttl = ip_hdr->ttl; + ctx->tos = ip_hdr->tos; + ctx->flags = ip_hdr->frag_off >> 13; + ctx->options_size = *ip_hdr_len - sizeof(*ip_hdr);
return TRUE; }
#ifdef __linux__ -static BOOL ipv4_linux_ping_parse_ip_hdr( struct msghdr *msg, int recvd, - int *ip_hdr_len, struct nsiproxy_icmp_echo_reply *reply, void **opts ) +static BOOL ipv4_linux_ping_parse_ip_hdr( struct msghdr *msg, int recvd, int *ip_hdr_len, + struct icmp_reply_ctx *ctx ) { struct cmsghdr *cmsg;
*ip_hdr_len = 0; - *opts = NULL; - reply->opts.ttl = 0; - reply->opts.tos = 0; - reply->opts.flags = 0; - reply->opts.options_size = 0; /* FIXME from IP_OPTIONS but will require checking for space in the reply */ + ctx->options_data = NULL; + ctx->ttl = 0; + ctx->tos = 0; + ctx->flags = 0; + ctx->options_size = 0; /* FIXME from IP_OPTIONS but will require checking for space in the reply */
for (cmsg = CMSG_FIRSTHDR( msg ); cmsg; cmsg = CMSG_NXTHDR( msg, cmsg )) { @@ -282,10 +298,10 @@ static BOOL ipv4_linux_ping_parse_ip_hdr( struct msghdr *msg, int recvd, switch (cmsg->cmsg_type) { case IP_TTL: - reply->opts.ttl = *(BYTE *)CMSG_DATA( cmsg ); + ctx->ttl = *(BYTE *)CMSG_DATA( cmsg ); break; case IP_TOS: - reply->opts.tos = *(BYTE *)CMSG_DATA( cmsg ); + ctx->tos = *(BYTE *)CMSG_DATA( cmsg ); break; } } @@ -294,7 +310,7 @@ static BOOL ipv4_linux_ping_parse_ip_hdr( struct msghdr *msg, int recvd, #endif
static int ipv4_parse_icmp_hdr_( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_size, - struct nsiproxy_icmp_echo_reply *reply, int ping_socket ) + struct icmp_reply_ctx *ctx, int ping_socket ) { static const IP_STATUS unreach_codes[] = { @@ -326,7 +342,7 @@ static int ipv4_parse_icmp_hdr_( struct icmp_data *data, struct icmp_hdr *icmp, if ((!ping_socket && icmp->un.echo.id != data->id) || icmp->un.echo.sequence != data->seq) return -1;
- reply->status = IP_SUCCESS; + ctx->status = IP_SUCCESS; return icmp_size - sizeof(*icmp);
case ICMP4_DST_UNREACH: @@ -369,24 +385,90 @@ static int ipv4_parse_icmp_hdr_( struct icmp_data *data, struct icmp_hdr *icmp, (!ping_socket && orig_icmp_hdr->un.echo.id != data->id) || orig_icmp_hdr->un.echo.sequence != data->seq) return -1;
- reply->status = status; + ctx->status = status; return 0; }
-static int ipv4_parse_icmp_hdr( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_size, - struct nsiproxy_icmp_echo_reply *reply ) +static int ipv4_parse_icmp_hdr( struct icmp_data *data, struct icmp_hdr *icmp, + int icmp_size, struct icmp_reply_ctx *ctx) { - return ipv4_parse_icmp_hdr_( data, icmp, icmp_size, reply, 0 ); + return ipv4_parse_icmp_hdr_( data, icmp, icmp_size, ctx, 0 ); }
#ifdef __linux__ -static int ipv4_linux_ping_parse_icmp_hdr( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_size, - struct nsiproxy_icmp_echo_reply *reply ) +static int ipv4_linux_ping_parse_icmp_hdr( struct icmp_data *data, struct icmp_hdr *icmp, + int icmp_size, struct icmp_reply_ctx *ctx ) { - return ipv4_parse_icmp_hdr_( data, icmp, icmp_size, reply, 1 ); + return ipv4_parse_icmp_hdr_( data, icmp, icmp_size, ctx, 1 ); } #endif
+static NTSTATUS ipv4_set_reply_ip_status( struct icmp_listen_params *params, IP_STATUS ip_status ) +{ + if (params->bits == 32) + { + struct icmp_echo_reply_32 *reply = params->reply; + memset( reply, 0, sizeof(*reply) ); + reply->status = ip_status; + params->reply_len = sizeof(*reply); + } + else + { + struct icmp_echo_reply_64 *reply = params->reply; + memset( reply, 0, sizeof(*reply) ); + reply->status = ip_status; + params->reply_len = sizeof(*reply); + } + return STATUS_SUCCESS; +} + +static void ipv4_fill_reply( struct icmp_listen_params *params, struct icmp_reply_ctx *ctx) +{ + void *options_data; + ULONG data_offset; + if (params->bits == 32) + { + struct icmp_echo_reply_32 *reply = params->reply; + data_offset = sizeof(*reply) + ((ctx->options_size + 3) & ~3); + reply->addr = ctx->addr.Ipv4.sin_addr.WS_s_addr; + reply->status = ctx->status; + reply->round_trip_time = ctx->round_trip_time; + reply->data_size = ctx->data_size; + reply->num_of_pkts = 1; + reply->data_ptr = params->user_reply_ptr + data_offset; + reply->opts.ttl = ctx->ttl; + reply->opts.tos = ctx->tos; + reply->opts.flags = ctx->flags; + reply->opts.options_size = ctx->options_size; + reply->opts.options_ptr = params->user_reply_ptr + sizeof(*reply); + options_data = reply + 1; + } + else + { + struct icmp_echo_reply_64 *reply = params->reply; + data_offset = sizeof(*reply) + ((ctx->options_size + 3) & ~3); + reply->addr = ctx->addr.Ipv4.sin_addr.WS_s_addr; + reply->status = ctx->status; + reply->round_trip_time = ctx->round_trip_time; + reply->data_size = ctx->data_size; + reply->num_of_pkts = 1; + reply->data_ptr = params->user_reply_ptr + data_offset; + reply->opts.ttl = ctx->ttl; + reply->opts.tos = ctx->tos; + reply->opts.flags = ctx->flags; + reply->opts.options_size = ctx->options_size; + reply->opts.options_ptr = params->user_reply_ptr + sizeof(*reply); + options_data = reply + 1; + } + + memcpy( options_data, ctx->options_data, ctx->options_size ); + if (ctx->options_size & 3) + memset( (char *)options_data + ctx->options_size, 0, 4 - (ctx->options_size & 3) ); + + memcpy( (char *)params->reply + data_offset, ctx->data, ctx->data_size ); + params->reply_len = data_offset + ctx->data_size; +} + struct family_ops { int family; @@ -394,11 +476,11 @@ struct family_ops void (*init_icmp_hdr)( struct icmp_data *data, struct icmp_hdr *icmp_hdr ); unsigned short (*chksum)( BYTE *data, unsigned int count ); void (*set_socket_opts)( struct icmp_data *data, struct icmp_send_echo_params *params ); - int (*reply_buffer_len)( int reply_len ); - BOOL (*parse_ip_hdr)( struct msghdr *msg, int recvd, - int *ip_hdr_len, struct nsiproxy_icmp_echo_reply *reply, void **opts ); - int (*parse_icmp_hdr)( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_len, - struct nsiproxy_icmp_echo_reply *reply ); + int (*reply_buffer_len)( struct icmp_listen_params *params ); + BOOL (*parse_ip_hdr)( struct msghdr *msg, int recvd, int *ip_hdr_len, struct icmp_reply_ctx *ctx ); + int (*parse_icmp_hdr)( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_len, struct icmp_reply_ctx *ctx ); + NTSTATUS (*set_reply_ip_status)( struct icmp_listen_params *params, IP_STATUS ip_status ); + void (*fill_reply)( struct icmp_listen_params *params, struct icmp_reply_ctx *ctx ); };
static const struct family_ops ipv4 = @@ -411,6 +493,8 @@ static const struct family_ops ipv4 = ipv4_reply_buffer_len, ipv4_parse_ip_hdr, ipv4_parse_icmp_hdr, + ipv4_set_reply_ip_status, + ipv4_fill_reply, };
#ifdef __linux__ @@ -425,6 +509,8 @@ static const struct family_ops ipv4_linux_ping = ipv4_linux_ping_reply_buffer_len, ipv4_linux_ping_parse_ip_hdr, ipv4_linux_ping_parse_icmp_hdr, + ipv4_set_reply_ip_status, + ipv4_fill_reply, }; #endif
@@ -584,16 +670,6 @@ NTSTATUS icmp_send_echo( void *args ) return params->handle ? STATUS_PENDING : STATUS_NO_MEMORY; }
-static NTSTATUS set_reply_ip_status( struct icmp_listen_params *params, IP_STATUS ip_status ) -{ - struct nsiproxy_icmp_echo_reply *reply = params->reply; - - memset( reply, 0, sizeof(*reply) ); - reply->status = ip_status; - params->reply_len = sizeof(*reply); - return STATUS_SUCCESS; -} - static int get_timeout( LARGE_INTEGER start, DWORD timeout ) { LARGE_INTEGER now, end; @@ -615,19 +691,18 @@ static ULONG get_rtt( LARGE_INTEGER start )
static NTSTATUS recv_msg( struct icmp_data *data, struct icmp_listen_params *params ) { - struct nsiproxy_icmp_echo_reply *reply = (struct nsiproxy_icmp_echo_reply *)params->reply; struct sockaddr_storage addr; + struct icmp_reply_ctx ctx; struct iovec iov[1]; BYTE cmsg_buf[1024]; struct msghdr msg = { .msg_name = &addr, .msg_namelen = sizeof(addr), .msg_iov = iov, .msg_iovlen = ARRAY_SIZE(iov), .msg_control = cmsg_buf, .msg_controllen = sizeof(cmsg_buf) }; - int ip_hdr_len, recvd, reply_buf_len, data_size; + int ip_hdr_len, recvd, reply_buf_len; char *reply_buf; - void *opts; struct icmp_hdr *icmp_hdr;
- reply_buf_len = data->ops->reply_buffer_len( params->reply_len ); + reply_buf_len = data->ops->reply_buffer_len( params ); reply_buf = malloc( reply_buf_len ); if (!reply_buf) return STATUS_NO_MEMORY;
@@ -638,31 +713,23 @@ static NTSTATUS recv_msg( struct icmp_data *data, struct icmp_listen_params *par TRACE( "recvmsg() rets %d errno %d addr_len %d iovlen %d msg_flags %x\n", recvd, errno, msg.msg_namelen, (int)iov[0].iov_len, msg.msg_flags );
- if (!data->ops->parse_ip_hdr( &msg, recvd, &ip_hdr_len, reply, &opts )) goto skip; + if (!data->ops->parse_ip_hdr( &msg, recvd, &ip_hdr_len, &ctx )) goto skip; if (recvd < ip_hdr_len + sizeof(*icmp_hdr)) goto skip;
icmp_hdr = (struct icmp_hdr *)(reply_buf + ip_hdr_len); - if ((data_size = data->ops->parse_icmp_hdr( data, icmp_hdr, recvd - ip_hdr_len, reply )) < 0) goto skip; - reply->data_size = data_size; - if (reply->data_size && msg.msg_flags & MSG_TRUNC) + if ((ctx.data_size = data->ops->parse_icmp_hdr( data, icmp_hdr, recvd - ip_hdr_len, &ctx )) < 0) goto skip; + if (ctx.data_size && msg.msg_flags & MSG_TRUNC) { free( reply_buf ); - return set_reply_ip_status( params, IP_GENERAL_FAILURE ); + return data->ops->set_reply_ip_status( params, IP_GENERAL_FAILURE ); }
- sockaddr_to_SOCKADDR_INET( (struct sockaddr *)&addr, &reply->addr ); - reply->round_trip_time = get_rtt( data->send_time ); - reply->num_of_pkts = 1; - reply->opts.options_offset = sizeof(*reply); - reply->data_offset = sizeof(*reply) + ((reply->opts.options_size + 3) & ~3); - if (reply->opts.options_size) - memcpy( (char *)reply + reply->opts.options_offset, opts, reply->opts.options_size ); - if (reply->opts.options_size & 3) - memset( (char *)reply + reply->opts.options_offset + reply->opts.options_size, 0, 4 - (reply->opts.options_size & 3) ); - if (reply->data_size) - memcpy( (char *)reply + reply->data_offset, icmp_hdr + 1, reply->data_size ); - - params->reply_len = reply->data_offset + reply->data_size; + sockaddr_to_SOCKADDR_INET( (struct sockaddr *)&addr, &ctx.addr ); + ctx.round_trip_time = get_rtt( data->send_time ); + ctx.data = icmp_hdr + 1; + + data->ops->fill_reply( params, &ctx ); + free( reply_buf ); return STATUS_SUCCESS;
@@ -703,10 +770,10 @@ NTSTATUS icmp_listen( void *args ) if (!ret) /* timeout */ { TRACE( "timeout\n" ); - return set_reply_ip_status( params, IP_REQ_TIMED_OUT ); + return data->ops->set_reply_ip_status( params, IP_REQ_TIMED_OUT ); } /* ret < 0 */ - return set_reply_ip_status( params, errno_to_ip_status( errno ) ); + return data->ops->set_reply_ip_status( params, errno_to_ip_status( errno ) ); }
NTSTATUS icmp_cancel_listen( void *args ) diff --git a/dlls/nsiproxy.sys/nsiproxy_private.h b/dlls/nsiproxy.sys/nsiproxy_private.h index 91dd393..c0b8ca0 100644 --- a/dlls/nsiproxy.sys/nsiproxy_private.h +++ b/dlls/nsiproxy.sys/nsiproxy_private.h @@ -21,7 +21,9 @@ struct icmp_listen_params { HANDLE handle; void *reply; + ULONGLONG user_reply_ptr; unsigned int reply_len; + unsigned int bits; int timeout; };
@@ -34,3 +36,40 @@ struct icmp_send_echo_params HANDLE handle; ULONG ip_status; }; + +/* output for IOCTL_NSIPROXY_WINE_ICMP_ECHO - cf. ICMP_ECHO_REPLY */ +struct icmp_echo_reply_32 +{ + ULONG addr; + ULONG status; + ULONG round_trip_time; + USHORT data_size; + USHORT num_of_pkts; + ULONG data_ptr; + struct + { + BYTE ttl; + BYTE tos; + BYTE flags; + BYTE options_size; + ULONG options_ptr; + } opts; +}; + +struct icmp_echo_reply_64 +{ + ULONG addr; + ULONG status; + ULONG round_trip_time; + USHORT data_size; + USHORT num_of_pkts; + ULONGLONG data_ptr; + struct + { + BYTE ttl; + BYTE tos; + BYTE flags; + BYTE options_size; + ULONGLONG options_ptr; + } opts; +}; diff --git a/include/wine/nsi.h b/include/wine/nsi.h index 9664b53..8c3488d 100644 --- a/include/wine/nsi.h +++ b/include/wine/nsi.h @@ -426,6 +426,8 @@ struct nsiproxy_icmp_echo { SOCKADDR_INET src; SOCKADDR_INET dst; + ULONGLONG user_reply_ptr; + BYTE bits; BYTE ttl; BYTE tos; BYTE flags; @@ -435,25 +437,6 @@ struct nsiproxy_icmp_echo BYTE data[1]; /* ((opt_size + 3) & ~3) + req_size */ };
-/* output for IOCTL_NSIPROXY_WINE_ICMP_ECHO - cf. ICMP_ECHO_REPLY */ -struct nsiproxy_icmp_echo_reply -{ - SOCKADDR_INET addr; - ULONG status; - ULONG round_trip_time; - USHORT data_size; - USHORT num_of_pkts; - DWORD data_offset; - struct - { - BYTE ttl; - BYTE tos; - BYTE flags; - BYTE options_size; - DWORD options_offset; - } opts; -}; - /* Undocumented Nsi api */
#define NSI_PARAM_TYPE_RW 0