Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenrawip.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
1.7.6.1
|