ReactOS 0.4.16-dev-197-g92996da
icmp.c File Reference
#include "precomp.h"
#include <checksum.h>
Include dependency graph for icmp.c:

Go to the source code of this file.

Classes

struct  _ICMP_PACKET_CONTEXT
 

Macros

#define UINT16_MAX   (65535U)
 

Typedefs

typedef struct _ICMP_PACKET_CONTEXT ICMP_PACKET_CONTEXT
 
typedef struct _ICMP_PACKET_CONTEXTPICMP_PACKET_CONTEXT
 

Functions

static UINT32 GetReplyStatus (PICMP_HEADER IcmpHeader)
 
static VOID ClearReceiveHandler (_In_ PADDRESS_FILE AddrFile)
 
VOID NTAPI EndRequestHandler (PDEVICE_OBJECT DeviceObject, PVOID _Context)
 
NTSTATUS NTAPI ReceiveDatagram (_In_opt_ PVOID TdiEventContext, _In_ LONG SourceAddressLength, _In_reads_bytes_(SourceAddressLength) PVOID SourceAddress, _In_ LONG OptionsLength, _In_reads_bytes_opt_(OptionsLength) PVOID Options, _In_ ULONG ReceiveDatagramFlags, _In_ ULONG BytesIndicated, _In_ ULONG BytesAvailable, _Out_ ULONG *OutBytesTaken, _In_ PVOID Tsdu, _Out_opt_ PIRP *IoRequestPacket)
 
VOID NTAPI TimeoutHandler (_In_ PKDPC Dpc, _In_opt_ PVOID _Context, _In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument2)
 
NTSTATUS DispEchoRequest (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PIO_STACK_LOCATION IrpSp)
 

Variables

static volatile INT16 IcmpSequence = 0
 
IO_WORKITEM_ROUTINE EndRequestHandler
 
KDEFERRED_ROUTINE TimeoutHandler
 

Macro Definition Documentation

◆ UINT16_MAX

#define UINT16_MAX   (65535U)

Definition at line 12 of file icmp.c.

Typedef Documentation

◆ ICMP_PACKET_CONTEXT

◆ PICMP_PACKET_CONTEXT

Function Documentation

◆ ClearReceiveHandler()

static VOID ClearReceiveHandler ( _In_ PADDRESS_FILE  AddrFile)
static

Definition at line 74 of file icmp.c.

76{
77 LockObject(AddrFile);
78 AddrFile->RegisteredReceiveDatagramHandler = FALSE;
79 UnlockObject(AddrFile);
80}
#define FALSE
Definition: types.h:117
#define UnlockObject(Object)
Definition: titypes.h:44
#define LockObject(Object)
Definition: titypes.h:34

Referenced by DispEchoRequest(), EndRequestHandler(), and ReceiveDatagram().

◆ DispEchoRequest()

NTSTATUS DispEchoRequest ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_ PIO_STACK_LOCATION  IrpSp 
)

Definition at line 275 of file icmp.c.

