windows-nt/Source/XPSP1/NT/net/nwlink/spx/spxpkt.h
2020-09-26 16:20:57 +08:00

531 lines
16 KiB
C

/*++
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 <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 - 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);