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

datagram.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/datagram/datagram.c
00005  * PURPOSE:     Routines for sending and receiving datagrams
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 BOOLEAN DGRemoveIRP(
00014     PADDRESS_FILE AddrFile,
00015     PIRP Irp)
00016 {
00017     PLIST_ENTRY ListEntry;
00018     PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
00019     KIRQL OldIrql;
00020     BOOLEAN Found = FALSE;
00021 
00022     TI_DbgPrint(MAX_TRACE, ("Called (Cancel IRP %08x for file %08x).\n",
00023                             Irp, AddrFile));
00024 
00025     LockObject(AddrFile, &OldIrql);
00026 
00027     for( ListEntry = AddrFile->ReceiveQueue.Flink; 
00028          ListEntry != &AddrFile->ReceiveQueue;
00029          ListEntry = ListEntry->Flink )
00030     {
00031         ReceiveRequest = CONTAINING_RECORD
00032             (ListEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
00033 
00034         TI_DbgPrint(MAX_TRACE, ("Request: %08x?\n", ReceiveRequest));
00035 
00036         if (ReceiveRequest->Irp == Irp)
00037         {
00038             RemoveEntryList(&ReceiveRequest->ListEntry);
00039             ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG);
00040             Found = TRUE;
00041             break;
00042         }
00043     }
00044 
00045     UnlockObject(AddrFile, OldIrql);
00046 
00047     TI_DbgPrint(MAX_TRACE, ("Done.\n"));
00048 
00049     return Found;
00050 }
00051 
00052 VOID DGDeliverData(
00053   PADDRESS_FILE AddrFile,
00054   PIP_ADDRESS SrcAddress,
00055   PIP_ADDRESS DstAddress,
00056   USHORT SrcPort,
00057   USHORT DstPort,
00058   PIP_PACKET IPPacket,
00059   UINT DataSize)
00060 /*
00061  * FUNCTION: Delivers datagram data to a user
00062  * ARGUMENTS:
00063  *     AddrFile = Address file to deliver data to
00064  *     Address  = Remote address the packet came from
00065  *     IPPacket = Pointer to IP packet to deliver
00066  *     DataSize = Number of bytes in data area
00067  *                (incl. IP header for raw IP file objects)
00068  * NOTES:
00069  *     If there is a receive request, then we copy the data to the
00070  *     buffer supplied by the user and complete the receive request.
00071  *     If no suitable receive request exists, then we call the event
00072  *     handler if it exists, otherwise we drop the packet.
00073  */
00074 {
00075   KIRQL OldIrql;
00076   PTDI_IND_RECEIVE_DATAGRAM ReceiveHandler;
00077   PVOID HandlerContext;
00078   LONG AddressLength;
00079   PVOID SourceAddress;
00080   ULONG BytesTaken;
00081   NTSTATUS Status;
00082   PVOID DataBuffer;
00083 
00084   TI_DbgPrint(MAX_TRACE, ("Called.\n"));
00085 
00086   LockObject(AddrFile, &OldIrql);
00087 
00088   if (AddrFile->Protocol == IPPROTO_UDP)
00089     {
00090       DataBuffer = IPPacket->Data;
00091     }
00092   else
00093     {
00094       if (AddrFile->HeaderIncl)
00095           DataBuffer = IPPacket->Header;
00096       else
00097       {
00098           DataBuffer = IPPacket->Data;
00099           DataSize -= IPPacket->HeaderSize;
00100       }
00101     }
00102 
00103   if (!IsListEmpty(&AddrFile->ReceiveQueue))
00104     {
00105       PLIST_ENTRY CurrentEntry;
00106       PDATAGRAM_RECEIVE_REQUEST Current = NULL;
00107       PTA_IP_ADDRESS RTAIPAddress;
00108 
00109       TI_DbgPrint(MAX_TRACE, ("There is a receive request.\n"));
00110 
00111       /* Search receive request list to find a match */
00112       CurrentEntry = AddrFile->ReceiveQueue.Flink;
00113       while(CurrentEntry != &AddrFile->ReceiveQueue) {
00114           Current = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry);
00115           CurrentEntry = CurrentEntry->Flink;
00116       if( DstPort == AddrFile->Port &&
00117               (AddrIsEqual(DstAddress, &AddrFile->Address) ||
00118                AddrIsUnspecified(&AddrFile->Address) ||
00119                AddrIsUnspecified(DstAddress))) {
00120 
00121           /* Remove the request from the queue */
00122           RemoveEntryList(&Current->ListEntry);
00123 
00124               TI_DbgPrint(MAX_TRACE, ("Suitable receive request found.\n"));
00125 
00126               TI_DbgPrint(MAX_TRACE,
00127                            ("Target Buffer: %x, Source Buffer: %x, Size %d\n",
00128                             Current->Buffer, DataBuffer, DataSize));
00129 
00130               /* Copy the data into buffer provided by the user */
00131           RtlCopyMemory( Current->Buffer,
00132                  DataBuffer,
00133                  MIN(Current->BufferSize, DataSize) );
00134 
00135           RTAIPAddress = (PTA_IP_ADDRESS)Current->ReturnInfo->RemoteAddress;
00136           RTAIPAddress->TAAddressCount = 1;
00137           RTAIPAddress->Address->AddressType = TDI_ADDRESS_TYPE_IP;
00138           RTAIPAddress->Address->AddressLength = TDI_ADDRESS_LENGTH_IP;
00139           RTAIPAddress->Address->Address->sin_port = SrcPort;
00140           RTAIPAddress->Address->Address->in_addr = SrcAddress->Address.IPv4Address;
00141           RtlZeroMemory(RTAIPAddress->Address->Address->sin_zero, 8);
00142 
00143           TI_DbgPrint(MAX_TRACE, ("(A: %08x) Addr %08x Port %04x\n",
00144                       RTAIPAddress,
00145                       SrcAddress->Address.IPv4Address, SrcPort));
00146 
00147               ReferenceObject(AddrFile);
00148               UnlockObject(AddrFile, OldIrql);
00149 
00150               /* Complete the receive request */
00151               if (Current->BufferSize < DataSize)
00152                   Current->Complete(Current->Context, STATUS_BUFFER_OVERFLOW, Current->BufferSize);
00153               else
00154                   Current->Complete(Current->Context, STATUS_SUCCESS, DataSize);
00155 
00156               LockObject(AddrFile, &OldIrql);
00157               DereferenceObject(AddrFile);
00158       }
00159       }
00160 
00161       UnlockObject(AddrFile, OldIrql);
00162     }
00163   else if (AddrFile->RegisteredReceiveDatagramHandler)
00164     {
00165       TI_DbgPrint(MAX_TRACE, ("Calling receive event handler.\n"));
00166 
00167       ReceiveHandler = AddrFile->ReceiveDatagramHandler;
00168       HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
00169 
00170       if (SrcAddress->Type == IP_ADDRESS_V4)
00171         {
00172           AddressLength = sizeof(IPv4_RAW_ADDRESS);
00173           SourceAddress = &SrcAddress->Address.IPv4Address;
00174         }
00175       else /* (Address->Type == IP_ADDRESS_V6) */
00176         {
00177           AddressLength = sizeof(IPv6_RAW_ADDRESS);
00178           SourceAddress = SrcAddress->Address.IPv6Address;
00179         }
00180 
00181       ReferenceObject(AddrFile);
00182       UnlockObject(AddrFile, OldIrql);
00183 
00184       Status = (*ReceiveHandler)(HandlerContext,
00185         AddressLength,
00186         SourceAddress,
00187         0,
00188         NULL,
00189         TDI_RECEIVE_ENTIRE_MESSAGE,
00190         DataSize,
00191         DataSize,
00192         &BytesTaken,
00193         DataBuffer,
00194         NULL);
00195 
00196       if (STATUS_SUCCESS != Status)
00197           TI_DbgPrint(MAX_TRACE, ("receive handler signaled failure with Status 0x%x\n", Status));
00198 
00199       DereferenceObject(AddrFile);
00200     }
00201   else
00202     {
00203       UnlockObject(AddrFile, OldIrql);
00204       TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
00205     }
00206 
00207   TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
00208 }
00209 
00210 
00211 VOID DGReceiveComplete(PVOID Context, NTSTATUS Status, ULONG Count) {
00212     PDATAGRAM_RECEIVE_REQUEST ReceiveRequest =
00213     (PDATAGRAM_RECEIVE_REQUEST)Context;
00214     TI_DbgPrint(MAX_TRACE,("Called (%08x:%08x)\n", Status, Count));
00215     ReceiveRequest->UserComplete( ReceiveRequest->UserContext, Status, Count );
00216     ExFreePoolWithTag( ReceiveRequest, DATAGRAM_RECV_TAG );
00217     TI_DbgPrint(MAX_TRACE,("Done\n"));
00218 }
00219 
00220 NTSTATUS DGReceiveDatagram(
00221     PADDRESS_FILE AddrFile,
00222     PTDI_CONNECTION_INFORMATION ConnInfo,
00223     PCHAR BufferData,
00224     ULONG ReceiveLength,
00225     ULONG ReceiveFlags,
00226     PTDI_CONNECTION_INFORMATION ReturnInfo,
00227     PULONG BytesReceived,
00228     PDATAGRAM_COMPLETION_ROUTINE Complete,
00229     PVOID Context,
00230     PIRP Irp)
00231 /*
00232  * FUNCTION: Attempts to receive an DG datagram from a remote address
00233  * ARGUMENTS:
00234  *     Request       = Pointer to TDI request
00235  *     ConnInfo      = Pointer to connection information
00236  *     Buffer        = Pointer to NDIS buffer chain to store received data
00237  *     ReceiveLength = Maximum size to use of buffer, 0 if all can be used
00238  *     ReceiveFlags  = Receive flags (None, Normal, Peek)
00239  *     ReturnInfo    = Pointer to structure for return information
00240  *     BytesReceive  = Pointer to structure for number of bytes received
00241  * RETURNS:
00242  *     Status of operation
00243  * NOTES:
00244  *     This is the high level interface for receiving DG datagrams
00245  */
00246 {
00247     NTSTATUS Status;
00248     PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
00249     KIRQL OldIrql;
00250 
00251     TI_DbgPrint(MAX_TRACE, ("Called.\n"));
00252 
00253     LockObject(AddrFile, &OldIrql);
00254 
00255     ReceiveRequest = ExAllocatePoolWithTag(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST),
00256                                            DATAGRAM_RECV_TAG);
00257     if (ReceiveRequest)
00258     {
00259     /* Initialize a receive request */
00260 
00261     /* Extract the remote address filter from the request (if any) */
00262     if ((ConnInfo->RemoteAddressLength != 0) &&
00263         (ConnInfo->RemoteAddress))
00264         {
00265         Status = AddrGetAddress(ConnInfo->RemoteAddress,
00266                     &ReceiveRequest->RemoteAddress,
00267                     &ReceiveRequest->RemotePort);
00268         if (!NT_SUCCESS(Status))
00269             {
00270         ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG);
00271             UnlockObject(AddrFile, OldIrql);
00272         return Status;
00273             }
00274     }
00275     else
00276         {
00277         ReceiveRequest->RemotePort = 0;
00278         AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0);
00279         }
00280 
00281     IoMarkIrpPending(Irp);
00282 
00283     ReceiveRequest->ReturnInfo = ReturnInfo;
00284     ReceiveRequest->Buffer = BufferData;
00285     ReceiveRequest->BufferSize = ReceiveLength;
00286     ReceiveRequest->UserComplete = Complete;
00287     ReceiveRequest->UserContext = Context;
00288     ReceiveRequest->Complete =
00289         (PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete;
00290     ReceiveRequest->Context = ReceiveRequest;
00291         ReceiveRequest->AddressFile = AddrFile;
00292         ReceiveRequest->Irp = Irp;
00293 
00294     /* Queue receive request */
00295     InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
00296 
00297     TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest));
00298 
00299     UnlockObject(AddrFile, OldIrql);
00300 
00301     return STATUS_PENDING;
00302     }
00303     else
00304     {
00305     UnlockObject(AddrFile, OldIrql);
00306         Status = STATUS_INSUFFICIENT_RESOURCES;
00307     }
00308 
00309     TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status));
00310 
00311     return Status;
00312 }

Generated on Sat May 26 2012 04:34:54 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.