1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
|
/*++
Copyright (c) 1989-1993 Microsoft Corporation
Module Name:
spxpkt.h
Abstract:
Author:
Nikhil Kamkolkar (nikhilk) 11-November-1993
Environment:
Kernel mode
Revision History:
--*/
// Use our own NDIS packets
#define SPX_OWN_PACKETS 1
// Offsets into the IPX header
#define IPX_HDRSIZE 30 // Size of the IPX header
#define IPX_CHECKSUM 0 // Checksum
#define IPX_LENGTH 2 // Length
#define IPX_XPORTCTL 4 // Transport Control
#define IPX_PKTTYPE 5 // Packet Type
#define IPX_DESTADDR 6 // Dest. Address (Total)
#define IPX_DESTNET 6 // Dest. Network Address
#define IPX_DESTNODE 10 // Dest. Node Address
#define IPX_DESTSOCK 16 // Dest. Socket Number
#define IPX_SRCADDR 18 // Source Address (Total)
#define IPX_SRCNET 18 // Source Network Address
#define IPX_SRCNODE 22 // Source Node Address
#define IPX_SRCSOCK 28 // Source Socket Number
#define IPX_NET_LEN 4
#define IPX_NODE_LEN 6
#include <packon.h>
// Definition of the IPX/SPX header.
typedef struct _IPXSPX_HEADER
{
USHORT hdr_CheckSum;
USHORT hdr_PktLen;
UCHAR hdr_XportCtrl;
UCHAR hdr_PktType;
UCHAR hdr_DestNet[4];
UCHAR hdr_DestNode[6];
USHORT hdr_DestSkt;
UCHAR hdr_SrcNet[4];
UCHAR hdr_SrcNode[6];
USHORT hdr_SrcSkt;
// SPX Header Elements
UCHAR hdr_ConnCtrl;
UCHAR hdr_DataType;
USHORT hdr_SrcConnId;
USHORT hdr_DestConnId;
USHORT hdr_SeqNum;
USHORT hdr_AckNum;
USHORT hdr_AllocNum;
// For non-CR SPXII packets only
USHORT hdr_NegSize;
} IPXSPX_HDR, *PIPXSPX_HDR;
#include <packoff.h>
// NDIS Packet size
#define NDIS_PACKET_SIZE 48
// Minimum header size (doesnt include neg size)
#define MIN_IPXSPX_HDRSIZE (sizeof(IPXSPX_HDR) - sizeof(USHORT))
#define MIN_IPXSPX2_HDRSIZE sizeof(IPXSPX_HDR)
#define SPX_CR_PKTLEN 42
// SPX packet type
#define SPX_PKT_TYPE 0x5
// Connection control fields
#define SPX_CC_XHD 0x01
#define SPX_CC_RES1 0x02
#define SPX_CC_NEG 0x04
#define SPX_CC_SPX2 0x08
#define SPX_CC_EOM 0x10
#define SPX_CC_ATN 0x20
#define SPX_CC_ACK 0x40
#define SPX_CC_SYS 0x80
#define SPX_CC_CR (SPX_CC_ACK | SPX_CC_SYS)
// Data stream types
#define SPX2_DT_ORDREL 0xFD
#define SPX2_DT_IDISC 0xFE
#define SPX2_DT_IDISC_ACK 0xFF
// Negotiation size
#define SPX_MAX_PACKET 576
#define SPX_NEG_MIN SPX_MAX_PACKET
#define SPX_NEG_MAX 65535
// No packet references connection. But if the sends are being aborted, and
// the packet happens to be owned by ipx at the time, the pkt is dequeued from
// conn, the ABORT flag is set and conn is referenced for packet.
//
// Send packet states
// ABORT : Used for aborted packet. Calls AbortSendPkt().
// IPXOWNS : Currently owned by ipx
// FREEDATA: Frees the data associated with second ndis buffer desc
// ACKREQ : Only for sequenced packets. Set by retry timer in packets it wants
// resent (1 for spx1, all pending for spx2) with ack bit set.
// DESTROY : Only for non-sequenced packets, dequeue packet from list and free.
// REQ : For both seq/non-seq. A request is associated with the packet
// SEQ : Packet is a sequenced packet.
// LASTPKT : Packet is last packet comprising the request, if acked req is done.
// EOM : Send EOM with the last packet for this request
// ACKEDPKT: Send completion must only deref req with pkt and complete if zero.
//
#define SPX_SENDPKT_IDLE 0
#define SPX_SENDPKT_ABORT 0x0002
#define SPX_SENDPKT_IPXOWNS 0x0004
#define SPX_SENDPKT_FREEDATA 0x0008
#define SPX_SENDPKT_ACKREQ 0x0010
#define SPX_SENDPKT_DESTROY 0x0020
#define SPX_SENDPKT_REQ 0x0040
#define SPX_SENDPKT_SEQ 0x0080
#define SPX_SENDPKT_LASTPKT 0x0100
#define SPX_SENDPKT_ACKEDPKT 0x0200
#define SPX_SENDPKT_EOM 0x0400
#define SPX_SENDPKT_REXMIT 0x0800
// Packet types
#define SPX_TYPE_CR 0x01
#define SPX_TYPE_CRACK 0x02
#define SPX_TYPE_SN 0x03
#define SPX_TYPE_SNACK 0x04
#define SPX_TYPE_SS 0x05
#define SPX_TYPE_SSACK 0x06
#define SPX_TYPE_RR 0x07
#define SPX_TYPE_RRACK 0x08
#define SPX_TYPE_IDISC 0x09
#define SPX_TYPE_IDISCACK 0x0a
#define SPX_TYPE_ORDREL 0x0b
#define SPX_TYPE_ORDRELACK 0x0c
#define SPX_TYPE_DATA 0x0d
#define SPX_TYPE_DATAACK 0x0e
#define SPX_TYPE_DATANACK 0x0f
#define SPX_TYPE_PROBE 0x10
// Definition of the protocol reserved field of a send packet.
// BUGBUG: Make Len/HdrLen USHORTS, move to the end before the
// sr_SentTime so we dont use padding space.
typedef struct _SPX_SEND_RESD
{
UCHAR sr_Id; // Set to SPX
UCHAR sr_Type; // What kind of packet
USHORT sr_State; // State of send packet
PVOID sr_Reserved1; // Needed by IPX
PVOID sr_Reserved2; // Needed by IPX
#if defined(_PNP_POWER)
PVOID sr_Reserved[SEND_RESERVED_COMMON_SIZE-2]; // needed by IPX for local target
#endif _PNP_POWER
ULONG sr_Len; // Length of packet
ULONG sr_HdrLen; // Included header length
struct _SPX_SEND_RESD * sr_Next; // Points to next packet
// in send queue in conn.
PREQUEST sr_Request; // request associated
ULONG sr_Offset; // Offset in mdl for sends
#ifndef SPX_OWN_PACKETS
PVOID sr_FreePtr; // Ptr to use in free chunk
#endif
struct _SPX_CONN_FILE * sr_ConnFile; // that this send is on
USHORT sr_SeqNum; // Seq num for seq pkts
// Quad word aligned.
LARGE_INTEGER sr_SentTime; // Time packet was sent
// Only valid for data pkt
// with ACKREQ set.
} SPX_SEND_RESD, *PSPX_SEND_RESD;
// Recv packet states
#define SPX_RECVPKT_IDLE 0
#define SPX_RECVPKT_BUFFERING 0x0001
#define SPX_RECVPKT_IDISC 0x0002
#define SPX_RECVPKT_ORD_DISC 0x0004
#define SPX_RECVPKT_INDICATED 0x0008
#define SPX_RECVPKT_SENDACK 0x0010
#define SPX_RECVPKT_EOM 0x0020
#define SPX_RECVPKT_IMMEDACK 0x0040
#define SPX_RECVPKT_DISCMASK (SPX_RECVPKT_ORD_DISC | SPX_RECVPKT_IDISC)
// Definition of the protocol reserved field of a receive packet.
typedef struct _SPX_RECV_RESD
{
UCHAR rr_Id; // Set to SPX
USHORT rr_State; // State of receive packet
struct _SPX_RECV_RESD * rr_Next; // Points to next packet
ULONG rr_DataOffset; // To indicate/copy from
#ifndef SPX_OWN_PACKETS
PVOID rr_FreePtr; // Ptr to use in free chunk
#endif
#if DBG
USHORT rr_SeqNum; // Seq num of packet
#endif
PREQUEST rr_Request; // request waiting on xfer
struct _SPX_CONN_FILE * rr_ConnFile; // that this recv is on
} SPX_RECV_RESD, *PSPX_RECV_RESD;
// Destination built as an assign of 3 ulongs.
#define SpxBuildIpxHdr(pIpxSpxHdr, PktLen, pRemAddr, SrcSkt) \
{ \
PBYTE pDestIpxAddr = (PBYTE)pIpxSpxHdr->hdr_DestNet; \
(pIpxSpxHdr)->hdr_CheckSum = 0xFFFF; \
PUTSHORT2SHORT((PUSHORT)(&(pIpxSpxHdr)->hdr_PktLen), (PktLen)); \
(pIpxSpxHdr)->hdr_XportCtrl = 0; \
(pIpxSpxHdr)->hdr_PktType = SPX_PKT_TYPE; \
*((UNALIGNED ULONG *)pDestIpxAddr) = \
*((UNALIGNED ULONG *)pRemAddr); \
*((UNALIGNED ULONG *)(pDestIpxAddr+4)) = \
*((UNALIGNED ULONG *)(pRemAddr+4)); \
*((UNALIGNED ULONG *)(pDestIpxAddr+8)) = \
*((UNALIGNED ULONG *)(pRemAddr+8)); \
*((UNALIGNED ULONG *)((pIpxSpxHdr)->hdr_SrcNet))= \
*((UNALIGNED ULONG *)(SpxDevice->dev_Network)); \
*((UNALIGNED ULONG *)((pIpxSpxHdr)->hdr_SrcNode)) = \
*((UNALIGNED ULONG *)SpxDevice->dev_Node); \
*((UNALIGNED USHORT *)((pIpxSpxHdr)->hdr_SrcNode+4)) = \
*((UNALIGNED USHORT *)(SpxDevice->dev_Node+4)); \
*((UNALIGNED USHORT *)&((pIpxSpxHdr)->hdr_SrcSkt)) = \
SrcSkt; \
}
#define SpxCopyIpxAddr(pIpxSpxHdr, pDestIpxAddr) \
{ \
PBYTE pRemAddr = (PBYTE)pIpxSpxHdr->hdr_SrcNet; \
*((UNALIGNED ULONG *)pDestIpxAddr) = \
*((UNALIGNED ULONG *)pRemAddr); \
*((UNALIGNED ULONG *)(pDestIpxAddr+4)) = \
*((UNALIGNED ULONG *)(pRemAddr+4)); \
*((UNALIGNED ULONG *)(pDestIpxAddr+8)) = \
*((UNALIGNED ULONG *)(pRemAddr+8)); \
}
#ifndef SPX_OWN_PACKETS
#define SpxAllocSendPacket(_Device,_SendPacket,_Status) \
{ \
NDIS_HANDLE _Handle; \
NdisAllocatePacketPool(_Status, &(_Handle),1,sizeof(SPX_SEND_RESD));\
if (*(_Status) == NDIS_STATUS_SUCCESS) { \
NdisAllocatePacket(_Status, &(_SendPacket), (_Handle)); \
SEND_RESD(_SendPacket)->sr_PoolHandle = (_Handle); \
} \
}
#define SpxAllocRecvPacket(_Device,_RecvPacket,_Status) \
{ \
NDIS_HANDLE _Handle; \
NdisAllocatePacketPool(_Status, &(_Handle),1,sizeof(SPX_RECV_RESD));\
if (*(_Status) == NDIS_STATUS_SUCCESS) { \
NdisAllocatePacket(_Status, &(_RecvPacket), (_Handle)); \
RECV_RESD(_RecvPacket)->sr_PoolHandle = (_Handle); \
} \
}
#define SpxFreeSendPacket(_Device,_Packet) \
{ \
NDIS_HANDLE _Handle = SEND_RESD(_Packet)->sr_PoolHandle; \
NdisFreePacket(_Packet); \
NdisFreePacketPool(_Handle); \
}
#define SpxFreeRecvPacket(_Device,_Packet) \
{ \
NDIS_HANDLE _Handle = RECV_RESD(_Packet)->rr_PoolHandle; \
NdisFreePacket(_Packet); \
NdisFreePacketPool(_Handle); \
}
#define SpxReInitSendPacket(_Packet)
{
NDIS_HANDLE _Handle = SEND_RESD(_Packet)->sr_PoolHandle;
NdisReInitializePacket(_Packet);
SEND_RESD(_Packet)->sr_PoolHandle = (_Handle);
}
#define SpxReInitRecvPacket(_Packet)
{
NDIS_HANDLE _Handle = RECV_RESD(_Packet)->rr_PoolHandle;
NdisReInitializePacket(_Packet);
RECV_RESD(_Packet)->rr_PoolHandle = (_Handle);
}
#define SEND_RESD(_Packet) ((PSPX_SEND_RESD)((_Packet)->ProtocolReserved))
#define RECV_RESD(_Packet) ((PSPX_RECV_RESD)((_Packet)->ProtocolReserved))
#else
#define SpxAllocSendPacket(_Device, _SendPacket, _Status) \
{ \
if (*(_SendPacket) = SpxBPAllocBlock(BLKID_NDISSEND)) \
*(_Status) = NDIS_STATUS_SUCCESS; \
else \
*(_Status) = NDIS_STATUS_RESOURCES; \
}
#define SpxAllocRecvPacket(_Device,_RecvPacket,_Status) \
{ \
if (*(_RecvPacket) = SpxBPAllocBlock(BLKID_NDISRECV)) \
*(_Status) = NDIS_STATUS_SUCCESS; \
else \
*(_Status) = NDIS_STATUS_RESOURCES; \
}
#define SpxFreeSendPacket(_Device,_Packet) \
{ \
SpxBPFreeBlock(_Packet, BLKID_NDISSEND); \
}
#define SpxFreeRecvPacket(_Device,_Packet) \
{ \
SpxBPFreeBlock(_Packet, BLKID_NDISRECV); \
}
#define SpxReInitSendPacket(_Packet) \
{ \
}
#define SpxReInitRecvPacket(_Packet) \
{ \
}
#define SEND_RESD(_Packet) ((PSPX_SEND_RESD)((_Packet)->ProtocolReserved))
#define RECV_RESD(_Packet) ((PSPX_RECV_RESD)((_Packet)->ProtocolReserved))
#endif
//
// Routine Prototypes
//
VOID
SpxPktBuildCr(
IN struct _SPX_CONN_FILE * pSpxConnFile,
IN struct _SPX_ADDR * pSpxAddr,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State,
IN BOOLEAN fSpx2);
VOID
SpxPktBuildCrAck(
IN struct _SPX_CONN_FILE * pSpxConnFile,
IN struct _SPX_ADDR * pSpxAddr,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State,
IN BOOLEAN fNeg,
IN BOOLEAN fSpx2);
VOID
SpxPktBuildSn(
IN struct _SPX_CONN_FILE * pSpxConnFile,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State);
VOID
SpxPktBuildSs(
IN struct _SPX_CONN_FILE * pSpxConnFile,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State);
VOID
SpxPktBuildSsAck(
IN struct _SPX_CONN_FILE * pSpxConnFile,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State);
VOID
SpxPktBuildSnAck(
IN struct _SPX_CONN_FILE * pSpxConnFile,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State);
VOID
SpxPktBuildRr(
IN struct _SPX_CONN_FILE * pSpxConnFile,
OUT PNDIS_PACKET * ppPkt,
IN USHORT SeqNum,
IN USHORT State);
VOID
SpxPktBuildRrAck(
IN struct _SPX_CONN_FILE * pSpxConnFile,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State,
IN USHORT MaxPktSize);
VOID
SpxPktBuildProbe(
IN struct _SPX_CONN_FILE * pSpxConnFile,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State,
IN BOOLEAN fSpx2);
VOID
SpxPktBuildData(
IN struct _SPX_CONN_FILE * pSpxConnFile,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State,
IN USHORT Length);
VOID
SpxCopyBufferChain(
OUT PNDIS_STATUS Status,
OUT PNDIS_BUFFER * TargetChain,
IN NDIS_HANDLE PoolHandle,
IN PNDIS_BUFFER SourceChain,
IN UINT Offset,
IN UINT Length
);
VOID
SpxPktBuildAck(
IN struct _SPX_CONN_FILE * pSpxConnFile,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State,
IN BOOLEAN fBuildNack,
IN USHORT NumToResend);
VOID
SpxPktBuildDisc(
IN struct _SPX_CONN_FILE * pSpxConnFile,
IN PREQUEST pRequest,
OUT PNDIS_PACKET * ppPkt,
IN USHORT State,
IN UCHAR DataType);
VOID
SpxPktRecvRelease(
IN PNDIS_PACKET pPkt);
VOID
SpxPktSendRelease(
IN PNDIS_PACKET pPkt);
|