2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: transport/rawip/rawip.c
5 * PURPOSE: Raw IP routines
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
18 BOOLEAN RawIPInitialized = FALSE;
21 NTSTATUS BuildRawIPPacket(
23 PIP_ADDRESS LocalAddress,
27 * FUNCTION: Builds an UDP packet
29 * Context = Pointer to context information (DATAGRAM_SEND_REQUEST)
30 * LocalAddress = Pointer to our local address (NULL)
31 * LocalPort = The port we send this datagram from (0)
32 * IPPacket = Address of pointer to IP packet
39 NDIS_STATUS NdisStatus;
40 PNDIS_BUFFER HeaderBuffer;
41 PDATAGRAM_SEND_REQUEST SendRequest = (PDATAGRAM_SEND_REQUEST)Context;
43 TI_DbgPrint(MAX_TRACE, ("TCPIP.SYS: NDIS data buffer is at (0x%X).\n", SendRequest->Buffer));
44 TI_DbgPrint(MAX_TRACE, ("NDIS data buffer Next is at (0x%X).\n", SendRequest->Buffer->Next));
45 TI_DbgPrint(MAX_TRACE, ("NDIS data buffer Size is (0x%X).\n", SendRequest->Buffer->Size));
46 TI_DbgPrint(MAX_TRACE, ("NDIS data buffer MappedSystemVa is (0x%X).\n", SendRequest->Buffer->MappedSystemVa));
47 TI_DbgPrint(MAX_TRACE, ("NDIS data buffer StartVa is (0x%X).\n", SendRequest->Buffer->StartVa));
48 TI_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteCount is (0x%X).\n", SendRequest->Buffer->ByteCount));
49 TI_DbgPrint(MAX_TRACE, ("NDIS data buffer ByteOffset is (0x%X).\n", SendRequest->Buffer->ByteOffset));
53 /* FIXME: Assumes IPv4 */
54 Packet = IPCreatePacket(IP_ADDRESS_V4);
56 return STATUS_INSUFFICIENT_RESOURCES;
58 Packet->Flags = IP_PACKET_FLAG_RAW; /* Don't touch IP header */
59 Packet->TotalSize = SendRequest->BufferSize;
61 /* Allocate NDIS packet */
62 NdisAllocatePacket(&NdisStatus, &Packet->NdisPacket, GlobalPacketPool);
63 if (NdisStatus != NDIS_STATUS_SUCCESS) {
64 TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS packet. NdisStatus = (0x%X)\n", NdisStatus))
65 (*Packet->Free)(Packet);
66 return STATUS_INSUFFICIENT_RESOURCES;
69 if (MaxLLHeaderSize != 0) {
70 Header = ExAllocatePool(NonPagedPool, MaxLLHeaderSize);
72 TI_DbgPrint(MIN_TRACE, ("Cannot allocate memory for packet headers.\n"));
73 NdisFreePacket(Packet->NdisPacket);
74 (*Packet->Free)(Packet);
75 return STATUS_INSUFFICIENT_RESOURCES;
78 TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n",
79 MaxLLHeaderSize, Header));
81 /* Allocate NDIS buffer for maximum link level header */
82 NdisAllocateBuffer(&NdisStatus,
87 if (NdisStatus != NDIS_STATUS_SUCCESS) {
88 TI_DbgPrint(MIN_TRACE, ("Cannot allocate NDIS buffer for packet headers. NdisStatus = (0x%X)\n", NdisStatus));
90 NdisFreePacket(Packet->NdisPacket);
91 (*Packet->Free)(Packet);
92 return STATUS_INSUFFICIENT_RESOURCES;
94 /* Chain header at front of packet */
95 NdisChainBufferAtFront(Packet->NdisPacket, HeaderBuffer);
98 /* Chain data after link level header if it exists */
99 NdisChainBufferAtBack(Packet->NdisPacket, SendRequest->Buffer);
101 DISPLAY_IP_PACKET(Packet);
105 return STATUS_SUCCESS;
109 NTSTATUS RawIPSendDatagram(
110 PTDI_REQUEST Request,
111 PTDI_CONNECTION_INFORMATION ConnInfo,
115 * FUNCTION: Sends a raw IP datagram to a remote address
117 * Request = Pointer to TDI request
118 * ConnInfo = Pointer to connection information
119 * Buffer = Pointer to NDIS buffer with data
120 * DataSize = Size in bytes of data to be sent
122 * Status of operation
125 return DGSendDatagram(Request, ConnInfo,
126 Buffer, DataSize, BuildRawIPPacket);
131 PNET_TABLE_ENTRY NTE,
134 * FUNCTION: Receives and queues a raw IP datagram
136 * NTE = Pointer to net table entry which the packet was received on
137 * IPPacket = Pointer to an IP packet that was received
139 * This is the low level interface for receiving ICMP datagrams.
140 * It delivers the packet header and data to anyone that wants it
141 * When we get here the datagram has already passed sanity checks
144 AF_SEARCH SearchContext;
145 PADDRESS_FILE AddrFile;
146 PIP_ADDRESS DstAddress;
148 TI_DbgPrint(MAX_TRACE, ("Called.\n"));
150 switch (IPPacket->Type) {
153 DstAddress = &IPPacket->DstAddr;
158 TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 raw IP datagram (%i bytes).\n",
159 IPPacket->TotalSize));
161 /* FIXME: IPv6 is not supported */
168 /* Locate a receive request on destination address file object
169 and deliver the packet if one is found. If there is no receive
170 request on the address file object, call the associated receive
171 handler. If no receive handler is registered, drop the packet */
173 AddrFile = AddrSearchFirst(DstAddress,
179 DGDeliverData(AddrFile,
182 IPPacket->TotalSize);
183 } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
185 /* There are no open address files that will take this datagram */
186 /* FIXME: IPv4 only */
187 TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 ICMP datagram to address (0x%X).\n",
188 DN2H(DstAddress->Address.IPv4Address)));
190 TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
194 NTSTATUS RawIPStartup(
197 * FUNCTION: Initializes the Raw IP subsystem
199 * Status of operation
202 RawIPInitialized = TRUE;
204 return STATUS_SUCCESS;
208 NTSTATUS RawIPShutdown(
211 * FUNCTION: Shuts down the Raw IP subsystem
213 * Status of operation
216 if (!RawIPInitialized)
217 return STATUS_SUCCESS;
219 return STATUS_SUCCESS;