ReactOS 0.4.15-dev-8241-g63935f8
transmit.c File Reference
#include "precomp.h"
Include dependency graph for transmit.c:

Go to the source code of this file.

Functions

BOOLEAN PrepareNextFragment (PIPFRAGMENT_CONTEXT IFC)
 
NTSTATUS IPSendFragment (PNDIS_PACKET NdisPacket, PNEIGHBOR_CACHE_ENTRY NCE, PIPFRAGMENT_CONTEXT IFC)
 
VOID IPSendComplete (PVOID Context, PNDIS_PACKET NdisPacket, NDIS_STATUS NdisStatus)
 
NTSTATUS SendFragments (PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE, UINT PathMTU)
 
NTSTATUS IPSendDatagram (PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE)
 

Function Documentation

◆ IPSendComplete()

VOID IPSendComplete ( PVOID  Context,
PNDIS_PACKET  NdisPacket,
NDIS_STATUS  NdisStatus 
)

Definition at line 18 of file transmit.c.

29{
31
33 (MAX_TRACE,
34 ("Called. Context (0x%X) NdisPacket (0x%X) NdisStatus (0x%X)\n",
35 Context, NdisPacket, NdisStatus));
36
37 IFC->Status = NdisStatus;
38 KeSetEvent(&IFC->Event, 0, FALSE);
39}
#define MAX_TRACE
Definition: debug.h:16
#define FALSE
Definition: types.h:117
#define TI_DbgPrint(_t_, _x_)
Definition: debug.h:45
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
NDIS_STATUS Status
Definition: transmit.h:29
struct IPFRAGMENT_CONTEXT * PIPFRAGMENT_CONTEXT

Referenced by IPSendFragment().

◆ IPSendDatagram()

NTSTATUS IPSendDatagram ( PIP_PACKET  IPPacket,
PNEIGHBOR_CACHE_ENTRY  NCE 
)

Definition at line 223 of file transmit.c.

236{
237 TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) NCE (0x%X)\n", IPPacket, NCE));
238
239 DISPLAY_IP_PACKET(IPPacket);
240
241 /* Fetch path MTU now, because it may change */
242 TI_DbgPrint(MID_TRACE,("PathMTU: %d\n", NCE->Interface->MTU));
243
244 return SendFragments(IPPacket, NCE, NCE->Interface->MTU);
245}
#define MID_TRACE
Definition: debug.h:15
NTSTATUS SendFragments(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE, UINT PathMTU)
Definition: transmit.c:132
#define DISPLAY_IP_PACKET(x)
Definition: routines.h:69
PIP_INTERFACE Interface
Definition: neighbor.h:33
UINT MTU
Definition: ip.h:157

Referenced by ICMPReply(), RawIPSendDatagram(), TCPSendDataCallback(), and UDPSendDatagram().

◆ IPSendFragment()

NTSTATUS IPSendFragment ( PNDIS_PACKET  NdisPacket,
PNEIGHBOR_CACHE_ENTRY  NCE,
PIPFRAGMENT_CONTEXT  IFC 
)

Definition at line 41 of file transmit.c.

55{
56 TI_DbgPrint(MAX_TRACE, ("Called. NdisPacket (0x%X) NCE (0x%X).\n", NdisPacket, NCE));
57
58 TI_DbgPrint(MAX_TRACE, ("NCE->State = %d.\n", NCE->State));
59 return NBQueuePacket(NCE, NdisPacket, IPSendComplete, IFC);
60}
VOID IPSendComplete(PVOID Context, PNDIS_PACKET NdisPacket, NDIS_STATUS NdisStatus)
Definition: transmit.c:19
BOOLEAN NBQueuePacket(PNEIGHBOR_CACHE_ENTRY NCE, PNDIS_PACKET NdisPacket, PNEIGHBOR_PACKET_COMPLETE PacketComplete, PVOID PacketContext)
Definition: neighbor.c:541
UCHAR State
Definition: neighbor.h:30

Referenced by SendFragments().

◆ PrepareNextFragment()

BOOLEAN PrepareNextFragment ( PIPFRAGMENT_CONTEXT  IFC)

Definition at line 62 of file transmit.c.

72{
73 UINT MaxData;
76 BOOLEAN MoreFragments;
77 USHORT FragOfs;
78
79 TI_DbgPrint(MAX_TRACE, ("Called. IFC (0x%X)\n", IFC));
80
81 if (IFC->BytesLeft > 0) {
82
83 TI_DbgPrint(MAX_TRACE, ("Preparing 1 fragment.\n"));
84
85 MaxData = IFC->PathMTU - IFC->HeaderSize;
86 /* Make fragment a multiplum of 64bit */
87 MaxData -= MaxData % 8;
88 if (IFC->BytesLeft > MaxData) {
89 DataSize = MaxData;
90 MoreFragments = TRUE;
91 } else {
92 DataSize = IFC->BytesLeft;
93 MoreFragments = FALSE;
94 }
95
96 TI_DbgPrint(MID_TRACE,("Copying data from %x to %x (%d)\n",
97 IFC->DatagramData, IFC->Data, DataSize));
98
99 RtlCopyMemory(IFC->Data, IFC->DatagramData, DataSize); // SAFE
100
101 /* Fragment offset is in 8 byte blocks */
102 FragOfs = (USHORT)(IFC->Position / 8);
103
104 if (MoreFragments)
105 FragOfs |= IPv4_MF_MASK;
106 else
107 FragOfs &= ~IPv4_MF_MASK;
108
109 Header = IFC->Header;
110 Header->FlagsFragOfs = WH2N(FragOfs);
111 Header->TotalLength = WH2N((USHORT)(DataSize + IFC->HeaderSize));
112
113 /* FIXME: Handle options */
114
115 /* Calculate checksum of IP header */
116 Header->Checksum = 0;
117 Header->Checksum = (USHORT)IPv4Checksum(Header, IFC->HeaderSize, 0);
118 TI_DbgPrint(MID_TRACE,("IP Check: %x\n", Header->Checksum));
119
120 /* Update pointers */
122 IFC->Position += DataSize;
123 IFC->BytesLeft -= DataSize;
124
125 return TRUE;
126 } else {
127 TI_DbgPrint(MAX_TRACE, ("No more fragments.\n"));
128 return FALSE;
129 }
130}
unsigned char BOOLEAN
#define WH2N(w)
Definition: addrconv.c:40
#define IPv4Checksum(Data, Count, Seed)
Definition: checksum.h:30
Definition: Header.h:9
#define TRUE
Definition: types.h:120
#define IPv4_MF_MASK
Definition: ip.h:66
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
unsigned int UINT
Definition: ndis.h:50
unsigned short USHORT
Definition: pedump.c:61
PVOID DatagramData
Definition: transmit.h:18
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by SendFragments().