279{
280 PICMP_ECHO_REQUEST Request = Irp->AssociatedIrp.SystemBuffer;
284 TDI_CONNECTION_INFORMATION ConnectionInfo;
285 TA_IP_ADDRESS RemoteAddressTa, LocalAddressTa;
286 PADDRESS_FILE AddrFile;
287 ULONG DataUsed;
290 PICMP_PACKET_CONTEXT SendContext;
291 LARGE_INTEGER RequestTimeout;
292 UINT8 SavedTtl;
293
294 TI_DbgPrint(DEBUG_ICMP, ("About to send datagram, OutputBufferLength: %u, SystemBuffer: %p\n", OutputBufferLength, Irp->AssociatedIrp.SystemBuffer));
295
296 // check buffers
298 {
300 }
301
302 // check request parameters
303 if ((Request->DataSize > UINT16_MAX - sizeof(ICMP_HEADER) - sizeof(IPv4_HEADER)) ||
304 ((UINT32)Request->DataOffset + Request->DataSize > InputBufferLength) ||
305 ((UINT32)Request->OptionsOffset + Request->OptionsSize > InputBufferLength))
306 {
308 }
309
310 SendContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(*SendContext), OUT_DATA_TAG);
311 if (!SendContext)
312 {
314 }
315
316 RtlZeroMemory(&SendContext->TdiRequest, sizeof(SendContext->TdiRequest));
317 SendContext->TdiRequest.RequestContext = Irp;
318
319 // setting up everything needed for sending the packet
320
321 RtlZeroMemory(&RemoteAddressTa, sizeof(RemoteAddressTa));
322 RtlZeroMemory(&LocalAddressTa, sizeof(LocalAddressTa));
323 RtlZeroMemory(&ConnectionInfo, sizeof(ConnectionInfo));
324
325 RemoteAddressTa.TAAddressCount = 1;
326 RemoteAddressTa.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
327 RemoteAddressTa.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
328 RemoteAddressTa.Address[0].Address[0].in_addr = Request->Address;
329
330 LocalAddressTa.TAAddressCount = 1;
331 LocalAddressTa.Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP;
332 LocalAddressTa.Address[0].AddressType = TDI_ADDRESS_TYPE_IP;
333 LocalAddressTa.Address[0].Address[0].in_addr = 0;
334
335 Status = FileOpenAddress(&SendContext->TdiRequest, &LocalAddressTa, IPPROTO_ICMP, FALSE, NULL);
336
337 if (!NT_SUCCESS(Status))
338 {
339 TI_DbgPrint(DEBUG_ICMP, ("Failed to open address file status: 0x%x\n", Status));
340
341 ExFreePoolWithTag(SendContext, OUT_DATA_TAG);
342
343 return Status;
344 }
345
346 AddrFile = (PADDRESS_FILE)SendContext->TdiRequest.Handle.AddressHandle;
347
348 // setting up the context
349
351 SendContext->Irp = Irp;
352 SendContext->CurrentReply = Irp->AssociatedIrp.SystemBuffer;
353 SendContext->RemainingSize = OutputBufferLength;
354 SendContext->nReplies = 0;
358
359 KeInitializeDpc(&SendContext->TimeoutDpc, &TimeoutHandler, SendContext);
361
362 RequestTimeout.QuadPart = (-1LL) * 10 * 1000 * Request->Timeout;
363
364 ConnectionInfo.RemoteAddress = &RemoteAddressTa;
365 ConnectionInfo.RemoteAddressLength = sizeof(RemoteAddressTa);
366
367 RequestSize = sizeof(ICMP_HEADER) + Request->DataSize;
368
369 // making up the request packet
371
372 if (!Buffer)
373 {
374 ExFreePoolWithTag(SendContext, OUT_DATA_TAG);
375
377 }
378
381 ((PICMP_HEADER)Buffer)->Checksum = 0;
384 memcpy(Buffer + sizeof(ICMP_HEADER), (PUCHAR)Request + Request->DataOffset, Request->DataSize);
386 SavedTtl = Request->Ttl;
387
388 RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, OutputBufferLength);
389
390 LockObject(AddrFile);
391
392 AddrFile->TTL = SavedTtl;
393 AddrFile->ReceiveDatagramHandlerContext = SendContext;
396
397 UnlockObject(AddrFile);
398
399 Status = AddrFile->Send(AddrFile, &ConnectionInfo, (PCHAR)Buffer, RequestSize, &DataUsed);
400
401 // From this point we may receive a reply packet.
402 // But we are not ready for it thus InitializationFinishedEvent is needed (see below)
403
405
407
408 if (!NT_SUCCESS(Status))
409 {
410 NTSTATUS _Status;
411
412 ClearReceiveHandler(AddrFile);
413 _Status = FileCloseAddress(&SendContext->TdiRequest);
414 ASSERT(NT_SUCCESS(_Status));
415
416 IoFreeWorkItem(SendContext->FinishWorker);
417 ExFreePoolWithTag(SendContext, OUT_DATA_TAG);
418
419 TI_DbgPrint(DEBUG_ICMP, ("Failed to send a datagram: 0x%x\n", Status));
420 return Status;
421 }
422
424 KeSetTimer(&SendContext->TimeoutTimer, RequestTimeout, &SendContext->TimeoutDpc);
426
427 return STATUS_PENDING;
428}
unsigned short UINT16
unsigned char UINT8
unsigned int UINT32
LONG NTSTATUS
Definition: precomp.h:26
#define IPv4Checksum(Data, Count, Seed)
Definition: checksum.h:30
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID NTAPI KeInitializeDpc(IN PKDPC Dpc, IN PKDEFERRED_ROUTINE DeferredRoutine, IN PVOID DeferredContext)
Definition: dpc.c:712
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define DEBUG_ICMP
Definition: debug.h:29
#define TI_DbgPrint(_t_, _x_)
Definition: debug.h:45
#define IPPROTO_ICMP
Definition: ip.h:194
#define OUT_DATA_TAG
Definition: tags.h:39
NTSTATUS NTAPI ReceiveDatagram(_In_opt_ PVOID TdiEventContext, _In_ LONG SourceAddressLength, _In_reads_bytes_(SourceAddressLength) PVOID SourceAddress, _In_ LONG OptionsLength, _In_reads_bytes_opt_(OptionsLength) PVOID Options, _In_ ULONG ReceiveDatagramFlags, _In_ ULONG BytesIndicated, _In_ ULONG BytesAvailable, _Out_ ULONG *OutBytesTaken, _In_ PVOID Tsdu, _Out_opt_ PIRP *IoRequestPacket)
Definition: icmp.c:143
#define UINT16_MAX
Definition: icmp.c:12
static VOID ClearReceiveHandler(_In_ PADDRESS_FILE AddrFile)
Definition: icmp.c:74
KDEFERRED_ROUTINE TimeoutHandler
Definition: icmp.c:259
static volatile INT16 IcmpSequence
Definition: icmp.c:30
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define NonPagedPool
Definition: env_spec_w32.h:307
NTSTATUS FileCloseAddress(PTDI_REQUEST Request)
Definition: fileobjs.c:591
NTSTATUS FileOpenAddress(PTDI_REQUEST Request, PTA_IP_ADDRESS AddrList, USHORT Protocol, BOOLEAN Shared, PVOID Options)
Definition: fileobjs.c:399
Status
Definition: gdiplustypes.h:25
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
#define ICMP_TYPE_ECHO_REPLY
Definition: icmp.h:21
#define ICMP_TYPE_ECHO_REQUEST
Definition: icmp.h:25
struct ICMP_HEADER * PICMP_HEADER
#define InterlockedIncrement16
Definition: interlocked.h:206
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
IoMarkIrpPending(Irp)
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
@ NotificationEvent
@ SynchronizationTimer
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
static ULONG RequestSize
Definition: ping.c:63
BOOLEAN RegisteredReceiveDatagramHandler
Definition: titypes.h:163
DATAGRAM_SEND_ROUTINE Send
Definition: titypes.h:128
PVOID ReceiveDatagramHandlerContext
Definition: titypes.h:162
PTDI_IND_RECEIVE_DATAGRAM ReceiveDatagramHandler
Definition: titypes.h:161
UCHAR TTL
Definition: titypes.h:122
INT64 StartTicks
Definition: icmp.c:21
LARGE_INTEGER TimerResolution
Definition: icmp.c:20
TDI_REQUEST TdiRequest
Definition: icmp.c:16
KEVENT DatagramProcessedEvent
Definition: icmp.c:19
KTIMER TimeoutTimer
Definition: icmp.c:27
KEVENT InitializationFinishedEvent
Definition: icmp.c:18
PUCHAR CurrentReply
Definition: icmp.c:23
PIO_WORKITEM FinishWorker
Definition: icmp.c:26
UINT32 RemainingSize
Definition: icmp.c:24
struct _IO_STACK_LOCATION::@1575::@1576 DeviceIoControl
union _IO_STACK_LOCATION::@1575 Parameters
struct _TA_ADDRESS_IP::_AddrIp Address[1]
LONG TAAddressCount
Definition: tdi.h:523
PVOID RequestContext
Definition: tdi.h:55
HANDLE AddressHandle
Definition: tdi.h:50
union _TDI_REQUEST::@3236 Handle
#define TDI_ADDRESS_LENGTH_IP
Definition: tdi.h:413
#define TDI_ADDRESS_TYPE_IP
Definition: tdi.h:345
BOOLEAN NTAPI KeSetTimer(IN OUT PKTIMER Timer, IN LARGE_INTEGER DueTime, IN PKDPC Dpc OPTIONAL)
Definition: timerobj.c:281
VOID NTAPI KeInitializeTimerEx(OUT PKTIMER Timer, IN TIMER_TYPE Type)
Definition: timerobj.c:244
struct _ADDRESS_FILE * PADDRESS_FILE
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
#define IO_NO_INCREMENT
Definition: iotypes.h:598

