www.pudn.com > PPPOE.rar > pppoepkt.cpp
//********************************************************************
// ÈÕÆÚ: 2004/08/24 - 24:8:2004 22:30
// Ãûǰ: tiamo
// ÃèÊö: pppoe
//*********************************************************************
#include "Stdafx.h"
// insert tag in packet
VOID PacketInsertTag(USHORT ucTag,PPACKET pPacket,PUCHAR pBuffer,USHORT usLen,PUCHAR *ppOutBuffer)
{
if(ppOutBuffer)
*ppOutBuffer = NULL;
USHORT usCurrentLen = ntohs(pPacket->m_pFrame->m_pppFrame.m_usLen);
USHORT usMaxLen = pPacket->m_pFrame->m_pppFrame.m_ucCode == PPPOE_CODE_PADI ? PPPOE_MAX_DATA_SIZE : PPPOE_MAX_PADI_DATA_SIZE;
// check size
if(usCurrentLen + usLen + sizeof(PPP_TAG) > usMaxLen)
{
// must have a seh frame
ExRaiseStatus(NDIS_STATUS_BUFFER_OVERFLOW);
}
// set tag
PPPP_TAG pTag = reinterpret_cast(pPacket->m_pucDataBuffer + usCurrentLen);
pTag->m_usType = ucTag;
pTag->m_usLen = htons(usLen);
if(ppOutBuffer)
*ppOutBuffer = pPacket->m_pucDataBuffer + usCurrentLen + sizeof(PPP_TAG);
// check buffer pointer first,then copy it
if(pBuffer)
{
NdisMoveMemory(pTag + 1,pBuffer,usLen);
}
// modify len
pPacket->m_pFrame->m_pppFrame.m_usLen = htons(usCurrentLen + usLen + sizeof(PPP_TAG));
}
// prepare packet for send
VOID PreparePacketForSend(PPACKET pPacket)
{
/*
* Serive AC Host ACCookie Relay
* 101 102 103 104 110
* PAY_LOAD
* PADT
* PADI: M O
* PADO: M O O O O
* PADR: M O O O
* PADS: M O O
*/
switch(pPacket->m_pFrame->m_pppFrame.m_ucCode)
{
// pay load
case PPPOE_CODE_PAY_LOAD:
// PADT
case PPPOE_CODE_PADT:
break;
// PADO
case PPPOE_CODE_PADO:
// 0x102 AC name
PacketInsertTag(PPPOE_TAG_AC,pPacket,pPacket->m_pACName,pPacket->m_usACName,&pPacket->m_pACName);
// fall through
// PADR
case PPPOE_CODE_PADR:
// 0x104 AC cookie
if(pPacket->m_pFrame->m_pppFrame.m_ucCode != PPPOE_CODE_PADR || pPacket->m_usACCookie)
PacketInsertTag(PPPOE_TAG_AC_COOKIE,pPacket,pPacket->m_pACCookie,pPacket->m_usACCookie,&pPacket->m_pACCookie);
// fall through
// PADS
case PPPOE_CODE_PADS:
// 0x110 relay session id
if(pPacket->m_usRelaySessionId)
PacketInsertTag(PPPOE_TAG_RELAY_SESSION_ID,pPacket,pPacket->m_pRelaySessionId,pPacket->m_usRelaySessionId,
&pPacket->m_pRelaySessionId);
// fall through
// PADI
case PPPOE_CODE_PADI:
// 0x101 service name
PacketInsertTag(PPPOE_TAG_SERVICE,pPacket,pPacket->m_pServiceName,pPacket->m_usServiceName,&pPacket->m_pServiceName);
// 0x103 host unique
if(pPacket->m_usHostUnique)
PacketInsertTag(PPPOE_TAG_HOST_UNIQUE,pPacket,pPacket->m_pHostUnique,pPacket->m_usHostUnique,
&pPacket->m_pHostUnique);
break;
}
// set buffer len
NdisAdjustBufferLength(pPacket->m_pNdisDataBuffer,ntohs(pPacket->m_pFrame->m_pppFrame.m_usLen));
}
// build packet for send
PPACKET BuildPacketForSend(PCHANNEL pChannel,PNDIS_PACKET pOrgPacket)
{
PPACKET pRetPacket = NULL;
NDIS_STATUS status;
__try
{
// alloc the packet
pRetPacket = AllocPacket();
pRetPacket->m_pNdisPacket = GetNdisPacketFromPool(&g_poolPacket,&pRetPacket->m_pPacketItem);
PPROTOCOL_RESERVED pResv = reinterpret_cast(pRetPacket->m_pNdisPacket->ProtocolReserved);
pResv->m_pPacket = pRetPacket;
pResv->m_pOrginalPacket = pOrgPacket;
pResv->m_pChannel = pChannel;
// packet from pool
pRetPacket->m_ulFlags |= PPPOE_PACKET_FROM_POOL;
// packet len
UINT uLen;
NdisQueryPacketLength(pOrgPacket,&uLen);
// get data buffer,unchain if
NdisUnchainBufferAtFront(pOrgPacket,&pRetPacket->m_pNdisDataBuffer);
// send complete needed
pRetPacket->m_ulFlags |= PPPOE_PACKET_NEED_CALL_SEND_COMPLETE;
// chain data buffer first
NdisChainBufferAtFront(pRetPacket->m_pNdisPacket,pRetPacket->m_pNdisDataBuffer);
pRetPacket->m_ulFlags |= PPPOE_PACKET_DATA_BUFFER_CHAINED;
// allocate header buffer
NdisAllocateBuffer(&status,&pRetPacket->m_pNdisHeaderBuffer,g_hNdisBufferPool,&pRetPacket->m_ethFrame,PPPOE_HEADER_LEN);
// chain header buffer
NdisChainBufferAtFront(pRetPacket->m_pNdisPacket,pRetPacket->m_pNdisHeaderBuffer);
pRetPacket->m_ulFlags |= (PPPOE_PACKET_HEADER_BUFFER_CHAINED | PPPOE_PACKET_HEADER_BUFFER_FROM_NDIS);
// set frame pointer,data buffer do not need to set,we will not touch it;
pRetPacket->m_pFrame = &pRetPacket->m_ethFrame;
// copy dst and src mac addr
NdisMoveMemory(pRetPacket->m_pFrame->m_dstMac,pChannel->m_macPeer,ETH_ADDR_LEN);
NdisMoveMemory(pRetPacket->m_pFrame->m_srcMac,pChannel->m_macSelf,ETH_ADDR_LEN);
// set ethernet type
pRetPacket->m_pFrame->m_usProtocolType = PPPOE_SESSION;
// set session id
pRetPacket->m_pFrame->m_pppFrame.m_usSession = htons(pChannel->m_usSessionId);
// set other
pRetPacket->m_pFrame->m_pppFrame.m_ucCode = PPPOE_CODE_PAY_LOAD;
pRetPacket->m_pFrame->m_pppFrame.m_ucType = PPPOE_TYPE;
pRetPacket->m_pFrame->m_pppFrame.m_ucVer = PPPOE_VER;
pRetPacket->m_pFrame->m_pppFrame.m_usLen = htons(static_cast(uLen));
// prepare it
PreparePacketForSend(pRetPacket);
// inc send packets
NdisInterlockedIncrement(&pChannel->m_lSendingPackets);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(pRetPacket)
{
DereferencePacket(pRetPacket);
pRetPacket = NULL;
}
}
return pRetPacket;
}
// init packet member value
BOOLEAN InitializePacketForRecved(PPACKET pPacket)
{
/*
* Serive AC Host ACCookie Relay
* 101 102 103 104 110
* PAY_LOAD
* PADT
* PADI: M O O
* PADO: M M O O O
* PADR: M O O O
* PADS: M O
*/
// check pppoe format
if(!CheckIsPPPoEPacket(pPacket))
return FALSE;
// check len
UCHAR ucCode = pPacket->m_pFrame->m_pppFrame.m_ucCode;
// ctrl packet only check len
if(ucCode)
{
PUCHAR pEnd = pPacket->m_pucDataBuffer + ntohs(pPacket->m_pFrame->m_pppFrame.m_usLen);
PUCHAR pCurrent = pPacket->m_pucDataBuffer;
while(pCurrent < pEnd)
{
PPPP_TAG pTag = reinterpret_cast(pCurrent);
pCurrent += ntohs(pTag->m_usLen) + sizeof(PPP_TAG);
}
if(pCurrent != pEnd)
return FALSE;
}
// build member value
switch(pPacket->m_pFrame->m_pppFrame.m_ucCode)
{
case PPPOE_CODE_PAY_LOAD:
case PPPOE_CODE_PADT:
break;
// PADO
case PPPOE_CODE_PADO:
{
// get service name
RetrieveTag(PPPOE_TAG_SERVICE,pPacket,&pPacket->m_pServiceName,&pPacket->m_usServiceName,TRUE);
if(pPacket->m_pServiceName)
{
// get ac name
RetrieveTag(PPPOE_TAG_AC,pPacket,&pPacket->m_pACName,&pPacket->m_usACName,TRUE);
if(pPacket->m_pACName)
{
// ac cookie
RetrieveTag(PPPOE_TAG_AC_COOKIE,pPacket,&pPacket->m_pACCookie,&pPacket->m_usACCookie,TRUE);
// host unique
RetrieveTag(PPPOE_TAG_HOST_UNIQUE,pPacket,&pPacket->m_pHostUnique,&pPacket->m_usHostUnique,TRUE);
// relay session id
RetrieveTag(PPPOE_TAG_RELAY_SESSION_ID,pPacket,&pPacket->m_pRelaySessionId,&pPacket->m_usRelaySessionId,TRUE);
}
}
}
break;
// PADI
case PPPOE_CODE_PADI:
{
// get service name
RetrieveTag(PPPOE_TAG_SERVICE,pPacket,&pPacket->m_pServiceName,&pPacket->m_usServiceName,TRUE);
if(pPacket->m_pServiceName)
{
// host unique
RetrieveTag(PPPOE_TAG_HOST_UNIQUE,pPacket,&pPacket->m_pHostUnique,&pPacket->m_usHostUnique,TRUE);
// relay session id
RetrieveTag(PPPOE_TAG_RELAY_SESSION_ID,pPacket,&pPacket->m_pRelaySessionId,&pPacket->m_usRelaySessionId,TRUE);
}
}
break;
// PADR
case PPPOE_CODE_PADR:
{
// get service name
RetrieveTag(PPPOE_TAG_SERVICE,pPacket,&pPacket->m_pServiceName,&pPacket->m_usServiceName,TRUE);
if(pPacket->m_pServiceName)
{
// ac cookie
RetrieveTag(PPPOE_TAG_AC_COOKIE,pPacket,&pPacket->m_pACCookie,&pPacket->m_usACCookie,TRUE);
// host unique
RetrieveTag(PPPOE_TAG_HOST_UNIQUE,pPacket,&pPacket->m_pHostUnique,&pPacket->m_usHostUnique,TRUE);
// relay session id
RetrieveTag(PPPOE_TAG_RELAY_SESSION_ID,pPacket,&pPacket->m_pRelaySessionId,&pPacket->m_usRelaySessionId,TRUE);
}
}
break;
// PADS
case PPPOE_CODE_PADS:
{
// get service name
RetrieveTag(PPPOE_TAG_SERVICE,pPacket,&pPacket->m_pServiceName,&pPacket->m_usServiceName,TRUE);
if(pPacket->m_pServiceName)
{
// host unique
RetrieveTag(PPPOE_TAG_HOST_UNIQUE,pPacket,&pPacket->m_pHostUnique,&pPacket->m_usHostUnique,TRUE);
}
}
break;
}
// get error tag
RetrieveErrorTag(pPacket);
return TRUE;
}
// convert recved ndis packet
PPACKET ConvertRecvedNdisPacket(PBIND_CONTEXT pBind,PNDIS_PACKET pNdisPacket,PBOOLEAN pNeedCallReturn)
{
*pNeedCallReturn = FALSE;
PPACKET pPacket = NULL;
PNDIS_BUFFER pFirstBuffer = NULL;
UINT nBufferCount = 0;
UINT nTotalLen = 0;
// query packet
NdisQueryPacket(pNdisPacket,NULL,&nBufferCount,&pFirstBuffer,&nTotalLen);
// check len
if(nTotalLen > PPPOE_MAX_ETH_FRAME_SIZE)
return NULL;
// get status
NDIS_STATUS status = NDIS_GET_PACKET_STATUS(pNdisPacket);
// we can use the buffer in the packet
if(status != NDIS_STATUS_RESOURCES && nBufferCount == 1)
{
PPPPOE_FRAME pFrame;
UINT uLen;
// query buffer
NdisQueryBufferSafe(pFirstBuffer,(PVOID *)&pFrame,&uLen,NormalPagePriority);
// check return value
if(pFrame && uLen > PPPOE_MIN_ETH_FRAME_SIZE)
{
// check pppoe frame
if(FastCheckIsPPPoEFrame(pFrame,PPPOE_MIN_ETH_FRAME_SIZE))
{
// check frame size
if((UINT)ntohs(pFrame->m_pppFrame.m_usLen) <= uLen)
{
// reuse the buffers
pPacket = ReuseRecvedPacketBuffer(pBind,pNdisPacket,pFrame,nTotalLen);
}
}
}
if(pPacket)
{
*pNeedCallReturn = TRUE;
NdisInterlockedIncrement(&pBind->m_lPacketNeedReturn);
}
}
else
{
// create new packet
pPacket = GetSimplePacket();
UINT uCurrentOffset = 0;
PUCHAR pFrame;
UINT uLen;
for(;pFirstBuffer;)
{
// query buffer
NdisQueryBufferSafe(pFirstBuffer,(PVOID *)&pFrame,&uLen,NormalPagePriority);
NdisMoveMemory(pPacket->m_pucFrame + uCurrentOffset,pFrame,uLen);
uCurrentOffset += uLen;
NdisGetNextBuffer(pFirstBuffer,&pFirstBuffer);
if(uCurrentOffset < PPPOE_MIN_ETH_FRAME_SIZE)
continue;
if(!FastCheckIsPPPoEFrame(pPacket->m_pFrame,PPPOE_MIN_ETH_FRAME_SIZE))
{
uCurrentOffset = 0;
break;
}
}
// check the packet
if(uCurrentOffset < PPPOE_MIN_ETH_FRAME_SIZE || uCurrentOffset < nTotalLen)
DereferencePacket(pPacket);
}
return pPacket;
}
// fast check pppoe frame
BOOLEAN FastCheckIsPPPoEFrame(PPPPOE_FRAME pFrame,ULONG ulSize)
{
if(ulSize != PPPOE_MIN_ETH_FRAME_SIZE)
return FALSE;
if(pFrame->m_usProtocolType != PPPOE_DISCOVERY && pFrame->m_usProtocolType != PPPOE_SESSION)
return FALSE;
return TRUE;
}
// full check pppoe packet
BOOLEAN CheckIsPPPoEPacket(PPACKET pPacket)
{
if(pPacket->m_pFrame->m_usProtocolType != PPPOE_DISCOVERY && pPacket->m_pFrame->m_usProtocolType != PPPOE_SESSION)
return FALSE;
if(pPacket->m_pFrame->m_pppFrame.m_ucVer != PPPOE_VER || pPacket->m_pFrame->m_pppFrame.m_ucType != PPPOE_TYPE)
return FALSE;
if(ntohs(pPacket->m_pFrame->m_pppFrame.m_usLen) > PPPOE_MAX_DATA_SIZE)
return FALSE;
BOOLEAN bRet = FALSE;
if( pPacket->m_pFrame->m_pppFrame.m_ucCode == PPPOE_CODE_PAY_LOAD ||
pPacket->m_pFrame->m_pppFrame.m_ucCode == PPPOE_CODE_PADT ||
pPacket->m_pFrame->m_pppFrame.m_ucCode == PPPOE_CODE_PADS)
{
bRet = pPacket->m_pFrame->m_pppFrame.m_usSession != 0;
}
else
{
bRet = pPacket->m_pFrame->m_pppFrame.m_usSession == 0;
}
return bRet;
}
// reuse recved packet buffer
PPACKET ReuseRecvedPacketBuffer(PBIND_CONTEXT pBind,PNDIS_PACKET pNdisPacket,PPPPOE_FRAME pFrame,UINT uLen)
{
PPACKET pRet = NULL;
__try
{
pRet = AllocPacket();
// unchain org buffer
NdisUnchainBufferAtFront(pNdisPacket,&pRet->m_pNdisReturnBuffer);
// need return
pRet->m_ulFlags |= PPPOE_PACKET_NEED_RETURN_PACKET;
// reuse packet
pRet->m_pNdisPacket = pNdisPacket;
// copy frame
pRet->m_pFrame = &pRet->m_ethFrame;
NdisMoveMemory(pRet->m_pFrame,pFrame,PPPOE_HEADER_LEN);
// set data buffer
pRet->m_pRealBuffer = pFrame + 1;
// bind context
pRet->m_pBindContext = pBind;
NDIS_STATUS status;
// allocate data buffer
NdisAllocateBuffer(&status,&pRet->m_pNdisDataBuffer,g_hNdisBufferPool,pRet->m_pucDataBuffer,uLen - PPPOE_HEADER_LEN);
if(status != NDIS_STATUS_SUCCESS)
ExRaiseStatus(status);
pRet->m_ulFlags |= PPPOE_PACKET_DATA_BUFFER_FROM_NDIS;
// allocate header buffer
NdisAllocateBuffer(&status,&pRet->m_pNdisHeaderBuffer,g_hNdisBufferPool,pRet->m_pFrame,PPPOE_HEADER_LEN);
if(status != NDIS_STATUS_SUCCESS)
ExRaiseStatus(status);
pRet->m_ulFlags |= PPPOE_PACKET_HEADER_BUFFER_FROM_NDIS;
// chain data buffer
NdisChainBufferAtFront(pRet->m_pNdisPacket,pRet->m_pNdisDataBuffer);
pRet->m_ulFlags |= PPPOE_PACKET_DATA_BUFFER_CHAINED;
// chain header buffer
NdisChainBufferAtFront(pRet->m_pNdisPacket,pRet->m_pNdisHeaderBuffer);
pRet->m_ulFlags |= PPPOE_PACKET_HEADER_BUFFER_CHAINED;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(pRet)
DereferencePacket(pRet);
pRet = NULL;
}
return pRet;
}
// get tag from buffer
VOID RetrieveTag(USHORT usTag,PPACKET pPacket,PUCHAR *ppBuffer,PUSHORT pBufferLen,BOOLEAN bSaveToPacket)
{
*ppBuffer = NULL;
*pBufferLen = 0;
// check code first
if(!pPacket->m_pFrame->m_pppFrame.m_ucCode)
return;
PUCHAR pTagBuffer = NULL;
USHORT usTagLen = 0;
PUCHAR pCurrent = pPacket->m_pucDataBuffer;
PUCHAR pEnd = pCurrent + ntohs(pPacket->m_pFrame->m_pppFrame.m_usLen);
// loop find
while(pCurrent < pEnd)
{
PPPP_TAG pTag = reinterpret_cast(pCurrent);
if(pTag->m_usType == usTag)
{
pTagBuffer = pCurrent + sizeof(PPP_TAG);
usTagLen = ntohs(pTag->m_usLen);
break;
}
pCurrent += ntohs(pTag->m_usLen) + sizeof(PPP_TAG);
}
// save
*ppBuffer = pTagBuffer;
*pBufferLen = usTagLen;
// save it to packet
if(pTagBuffer && bSaveToPacket)
{
switch(usTag)
{
case PPPOE_TAG_SERVICE:
pPacket->m_pServiceName = pTagBuffer;
pPacket->m_usServiceName = usTagLen;
break;
case PPPOE_TAG_AC:
pPacket->m_pACName = pTagBuffer;
pPacket->m_usACName = usTagLen;
break;
case PPPOE_TAG_AC_COOKIE:
pPacket->m_pACCookie = pTagBuffer;
pPacket->m_usACCookie = usTagLen;
break;
case PPPOE_TAG_HOST_UNIQUE:
pPacket->m_pHostUnique = pTagBuffer;
pPacket->m_usHostUnique = usTagLen;
break;
case PPPOE_TAG_RELAY_SESSION_ID:
pPacket->m_pRelaySessionId = pTagBuffer;
pPacket->m_usRelaySessionId = usTagLen;
break;
case PPPOE_TAG_SERVICE_NAME_ERROR:
case PPPOE_TAG_AC_SYSTEM_ERROR:
case PPPOE_TAG_GEN_ERROR:
pPacket->m_pError = pTagBuffer;
pPacket->m_usError = usTagLen;
pPacket->m_ulErrorTag = usTag;
break;
}
}
}
// get error tags
VOID RetrieveErrorTag(PPACKET pPacket)
{
PUCHAR pBuffer;
USHORT usLen;
// service name error = 201
RetrieveTag(PPPOE_TAG_SERVICE_NAME_ERROR,pPacket,&pBuffer,&usLen,TRUE);
if(pBuffer)
pPacket->m_ulFlags |= PPPOE_PACKET_ERROR_TAG_RECV;
if(pPacket->m_ulFlags & PPPOE_PACKET_ERROR_TAG_RECV)
return;
// ac system error = 202
RetrieveTag(PPPOE_TAG_AC_SYSTEM_ERROR,pPacket,&pBuffer,&usLen,TRUE);
if(pBuffer)
pPacket->m_ulFlags |= PPPOE_PACKET_ERROR_TAG_RECV;
if(pPacket->m_ulFlags & PPPOE_PACKET_ERROR_TAG_RECV)
return;
// generice error = 203
RetrieveTag(PPPOE_TAG_GEN_ERROR,pPacket,&pBuffer,&usLen,TRUE);
if(pBuffer)
pPacket->m_ulFlags |= PPPOE_PACKET_ERROR_TAG_RECV;
if(pPacket->m_ulFlags & PPPOE_PACKET_ERROR_TAG_RECV)
return;
// ac cookie error = 204
RetrieveTag(PPPOE_TAG_AC_COOKIE_ERROR,pPacket,&pBuffer,&usLen,TRUE);
if(pBuffer)
pPacket->m_ulFlags |= PPPOE_PACKET_ERROR_TAG_RECV;
}
// get service name from buffer
VOID RetrieveServiceName(PPACKET pPacket,PUCHAR *ppBuffer,PUSHORT pBufferLen,PUCHAR pStart,USHORT usTotalLen)
{
if(!pStart || !usTotalLen)
{
*ppBuffer = pPacket->m_pServiceName;
*pBufferLen = pPacket->m_usServiceName;
}
else
{
PUCHAR pEnd = pStart + usTotalLen;
PUCHAR pTagBuffer = NULL;
USHORT usTagLen = 0;
// loop find
while(pStart < pEnd)
{
PPPP_TAG pTag = reinterpret_cast(pStart);
if(pTag->m_usType == PPPOE_TAG_SERVICE && ntohs(pTag->m_usLen) + pStart + sizeof(PPP_TAG) <= pEnd)
{
pTagBuffer = pStart + sizeof(PPP_TAG);
usTagLen = ntohs(pTag->m_usLen);
break;
}
pStart += ntohs(pTag->m_usLen) + sizeof(PPP_TAG);
}
// save
*ppBuffer = pTagBuffer;
*pBufferLen = usTagLen;
}
}
// verify ac cookie
BOOLEAN VerifyACCookie(PPACKET pPacket)
{
if(pPacket->m_usACCookie != ETH_ADDR_LEN)
return FALSE;
// ac cookie will be client mac address
return RtlCompareMemory(pPacket->m_pACCookie,pPacket->m_pFrame->m_srcMac,ETH_ADDR_LEN) == ETH_ADDR_LEN;
}
// verify service name
BOOLEAN VerifyServiceName(PUCHAR pServiceName,USHORT usServiceNameLen,PPACKET pPacket,BOOLEAN bStrict)
{
PUCHAR pBuffer;
USHORT usLen;
RetrieveTag(PPPOE_TAG_SERVICE,pPacket,&pBuffer,&usLen,FALSE);
BOOLEAN bRet = FALSE;
if(!bStrict)
{
bRet = RtlCompareMemory(pBuffer,pServiceName,usLen) == usLen;
}
else
{
bRet = usLen == usServiceNameLen && pBuffer && RtlCompareMemory(pBuffer,pServiceName,usLen) == usLen;
}
return bRet;
}
// build a PADI to send
PPACKET InitializePADIToSend(PUCHAR pServiceName,USHORT usServiceName,PUCHAR pHostUnique,USHORT usHostUnique)
{
static UCHAR _s_macBroadcast[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
PPACKET pRet = NULL;
__try
{
pRet = GetSimplePacket();
NdisMoveMemory(pRet->m_pFrame->m_dstMac,_s_macBroadcast,6);
pRet->m_pFrame->m_usProtocolType = PPPOE_DISCOVERY;
pRet->m_pFrame->m_pppFrame.m_ucVer = PPPOE_VER;
pRet->m_pFrame->m_pppFrame.m_ucType = PPPOE_TYPE;
pRet->m_pFrame->m_pppFrame.m_usSession = 0;
pRet->m_pFrame->m_pppFrame.m_ucCode = PPPOE_CODE_PADI;
pRet->m_pFrame->m_pppFrame.m_usLen = 0;
pRet->m_pServiceName = pServiceName;
pRet->m_usServiceName = usServiceName;
pRet->m_pHostUnique = pHostUnique;
pRet->m_usHostUnique = usHostUnique;
PreparePacketForSend(pRet);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(pRet)
DereferencePacket(pRet);
}
return pRet;
}
// build a PADO to send
PPACKET InitializePADOToSend(PPACKET pRecvedPacket,PUCHAR pSelfMac,PUCHAR pServiceName,USHORT usServiceName,
PUCHAR pACName,USHORT usACNameLen,BOOLEAN bSetACCookie)
{
PPACKET pRet = NULL;
__try
{
pRet = GetSimplePacket();
NdisMoveMemory(pRet->m_pFrame->m_dstMac,pRecvedPacket->m_pFrame->m_srcMac,6);
NdisMoveMemory(pRet->m_pFrame->m_srcMac,pSelfMac,6);
pRet->m_pFrame->m_usProtocolType = PPPOE_DISCOVERY;
pRet->m_pFrame->m_pppFrame.m_ucVer = PPPOE_VER;
pRet->m_pFrame->m_pppFrame.m_ucType = PPPOE_TYPE;
pRet->m_pFrame->m_pppFrame.m_usSession = 0;
pRet->m_pFrame->m_pppFrame.m_ucCode = PPPOE_CODE_PADO;
pRet->m_pFrame->m_pppFrame.m_usLen = 0;
pRet->m_pACName = pACName;
pRet->m_usACName = usACNameLen;
pRet->m_pServiceName = pServiceName;
pRet->m_usServiceName = usServiceName;
if(bSetACCookie)
{
pRet->m_pACCookie = pRecvedPacket->m_pFrame->m_srcMac;
pRet->m_usACCookie = 6;
}
pRet->m_pHostUnique = pRecvedPacket->m_pHostUnique;
pRet->m_usHostUnique = pRecvedPacket->m_usHostUnique;
pRet->m_pRelaySessionId = pRecvedPacket->m_pRelaySessionId;
pRet->m_usRelaySessionId = pRecvedPacket->m_usRelaySessionId;
PreparePacketForSend(pRet);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(pRet)
DereferencePacket(pRet);
}
return pRet;
}
// build PADR to send
PPACKET InitializePADRToSend(PPACKET pRecvedPacket,PUCHAR pServiceName,USHORT usServiceName,PUCHAR pHostUnique,USHORT usHostUnique)
{
PPACKET pRet = NULL;
__try
{
pRet = GetSimplePacket();
NdisMoveMemory(pRet->m_pFrame->m_dstMac,pRecvedPacket->m_pFrame->m_srcMac,6);
NdisMoveMemory(pRet->m_pFrame->m_srcMac,pRecvedPacket->m_pFrame->m_dstMac,6);
pRet->m_pFrame->m_usProtocolType = PPPOE_DISCOVERY;
pRet->m_pFrame->m_pppFrame.m_ucVer = PPPOE_VER;
pRet->m_pFrame->m_pppFrame.m_ucType = PPPOE_TYPE;
pRet->m_pFrame->m_pppFrame.m_usSession = 0;
pRet->m_pFrame->m_pppFrame.m_ucCode = PPPOE_CODE_PADR;
pRet->m_pFrame->m_pppFrame.m_usLen = 0;
pRet->m_pServiceName = pServiceName;
pRet->m_usServiceName = usServiceName;
pRet->m_pHostUnique = pHostUnique;
pRet->m_usHostUnique = usHostUnique;
pRet->m_pRelaySessionId = pRecvedPacket->m_pRelaySessionId;
pRet->m_usRelaySessionId = pRecvedPacket->m_usRelaySessionId;
pRet->m_pACCookie = pRecvedPacket->m_pACCookie;
pRet->m_usACCookie = pRecvedPacket->m_usACCookie;
PreparePacketForSend(pRet);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(pRet)
DereferencePacket(pRet);
}
return pRet;
}
// build PADS to send
PPACKET InitializePADSToSend(PPACKET pRecvedPacket,USHORT usSessionId)
{
PPACKET pRet = NULL;
__try
{
pRet = GetSimplePacket();
NdisMoveMemory(pRet->m_pFrame->m_dstMac,pRecvedPacket->m_pFrame->m_srcMac,6);
NdisMoveMemory(pRet->m_pFrame->m_srcMac,pRecvedPacket->m_pFrame->m_dstMac,6);
pRet->m_pFrame->m_usProtocolType = PPPOE_DISCOVERY;
pRet->m_pFrame->m_pppFrame.m_ucVer = PPPOE_VER;
pRet->m_pFrame->m_pppFrame.m_ucType = PPPOE_TYPE;
pRet->m_pFrame->m_pppFrame.m_usSession = htons(usSessionId);
pRet->m_pFrame->m_pppFrame.m_ucCode = PPPOE_CODE_PADS;
pRet->m_pFrame->m_pppFrame.m_usLen = 0;
pRet->m_pServiceName = pRecvedPacket->m_pServiceName;
pRet->m_usServiceName = pRecvedPacket->m_usServiceName;
pRet->m_pHostUnique = pRecvedPacket->m_pHostUnique;
pRet->m_usHostUnique = pRecvedPacket->m_usHostUnique;
pRet->m_pRelaySessionId = pRecvedPacket->m_pRelaySessionId;
pRet->m_usRelaySessionId = pRecvedPacket->m_usRelaySessionId;
PreparePacketForSend(pRet);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(pRet)
DereferencePacket(pRet);
}
return pRet;
}
// build PADT to send
PPACKET InitializePADTToSend(PUCHAR pDstAddr,PUCHAR pSrcAddr,USHORT usSession)
{
PPACKET pSendPacket = NULL;
__try
{
pSendPacket = GetSimplePacket();
NdisMoveMemory(pSendPacket->m_pFrame->m_dstMac,pDstAddr,6);
NdisMoveMemory(pSendPacket->m_pFrame->m_srcMac,pSrcAddr,6);
pSendPacket->m_pFrame->m_usProtocolType = PPPOE_DISCOVERY;
pSendPacket->m_pFrame->m_pppFrame.m_ucVer = PPPOE_VER;
pSendPacket->m_pFrame->m_pppFrame.m_ucType = PPPOE_TYPE;
pSendPacket->m_pFrame->m_pppFrame.m_usSession = htons(usSession);
pSendPacket->m_pFrame->m_pppFrame.m_ucCode = PPPOE_CODE_PADT;
pSendPacket->m_pFrame->m_pppFrame.m_usLen = 0;
PreparePacketForSend(pSendPacket);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if(pSendPacket)
DereferencePacket(pSendPacket);
}
return pSendPacket;
}
// send error PADS
VOID SendPADSWithError(USHORT usTag,PBIND_CONTEXT pBind,PPACKET pRecvedPacket)
{
PPACKET pSendPacket = NULL;
__try
{
pSendPacket = InitializePADSToSend(pRecvedPacket,1234);
switch(usTag)
{
case PPPOE_TAG_SERVICE_NAME_ERROR:
{
static CHAR error[] = "Service name error";
PacketInsertTag(usTag,pSendPacket,reinterpret_cast(error),(USHORT)sizeof(error) + 2,NULL);
}
break;
case PPPOE_TAG_AC_SYSTEM_ERROR:
{
static CHAR error[] = "AC system error";
PacketInsertTag(usTag,pSendPacket,reinterpret_cast(error),(USHORT)sizeof(error) + 2,NULL);
}
break;
case PPPOE_TAG_GEN_ERROR:
{
static CHAR error[] = "Generic error";
PacketInsertTag(usTag,pSendPacket,reinterpret_cast(error),(USHORT)sizeof(error) + 2,NULL);
}
break;
case PPPOE_TAG_AC_COOKIE_ERROR:
{
static CHAR error[] = "AC cookie error";
PacketInsertTag(usTag,pSendPacket,reinterpret_cast(error),(USHORT)sizeof(error) + 2,NULL);
}
break;
}
PreparePacketForSend(pSendPacket);
ReferencePacket(pSendPacket);
ReferenceBind(pBind,TRUE);
SendPacket(pBind,pSendPacket);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
if(pSendPacket)
DereferencePacket(pSendPacket);
}