◆ SendFragments()

NTSTATUS SendFragments ( PIP_PACKET  IPPacket,
PNEIGHBOR_CACHE_ENTRY  NCE,
UINT  PathMTU 
)

Definition at line 132 of file transmit.c.

147{
149 NDIS_STATUS NdisStatus;
150 PVOID Data;
151 UINT BufferSize = PathMTU, InSize;
152 PCHAR InData;
153
154 TI_DbgPrint(MAX_TRACE, ("Called. IPPacket (0x%X) NCE (0x%X) PathMTU (%d).\n",
155 IPPacket, NCE, PathMTU));
156
157 /* Make a smaller buffer if we will only send one fragment */
158 GetDataPtr( IPPacket->NdisPacket, IPPacket->Position, &InData, &InSize );
159 if( InSize < BufferSize ) BufferSize = InSize;
160
161 TI_DbgPrint(MAX_TRACE, ("Fragment buffer is %d bytes\n", BufferSize));
162
164 if (IFC == NULL)
165 {
166 IPPacket->Free(IPPacket);
168 }
169
170 /* Allocate NDIS packet */
171 NdisStatus = AllocatePacketWithBuffer
172 ( &IFC->NdisPacket, NULL, BufferSize );
173
174 if( !NT_SUCCESS(NdisStatus) ) {
175 IPPacket->Free(IPPacket);
177 return NdisStatus;
178 }
179
180 GetDataPtr( IFC->NdisPacket, 0, (PCHAR *)&Data, &InSize );
181
182 IFC->Header = ((PCHAR)Data);
183 IFC->Datagram = IPPacket->NdisPacket;
184 IFC->DatagramData = ((PCHAR)IPPacket->Header) + IPPacket->HeaderSize;
185 IFC->HeaderSize = IPPacket->HeaderSize;
186 IFC->PathMTU = PathMTU;
187 IFC->NCE = NCE;
188 IFC->Position = 0;
189 IFC->BytesLeft = IPPacket->TotalSize - IPPacket->HeaderSize;
190 IFC->Data = (PVOID)((ULONG_PTR)IFC->Header + IPPacket->HeaderSize);
192
193 TI_DbgPrint(MID_TRACE,("Copying header from %x to %x (%d)\n",
194 IPPacket->Header, IFC->Header,
195 IPPacket->HeaderSize));
196
197 RtlCopyMemory( IFC->Header, IPPacket->Header, IPPacket->HeaderSize );
198
199 while (PrepareNextFragment(IFC))
200 {
201 NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC);
202 if (NT_SUCCESS(NdisStatus))
203 {
205 Executive,
207 FALSE,
208 NULL);
209 NdisStatus = IFC->Status;
210 }
211
212 if (!NT_SUCCESS(NdisStatus))
213 break;
214 }
215
218 IPPacket->Free(IPPacket);
219
220 return NdisStatus;
221}
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IFC_TAG
Definition: tags.h:30
BOOLEAN PrepareNextFragment(PIPFRAGMENT_CONTEXT IFC)
Definition: transmit.c:62
NTSTATUS IPSendFragment(PNDIS_PACKET NdisPacket, PNEIGHBOR_CACHE_ENTRY NCE, PIPFRAGMENT_CONTEXT IFC)
Definition: transmit.c:41
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NonPagedPool
Definition: env_spec_w32.h:307
void GetDataPtr(PNDIS_PACKET Packet, UINT Offset, PCHAR *DataOut, PUINT Size)
Definition: routines.c:65
#define AllocatePacketWithBuffer(x, y, z)
Definition: memtrack.h:7
#define FreeNdisPacket(x)
Definition: memtrack.h:8
#define PCHAR
Definition: match.c:90
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KernelMode
Definition: asm.h:34
int NDIS_STATUS
Definition: ntddndis.h:475
@ NotificationEvent
PNDIS_PACKET NdisPacket
Definition: transmit.h:20
PNDIS_PACKET Datagram
Definition: transmit.h:17
PNEIGHBOR_CACHE_ENTRY NCE
Definition: transmit.h:27
OBJECT_FREE_ROUTINE Free
Definition: ip.h:78
UINT Position
Definition: ip.h:87
PNDIS_PACKET NdisPacket
Definition: ip.h:88
UINT HeaderSize
Definition: ip.h:84
PVOID Header
Definition: ip.h:83
UINT TotalSize
Definition: ip.h:86
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
@ Executive
Definition: ketypes.h:415

Referenced by IPSendDatagram().