◆ EndRequestHandler()

VOID NTAPI EndRequestHandler ( PDEVICE_OBJECT  DeviceObject,
PVOID  _Context 
)

Definition at line 86 of file icmp.c.

89{
91 PIO_STACK_LOCATION CurrentStack;
92 PIRP Irp;
93 UINT32 nReplies;
95
96 ClearReceiveHandler((PADDRESS_FILE)Context->TdiRequest.Handle.AddressHandle);
97
98 KeWaitForSingleObject(&Context->DatagramProcessedEvent, Executive, KernelMode, FALSE, NULL);
99
100 TI_DbgPrint(DEBUG_ICMP, ("Finishing request Context: %p\n", Context));
101
102 Irp = Context->Irp;
103 CurrentStack = IoGetCurrentIrpStackLocation(Irp);
104
105 if (Context->nReplies > 0)
106 {
107 ((PICMP_ECHO_REPLY)Irp->AssociatedIrp.SystemBuffer)->Reserved = Context->nReplies;
108 Irp->IoStatus.Status = STATUS_SUCCESS;
109 Irp->IoStatus.Information = CurrentStack->Parameters.DeviceIoControl.OutputBufferLength;
110 }
111 else
112 {
113 PICMP_ECHO_REPLY ReplyBuffer = (PICMP_ECHO_REPLY)Irp->AssociatedIrp.SystemBuffer;
116
117 Irp->IoStatus.Status = STATUS_TIMEOUT;
118 Irp->IoStatus.Information = sizeof(*ReplyBuffer);
119 }
120
121 // for debugging
122 nReplies = ((PICMP_ECHO_REPLY)Irp->AssociatedIrp.SystemBuffer)->Reserved;
123
124 // taken from dispatch.c:IRPFinish
129
130 {
131 NTSTATUS _Status = FileCloseAddress(&Context->TdiRequest);
132 ASSERT(NT_SUCCESS(_Status));
133 }
134
135 IoFreeWorkItem(Context->FinishWorker);
137
138 TI_DbgPrint(DEBUG_ICMP, ("Leaving, nReplies: %u\n", nReplies));
139}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define IO_NETWORK_INCREMENT
Definition: tcpip.h:43
struct _ICMP_PACKET_CONTEXT * PICMP_PACKET_CONTEXT
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
_Must_inspect_result_ _In_ PFLT_PORT _In_ ULONG _Out_writes_bytes_opt_ ReplyLength PVOID ReplyBuffer
Definition: fltkernel.h:1902
struct icmp_echo_reply * PICMP_ECHO_REPLY
#define IP_REQ_TIMED_OUT
Definition: ipexport.h:123
IoSetCancelRoutine(Irp, CancelRoutine)
#define KernelMode
Definition: asm.h:34
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
#define STATUS_SUCCESS
Definition: shellext.h:65
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ Executive
Definition: ketypes.h:415

