ReactOS  0.4.15-dev-3187-ge372f2b
rawip.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS TCP/IP protocol driver
4  * FILE: transport/rawip/rawip.c
5  * PURPOSE: User Datagram Protocol routines
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * REVISIONS:
8  * CSH 01/08-2000 Created
9  */
10 
11 #include "precomp.h"
12 
14  PADDRESS_FILE AddrFile,
16  USHORT RemotePort,
18  USHORT LocalPort,
19  PIP_PACKET IPPacket,
21  UINT Protocol,
22  UINT ExtraLength,
23  PVOID *NextHeader )
24 /*
25  * FUNCTION: Adds an IPv4 and RawIp header to an IP packet
26  * ARGUMENTS:
27  * SendRequest = Pointer to send request
28  * LocalAddress = Pointer to our local address
29  * LocalPort = The port we send this datagram from
30  * IPPacket = Pointer to IP packet
31  * RETURNS:
32  * Status of operation
33  */
34 {
37 
38  TI_DbgPrint(MID_TRACE, ("Packet: %x NdisPacket %x\n",
39  IPPacket, IPPacket->NdisPacket));
40 
41  BufferSize = sizeof(IPv4_HEADER) + ExtraLength;
42 
43  GetDataPtr( IPPacket->NdisPacket,
44  0,
45  (PCHAR *)&IPPacket->Header,
46  &IPPacket->TotalSize );
47  IPPacket->MappedHeader = TRUE;
48 
49  IPPacket->HeaderSize = sizeof(IPv4_HEADER);
50 
51  TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n",
52  BufferSize, IPPacket->Header));
53  TI_DbgPrint(MAX_TRACE, ("Packet total length %d\n", IPPacket->TotalSize));
54 
55  /* Build IPv4 header */
56  IPHeader = (PIPv4_HEADER)IPPacket->Header;
57  /* Version = 4, Length = 5 DWORDs */
58  IPHeader->VerIHL = 0x45;
59  /* Normal Type-of-Service */
60  IPHeader->Tos = 0;
61  /* Length of header and data */
62  IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize);
63  /* Identification */
64  IPHeader->Id = (USHORT)Random();
65  /* One fragment at offset 0 */
66  IPHeader->FlagsFragOfs = 0;
67  /* Time-to-Live */
68  IPHeader->Ttl = AddrFile->TTL;
69  /* Protocol */
70  IPHeader->Protocol = Protocol;
71  /* Checksum is 0 (for later calculation of this) */
72  IPHeader->Checksum = 0;
73  /* Source address */
74  IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
75  /* Destination address. FIXME: IPv4 only */
76  IPHeader->DstAddr = RemoteAddress->Address.IPv4Address;
77 
78  /* Build RawIp header */
79  *NextHeader = (((PCHAR)IPHeader) + sizeof(IPv4_HEADER));
80  IPPacket->Data = ((PCHAR)*NextHeader) + ExtraLength;
81 
82  return STATUS_SUCCESS;
83 }
84 
85 
87  PADDRESS_FILE AddrFile,
90  USHORT RemotePort,
92  USHORT LocalPort,
93  PCHAR DataBuffer,
94  UINT DataLen )
95 /*
96  * FUNCTION: Builds an RawIp packet
97  * ARGUMENTS:
98  * Context = Pointer to context information (DATAGRAM_SEND_REQUEST)
99  * LocalAddress = Pointer to our local address
100  * LocalPort = The port we send this datagram from
101  * IPPacket = Address of pointer to IP packet
102  * RETURNS:
103  * Status of operation
104  */
105 {
107  PCHAR Payload;
108 
109  TI_DbgPrint(MAX_TRACE, ("Called.\n"));
110 
111  /* FIXME: Assumes IPv4 */
113 
114  Packet->TotalSize = sizeof(IPv4_HEADER) + DataLen;
115 
116  /* Prepare packet */
117  Status = AllocatePacketWithBuffer( &Packet->NdisPacket,
118  NULL,
119  Packet->TotalSize );
120 
121  if( !NT_SUCCESS(Status) ) return Status;
122 
123  TI_DbgPrint(MID_TRACE, ("Allocated packet: %x\n", Packet->NdisPacket));
124  TI_DbgPrint(MID_TRACE, ("Local Addr : %s\n", A2S(LocalAddress)));
125  TI_DbgPrint(MID_TRACE, ("Remote Addr: %s\n", A2S(RemoteAddress)));
126 
127  switch (RemoteAddress->Type) {
128  case IP_ADDRESS_V4:
130  (AddrFile, RemoteAddress, RemotePort,
131  LocalAddress, LocalPort, Packet, DataLen,
132  AddrFile->Protocol,
133  0, (PVOID *)&Payload );
134  break;
135  case IP_ADDRESS_V6:
136  /* FIXME: Support IPv6 */
138  TI_DbgPrint(MIN_TRACE, ("IPv6 RawIp datagrams are not supported.\n"));
139  break;
140 
141  default:
143  TI_DbgPrint(MIN_TRACE, ("Bad Address Type %d\n", RemoteAddress->Type));
144  break;
145  }
146 
147  if( !NT_SUCCESS(Status) ) {
148  TI_DbgPrint(MIN_TRACE, ("Cannot add header. Status = (0x%X)\n",
149  Status));
150  Packet->Free(Packet);
151  return Status;
152  }
153 
154  TI_DbgPrint(MID_TRACE, ("Copying data (hdr %x data %x (%d))\n",
155  Packet->Header, Packet->Data,
156  (PCHAR)Packet->Data - (PCHAR)Packet->Header));
157 
158  RtlCopyMemory( Packet->Data, DataBuffer, DataLen );
159 
160  Packet->Flags |= IP_PACKET_FLAG_RAW;
161 
162  TI_DbgPrint(MID_TRACE, ("Displaying packet\n"));
163 
165 
166  TI_DbgPrint(MID_TRACE, ("Leaving\n"));
167 
168  return STATUS_SUCCESS;
169 }
170 
172  PADDRESS_FILE AddrFile,
174  PCHAR BufferData,
175  ULONG DataSize,
176  PULONG DataUsed )
177 /*
178  * FUNCTION: Sends an RawIp datagram to a remote address
179  * ARGUMENTS:
180  * Request = Pointer to TDI request
181  * ConnInfo = Pointer to connection information
182  * Buffer = Pointer to NDIS buffer with data
183  * DataSize = Size in bytes of data to be sent
184  * RETURNS:
185  * Status of operation
186  */
187 {
189  PTA_IP_ADDRESS RemoteAddressTa = (PTA_IP_ADDRESS)ConnInfo->RemoteAddress;
191  USHORT RemotePort;
194 
195  LockObject(AddrFile);
196 
197  TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
198  AddrFile, ConnInfo, BufferData, DataSize));
199  TI_DbgPrint(MID_TRACE,("RemoteAddressTa: %x\n", RemoteAddressTa));
200 
201  switch( RemoteAddressTa->Address[0].AddressType ) {
202  case TDI_ADDRESS_TYPE_IP:
204  RemoteAddress.Address.IPv4Address =
205  RemoteAddressTa->Address[0].Address[0].in_addr;
206  RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port;
207  break;
208 
209  default:
210  UnlockObject(AddrFile);
211  return STATUS_UNSUCCESSFUL;
212  }
213 
214  TI_DbgPrint(MID_TRACE,("About to get route to destination\n"));
215 
216  LocalAddress = AddrFile->Address;
218  {
219  /* If the local address is unspecified (0),
220  * then use the unicast address of the
221  * interface we're sending over
222  */
223  if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
224  UnlockObject(AddrFile);
226  }
227 
228  LocalAddress = NCE->Interface->Unicast;
229  }
230  else
231  {
232  if(!(NCE = NBLocateNeighbor( &LocalAddress, NULL ))) {
233  UnlockObject(AddrFile);
235  }
236  }
237 
238  Status = BuildRawIpPacket( AddrFile,
239  &Packet,
240  &RemoteAddress,
241  RemotePort,
242  &LocalAddress,
243  AddrFile->Port,
244  BufferData,
245  DataSize );
246 
247  UnlockObject(AddrFile);
248 
249  if( !NT_SUCCESS(Status) )
250  return Status;
251 
252  TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
253 
254  Status = IPSendDatagram(&Packet, NCE);
255  if (!NT_SUCCESS(Status))
256  return Status;
257 
258  *DataUsed = DataSize;
259 
260  TI_DbgPrint(MID_TRACE,("Leaving\n"));
261 
262  return STATUS_SUCCESS;
263 }
264 
265 
267 /*
268  * FUNCTION: Receives and queues a RawIp datagram
269  * ARGUMENTS:
270  * NTE = Pointer to net table entry which the packet was received on
271 * IPPacket = Pointer to an IP packet that was received
272 * NOTES:
273 * This is the low level interface for receiving RawIp datagrams. It strips
274 * the RawIp header from a packet and delivers the data to anyone that wants it
275 */
276 {
277  AF_SEARCH SearchContext;
279  PADDRESS_FILE AddrFile;
280  PIP_ADDRESS DstAddress, SrcAddress;
281  UINT DataSize;
282 
283  TI_DbgPrint(MAX_TRACE, ("Called.\n"));
284 
285  switch (IPPacket->Type) {
286  /* IPv4 packet */
287  case IP_ADDRESS_V4:
288  IPv4Header = IPPacket->Header;
289  DstAddress = &IPPacket->DstAddr;
290  SrcAddress = &IPPacket->SrcAddr;
291  DataSize = IPPacket->TotalSize;
292  break;
293 
294  /* IPv6 packet */
295  case IP_ADDRESS_V6:
296  TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 datagram (%i bytes).\n", IPPacket->TotalSize));
297 
298  /* FIXME: IPv6 is not supported */
299  return;
300 
301  default:
302  return;
303  }
304 
305  /* Locate a receive request on destination address file object
306  and deliver the packet if one is found. If there is no receive
307  request on the address file object, call the associated receive
308  handler. If no receive handler is registered, drop the packet */
309 
310  AddrFile = AddrSearchFirst(DstAddress,
311  0,
312  IPv4Header->Protocol,
313  &SearchContext);
314  if (AddrFile) {
315  do {
316  DGDeliverData(AddrFile,
317  SrcAddress,
318  DstAddress,
319  0,
320  0,
321  IPPacket,
322  DataSize);
323  DereferenceObject(AddrFile);
324  } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
325  } else {
326  /* There are no open address files that will take this datagram */
327  /* FIXME: IPv4 only */
328  TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 raw datagram to address (0x%X).\n",
329  DN2H(DstAddress->Address.IPv4Address)));
330 
331  /* FIXME: Send ICMP reply */
332  }
333  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
334 }
335 
336 
338 /*
339  * FUNCTION: Initializes the UDP subsystem
340  * RETURNS:
341  * Status of operation
342  */
343 {
344 #ifdef __NTDRIVER__
346 #endif
347 
348  /* Register this protocol with IP layer */
350 
351  return STATUS_SUCCESS;
352 }
353 
354 
356 /*
357  * FUNCTION: Shuts down the UDP subsystem
358  * RETURNS:
359  * Status of operation
360  */
361 {
362  /* Deregister this protocol with IP layer */
364 
365  return STATUS_SUCCESS;
366 }
367 
368 /* EOF */
BOOLEAN AddrIsUnspecified(PIP_ADDRESS Address)
Definition: address.c:113
signed char * PCHAR
Definition: retypes.h:7
#define TI_DbgPrint(_t_, _x_)
Definition: debug.h:45
NTSTATUS BuildRawIpPacket(PADDRESS_FILE AddrFile, PIP_PACKET Packet, PIP_ADDRESS RemoteAddress, USHORT RemotePort, PIP_ADDRESS LocalAddress, USHORT LocalPort, PCHAR DataBuffer, UINT DataLen)
Definition: rawip.c:86
IPv4_RAW_ADDRESS IPv4Address
Definition: ip.h:26
#define DISPLAY_IP_PACKET(x)
Definition: routines.h:69
#define MID_TRACE
Definition: debug.h:15
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
UCHAR TTL
Definition: titypes.h:122
Definition: neighbor.h:28
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
union IP_ADDRESS::@974 Address
void GetDataPtr(PNDIS_PACKET Packet, UINT Offset, PCHAR *DataOut, PUINT Size)
Definition: routines.c:65
NTSTATUS RawIPStartup(VOID)
Definition: rawip.c:337
struct _TA_ADDRESS_IP * PTA_IP_ADDRESS
IP_ADDRESS SrcAddr
Definition: ip.h:89
LONG NTSTATUS
Definition: precomp.h:26
USHORT Protocol
Definition: titypes.h:119
_In_ USHORT _In_ ULONG Protocol
Definition: wsk.h:182
#define WH2N(w)
Definition: addrconv.c:40
PNEIGHBOR_CACHE_ENTRY RouteGetRouteToDestination(PIP_ADDRESS Destination)
Definition: router.c:300
PNEIGHBOR_CACHE_ENTRY NBLocateNeighbor(PIP_ADDRESS Address, PIP_INTERFACE Interface)
Definition: neighbor.c:417
NTSTATUS RawIPSendDatagram(PADDRESS_FILE AddrFile, PTDI_CONNECTION_INFORMATION ConnInfo, PCHAR BufferData, ULONG DataSize, PULONG DataUsed)
Definition: rawip.c:171
VOID DGDeliverData(PADDRESS_FILE AddrFile, PIP_ADDRESS SrcAddress, PIP_ADDRESS DstAddress, USHORT SrcPort, USHORT DstPort, PIP_PACKET IPPacket, UINT DataSize)
Definition: datagram.c:52
VOID IPRegisterProtocol(UINT ProtocolNumber, IP_PROTOCOL_HANDLER Handler)
Definition: ip.c:390
#define DereferenceObject(Object)
Definition: titypes.h:24
struct _tagIPv4Header IPv4Header
PVOID Data
Definition: ip.h:85
Definition: ip.h:23
PADDRESS_FILE AddrSearchFirst(PIP_ADDRESS Address, USHORT Port, USHORT Protocol, PAF_SEARCH SearchContext)
Definition: fileobjs.c:38
NTSTATUS AddGenericHeaderIPv4(PADDRESS_FILE AddrFile, PIP_ADDRESS RemoteAddress, USHORT RemotePort, PIP_ADDRESS LocalAddress, USHORT LocalPort, PIP_PACKET IPPacket, UINT DataLength, UINT Protocol, UINT ExtraLength, PVOID *NextHeader)
Definition: rawip.c:13
#define IP_ADDRESS_V4
Definition: ip.h:32
PIP_PACKET IPInitializePacket(PIP_PACKET IPPacket, ULONG Type)
Definition: ip.c:92
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE)
Definition: transmit.c:223
#define AllocatePacketWithBuffer(x, y, z)
Definition: memtrack.h:7
PVOID Header
Definition: ip.h:83
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1437
struct _TA_ADDRESS_IP::_AddrIp Address[1]
#define IP_ADDRESS_V6
Definition: ip.h:33
struct IPv4_HEADER IPv4_HEADER
#define IP_PACKET_FLAG_RAW
Definition: ip.h:93
#define PCHAR
Definition: match.c:90
Status
Definition: gdiplustypes.h:24
UINT Random(VOID)
Definition: routines.c:16
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UINT TotalSize
Definition: ip.h:86
UCHAR Type
Definition: ip.h:79
VOID RawIpReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
Definition: rawip.c:266
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
UINT HeaderSize
Definition: ip.h:84
#define TDI_ADDRESS_TYPE_IP
Definition: tdi.h:345
UDP_STATISTICS UDPStats
Definition: main.c:26
PADDRESS_FILE AddrSearchNext(PAF_SEARCH SearchContext)
Definition: fileobjs.c:231
#define UnlockObject(Object)
Definition: titypes.h:44
#define MAX_TRACE
Definition: debug.h:16
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:361
unsigned short USHORT
Definition: pedump.c:61
IP_ADDRESS Address
Definition: titypes.h:117
#define DN2H(dw)
Definition: addrconv.c:21
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
PNDIS_PACKET NdisPacket
Definition: ip.h:88
Definition: ip.h:37
BOOLEAN MappedHeader
Definition: ip.h:81
NTSTATUS RawIPShutdown(VOID)
Definition: rawip.c:355
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MIN_TRACE
Definition: debug.h:14
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
IP_ADDRESS DstAddr
Definition: ip.h:90
Definition: ip.h:77
USHORT Port
Definition: titypes.h:120
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NETWORK_UNREACHABLE
Definition: ntstatus.h:704
struct IPv4_HEADER * PIPv4_HEADER
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
#define BufferSize
Definition: mmc.h:75
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:251
_Must_inspect_result_ _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR RemoteAddress
Definition: wsk.h:170
PCHAR A2S(PIP_ADDRESS Address)
Definition: address.c:17
_Must_inspect_result_ _In_ ULONG _In_ PSOCKADDR LocalAddress
Definition: wsk.h:170
#define LockObject(Object)
Definition: titypes.h:34