ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

rawip.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:   See COPYING in the top level directory
00003  * PROJECT:     ReactOS TCP/IP protocol driver
00004  * FILE:        transport/rawip/rawip.c
00005  * PURPOSE:     User Datagram Protocol routines
00006  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
00007  * REVISIONS:
00008  *   CSH 01/08-2000 Created
00009  */
00010 
00011 #include "precomp.h"
00012 
00013 NTSTATUS AddGenericHeaderIPv4(
00014     PADDRESS_FILE AddrFile,
00015     PIP_ADDRESS RemoteAddress,
00016     USHORT RemotePort,
00017     PIP_ADDRESS LocalAddress,
00018     USHORT LocalPort,
00019     PIP_PACKET IPPacket,
00020     UINT DataLength,
00021     UINT Protocol,
00022     UINT ExtraLength,
00023     PVOID *NextHeader )
00024 /*
00025  * FUNCTION: Adds an IPv4 and RawIp header to an IP packet
00026  * ARGUMENTS:
00027  *     SendRequest  = Pointer to send request
00028  *     LocalAddress = Pointer to our local address
00029  *     LocalPort    = The port we send this datagram from
00030  *     IPPacket     = Pointer to IP packet
00031  * RETURNS:
00032  *     Status of operation
00033  */
00034 {
00035     PIPv4_HEADER IPHeader;
00036     ULONG BufferSize;
00037 
00038     TI_DbgPrint(MID_TRACE, ("Packet: %x NdisPacket %x\n",
00039                 IPPacket, IPPacket->NdisPacket));
00040 
00041     BufferSize = sizeof(IPv4_HEADER) + ExtraLength;
00042 
00043     GetDataPtr( IPPacket->NdisPacket,
00044         0,
00045         (PCHAR *)&IPPacket->Header,
00046         &IPPacket->TotalSize );
00047     IPPacket->MappedHeader = TRUE;
00048 
00049     IPPacket->HeaderSize = 20;
00050 
00051     TI_DbgPrint(MAX_TRACE, ("Allocated %d bytes for headers at 0x%X.\n",
00052                 BufferSize, IPPacket->Header));
00053     TI_DbgPrint(MAX_TRACE, ("Packet total length %d\n", IPPacket->TotalSize));
00054 
00055     /* Build IPv4 header */
00056     IPHeader = (PIPv4_HEADER)IPPacket->Header;
00057     /* Version = 4, Length = 5 DWORDs */
00058     IPHeader->VerIHL = 0x45;
00059     /* Normal Type-of-Service */
00060     IPHeader->Tos = 0;
00061     /* Length of header and data */
00062     IPHeader->TotalLength = WH2N((USHORT)IPPacket->TotalSize);
00063     /* Identification */
00064     IPHeader->Id = (USHORT)Random();
00065     /* One fragment at offset 0 */
00066     IPHeader->FlagsFragOfs = 0;
00067     /* Time-to-Live */
00068     IPHeader->Ttl = AddrFile->TTL;
00069     /* Protocol */
00070     IPHeader->Protocol = Protocol;
00071     /* Checksum is 0 (for later calculation of this) */
00072     IPHeader->Checksum = 0;
00073     /* Source address */
00074     IPHeader->SrcAddr = LocalAddress->Address.IPv4Address;
00075     /* Destination address. FIXME: IPv4 only */
00076     IPHeader->DstAddr = RemoteAddress->Address.IPv4Address;
00077 
00078     /* Build RawIp header */
00079     *NextHeader = (((PCHAR)IPHeader) + sizeof(IPv4_HEADER));
00080     IPPacket->Data = ((PCHAR)*NextHeader) + ExtraLength;
00081 
00082     return STATUS_SUCCESS;
00083 }
00084 
00085 
00086 NTSTATUS BuildRawIpPacket(
00087     PADDRESS_FILE AddrFile,
00088     PIP_PACKET Packet,
00089     PIP_ADDRESS RemoteAddress,
00090     USHORT RemotePort,
00091     PIP_ADDRESS LocalAddress,
00092     USHORT LocalPort,
00093     PCHAR DataBuffer,
00094     UINT DataLen )
00095 /*
00096  * FUNCTION: Builds an RawIp packet
00097  * ARGUMENTS:
00098  *     Context      = Pointer to context information (DATAGRAM_SEND_REQUEST)
00099  *     LocalAddress = Pointer to our local address
00100  *     LocalPort    = The port we send this datagram from
00101  *     IPPacket     = Address of pointer to IP packet
00102  * RETURNS:
00103  *     Status of operation
00104  */
00105 {
00106     NTSTATUS Status;
00107     PCHAR Payload;
00108 
00109     TI_DbgPrint(MAX_TRACE, ("Called.\n"));
00110 
00111     /* FIXME: Assumes IPv4 */
00112     IPInitializePacket(Packet, IP_ADDRESS_V4);
00113 
00114     Packet->TotalSize = sizeof(IPv4_HEADER) + DataLen;
00115 
00116     /* Prepare packet */
00117     Status = AllocatePacketWithBuffer( &Packet->NdisPacket,
00118                        NULL,
00119                        Packet->TotalSize );
00120 
00121     if( !NT_SUCCESS(Status) ) return Status;
00122 
00123     TI_DbgPrint(MID_TRACE, ("Allocated packet: %x\n", Packet->NdisPacket));
00124     TI_DbgPrint(MID_TRACE, ("Local Addr : %s\n", A2S(LocalAddress)));
00125     TI_DbgPrint(MID_TRACE, ("Remote Addr: %s\n", A2S(RemoteAddress)));
00126 
00127     switch (RemoteAddress->Type) {
00128     case IP_ADDRESS_V4:
00129     Status = AddGenericHeaderIPv4
00130             (AddrFile, RemoteAddress, RemotePort,
00131              LocalAddress, LocalPort, Packet, DataLen,
00132              AddrFile->Protocol,
00133              0, (PVOID *)&Payload );
00134     break;
00135     case IP_ADDRESS_V6:
00136     /* FIXME: Support IPv6 */
00137         Status = STATUS_UNSUCCESSFUL;
00138     TI_DbgPrint(MIN_TRACE, ("IPv6 RawIp datagrams are not supported.\n"));
00139         break;
00140 
00141     default:
00142     Status = STATUS_UNSUCCESSFUL;
00143         TI_DbgPrint(MIN_TRACE, ("Bad Address Type %d\n", RemoteAddress->Type));
00144     break;
00145     }
00146 
00147     if( !NT_SUCCESS(Status) ) {
00148         TI_DbgPrint(MIN_TRACE, ("Cannot add header. Status = (0x%X)\n",
00149                                 Status));
00150         Packet->Free(Packet);
00151         return Status;
00152     }
00153 
00154     TI_DbgPrint(MID_TRACE, ("Copying data (hdr %x data %x (%d))\n",
00155                 Packet->Header, Packet->Data,
00156                 (PCHAR)Packet->Data - (PCHAR)Packet->Header));
00157 
00158     RtlCopyMemory( Packet->Data, DataBuffer, DataLen );
00159 
00160     Packet->Flags |= IP_PACKET_FLAG_RAW;
00161 
00162     TI_DbgPrint(MID_TRACE, ("Displaying packet\n"));
00163 
00164     DISPLAY_IP_PACKET(Packet);
00165 
00166     TI_DbgPrint(MID_TRACE, ("Leaving\n"));
00167 
00168     return STATUS_SUCCESS;
00169 }
00170 
00171 NTSTATUS RawIPSendDatagram(
00172     PADDRESS_FILE AddrFile,
00173     PTDI_CONNECTION_INFORMATION ConnInfo,
00174     PCHAR BufferData,
00175     ULONG DataSize,
00176     PULONG DataUsed )
00177 /*
00178  * FUNCTION: Sends an RawIp datagram to a remote address
00179  * ARGUMENTS:
00180  *     Request   = Pointer to TDI request
00181  *     ConnInfo  = Pointer to connection information
00182  *     Buffer    = Pointer to NDIS buffer with data
00183  *     DataSize  = Size in bytes of data to be sent
00184  * RETURNS:
00185  *     Status of operation
00186  */
00187 {
00188     IP_PACKET Packet;
00189     PTA_IP_ADDRESS RemoteAddressTa = (PTA_IP_ADDRESS)ConnInfo->RemoteAddress;
00190     IP_ADDRESS RemoteAddress,  LocalAddress;
00191     USHORT RemotePort;
00192     NTSTATUS Status;
00193     PNEIGHBOR_CACHE_ENTRY NCE;
00194     KIRQL OldIrql;
00195 
00196     LockObject(AddrFile, &OldIrql);
00197 
00198     TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n",
00199                AddrFile, ConnInfo, BufferData, DataSize));
00200     TI_DbgPrint(MID_TRACE,("RemoteAddressTa: %x\n", RemoteAddressTa));
00201 
00202     switch( RemoteAddressTa->Address[0].AddressType ) {
00203         case TDI_ADDRESS_TYPE_IP:
00204             RemoteAddress.Type = IP_ADDRESS_V4;
00205             RemoteAddress.Address.IPv4Address =
00206             RemoteAddressTa->Address[0].Address[0].in_addr;
00207             RemotePort = RemoteAddressTa->Address[0].Address[0].sin_port;
00208             break;
00209 
00210         default:
00211             UnlockObject(AddrFile, OldIrql);
00212             return STATUS_UNSUCCESSFUL;
00213     }
00214 
00215     TI_DbgPrint(MID_TRACE,("About to get route to destination\n"));
00216 
00217     LocalAddress = AddrFile->Address;
00218     if (AddrIsUnspecified(&LocalAddress))
00219     {
00220         /* If the local address is unspecified (0),
00221          * then use the unicast address of the
00222          * interface we're sending over
00223          */
00224         if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
00225             UnlockObject(AddrFile, OldIrql);
00226             return STATUS_NETWORK_UNREACHABLE;
00227         }
00228 
00229         LocalAddress = NCE->Interface->Unicast;
00230     }
00231     else
00232     {
00233         if(!(NCE = NBLocateNeighbor( &LocalAddress ))) {
00234             UnlockObject(AddrFile, OldIrql);
00235             return STATUS_INVALID_PARAMETER;
00236         }
00237     }
00238 
00239     Status = BuildRawIpPacket( AddrFile,
00240                                &Packet,
00241                                &RemoteAddress,
00242                                RemotePort,
00243                                &LocalAddress,
00244                                AddrFile->Port,
00245                                BufferData,
00246                                DataSize );
00247 
00248     UnlockObject(AddrFile, OldIrql);
00249 
00250     if( !NT_SUCCESS(Status) )
00251         return Status;
00252 
00253     TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
00254 
00255     Status = IPSendDatagram(&Packet, NCE);
00256     if (!NT_SUCCESS(Status))
00257         return Status;
00258 
00259     *DataUsed = DataSize;
00260 
00261     TI_DbgPrint(MID_TRACE,("Leaving\n"));
00262 
00263     return STATUS_SUCCESS;
00264 }
00265 
00266 
00267 VOID RawIpReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
00268 /*
00269  * FUNCTION: Receives and queues a RawIp datagram
00270  * ARGUMENTS:
00271  *     NTE      = Pointer to net table entry which the packet was received on
00272 *     IPPacket = Pointer to an IP packet that was received
00273 * NOTES:
00274 *     This is the low level interface for receiving RawIp datagrams. It strips
00275 *     the RawIp header from a packet and delivers the data to anyone that wants it
00276 */
00277 {
00278   AF_SEARCH SearchContext;
00279   PIPv4_HEADER IPv4Header;
00280   PADDRESS_FILE AddrFile;
00281   PIP_ADDRESS DstAddress, SrcAddress;
00282   UINT DataSize;
00283 
00284   TI_DbgPrint(MAX_TRACE, ("Called.\n"));
00285 
00286   switch (IPPacket->Type) {
00287   /* IPv4 packet */
00288   case IP_ADDRESS_V4:
00289     IPv4Header = IPPacket->Header;
00290     DstAddress = &IPPacket->DstAddr;
00291     SrcAddress = &IPPacket->SrcAddr;
00292     DataSize = IPPacket->TotalSize;
00293     break;
00294 
00295   /* IPv6 packet */
00296   case IP_ADDRESS_V6:
00297     TI_DbgPrint(MIN_TRACE, ("Discarded IPv6 datagram (%i bytes).\n", IPPacket->TotalSize));
00298 
00299     /* FIXME: IPv6 is not supported */
00300     return;
00301 
00302   default:
00303     return;
00304   }
00305 
00306   /* Locate a receive request on destination address file object
00307      and deliver the packet if one is found. If there is no receive
00308      request on the address file object, call the associated receive
00309      handler. If no receive handler is registered, drop the packet */
00310 
00311   AddrFile = AddrSearchFirst(DstAddress,
00312                              0,
00313                              IPv4Header->Protocol,
00314                              &SearchContext);
00315   if (AddrFile) {
00316     do {
00317       DGDeliverData(AddrFile,
00318             SrcAddress,
00319                     DstAddress,
00320                     0,
00321                     0,
00322                     IPPacket,
00323                     DataSize);
00324     } while ((AddrFile = AddrSearchNext(&SearchContext)) != NULL);
00325   } else {
00326     /* There are no open address files that will take this datagram */
00327     /* FIXME: IPv4 only */
00328     TI_DbgPrint(MID_TRACE, ("Cannot deliver IPv4 raw datagram to address (0x%X).\n",
00329                             DN2H(DstAddress->Address.IPv4Address)));
00330 
00331     /* FIXME: Send ICMP reply */
00332   }
00333   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
00334 }
00335 
00336 
00337 NTSTATUS RawIPStartup(VOID)
00338 /*
00339  * FUNCTION: Initializes the UDP subsystem
00340  * RETURNS:
00341  *     Status of operation
00342  */
00343 {
00344 #ifdef __NTDRIVER__
00345   RtlZeroMemory(&UDPStats, sizeof(UDP_STATISTICS));
00346 #endif
00347 
00348   /* Register this protocol with IP layer */
00349   IPRegisterProtocol(IPPROTO_RAW, RawIpReceive);
00350 
00351   return STATUS_SUCCESS;
00352 }
00353 
00354 
00355 NTSTATUS RawIPShutdown(VOID)
00356 /*
00357  * FUNCTION: Shuts down the UDP subsystem
00358  * RETURNS:
00359  *     Status of operation
00360  */
00361 {
00362   /* Deregister this protocol with IP layer */
00363   IPRegisterProtocol(IPPROTO_RAW, NULL);
00364 
00365   return STATUS_SUCCESS;
00366 }
00367 
00368 /* EOF */

Generated on Mon May 28 2012 04:35:47 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.