diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/tdi/st/framesnd.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/ntos/tdi/st/framesnd.c')
-rw-r--r-- | private/ntos/tdi/st/framesnd.c | 371 |
1 files changed, 371 insertions, 0 deletions
diff --git a/private/ntos/tdi/st/framesnd.c b/private/ntos/tdi/st/framesnd.c new file mode 100644 index 000000000..0d9f5cff7 --- /dev/null +++ b/private/ntos/tdi/st/framesnd.c @@ -0,0 +1,371 @@ +/*++ + +Copyright (c) 1989-1993 Microsoft Corporation + +Module Name: + + framesnd.c + +Abstract: + + This module contains routines which build and send Sample transport + frames for other modules. + +Environment: + + Kernel mode + +Revision History: + +--*/ + +#include "st.h" + + + +NTSTATUS +StSendConnect( + IN PTP_CONNECTION Connection + ) + +/*++ + +Routine Description: + + This routine sends a CONNECT frame of the appropriate type given the + state of the specified connection. + +Arguments: + + Connection - Pointer to a transport connection object. + +Return Value: + + none. + +--*/ + +{ + NTSTATUS Status; + PDEVICE_CONTEXT DeviceContext; + PUCHAR SourceRouting; + UINT SourceRoutingLength; + UINT HeaderLength; + PSEND_PACKET_TAG SendTag; + PTP_PACKET Packet; + PST_HEADER StHeader; + + + DeviceContext = Connection->Provider; + + // + // Allocate a packet from the pool. + // + + Status = StCreatePacket (DeviceContext, &Packet); + if (!NT_SUCCESS (Status)) { // couldn't make frame. + return STATUS_INSUFFICIENT_RESOURCES; + } + + SendTag = (PSEND_PACKET_TAG)(Packet->NdisPacket->ProtocolReserved); + SendTag->Type = TYPE_C_FRAME; + SendTag->Packet = Packet; + SendTag->Owner = (PVOID)Connection; + + // + // Build the MAC header. + // + + // + // CONNECT frames go out as + // single-route source routing. + // + + MacReturnSingleRouteSR( + &DeviceContext->MacInfo, + &SourceRouting, + &SourceRoutingLength); + + MacConstructHeader ( + &DeviceContext->MacInfo, + Packet->Header, + DeviceContext->MulticastAddress.Address, + DeviceContext->LocalAddress.Address, + sizeof(ST_HEADER), + SourceRouting, + SourceRoutingLength, + &HeaderLength); + + + // + // Build the header: 'C', dest, source + // + + StHeader = (PST_HEADER)(&Packet->Header[HeaderLength]); + + StHeader->Signature = ST_SIGNATURE; + StHeader->Command = ST_CMD_CONNECT; + StHeader->Flags = 0; + + RtlCopyMemory (StHeader->Destination, Connection->CalledAddress.NetbiosName, 16); + RtlCopyMemory (StHeader->Source, Connection->AddressFile->Address->NetworkName->NetbiosName, 16); + + HeaderLength += sizeof(ST_HEADER); + + // + // Modify the packet length and send the it. + // + + StSetNdisPacketLength(Packet->NdisPacket, HeaderLength); + + StNdisSend (Packet); + + return STATUS_SUCCESS; +} /* StSendConnect */ + + +NTSTATUS +StSendDisconnect( + IN PTP_CONNECTION Connection + ) + +/*++ + +Routine Description: + + This routine sends a DISCONNECT frame of the appropriate type given the + state of the specified connection. + +Arguments: + + Connection - Pointer to a transport connection object. + +Return Value: + + none. + +--*/ + +{ + NTSTATUS Status; + PDEVICE_CONTEXT DeviceContext; + PUCHAR SourceRouting; + UINT SourceRoutingLength; + UINT HeaderLength; + PSEND_PACKET_TAG SendTag; + PTP_PACKET Packet; + PST_HEADER StHeader; + + + DeviceContext = Connection->Provider; + + // + // Allocate a packet from the pool. + // + + Status = StCreatePacket (DeviceContext, &Packet); + if (!NT_SUCCESS (Status)) { // couldn't make frame. + return STATUS_INSUFFICIENT_RESOURCES; + } + + SendTag = (PSEND_PACKET_TAG)(Packet->NdisPacket->ProtocolReserved); + SendTag->Type = TYPE_D_FRAME; + SendTag->Packet = Packet; + SendTag->Owner = (PVOID)Connection; + + // + // Build the MAC header. + // + + // + // CONNECT frames go out as + // single-route source routing. + // + + MacReturnSingleRouteSR( + &DeviceContext->MacInfo, + &SourceRouting, + &SourceRoutingLength); + + MacConstructHeader ( + &DeviceContext->MacInfo, + Packet->Header, + DeviceContext->MulticastAddress.Address, + DeviceContext->LocalAddress.Address, + sizeof(ST_HEADER), + SourceRouting, + SourceRoutingLength, + &HeaderLength); + + + // + // Build the header: 'D', dest, source + // + + StHeader = (PST_HEADER)(&Packet->Header[HeaderLength]); + + StHeader->Signature = ST_SIGNATURE; + StHeader->Command = ST_CMD_DISCONNECT; + StHeader->Flags = 0; + + RtlCopyMemory (StHeader->Destination, Connection->CalledAddress.NetbiosName, 16); + RtlCopyMemory (StHeader->Source, Connection->AddressFile->Address->NetworkName->NetbiosName, 16); + + HeaderLength += sizeof(ST_HEADER); + + // + // Modify the packet length and send the it. + // + + StSetNdisPacketLength(Packet->NdisPacket, HeaderLength); + + StNdisSend (Packet); + + return STATUS_SUCCESS; + +} /* StSendDisconnect */ + + +NTSTATUS +StSendAddressFrame( + PTP_ADDRESS Address + ) + +/*++ + +Routine Description: + + It is intended that this routine be used for sending datagrams and + braodcast datagrams. + + The datagram to be sent is described in the NDIS packet contained + in the Address. When the send completes, the send completion handler + returns the NDIS buffer describing the datagram to the buffer pool and + marks the address ndis packet as usable again. Thus, all datagram + frames are sequenced through the address they are sent on. + +Arguments: + + Address - pointer to the address from which to send this datagram. + +Return Value: + + NTSTATUS - status of operation. + +--*/ + +{ + PDEVICE_CONTEXT DeviceContext; + + + // + // Send the packet. + // + + DeviceContext = Address->Provider; + + INCREMENT_COUNTER (DeviceContext, PacketsSent); + + StNdisSend (Address->Packet); + + return STATUS_PENDING; +} /* StSendAddressFrame */ + + +VOID +StSendDatagramCompletion( + IN PTP_ADDRESS Address, + IN PNDIS_PACKET NdisPacket, + IN NDIS_STATUS NdisStatus + ) + +/*++ + +Routine Description: + + This routine is called as an I/O completion handler at the time a + StSendUIMdlFrame send request is completed. Because this handler is only + associated with StSendUIMdlFrame, and because StSendUIMdlFrame is only + used with datagrams and broadcast datagrams, we know that the I/O being + completed is a datagram. Here we complete the in-progress datagram, and + start-up the next one if there is one. + +Arguments: + + Address - Pointer to a transport address on which the datagram + is queued. + + NdisPacket - pointer to the NDIS packet describing this request. + +Return Value: + + none. + +--*/ + +{ + PTP_REQUEST Request; + PLIST_ENTRY p; + KIRQL oldirql; + PNDIS_BUFFER HeaderBuffer; + + UNREFERENCED_PARAMETER(NdisPacket); + + StReferenceAddress ("Complete datagram", Address); + + // + // Dequeue the current request and return it to the client. Release + // our hold on the send datagram queue. + // + // *** There may be no current request, if the one that was queued + // was aborted or timed out. + // + + ACQUIRE_SPIN_LOCK (&Address->SpinLock, &oldirql); + p = RemoveHeadList (&Address->SendDatagramQueue); + + if (p != &Address->SendDatagramQueue) { + + RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql); + + Request = CONTAINING_RECORD (p, TP_REQUEST, Linkage); + + // + // Strip off and unmap the buffers describing data and header. + // + + NdisUnchainBufferAtFront (Address->Packet->NdisPacket, &HeaderBuffer); + + // drop the rest of the packet + + NdisReinitializePacket (Address->Packet->NdisPacket); + + NDIS_BUFFER_LINKAGE(HeaderBuffer) = (PNDIS_BUFFER)NULL; + NdisChainBufferAtFront (Address->Packet->NdisPacket, HeaderBuffer); + + // + // Ignore NdisStatus; datagrams always "succeed". + // + + StCompleteRequest (Request, STATUS_SUCCESS, Request->Buffer2Length); + + ACQUIRE_SPIN_LOCK (&Address->SpinLock, &oldirql); + Address->Flags &= ~ADDRESS_FLAGS_SEND_IN_PROGRESS; + RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql); + + // + // Send more datagrams on the Address if possible. + // + + StSendDatagramsOnAddress (Address); // do more datagrams. + + } else { + + Address->Flags &= ~ADDRESS_FLAGS_SEND_IN_PROGRESS; + RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql); + + } + + StDereferenceAddress ("Complete datagram", Address); + +} /* StSendDatagramCompletion */ |