+++ /dev/null
-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS TCP/IP protocol driver
- * FILE: transport/rawip/rawip.c
- * PURPOSE: User Datagram Protocol routines
- * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
- * REVISIONS:
- * CSH 01/08-2000 Created
- */
-
-#include "precomp.h"
-
-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 )
-/*
- * FUNCTION: Adds an IPv4 and RawIp header to an IP packet
- * ARGUMENTS:
- * SendRequest = Pointer to send request
- * LocalAddress = Pointer to our local address
- * LocalPort = The port we send this datagram from
- * IPPacket = Pointer to IP packet
- * RETURNS:
- * Status of operation
- */
-{
- PIPv4_HEADER IPHeader;
- ULONG BufferSize;
-
- TI_DbgPrint(MID_TRACE, ("Packet: %x NdisPacket %x\n",
- IPPacket, IPPacket->NdisPacket));
-
- BufferSize = sizeof(IPv4_HEADER) + ExtraLength;
-
- GetDataPtr( IPPacket->NdisPacket,
- 0,
- (PCHAR *)&IPPacket->Header,
- &IPPacket->TotalSize );
- IPPacket->MappedHeader = TRUE;
-
- IPPacket->HeaderSize = sizeof(IPv4_HEADER);
-
- TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n",
- BufferSize, IPPacket->Header));
- TI_DbgPrint(MAX_TRACE, ("Packet total length %d\n", IPPacket->TotalSize));
-
- /* Build IPv4 header */
- IPHeader = (PIPv4_HEADER)IPPacket->Header;
- /* Version = 4, Length = 5 DWORDs */
- IPHeader->VerIHL = 0x45;
- /* Normal Type-of-Service */
- IPHeader->Tos = 0;
- /* Length of header and data */
- IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize);
- /* Identification */
- IPHeader->Id = (USHORT)Random();
- /* One fragment at offset 0 */
- IPHeader->FlagsFragOfs = 0;
- /* Time-to-Live */
- IPHeader->Ttl = AddrFile->TTL;
- /* Protocol */
- IPHeader->Protocol = Protocol;
- /* Checksum is 0 (for later calculation of this) */
- IPHeader->Checksum = 0;
- /* Source address */
- IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
- /* Destination address. FIXME: IPv4 only */
- IPHeader->DstAddr = RemoteAddress->Address.IPv4Address;
-
- /* Build RawIp header */
- *NextHeader = (((PCHAR)IPHeader) + sizeof(IPv4_HEADER));
- IPPacket->Data = ((PCHAR)*NextHeader) + ExtraLength;
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS BuildRawIpPacket(
- PADDRESS_FILE AddrFile,
- PIP_PACKET Packet,
- PIP_ADDRESS RemoteAddress,
- USHORT RemotePort,
- PIP_ADDRESS LocalAddress,
- USHORT LocalPort,
- PCHAR DataBuffer,
- UINT DataLen )
-/*
- * FUNCTION: Builds an RawIp packet
- * ARGUMENTS:
- * Context = Pointer to context information (DATAGRAM_SEND_REQUEST)
- * LocalAddress = Pointer to our local address
- * LocalPort = The port we send this datagram from
- * IPPacket = Address of pointer to IP packet
- * RETURNS:
- * Status of operation
- */
-{
- NTSTATUS Status;
- PCHAR Payload;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- /* FIXME: Assumes IPv4 */
- IPInitializePacket(Packet, IP_ADDRESS_V4);
-
- Packet->TotalSize = sizeof(IPv4_HEADER) + DataLen;
-
- /* Prepare packet */
- Status = AllocatePacketWithBuffer( &Packet->NdisPacket,
- NULL,
- Packet->TotalSize );
-
- if( !NT_SUCCESS(Status) ) return Status;
-
- TI_DbgPrint(MID_TRACE, ("Allocated packet: %x\n", Packet->NdisPacket));
- TI_DbgPrint(MID_TRACE, ("Local Addr : %s\n", A2S(LocalAddress)));
- TI_DbgPrint(MID_TRACE, ("Remote Addr: %s\n", A2S(RemoteAddress)));
-
- switch (RemoteAddress->Type) {
- case IP_ADDRESS_V4:
- Status = AddGenericHeaderIPv4
- (AddrFile, RemoteAddress, RemotePort,
- LocalAddress, LocalPort, Packet, DataLen,
- AddrFile->Protocol,
- 0, (PVOID *)&Payload );
- break;
- case IP_ADDRESS_V6:
- /* FIXME: Support IPv6 */
- Status = STATUS_UNSUCCESSFUL;
- TI_DbgPrint(MIN_TRACE, ("IPv6 RawIp datagrams are not supported.\n"));
- break;
-
- default:
- Status = STATUS_UNSUCCESSFUL;
- TI_DbgPrint(MIN_TRACE, ("Bad Address Type %d\n", RemoteAddress->Type));
- break;
- }
-
- if( !NT_SUCCESS(Status) ) {
- TI_DbgPrint(MIN_TRACE, ("Cannot add header. Status = (0x%X)\n",
- Status));
- Packet->Free(Packet);
- return Status;
- }
-
- TI_DbgPrint(MID_TRACE, ("Copying data (hdr %x data %x (%d))\n",
- Packet->Header, Packet->Data,
- (PCHAR)Packet->Data - (PCHAR)Packet->Header));
-
- RtlCopyMemory( Packet->Data, DataBuffer, DataLen );
-
- Packet->Flags |= IP_PACKET_FLAG_RAW;
-
- TI_DbgPrint(MID_TRACE, ("Displaying packet\n"));
-
- DISPLAY_IP_PACKET(Packet);
-
- TI_DbgPrint(MID_TRACE, ("Leaving\n"));
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS RawIPSendDatagram(
- PADDRESS_FILE AddrFile,
- PTDI_CONNECTION_INFORMATION ConnInfo,
- PCHAR BufferData,
- ULONG DataSize,
- PULONG DataUsed )
-/*
- * FUNCTION: Sends an RawIp datagram to a remote address
- * ARGUMENTS:
- * Request = Pointer to TDI request
- * ConnInfo = Pointer to connection information
- * Buffer = Pointer to NDIS buffer with data
- * DataSize = Size in bytes of data to be sent
- * RETURNS:
- * Status of operation
- */
-{
- IP_PACKET Packet;
- PTA_IP_ADDRESS RemoteAddressTa = (PTA_IP_ADDRESS)ConnInfo->RemoteAddress;
- IP_ADDRESS RemoteAddress, LocalAddress;
- USHORT RemotePort;
- NTSTATUS Status;
- PNEIGHBOR_CACHE_ENTRY NCE;
-
- LockObject(AddrFile);
-
- TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
- AddrFile, ConnInfo, BufferData, DataSize));
- TI_DbgPrint(MID_TRACE,("RemoteAddressTa: %x\n", RemoteAddressTa));
-
- switch( RemoteAddressTa->Address[0].AddressType ) {
- case TDI_ADDRESS_TYPE_IP:
- RemoteAddress.Type = IP_ADDRESS_V4;
- RemoteAddress.Address.IPv4Address =
- RemoteAddressTa->Address[0].Address[0].in_addr;
- RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port;
- break;
-
- default:
- UnlockObject(AddrFile);
- return STATUS_UNSUCCESSFUL;
- }
-
- TI_DbgPrint(MID_TRACE,("About to get route to destination\n"));
-
- LocalAddress = AddrFile->Address;
- if (AddrIsUnspecified(&LocalAddress))
- {
- /* If the local address is unspecified (0),
- * then use the unicast address of the
- * interface we're sending over
- */
- if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
- UnlockObject(AddrFile);
- return STATUS_NETWORK_UNREACHABLE;
- }
-
- LocalAddress = NCE->Interface->Unicast;
- }
- else
- {
- if(!(NCE = NBLocateNeighbor( &LocalAddress, NULL ))) {
- UnlockObject(AddrFile);
- return STATUS_INVALID_PARAMETER;
- }
- }
-
- Status = BuildRawIpPacket( AddrFile,
- &Packet,
- &RemoteAddress,
- RemotePort,
- &LocalAddress,
- AddrFile->Port,
- BufferData,
- DataSize );
-
- UnlockObject(AddrFile);
-
- if( !NT_SUCCESS(Status) )
- return Status;
-
- TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
-
- Status = IPSendDatagram(&Packet, NCE);
- if (!NT_SUCCESS(Status))
- return Status;
-
- *DataUsed = DataSize;
-
- TI_DbgPrint(MID_TRACE,("Leaving\n"));
-
- return STATUS_SUCCESS;
-}
-
-
-VOID RawIpReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
-/*
- * FUNCTION: Receives and queues a RawIp datagram
- * ARGUMENTS:
- * NTE = Pointer to net table entry which the packet was received on
-* IPPacket = Pointer to an IP packet that was received
-* NOTES:
-* This is the low level interface for receiving RawIp datagrams. It strips
-* the RawIp header from a packet and delivers the data to anyone that wants it
-*/
-{
- AF_SEARCH SearchContext;
- PIPv4_HEADER IPv4Header;
- PADDRESS_FILE AddrFile;
- PIP_ADDRESS DstAddress, SrcAddress;
- UINT DataSize;
-
- TI_DbgPrint(MAX_TRACE, ("Called.\n"));
-
- switch (IPPacket->Type) {
- /* IPv4 packet */
- case IP_ADDRESS_V4:
- IPv4Header = IPPacket->Header;
- DstAddress = &IPPacket->DstAddr;
- SrcAddress = &IPPacket->SrcAddr;
- DataSize = IPPacket->TotalSize;
- break;
-
- /* IPv6 packet */
- case IP_ADDRESS_V6:
- TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 datagram (%i bytes).\n", IPPacket->TotalSize));
-
- /* FIXME: IPv6 is not supported */
- return;
-
- default:
- return;
- }
-
- /* Locate a receive request on destination address file object
- and deliver the packet if one is found. If there is no receive
- request on the address file object, call the associated receive
- handler. If no receive handler is registered, drop the packet */
-
- AddrFile = AddrSearchFirst(DstAddress,
- 0,
- IPv4Header->Protocol,
- &SearchContext);
- if (AddrFile) {
- do {
- DGDeliverData(AddrFile,
- SrcAddress,
- DstAddress,
- 0,
- 0,
- IPPacket,
- DataSize);
- DereferenceObject(AddrFile);
- } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
- } else {
- /* There are no open address files that will take this datagram */
- /* FIXME: IPv4 only */
- TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 raw datagram to address (0x%X).\n",
- DN2H(DstAddress->Address.IPv4Address)));
-
- /* FIXME: Send ICMP reply */
- }
- TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
-}
-
-
-NTSTATUS RawIPStartup(VOID)
-/*
- * FUNCTION: Initializes the UDP subsystem
- * RETURNS:
- * Status of operation
- */
-{
- RtlZeroMemory(&UDPStats, sizeof(UDP_STATISTICS));
-
- /* Register this protocol with IP layer */
- IPRegisterProtocol(IPPROTO_RAW, RawIpReceive);
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS RawIPShutdown(VOID)
-/*
- * FUNCTION: Shuts down the UDP subsystem
- * RETURNS:
- * Status of operation
- */
-{
- /* Deregister this protocol with IP layer */
- IPRegisterProtocol(IPPROTO_RAW, NULL);
-
- return STATUS_SUCCESS;
-}
-
-/* EOF */