ReactOS  0.4.14-dev-554-g2f8d847
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 {
35  PIPv4_HEADER IPHeader;
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 = 20;
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  KIRQL OldIrql;
195 
196  LockObject(AddrFile, &OldIrql);
197 
198  TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
199  AddrFile, ConnInfo, BufferData, DataSize));
200  TI_DbgPrint(MID_TRACE,("RemoteAddressTa: %x\n", RemoteAddressTa));
201 
202  switch( RemoteAddressTa->Address[0].AddressType ) {
203  case TDI_ADDRESS_TYPE_IP:
205  RemoteAddress.Address.IPv4Address =
206  RemoteAddressTa->Address[0].Address[0].in_addr;
207  RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port;
208  break;
209 
210  default:
211  UnlockObject(AddrFile, OldIrql);
212  return STATUS_UNSUCCESSFUL;
213  }
214 
215  TI_DbgPrint(MID_TRACE,("About to get route to destination\n"));
216 
217  LocalAddress = AddrFile->Address;
219  {
220  /* If the local address is unspecified (0),
221  * then use the unicast address of the
222  * interface we're sending over
223  */
224  if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
225  UnlockObject(AddrFile, OldIrql);
227  }
228 
229  LocalAddress = NCE->Interface->Unicast;
230  }
231  else
232  {
233  if(!(NCE = NBLocateNeighbor( &LocalAddress, NULL ))) {
234  UnlockObject(AddrFile, OldIrql);
236  }
237  }
238 
239  Status = BuildRawIpPacket( AddrFile,
240  &Packet,
241  &RemoteAddress,
242  RemotePort,
243  &LocalAddress,
244  AddrFile->Port,
245  BufferData,
246  DataSize );
247 
248  UnlockObject(AddrFile, OldIrql);
249 
250  if( !NT_SUCCESS(Status) )
251  return Status;
252 
253  TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
254 
255  Status = IPSendDatagram(&Packet, NCE);
256  if (!NT_SUCCESS(Status))
257  return Status;
258 
259  *DataUsed = DataSize;
260 
261  TI_DbgPrint(MID_TRACE,("Leaving\n"));
262 
263  return STATUS_SUCCESS;
264 }
265 
266 
268 /*
269  * FUNCTION: Receives and queues a RawIp datagram
270  * ARGUMENTS:
271  * NTE = Pointer to net table entry which the packet was received on
272 * IPPacket = Pointer to an IP packet that was received
273 * NOTES:
274 * This is the low level interface for receiving RawIp datagrams. It strips
275 * the RawIp header from a packet and delivers the data to anyone that wants it
276 */
277 {
278  AF_SEARCH SearchContext;
279  PIPv4_HEADER IPv4Header;
280  PADDRESS_FILE AddrFile;
281  PIP_ADDRESS DstAddress, SrcAddress;
282  UINT DataSize;
283 
284  TI_DbgPrint(MAX_TRACE, ("Called.\n"));
285 
286  switch (IPPacket->Type) {
287  /* IPv4 packet */
288  case IP_ADDRESS_V4:
289  IPv4Header = IPPacket->Header;
290  DstAddress = &IPPacket->DstAddr;
291  SrcAddress = &IPPacket->SrcAddr;
292  DataSize = IPPacket->TotalSize;
293  break;
294 
295  /* IPv6 packet */
296  case IP_ADDRESS_V6:
297  TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 datagram (%i bytes).\n", IPPacket->TotalSize));
298 
299  /* FIXME: IPv6 is not supported */
300  return;
301 
302  default:
303  return;
304  }
305 
306  /* Locate a receive request on destination address file object
307  and deliver the packet if one is found. If there is no receive
308  request on the address file object, call the associated receive
309  handler. If no receive handler is registered, drop the packet */
310 
311  AddrFile = AddrSearchFirst(DstAddress,
312  0,
313  IPv4Header->Protocol,
314  &SearchContext);
315  if (AddrFile) {
316  do {
317  DGDeliverData(AddrFile,
318  SrcAddress,
319  DstAddress,
320  0,
321  0,
322  IPPacket,
323  DataSize);
324  DereferenceObject(AddrFile);
325  } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
326  } else {
327  /* There are no open address files that will take this datagram */
328  /* FIXME: IPv4 only */
329  TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 raw datagram to address (0x%X).\n",
330  DN2H(DstAddress->Address.IPv4Address)));
331 
332  /* FIXME: Send ICMP reply */
333  }
334  TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
335 }
336 
337 
339 /*
340  * FUNCTION: Initializes the UDP subsystem
341  * RETURNS:
342  * Status of operation
343  */
344 {
345 #ifdef __NTDRIVER__
347 #endif
348 
349  /* Register this protocol with IP layer */
351 
352  return STATUS_SUCCESS;
353 }
354 
355 
357 /*
358  * FUNCTION: Shuts down the UDP subsystem
359  * RETURNS:
360  * Status of operation
361  */
362 {
363  /* Deregister this protocol with IP layer */
365 
366  return STATUS_SUCCESS;
367 }
368 
369 /* 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 TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define MID_TRACE
Definition: debug.h:15
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
UCHAR Tos
Definition: ip.h:39
UCHAR TTL
Definition: titypes.h:141
Definition: neighbor.h:28
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
void GetDataPtr(PNDIS_PACKET Packet, UINT Offset, PCHAR *DataOut, PUINT Size)
Definition: routines.c:65
NTSTATUS RawIPStartup(VOID)
Definition: rawip.c:338
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:138
_In_ USHORT _In_ ULONG Protocol
Definition: wsk.h:182
USHORT TotalLength
Definition: ip.h:40
#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
#define LockObject(Object, Irql)
Definition: titypes.h:34
PVOID Data
Definition: ip.h:85
Definition: ip.h:23
UCHAR KIRQL
Definition: env_spec_w32.h:591
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
USHORT FlagsFragOfs
Definition: ip.h:42
#define IP_ADDRESS_V4
Definition: ip.h:32
PIP_PACKET IPInitializePacket(PIP_PACKET IPPacket, ULONG Type)
Definition: ip.c:92
#define UnlockObject(Object, OldIrql)
Definition: titypes.h:54
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE)
Definition: transmit.c:223
UCHAR VerIHL
Definition: ip.h:38
#define AllocatePacketWithBuffer(x, y, z)
Definition: memtrack.h:7
PVOID Header
Definition: ip.h:83
smooth NULL
Definition: ftsmooth.c:416
struct _TA_ADDRESS_IP::_AddrIp Address[1]
UCHAR Ttl
Definition: ip.h:43
#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
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
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
IPv4_RAW_ADDRESS DstAddr
Definition: ip.h:47
#define BufferSize
Definition: classpnp.h:419
VOID RawIpReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
Definition: rawip.c:267
UCHAR Protocol
Definition: ip.h:44
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
UINT HeaderSize
Definition: ip.h:84
USHORT Checksum
Definition: ip.h:45
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define TDI_ADDRESS_TYPE_IP
Definition: tdi.h:345
UDP_STATISTICS UDPStats
Definition: main.c:26
Status
Definition: gdiplustypes.h:24
PADDRESS_FILE AddrSearchNext(PAF_SEARCH SearchContext)
Definition: fileobjs.c:231
#define MAX_TRACE
Definition: debug.h:16
IPv4_RAW_ADDRESS SrcAddr
Definition: ip.h:46
unsigned short USHORT
Definition: pedump.c:61
IP_ADDRESS Address
Definition: titypes.h:136
#define DN2H(dw)
Definition: addrconv.c:21
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
PNDIS_PACKET NdisPacket
Definition: ip.h:88
Definition: ip.h:37
BOOLEAN MappedHeader
Definition: ip.h:81
NTSTATUS RawIPShutdown(VOID)
Definition: rawip.c:356
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define MIN_TRACE
Definition: debug.h:14
IP_ADDRESS DstAddr
Definition: ip.h:90
Definition: ip.h:77
USHORT Port
Definition: titypes.h:139
USHORT Id
Definition: ip.h:41
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define STATUS_NETWORK_UNREACHABLE
Definition: ntstatus.h:690
struct IPv4_HEADER * PIPv4_HEADER
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4751
union IP_ADDRESS::@990 Address
_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