📄 packet.cpp
字号:
}
return pRet;
}
// init a PADO packet to send
PPPPOE_PACKET InitializePADOToSend(PPPPOE_PACKET pRecvedPacket,PUCHAR pSelfMac,PUCHAR pServiceName,USHORT usServiceName,
PUCHAR pACName,USHORT usACNameLen,BOOLEAN bSetACCookie)
{
PPPPOE_PACKET pRet = NULL;
__try
{
pRet = GetSimplePPPOEPacket();
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;
}
// init a PADR
PPPPOE_PACKET InitializePADRToSend(PPPPOE_PACKET pRecvedPacket,PUCHAR pServiceName,USHORT usServiceName,
PUCHAR pHostUnique,USHORT usHostUnique)
{
PPPPOE_PACKET pRet = NULL;
__try
{
pRet = GetSimplePPPOEPacket();
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;
}
// init PADS
PPPPOE_PACKET InitializePADSToSend(PPPPOE_PACKET pRecvedPacket,USHORT usSessionId)
{
PPPPOE_PACKET pRet = NULL;
__try
{
pRet = GetSimplePPPOEPacket();
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;
}
// init PADT
PPPPOE_PACKET InitializePADTToSend(PUCHAR pDstAddr,PUCHAR pSrcAddr,USHORT usSession)
{
PPPPOE_PACKET pSendPacket = NULL;
__try
{
pSendPacket = GetSimplePPPOEPacket();
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,PPPPOE_PACKET pRecvedPacket)
{
PPPPOE_PACKET pSendPacket = NULL;
__try
{
pSendPacket = InitializePADSToSend(pRecvedPacket,0);
switch(usTag)
{
case PPPOE_TAG_SERVICE_NAME_ERROR:
{
static CHAR error[] = "Service name error";
PPPOEPacketInsertTag(usTag,pSendPacket,reinterpret_cast<PUCHAR>(error),(USHORT)sizeof(error) + 2,NULL);
}
break;
case PPPOE_TAG_AC_SYSTEM_ERROR:
{
static CHAR error[] = "AC system error";
PPPOEPacketInsertTag(usTag,pSendPacket,reinterpret_cast<PUCHAR>(error),(USHORT)sizeof(error) + 2,NULL);
}
break;
case PPPOE_TAG_GEN_ERROR:
{
static CHAR error[] = "Generic error";
PPPOEPacketInsertTag(usTag,pSendPacket,reinterpret_cast<PUCHAR>(error),(USHORT)sizeof(error) + 2,NULL);
}
break;
case PPPOE_TAG_AC_COOKIE_ERROR:
{
static CHAR error[] = "AC cookie error";
PPPOEPacketInsertTag(usTag,pSendPacket,reinterpret_cast<PUCHAR>(error),(USHORT)sizeof(error) + 2,NULL);
}
break;
}
PreparePacketForSend(pSendPacket);
ReferencePacket(pSendPacket);
ReferenceBind(pBind,TRUE);
SendPPPOEPacket(g_pAdapter,pBind,pSendPacket);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
}
if(pSendPacket)
DereferencePacket(pSendPacket);
}
// packet insert tag
VOID PPPOEPacketInsertTag(USHORT ucTag,PPPPOE_PACKET 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<PPPP_TAG>(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));
}
// retrive service name
VOID RetrieveServiceName(PPPPOE_PACKET 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<PPPP_TAG>(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;
}
}
// retrive tag
VOID RetrieveTag(USHORT usTag,PPPPOE_PACKET 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<PPPP_TAG>(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;
}
}
}
// retrive error tag
VOID RetrieveErrorTag(PPPPOE_PACKET 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;
}
// fast check packet
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;
}
// check pppoe packet
BOOLEAN CheckIsPPPOEPacket(PPPPOE_PACKET 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;
}
// verify service name
BOOLEAN VerifyServiceName(PADAPTER pAdapter,PPPPOE_PACKET pPacket,BOOLEAN bStrict)
{
PUCHAR pBuffer;
USHORT usLen;
RetrieveTag(PPPOE_TAG_SERVICE,pPacket,&pBuffer,&usLen,FALSE);
BOOLEAN bRet = FALSE;
if(!bStrict)
{
bRet = RtlCompareMemory(pBuffer,pAdapter->m_ucServiceName,usLen) == usLen;
}
else
{
bRet = usLen == pAdapter->m_usServiceNameLen &&
pBuffer &&
RtlCompareMemory(pBuffer,pAdapter->m_ucServiceName,usLen) == usLen;
}
return bRet;
}
// verify ac cookie
BOOLEAN VerifyACCookie(PPPPOE_PACKET pPacket)
{
if(pPacket->m_usACCookie != 6)
return FALSE;
// ac cookie will be client mac address
return RtlCompareMemory(pPacket->m_pACCookie,pPacket->m_pFrame->m_srcMac,6) == 6;
}
// check quota
BOOLEAN CheckClientQuota(PADAPTER pAdapter,PPPPOE_PACKET pPacket)
{
USHORT usIndex = static_cast<USHORT>(pAdapter->m_ulEndPoints * pAdapter->m_ulNumLineDevs / 2);
ULONG ulCalls = 0;
for(;usIndex < pAdapter->m_ulEndPoints * pAdapter->m_ulNumLineDevs; ++ usIndex)
{
PCALL_INFO pCall = GetCallPtrFromHandleTableIndex(pAdapter->m_pCallHandleTable,usIndex);
if(pCall)
{
if( RtlCompareMemory(pCall->m_macPeer,pPacket->m_pFrame->m_srcMac,6) == 6 &&
RtlCompareMemory(pCall->m_macSelf,pPacket->m_pFrame->m_dstMac,6) == 6)
{
ulCalls ++;
}
}
}
return ulCalls < pAdapter->m_ulMaxCallsPerClient;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -