|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1989-1993 Microsoft Corporation
4:
5: Module Name:
6:
7: framesnd.c
8:
9: Abstract:
10:
11: This module contains routines which build and send Sample transport
12: frames for other modules.
13:
14: Environment:
15:
16: Kernel mode
17:
18: Revision History:
19:
20: --*/
21:
22: #include "st.h"
23:
24:
25:
26: NTSTATUS
27: StSendConnect(
28: IN PTP_CONNECTION Connection
29: )
30:
31: /*++
32:
33: Routine Description:
34:
35: This routine sends a CONNECT frame of the appropriate type given the
36: state of the specified connection.
37:
38: Arguments:
39:
40: Connection - Pointer to a transport connection object.
41:
42: Return Value:
43:
44: none.
45:
46: --*/
47:
48: {
49: NTSTATUS Status;
50: PDEVICE_CONTEXT DeviceContext;
51: PUCHAR SourceRouting;
52: UINT SourceRoutingLength;
53: UINT HeaderLength;
54: PSEND_PACKET_TAG SendTag;
55: PTP_PACKET Packet;
56: PST_HEADER StHeader;
57:
58:
59: DeviceContext = Connection->Provider;
60:
61: //
62: // Allocate a packet from the pool.
63: //
64:
65: Status = StCreatePacket (DeviceContext, &Packet);
66: if (!NT_SUCCESS (Status)) { // couldn't make frame.
67: return STATUS_INSUFFICIENT_RESOURCES;
68: }
69:
70: SendTag = (PSEND_PACKET_TAG)(Packet->NdisPacket->ProtocolReserved);
71: SendTag->Type = TYPE_C_FRAME;
72: SendTag->Packet = Packet;
73: SendTag->Owner = (PVOID)Connection;
74:
75: //
76: // Build the MAC header.
77: //
78:
79: //
80: // CONNECT frames go out as
81: // single-route source routing.
82: //
83:
84: MacReturnSingleRouteSR(
85: &DeviceContext->MacInfo,
86: &SourceRouting,
87: &SourceRoutingLength);
88:
89: MacConstructHeader (
90: &DeviceContext->MacInfo,
91: Packet->Header,
92: DeviceContext->MulticastAddress.Address,
93: DeviceContext->LocalAddress.Address,
94: sizeof(ST_HEADER),
95: SourceRouting,
96: SourceRoutingLength,
97: &HeaderLength);
98:
99:
100: //
101: // Build the header: 'C', dest, source
102: //
103:
104: StHeader = (PST_HEADER)(&Packet->Header[HeaderLength]);
105:
106: StHeader->Signature = ST_SIGNATURE;
107: StHeader->Command = ST_CMD_CONNECT;
108: StHeader->Flags = 0;
109:
110: RtlCopyMemory (StHeader->Destination, Connection->CalledAddress.NetbiosName, 16);
111: RtlCopyMemory (StHeader->Source, Connection->AddressFile->Address->NetworkName->NetbiosName, 16);
112:
113: HeaderLength += sizeof(ST_HEADER);
114:
115: //
116: // Modify the packet length and send the it.
117: //
118:
119: StSetNdisPacketLength(Packet->NdisPacket, HeaderLength);
120:
121: StNdisSend (Packet);
122:
123: return STATUS_SUCCESS;
124: } /* StSendConnect */
125:
126:
127: NTSTATUS
128: StSendDisconnect(
129: IN PTP_CONNECTION Connection
130: )
131:
132: /*++
133:
134: Routine Description:
135:
136: This routine sends a DISCONNECT frame of the appropriate type given the
137: state of the specified connection.
138:
139: Arguments:
140:
141: Connection - Pointer to a transport connection object.
142:
143: Return Value:
144:
145: none.
146:
147: --*/
148:
149: {
150: NTSTATUS Status;
151: PDEVICE_CONTEXT DeviceContext;
152: PUCHAR SourceRouting;
153: UINT SourceRoutingLength;
154: UINT HeaderLength;
155: PSEND_PACKET_TAG SendTag;
156: PTP_PACKET Packet;
157: PST_HEADER StHeader;
158:
159:
160: DeviceContext = Connection->Provider;
161:
162: //
163: // Allocate a packet from the pool.
164: //
165:
166: Status = StCreatePacket (DeviceContext, &Packet);
167: if (!NT_SUCCESS (Status)) { // couldn't make frame.
168: return STATUS_INSUFFICIENT_RESOURCES;
169: }
170:
171: SendTag = (PSEND_PACKET_TAG)(Packet->NdisPacket->ProtocolReserved);
172: SendTag->Type = TYPE_D_FRAME;
173: SendTag->Packet = Packet;
174: SendTag->Owner = (PVOID)Connection;
175:
176: //
177: // Build the MAC header.
178: //
179:
180: //
181: // CONNECT frames go out as
182: // single-route source routing.
183: //
184:
185: MacReturnSingleRouteSR(
186: &DeviceContext->MacInfo,
187: &SourceRouting,
188: &SourceRoutingLength);
189:
190: MacConstructHeader (
191: &DeviceContext->MacInfo,
192: Packet->Header,
193: DeviceContext->MulticastAddress.Address,
194: DeviceContext->LocalAddress.Address,
195: sizeof(ST_HEADER),
196: SourceRouting,
197: SourceRoutingLength,
198: &HeaderLength);
199:
200:
201: //
202: // Build the header: 'D', dest, source
203: //
204:
205: StHeader = (PST_HEADER)(&Packet->Header[HeaderLength]);
206:
207: StHeader->Signature = ST_SIGNATURE;
208: StHeader->Command = ST_CMD_DISCONNECT;
209: StHeader->Flags = 0;
210:
211: RtlCopyMemory (StHeader->Destination, Connection->CalledAddress.NetbiosName, 16);
212: RtlCopyMemory (StHeader->Source, Connection->AddressFile->Address->NetworkName->NetbiosName, 16);
213:
214: HeaderLength += sizeof(ST_HEADER);
215:
216: //
217: // Modify the packet length and send the it.
218: //
219:
220: StSetNdisPacketLength(Packet->NdisPacket, HeaderLength);
221:
222: StNdisSend (Packet);
223:
224: return STATUS_SUCCESS;
225:
226: } /* StSendDisconnect */
227:
228:
229: NTSTATUS
230: StSendAddressFrame(
231: PTP_ADDRESS Address
232: )
233:
234: /*++
235:
236: Routine Description:
237:
238: It is intended that this routine be used for sending datagrams and
239: braodcast datagrams.
240:
241: The datagram to be sent is described in the NDIS packet contained
242: in the Address. When the send completes, the send completion handler
243: returns the NDIS buffer describing the datagram to the buffer pool and
244: marks the address ndis packet as usable again. Thus, all datagram
245: frames are sequenced through the address they are sent on.
246:
247: Arguments:
248:
249: Address - pointer to the address from which to send this datagram.
250:
251: Return Value:
252:
253: NTSTATUS - status of operation.
254:
255: --*/
256:
257: {
258: PDEVICE_CONTEXT DeviceContext;
259:
260:
261: //
262: // Send the packet.
263: //
264:
265: DeviceContext = Address->Provider;
266:
267: INCREMENT_COUNTER (DeviceContext, PacketsSent);
268:
269: StNdisSend (Address->Packet);
270:
271: return STATUS_PENDING;
272: } /* StSendAddressFrame */
273:
274:
275: VOID
276: StSendDatagramCompletion(
277: IN PTP_ADDRESS Address,
278: IN PNDIS_PACKET NdisPacket,
279: IN NDIS_STATUS NdisStatus
280: )
281:
282: /*++
283:
284: Routine Description:
285:
286: This routine is called as an I/O completion handler at the time a
287: StSendUIMdlFrame send request is completed. Because this handler is only
288: associated with StSendUIMdlFrame, and because StSendUIMdlFrame is only
289: used with datagrams and broadcast datagrams, we know that the I/O being
290: completed is a datagram. Here we complete the in-progress datagram, and
291: start-up the next one if there is one.
292:
293: Arguments:
294:
295: Address - Pointer to a transport address on which the datagram
296: is queued.
297:
298: NdisPacket - pointer to the NDIS packet describing this request.
299:
300: Return Value:
301:
302: none.
303:
304: --*/
305:
306: {
307: PTP_REQUEST Request;
308: PLIST_ENTRY p;
309: KIRQL oldirql;
310: PNDIS_BUFFER HeaderBuffer;
311:
312: UNREFERENCED_PARAMETER(NdisPacket);
313:
314: StReferenceAddress ("Complete datagram", Address);
315:
316: //
317: // Dequeue the current request and return it to the client. Release
318: // our hold on the send datagram queue.
319: //
320: // *** There may be no current request, if the one that was queued
321: // was aborted or timed out.
322: //
323:
324: ACQUIRE_SPIN_LOCK (&Address->SpinLock, &oldirql);
325: p = RemoveHeadList (&Address->SendDatagramQueue);
326:
327: if (p != &Address->SendDatagramQueue) {
328:
329: RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql);
330:
331: Request = CONTAINING_RECORD (p, TP_REQUEST, Linkage);
332:
333: //
334: // Strip off and unmap the buffers describing data and header.
335: //
336:
337: NdisUnchainBufferAtFront (Address->Packet->NdisPacket, &HeaderBuffer);
338:
339: // drop the rest of the packet
340:
341: NdisReinitializePacket (Address->Packet->NdisPacket);
342:
343: NDIS_BUFFER_LINKAGE(HeaderBuffer) = (PNDIS_BUFFER)NULL;
344: NdisChainBufferAtFront (Address->Packet->NdisPacket, HeaderBuffer);
345:
346: //
347: // Ignore NdisStatus; datagrams always "succeed".
348: //
349:
350: StCompleteRequest (Request, STATUS_SUCCESS, Request->Buffer2Length);
351:
352: ACQUIRE_SPIN_LOCK (&Address->SpinLock, &oldirql);
353: Address->Flags &= ~ADDRESS_FLAGS_SEND_IN_PROGRESS;
354: RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql);
355:
356: //
357: // Send more datagrams on the Address if possible.
358: //
359:
360: StSendDatagramsOnAddress (Address); // do more datagrams.
361:
362: } else {
363:
364: Address->Flags &= ~ADDRESS_FLAGS_SEND_IN_PROGRESS;
365: RELEASE_SPIN_LOCK (&Address->SpinLock, oldirql);
366:
367: }
368:
369: StDereferenceAddress ("Complete datagram", Address);
370:
371: } /* StSendDatagramCompletion */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.