|
|
#ifndef _PACKET_H_
#define _PACKET_H_
#ifndef _PPPOE_VERSION
#define _PPPOE_VERSION 1
#endif
typedef struct _ADAPTER* PADAPTER; typedef struct _BINDING* PBINDING;
//
// Network-to-Host and vice versa conversion macros
//
#if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175))
#define htons(x) _byteswap_ushort((USHORT)(x))
#define htonl(x) _byteswap_ulong((ULONG)(x))
#else
#define htons( a ) ((((a) & 0xFF00) >> 8) |\
(((a) & 0x00FF) << 8)) #define htonl( a ) ((((a) & 0xFF000000) >> 24) | \
(((a) & 0x00FF0000) >> 8) | \ (((a) & 0x0000FF00) << 8) | \ (((a) & 0x000000FF) << 24)) #endif
#define ntohs( a ) htons(a)
#define ntohl( a ) htonl(a)
//
// Constants related to packet lengths
//
#define PPPOE_PACKET_BUFFER_SIZE 1514
#define ETHERNET_HEADER_LENGTH 14
#define PPPOE_PACKET_HEADER_LENGTH 20 // Per RFC2156
#define PPPOE_TAG_HEADER_LENGTH 4 // Per RFC2156
#define PPP_MAX_HEADER_LENGTH 14 // maximum possible header length for ppp
#define PPPOE_AC_COOKIE_TAG_LENGTH 6
//
// Offsets for the header members
//
#define PPPOE_PACKET_DEST_ADDR_OFFSET 0 // Per RFC2156
#define PPPOE_PACKET_SRC_ADDR_OFFSET 6 // Per RFC2156
#define PPPOE_PACKET_ETHER_TYPE_OFFSET 12 // Per RFC2156
#define PPPOE_PACKET_VERSION_OFFSET 14 // Per RFC2156
#define PPPOE_PACKET_TYPE_OFFSET 14 // Per RFC2156
#define PPPOE_PACKET_CODE_OFFSET 15 // Per RFC2156
#define PPPOE_PACKET_SESSION_ID_OFFSET 16 // Per RFC2156
#define PPPOE_PACKET_LENGTH_OFFSET 18 // Per RFC2156
//
// Macros to set information in the header of the packet
//
#define PacketSetDestAddr( pP, addr ) \
NdisMoveMemory( ( pP->pHeader + PPPOE_PACKET_DEST_ADDR_OFFSET ), addr, 6 )
#define PacketSetSrcAddr( pP, addr ) \
NdisMoveMemory( ( pP->pHeader + PPPOE_PACKET_SRC_ADDR_OFFSET ), addr, 6 )
#define PacketSetEtherType( pP, type ) \
* ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_ETHER_TYPE_OFFSET ) = htons( (USHORT) type )
#define PacketSetVersion( pP, ver ) \
* ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_VERSION_OFFSET ) |= ( ( ( (UCHAR) ver ) << 4 ) & PACKET_VERSION_MASK )
#define PacketSetType( pP, type ) \
* ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_TYPE_OFFSET ) |= ( ( (UCHAR) type ) & PACKET_TYPE_MASK )
#define PacketSetCode( pP, code ) \
* ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_CODE_OFFSET ) = ( (UCHAR) code )
#define PacketSetSessionId( pP, ses_id ) \
* ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_SESSION_ID_OFFSET ) = htons( (USHORT) ses_id )
#define PacketSetLength( pP, len) \
* ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_LENGTH_OFFSET ) = htons( (USHORT) len )
#define PacketSetSendCompletionStatus( pP, s ) \
( pP->SendCompletionStatus = s )
//
// Macros to get information from the header of the packet
//
#define PacketGetDestAddr( pP ) \
( pP->pHeader + PPPOE_PACKET_DEST_ADDR_OFFSET )
#define PacketGetSrcAddr( pP ) \
( pP->pHeader + PPPOE_PACKET_SRC_ADDR_OFFSET )
#define PacketGetEtherType( pP ) \
ntohs( * ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_ETHER_TYPE_OFFSET ) )
#define PacketGetVersion( pP ) \
( ( ( * ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_VERSION_OFFSET ) ) & PACKET_VERSION_MASK ) >> 4 )
#define PacketGetType( pP ) \
( ( * ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_TYPE_OFFSET ) ) & PACKET_TYPE_MASK )
#define PacketGetCode( pP ) \
( * ( UCHAR UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_CODE_OFFSET ) )
#define PacketGetSessionId( pP ) \
ntohs( * ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_SESSION_ID_OFFSET ) )
#define PacketGetLength( pP ) \
ntohs( * ( USHORT UNALIGNED * ) ( pP->pHeader + PPPOE_PACKET_LENGTH_OFFSET ) )
#define PacketGetSendCompletionStatus( pP ) \
( pP->SendCompletionStatus )
//
// Macro that returns the Ndis Packet for a PPPoE packet
//
#define PacketGetNdisPacket( pP ) \
( pP->pNdisPacket )
//
// This structure is just a map, and it is not actually used in the code
//
typedef struct _PPPOE_HEADER {
CHAR DestAddr[6]; CHAR SrcAddr[6]; #define PACKET_BROADCAST_ADDRESS EthernetBroadcastAddress
USHORT usEtherType; #define PACKET_ETHERTYPE_DISCOVERY 0x8863
#define PACKET_ETHERTYPE_PAYLOAD 0x8864
union { //
// Version field is 4 bits and MUST be set to 0x1 for this version
//
CHAR usVersion; #define PACKET_VERSION_MASK 0xf0
#define PACKET_VERSION (USHORT)0x1
//
// Type field is 4 bits and MUST be set to 0x1 for this version
//
CHAR usType; #define PACKET_TYPE_MASK 0x0f
#define PACKET_TYPE (USHORT)0x1
} uVerType; //
// Code field is 8 bits and is defined as follows for Version 1
// Values selected from enumerated type PACKET_CODES (see below)
//
CHAR usCode; //
// Session Id field is 16 bits and define a unique session combined with
// the source and destination addresses
//
USHORT usSessionId; #define PACKET_NULL_SESSION 0x0000
//
// Length field is 16 bits and indicates the length of the payload field only.
// The length field excludes the PPPoE header block.
//
USHORT usLength; //
// Subtract Header size from Max PADI and MAX payload lengths per RFC2156
//
#define PACKET_PADI_MAX_LENGTH 1478 // (1514 - 20 - 16)
#define PACKET_GEN_MAX_LENGTH 1494 // (1514 - 20)
#define PACKET_PPP_PAYLOAD_MAX_LENGTH 1480 // (1514 - 20)
} PPPOE_HEADER;
//
// PACKET CODES defined by RFC2156
//
typedef enum _PACKET_CODES { PACKET_CODE_PADI = 0x09, PACKET_CODE_PADO = 0x07, PACKET_CODE_PADR = 0x19, PACKET_CODE_PADS = 0x65, PACKET_CODE_PADT = 0xa7, PACKET_CODE_PAYLOAD = 0x00 } PACKET_CODES;
//
// TAGS defined by RFC2156
//
typedef enum _PACKET_TAGS { tagEndOfList = 0x0000, tagServiceName = 0x0101, tagACName = 0x0102, tagHostUnique = 0x0103, tagACCookie = 0x0104, tagVendorSpecific = 0x0105,
tagRelaySessionId = 0x0110,
tagServiceNameError = 0x0201, tagACSystemError = 0x0202, tagGenericError = 0x0204 } PACKET_TAGS;
//
// This is the packet context.
//
// CAUTION: Packets are not protected by their own locks, however they must be accessed carefully
// by using their owner's locks.
//
typedef struct _PPPOE_PACKET { //
// Points to the previous and next packet contexts when in a doubly linked list
//
LIST_ENTRY linkPackets;
//
// Keeps references on the packet
// References added and removed for the following operations:
//
// (a) A reference is added when a packet is created and removed when it is freed.
//
// (b) A reference must be added before sending the packet and must be removed when
// send operation is completed.
//
LONG lRef;
//
// Quick look-up for tags.
//
// The value pointers mark the beginning of the tag value in the pPacket->pPayload section.
// The length values show the lengths of the values (not including the tag header)
//
USHORT tagServiceNameLength; CHAR* tagServiceNameValue;
USHORT tagACNameLength; CHAR* tagACNameValue;
USHORT tagHostUniqueLength; CHAR* tagHostUniqueValue;
USHORT tagACCookieLength; CHAR* tagACCookieValue;
USHORT tagRelaySessionIdLength; CHAR* tagRelaySessionIdValue;
PACKET_TAGS tagErrorType; USHORT tagErrorTagLength; CHAR* tagErrorTagValue;
//
// Points to the buffer that holds the header portion of a PPPoE packet in wire format.
// This points to the buffer portion of pNdisBuffer (see below)
//
CHAR* pHeader;
//
// Points to the payload portion of a PPPoE packet in wire format.
// This is calculated and is set as : pPacket->pHeader + PPPOE_PACKET_HEADER_LENGTH
//
CHAR* pPayload;
//
// Bit flags that identifies the nature of the buffer and packet
//
// (a) PCBF_BufferAllocatedFromNdisBufferPool: Indicates that pNdisBuffer points to a buffer allocated
// from gl_hNdisBufferpool, and it must be freed to that pool.
//
// (b) PCBF_BufferAllocatedFromOurBufferPool: Indicates that pNdisBuffer points to a buffer allocated
// from gl_poolBuffers, and it must be freed to that pool.
//
// (c) PCBF_PacketAllocatedFromOurPacketPool: Indicates that pNdisPacket points to a packet allocated
// from gl_poolPackets, and it must be freed to that pool.
//
// (d) PCBF_BufferChainedToPacket: Indicates that the buffer pointed to by pNdisBuffer is chained to
// the packet pointed to by pNdisPacket, and must be unchained before
// returning them back to their pools.
//
// (e) PCBF_CallNdisReturnPackets: Indicates that the packet was created using PacketCreateFromReceived()
// and we should call NdisReturnPackets() when we are done with it to
// return it back to NDIS.
//
//
// (f) PCBF_ErrorTagReceived: This flag is valid only for received packets.
// It indicates that when the packet was processed and a PPPoE packet was created
// some error tags were noticed in the packet.
//
ULONG ulFlags; #define PCBF_BufferAllocatedFromNdisBufferPool 0x00000001
#define PCBF_BufferAllocatedFromOurBufferPool 0x00000002
#define PCBF_PacketAllocatedFromOurPacketPool 0x00000004
#define PCBF_BufferChainedToPacket 0x00000008
#define PCBF_CallNdisReturnPackets 0x00000010
#define PCBF_CallNdisMWanSendComplete 0x00000020
#define PCBF_ErrorTagReceived 0x00000040
#define PCBF_PacketIndicatedIncomplete 0x00000080
//
// Pointer to the NdisBuffer
//
NDIS_BUFFER* pNdisBuffer;
//
// Points directly to the NDIS_PACKET
//
NDIS_PACKET* pNdisPacket; //
// pPacket->pNdisPacket->ProtocolReserved[0 * sizeof(PVOID)] = (PVOID) pPPPoEPacket;
// pPacket->pNdisPacket->ProtocolReserved[1 * sizeof(PVOID)] = (PVOID) pNdiswanPacket;
// pPacket->pNdisPacket->ProtocolReserved[2 * sizeof(PVOID)] = (PVOID) miniportAdapter;
//
//
// Points to the PACKETHEAD struct in ppool.h. It contains the pointer to NDIS_PACKET
//
PACKETHEAD* pPacketHead;
//
// This is needed to dereference the binding when PCBF_CallNdisReturnPackets flag is set.
//
PBINDING pBinding;
//
// Send completion status for the packet
//
NDIS_STATUS SendCompletionStatus;
} PPPOE_PACKET;
VOID PacketPoolInit();
VOID PacketPoolUninit();
VOID PacketPoolAlloc();
VOID PacketPoolFree();
PPPOE_PACKET* PacketAlloc();
VOID PacketFree( IN PPPOE_PACKET* pPacket ); VOID ReferencePacket( IN PPPOE_PACKET* pPacket );
VOID DereferencePacket( IN PPPOE_PACKET* pPacket );
PPPOE_PACKET* PacketCreateSimple();
PPPOE_PACKET* PacketCreateForReceived( PBINDING pBinding, PNDIS_PACKET pNdisPacket, PNDIS_BUFFER pNdisBuffer, PUCHAR pContents );
PPPOE_PACKET* PacketNdis2Pppoe( IN PBINDING pBinding, IN PNDIS_PACKET pNdisPacket, OUT PINT pRefCount );
BOOLEAN PacketFastIsPPPoE( IN CHAR* HeaderBuffer, IN UINT HeaderBufferSize ); VOID RetrieveTag( IN OUT PPPOE_PACKET* pPacket, IN PACKET_TAGS tagType, OUT USHORT* pTagLength, OUT CHAR** pTagValue, IN USHORT prevTagLength, IN CHAR* prevTagValue, IN BOOLEAN fSetTagInPacket );
NDIS_STATUS PacketInsertTag( IN PPPOE_PACKET* pPacket, IN PACKET_TAGS tagType, IN USHORT tagLength, IN CHAR* tagValue, OUT CHAR** pNewTagValue );
NDIS_STATUS PacketInitializePADIToSend( OUT PPPOE_PACKET** ppPacket, IN USHORT tagServiceNameLength, IN CHAR* tagServiceNameValue, IN USHORT tagHostUniqueLength, IN CHAR* tagHostUniqueValue );
NDIS_STATUS PacketInitializePADOToSend( IN PPPOE_PACKET* pPADI, OUT PPPOE_PACKET** ppPacket, IN CHAR* pSrcAddr, IN USHORT tagServiceNameLength, IN CHAR* tagServiceNameValue, IN USHORT tagACNameLength, IN CHAR* tagACNameValue, IN BOOLEAN fInsertACCookieTag ); NDIS_STATUS PacketInitializePADRToSend( IN PPPOE_PACKET* pPADO, OUT PPPOE_PACKET** ppPacket, IN USHORT tagServiceNameLength, IN CHAR* tagServiceNameValue, IN USHORT tagHostUniqueLength, IN CHAR* tagHostUniqueValue );
NDIS_STATUS PacketInitializePADSToSend( IN PPPOE_PACKET* pPADR, OUT PPPOE_PACKET** ppPacket, IN USHORT usSessionId );
NDIS_STATUS PacketInitializePADTToSend( OUT PPPOE_PACKET** ppPacket, IN CHAR* pSrcAddr, IN CHAR* pDestAddr, IN USHORT usSessionId ); NDIS_STATUS PacketInitializePAYLOADToSend( OUT PPPOE_PACKET** ppPacket, IN CHAR* pSrcAddr, IN CHAR* pDestAddr, IN USHORT usSessionId, IN NDIS_WAN_PACKET* pWanPacket, IN PADAPTER MiniportAdapter );
NDIS_STATUS PacketInitializeFromReceived( IN PPPOE_PACKET* pPacket );
BOOLEAN PacketAnyErrorTagsReceived( IN PPPOE_PACKET* pPacket );
VOID PacketRetrievePayload( IN PPPOE_PACKET* pPacket, OUT CHAR** ppPayload, OUT USHORT* pusLength );
VOID PacketRetrieveServiceNameTag( IN PPPOE_PACKET* pPacket, OUT USHORT* pTagLength, OUT CHAR** pTagValue, IN USHORT prevTagLength, IN CHAR* prevTagValue ); VOID PacketRetrieveHostUniqueTag( IN PPPOE_PACKET* pPacket, OUT USHORT* pTagLength, OUT CHAR** pTagValue );
VOID PacketRetrieveACNameTag( IN PPPOE_PACKET* pPacket, OUT USHORT* pTagLength, OUT CHAR** pTagValue );
VOID PacketRetrieveACCookieTag( IN PPPOE_PACKET* pPacket, OUT USHORT* pTagLength, OUT CHAR** pTagValue );
VOID PacketRetrieveErrorTag( IN PPPOE_PACKET* pPacket, OUT PACKET_TAGS* pTagType, OUT USHORT* pTagLength, OUT CHAR** pTagValue ); PPPOE_PACKET* PacketGetRelatedPppoePacket( IN NDIS_PACKET* pNdisPacket );
NDIS_WAN_PACKET* PacketGetRelatedNdiswanPacket( IN PPPOE_PACKET* pPacket );
PADAPTER PacketGetMiniportAdapter( IN PPPOE_PACKET* pPacket );
PPPOE_PACKET* PacketMakeClone( IN PPPOE_PACKET* pPacket );
VOID PacketGenerateACCookieTag( IN PPPOE_PACKET* pPacket, IN CHAR tagACCookieValue[ PPPOE_AC_COOKIE_TAG_LENGTH ] );
BOOLEAN PacketValidateACCookieTagInPADR( IN PPPOE_PACKET* pPacket );
//////////////////////////////////////////////////////////
//
// Error codes and messages
//
//////////////////////////////////////////////////////////
#define PPPOE_ERROR_BASE 0
#define PPPOE_NO_ERROR PPPOE_ERROR_BASE
#define PPPOE_ERROR_SERVICE_NOT_SUPPORTED PPPOE_ERROR_BASE + 1
#define PPPOE_ERROR_SERVICE_NOT_SUPPORTED_MSG "Service not supported"
#define PPPOE_ERROR_SERVICE_NOT_SUPPORTED_MSG_SIZE ( sizeof( PPPOE_ERROR_SERVICE_NOT_SUPPORTED_MSG ) / sizeof( CHAR ) )
#define PPPOE_ERROR_INVALID_AC_COOKIE_TAG PPPOE_ERROR_BASE + 2
#define PPPOE_ERROR_INVALID_AC_COOKIE_TAG_MSG "AC-Cookie tag is invalid"
#define PPPOE_ERROR_INVALID_AC_COOKIE_TAG_MSG_SIZE ( sizeof( PPPOE_ERROR_INVALID_AC_COOKIE_TAG_MSG ) / sizeof( CHAR ) )
#define PPPOE_ERROR_CLIENT_QUOTA_EXCEEDED PPPOE_ERROR_BASE + 3
#define PPPOE_ERROR_CLIENT_QUOTA_EXCEEDED_MSG "Can not accept any more connections from this machine"
#define PPPOE_ERROR_CLIENT_QUOTA_EXCEEDED_MSG_SIZE ( sizeof( PPPOE_ERROR_CLIENT_QUOTA_EXCEEDED_MSG ) / sizeof( CHAR ) )
#endif
|