/*++ 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 // // List of NDIS_PACKETS stored... // extern SLIST_HEADER SendPacketList; extern SLIST_HEADER RecvPacketList; EXTERNAL_LOCK(RecvHeaderLock); EXTERNAL_LOCK(SendHeaderLock); // 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 // 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 // NDIS Packet size - two more ulongs added... 11/26/96 #define NDIS_PACKET_SIZE 48+8 // 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. // 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. SINGLE_LIST_ENTRY Linkage; } 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 SINGLE_LIST_ENTRY Linkage; 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)); \ } #ifdef UNDEFINDED #define SpxAllocRecvPacket(_Device,_RecvPacket,_Status) \ { \ PSINGLE_LIST_ENTRY Link; \ \ Link = ExInterlockedPopEntrySList( \ &PacketList, \ &HeaderLock \ ); \ \ if (Link != NULL) { \ Common = STRUCT_OF(struct PCCommon, Link, pc_link); \ PC = STRUCT_OF(PacketContext, Common, pc_common); \ (*_RecvPacket) = STRUCT_OF(NDIS_PACKET, PC, ProtocolReserved); \ (*_Status) = NDIS_STATUS_SUCCESS; \ } else { \ \ (*_RecvPacket) = GrowSPXPacketsList(); \ (*_Status) = NDIS_STATUS_SUCCESS; \ if (NULL == _RecvPacket) { \ DBGPRINT(NDIS, ("Couldn't grow packets allocated...\r\n")); \ (*_Status) = NDIS_STATUS_RESOURCES; \ } \ } \ } #define SpxFreeSendPacket(_Device,_Packet) \ { \ DBGPRINT(NDIS \ ("SpxFreeSendPacket\n")); \ SpxFreePacket(_Device, _Packet); \ } \ #define SpxFreeRecvPacket(_Device,_Packet) \ { \ DBGPRINT(NDIS \ ("SpxFreeRecvPacket\n")); \ SpxFreePacket(_Device, _Packet); \ } \ #define SpxReInitSendPacket(_Packet) \ { \ DBGPRINT(NDIS \ ("SpxReInitSendPacket\n")); \ } \ #define SpxReInitRecvPacket(_Packet) \ { \ DBGPRINT(NDIS, \ ("SpxReInitRecvPacket\n")); \ } \ #endif #if !defined SPX_OWN_PACKETS #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 #if !defined SPX_OWN_PACKETS // // If we DO NOT use SPX_OWN_PACKETS, we would rather make it a function call // PNDIS_PACKET SpxAllocSendPacket( IN PDEVICE _Device, OUT PNDIS_PACKET *_SendPacket, OUT PNDIS_STATUS _Status ); PNDIS_PACKET SpxAllocRecvPacket( IN PDEVICE _Device, OUT PNDIS_PACKET *_SendPacket, OUT PNDIS_STATUS _Status ); void SpxFreeSendPacket( PDEVICE _Device, PNDIS_PACKET _Packet ); void SpxFreeRecvPacket( PDEVICE _Device, PNDIS_PACKET _Packet ); void SpxReInitSendPacket( PNDIS_PACKET _Packet ); void SpxReInitRecvPacket( PNDIS_PACKET _Packet ); #endif // SPX_OWN_PACKETS // // 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);