◆ GetReplyStatus()

static UINT32 GetReplyStatus ( PICMP_HEADER  IcmpHeader)
static

Definition at line 34 of file icmp.c.

35{
36 switch (IcmpHeader->Type)
37 {
39 return IP_SUCCESS;
41 switch (IcmpHeader->Code)
42 {
54 return IP_BAD_ROUTE;
55 default:
57 }
59 return IP_SOURCE_QUENCH;
61 if (IcmpHeader->Code == ICMP_CODE_TE_REASSEMBLY)
63 else
66 return IP_PARAM_PROBLEM;
67 default:
68 return IP_REQ_TIMED_OUT;
69 }
70}
#define ICMP_CODE_DU_HOST_UNREACH
Definition: icmp.h:35
#define ICMP_CODE_DU_SOURCE_ROUTE_FAILED
Definition: icmp.h:39
#define ICMP_CODE_DU_PORT_UNREACH
Definition: icmp.h:37
#define ICMP_TYPE_DEST_UNREACH
Definition: icmp.h:22
#define ICMP_CODE_DU_PROTOCOL_UNREACH
Definition: icmp.h:36
#define ICMP_TYPE_SOURCE_QUENCH
Definition: icmp.h:23
#define ICMP_CODE_TE_REASSEMBLY
Definition: icmp.h:49
#define ICMP_CODE_DU_NET_UNREACH
Definition: icmp.h:34
#define ICMP_CODE_DU_FRAG_DF_SET
Definition: icmp.h:38
#define ICMP_TYPE_TIME_EXCEEDED
Definition: icmp.h:26
#define ICMP_TYPE_PARAMETER
Definition: icmp.h:27
#define IP_DEST_NET_UNREACHABLE
Definition: ipexport.h:115
#define IP_SOURCE_QUENCH
Definition: ipexport.h:129
#define IP_TTL_EXPIRED_REASSEM
Definition: ipexport.h:127
#define IP_DEST_HOST_UNREACHABLE
Definition: ipexport.h:116
#define IP_DEST_PROT_UNREACHABLE
Definition: ipexport.h:117
#define IP_BAD_ROUTE
Definition: ipexport.h:125
#define IP_DEST_PORT_UNREACHABLE
Definition: ipexport.h:118
#define IP_PARAM_PROBLEM
Definition: ipexport.h:128
#define IP_TTL_EXPIRED_TRANSIT
Definition: ipexport.h:126
#define IP_SUCCESS
Definition: ipexport.h:113
UINT8 Type
Definition: icmp.h:12
UINT8 Code
Definition: icmp.h:13

Referenced by ReceiveDatagram().

◆ ReceiveDatagram()

NTSTATUS NTAPI ReceiveDatagram ( _In_opt_ PVOID  TdiEventContext,
_In_ LONG  SourceAddressLength,
_In_reads_bytes_(SourceAddressLength) PVOID  SourceAddress,
_In_ LONG  OptionsLength,
_In_reads_bytes_opt_(OptionsLength) PVOID  Options,
_In_ ULONG  ReceiveDatagramFlags,
_In_ ULONG  BytesIndicated,
_In_ ULONG  BytesAvailable,
_Out_ ULONG OutBytesTaken,
_In_ PVOID  Tsdu,
_Out_opt_ PIRP IoRequestPacket 
)

Definition at line 143 of file icmp.c.

155{
156 PICMP_PACKET_CONTEXT Context = TdiEventContext;
157 PIPv4_HEADER IpHeader = Tsdu;
158 UINT16 IpHeaderSize = sizeof(IPv4_HEADER) + OptionsLength;
159 PICMP_HEADER IcmpHeader = (PICMP_HEADER)((PUCHAR)Tsdu + IpHeaderSize);
160
161 PVOID DataBuffer = (PUCHAR)Tsdu + IpHeaderSize + sizeof(ICMP_HEADER);
162 INT32 DataSize = min(BytesAvailable, UINT16_MAX) - IpHeaderSize - sizeof(ICMP_HEADER);
163
164 INT64 CurrentTime;
165 UINT32 RoundTripTime;
166 PICMP_ECHO_REPLY CurrentReply;
167 PUCHAR CurrentUserBuffer;
168
169 // do not handle echo requests
170 if (DataSize >= 0 && IcmpHeader->Type == ICMP_TYPE_ECHO_REQUEST)
171 {
172 return STATUS_SUCCESS;
173 }
174
175 KeWaitForSingleObject(&Context->InitializationFinishedEvent, Executive, KernelMode, FALSE, NULL);
176 KeClearEvent(&Context->DatagramProcessedEvent);
177
178 ASSERT(SourceAddressLength == sizeof(IPAddr));
179 TI_DbgPrint(DEBUG_ICMP, ("Received datagram Context: 0x%p\n", TdiEventContext));
180
182 RoundTripTime = (CurrentTime - Context->StartTicks) * 1000 / Context->TimerResolution.QuadPart;
183 CurrentReply = (PICMP_ECHO_REPLY)Context->CurrentReply;
184
185 if (Context->RemainingSize >= sizeof(ICMP_ECHO_REPLY) && DataSize >= 0)
186 {
187 TI_DbgPrint(DEBUG_ICMP, ("RemainingSize: %u, RoundTripTime: %u\n", Context->RemainingSize, RoundTripTime));
188
189 memcpy(&CurrentReply->Address, SourceAddress, sizeof(CurrentReply->Address));
190 CurrentReply->Status = GetReplyStatus(IcmpHeader);
191 CurrentReply->RoundTripTime = RoundTripTime;
192 CurrentReply->Reserved = 0;
193 CurrentReply->Data = NULL;
194 CurrentReply->DataSize = 0;
195 CurrentReply->Options.Ttl = IpHeader->Ttl;
196 CurrentReply->Options.Tos = IpHeader->Tos;
197 CurrentReply->Options.Flags = IpHeader->FlagsFragOfs >> 13;
198 CurrentReply->Options.OptionsData = NULL;
199 CurrentReply->Options.OptionsSize = 0;
200
201 Context->RemainingSize -= sizeof(ICMP_ECHO_REPLY);
202 Context->CurrentReply += sizeof(ICMP_ECHO_REPLY);
203 }
204
205 CurrentUserBuffer = (PUCHAR)Context->Irp->UserBuffer + (Context->CurrentReply - (PUCHAR)Context->Irp->AssociatedIrp.SystemBuffer);
206
207 if (DataSize > 0 && Context->RemainingSize > 0)
208 {
209 UINT32 _DataSize = min(Context->RemainingSize, DataSize);
210
211 memcpy(Context->CurrentReply + Context->RemainingSize - _DataSize, DataBuffer, _DataSize);
212 CurrentReply->Data = CurrentUserBuffer + Context->RemainingSize - _DataSize;
213 CurrentReply->DataSize = _DataSize;
214
215 Context->RemainingSize -= _DataSize;
216 // Context->ReplyBuffer += _DataSize;
217 }
218 else
219 {
220 TI_DbgPrint(DEBUG_ICMP, ("RemainingSize: %u, DataSize: %d\n", Context->RemainingSize, DataSize));
221 }
222
223 if (OptionsLength > 0 && Context->RemainingSize > 0)
224 {
225 UINT32 _OptSize = min(Context->RemainingSize, OptionsLength);
226
227 memcpy(Context->CurrentReply + Context->RemainingSize + _OptSize, Options, _OptSize);
228 CurrentReply->Options.OptionsData = CurrentUserBuffer + Context->RemainingSize + _OptSize;
229 CurrentReply->Options.OptionsSize = _OptSize;
230
231 Context->RemainingSize -= _OptSize;
232 // Context->ReplyBuffer += _OptSize;
233 }
234 else
235 {
236 TI_DbgPrint(DEBUG_ICMP, ("RemainingSize: %u, OptSize: %d\n", Context->RemainingSize, OptionsLength));
237 }
238
239 Context->nReplies++;
240
241 if (Context->RemainingSize < sizeof(ICMP_ECHO_REPLY))
242 {
243 TI_DbgPrint(DEBUG_ICMP, ("The space is over: %u\n", Context->RemainingSize));
244
245 // if the timer was inserted, that means DPC has not been queued yet
246 if (KeCancelTimer(&Context->TimeoutTimer))
247 {
248 PADDRESS_FILE AddrFile = (PADDRESS_FILE)Context->TdiRequest.Handle.AddressHandle;
249 ClearReceiveHandler(AddrFile);
250
252 }
253 }
254
255 KeSetEvent(&Context->DatagramProcessedEvent, IO_NO_INCREMENT, FALSE);
256 return STATUS_SUCCESS;
257}
signed int INT32
signed long long INT64
static UINT32 GetReplyStatus(PICMP_HEADER IcmpHeader)
Definition: icmp.c:34
IO_WORKITEM_ROUTINE EndRequestHandler
Definition: icmp.c:82
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
struct icmp_echo_reply ICMP_ECHO_REPLY
#define min(a, b)
Definition: monoChain.cc:55
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
ULONG IPAddr
Definition: pfhook.h:35
UCHAR Tos
Definition: eth.h:29
UCHAR Ttl
Definition: eth.h:33
USHORT FlagsFragOfs
Definition: ip.h:42
UINT16 DataSize
Definition: ipexport.h:87
IPAddr Address
Definition: ipexport.h:84
IP_OPTION_INFORMATION Options
Definition: ipexport.h:90
UINT32 Status
Definition: ipexport.h:85
UINT16 Reserved
Definition: ipexport.h:88
UINT32 RoundTripTime
Definition: ipexport.h:86
unsigned char Flags
Definition: ipexport.h:35
unsigned char Ttl
Definition: ipexport.h:33
unsigned char * OptionsData
Definition: ipexport.h:37
unsigned char Tos
Definition: ipexport.h:34
unsigned char OptionsSize
Definition: ipexport.h:36
BOOLEAN NTAPI KeCancelTimer(IN OUT PKTIMER Timer)
Definition: timerobj.c:206
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3534
@ DelayedWorkQueue
Definition: extypes.h:190
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS SourceAddress
Definition: iotypes.h:1127

Referenced by DispEchoRequest().

◆ TimeoutHandler()

VOID NTAPI TimeoutHandler ( _In_ PKDPC  Dpc,
_In_opt_ PVOID  _Context,
_In_opt_ PVOID  SystemArgument1,
_In_opt_ PVOID  SystemArgument2 
)

Definition at line 263 of file icmp.c.

268{
270
271 IoQueueWorkItem(Context->FinishWorker, &EndRequestHandler, DelayedWorkQueue, _Context);
272}

Variable Documentation

◆ EndRequestHandler

IO_WORKITEM_ROUTINE EndRequestHandler

Definition at line 82 of file icmp.c.

Referenced by ReceiveDatagram(), and TimeoutHandler().

◆ IcmpSequence

volatile INT16 IcmpSequence = 0
static

Definition at line 30 of file icmp.c.

Referenced by DispEchoRequest().

◆ TimeoutHandler

KDEFERRED_ROUTINE TimeoutHandler

Definition at line 259 of file icmp.c.

Referenced by DispEchoRequest().