/*!Copyright (c) 2022-2023 TP-LINK Technologies CO.,LTD.
*All rights reserved.
*
*\file srvcPppoeCircuitId.c
*\brief The source file for srvcPppoeCircuitId
*
*\author hexiaocai
*\version 1.0.0
*\date 08/30/2022
*
*\history \arg 1.0.0 08/30/2022, hexiaocai, Create file.
\arg 1.0.1 02/19/2025, Songyuhang, 按照FEP平台规范修改代码,修改部分数据格式.
*/
/**************************************************************************************************/
/* INCLUDE_FILES */
/**************************************************************************************************/
/* libc header */
#include <stdio.h>
/* syscall header */
#include "tpDbg/tpdebug.h"
/* common header */
#include "fepTypes.h"
#include "fepDefs.h"
/* platform header */
#include "midware/tpConfig.h"
#include "midware/tpState.h"
#include "midware/dal.h"
#include "midware/tpNotify.h"
#include "timer/timer.h"
#include "libApp/libSysManage/libSysManage.h"
#include "libApp/libNetIf/libNetIf.h"
#include "userPort/user_port.h"
#include "userPort/up_str.h"
#define __DBG_MOD_SET__ "SRVCPPPOECIRCUITID"
/* application private header */
#include "srvcPppoeCircuitId.h"
#include "adPppoeCircuitId.h"
#include "data/dataPppoeCircuitId.h"
#include "pppoeCircuitId/pppoeSchema.h"
/**************************************************************************************************/
/* DEFINES */
/**************************************************************************************************/
#ifdef DBG_ON
#undef DBG_ON
#endif
#define DBG_ON 0
#ifdef DBG_MAJOR_ON
#undef DBG_MAJOR_ON
#endif
#define DBG_MAJOR_ON 1
#ifdef DBG_ERROR_ON
#undef DBG_ERROR_ON
#endif
#define DBG_ERROR_ON 1
#ifdef DBG_VRBS_ON
#undef DBG_VRBS_ON
#endif
#define DBG_VRBS_ON 1
/**************************************************************************************************/
/* TYPES */
/**************************************************************************************************/
/**************************************************************************************************/
/* EXTERN_PROTOTYPES */
/**************************************************************************************************/
/**************************************************************************************************/
/* LOCAL_PROTOTYPES */
/**************************************************************************************************/
/**************************************************************************************************/
/* VARIABLES */
/**************************************************************************************************/
PKT_HANDLE handlePppoe = NULL;
/**************************************************************************************************/
/* LOCAL_FUNCTIONS */
/**************************************************************************************************/
static int srvcPrintMsg(FEP_PACKET_SEND_T *rcvMsg)
{
int num = 0;
for (num = 0; num < rcvMsg->len; num++)
{
if (0 == (num % 16))
printf("\n[%04X] ", num);
printf("%02x ", rcvMsg->buffer[num]);
}
printf("\r\n");
return ERR_NO_ERROR;
}
/*!
*\fn STATUS ether2strCli (OUT char *buffer, IN UINT8 *ether, int flags)
*\brief Translate an Ether address to string.
for example: 12,34,56,78,9a,bc --> 12:34:56:78:9a:bc
*
*\param[in] ether the array that contian the ether address.
*\param[in] flags the translate mode
CSL_UPCASE use upper letter to translate.
CSL_LOWCASE use lower letter to translate
*\param[out] buffer the string that has been translated.
*
*\return OK
*\retval
*
*\note
*/
static int ether2strClnDlm(OUT char *buffer, IN const UINT8 *ether, int flags)
{
int i = 0;
int k = 0;
const char *number_table;
const char *number_char_table[] = {"0123456789abcdef", "0123456789ABCDEF"};
/* Determine which translation table to be used */
if (flags & CSL_UPCASE)
{
number_table = number_char_table[1];
}
else
{
number_table = number_char_table[0];
}
/* Translate binary number to ASCII character and
* put the result in temporary tempb */
for (i = 0; i < MAC_ADDR_SIZE; i++)
{
buffer[k++] = number_table[ether[i] / 16];
buffer[k++] = number_table[ether[i] % 16];
if (i < 5)
{
buffer[k++] = ':';
}
}
buffer[k] = '\0';
return OK;
}
/**************************************************************************************************/
/* PUBLIC_FUNCTIONS */
/**************************************************************************************************/
/*!
*\fn srvcPppoePktToCpuUpdate
*\brief 更新pppoe模块硬件配置
*\details
*
*\param[in]
*
*\param[out]
*
*\return ERR_NO_ERROR
*\retval ERR_NO_ERROR 执行成功
* other 见 FEP_ERR_CODE_PFM_E
*
*\note
*
*/
STATUS srvcPppoePktToCpuUpdate()
{
int ret = ERR_NO_ERROR;
int sysCfg = DISABLE_PPPOE_CIRCUIT;
/* 获取全局状态 */
APPL_IF_ERR_DONE(ret, dataGetPppoeState(&sysCfg));
APPL_IF_ERR_DONE(ret, adPppoePktToCpuSet(sysCfg));
done:
return ret;
}
/*!
*\fn srvcPppoeCb
*\brief pppoeCircuitId模块收包回调函数
*\details
*
*\param[in]
*
*\param[out]
*
*\return
*\retval
*\note
*
*/
void srvcPppoeCb(char *buff, UINT32 len, FEP_PACKET_EXTRA_T *extraArg)
{
FEP_PACKET_SEND_T rcvMsg = {};
rcvMsg.len = len;
rcvMsg.buffer = buff;
rcvMsg.extraArg = extraArg;
srvcPppoePacketCallBack(&rcvMsg);
return;
}
STATUS srvcPppoeFepPktUpdate()
{
int pppoeEnable = DISABLE_PPPOE_CIRCUIT;
APPL_IF_ERR_RET(dataGetPppoeState(&pppoeEnable));
if (pppoeEnable)
{
PFM_IF_FAIL_RET(fepPacketRecvAdd(handlePppoe, srvcPppoeCb)); // 开启收包
}
else
{
PFM_IF_FAIL_RET(fepPacketRecvRemove(handlePppoe)); // 关闭收包
}
return ERR_NO_ERROR;
}
static BOOL pppoePktTagExist(UINT8 *pVal)
{
if (pVal == NULL)
{
return FALSE;
}
switch (*pVal)
{
case 0x00:
if (*(pVal + 1) == 0x00)
{
return TRUE;
}
break;
case 0x01:
if (((*(pVal + 1) > 0x00 && *(pVal + 1) < 0x0A)) || *(pVal + 1) == 0x10 || *(pVal + 1) == 0x11)
{
return TRUE;
}
break;
case 0x02:
if ((*(pVal + 1) > 0x00 && *(pVal + 1) < 0x03))
{
return TRUE;
}
default:
break;
}
return FALSE;
}
STATUS pppoeIdCreat(UINT8 *idVal, UINT32 idType, int nport, UINT8 *srcMac, UINT32 vlanid, UINT *length)
{
UINT32 len = 0;
UINT32 tempLen = 0;
UINT32 tempPosition = 0;
UINT32 ifIndex = 0;
IF_ADDR ifAddr = {};
UINT8 mac[MAC_ADDR_SIZE] = {};
char tempStr[MAX_PPPOE_ID_LENGTH + 1] = {};
user_port up = {};
char macStr[MAC_ADDRESS_LENGTH] = {};
UINT8 portStr[4] = {};
int valType = PPPOE_CIRCUIT_IP_E;
PPPOE_CIRCUIT_PORT_CFG_T portCfg = {};
ether2strClnDlm(macStr, srcMac, 1);
UP_FROM_IDX(up, nport);
APPL_IF_ERR_RET(dataPppoePortCfgGet(nport, &portCfg));
valType = portCfg.type;
if ((idType & 0x1) && (portCfg.state & 0x1)) // 0x1 is circuit-ID Enable and no circuit ID
{
if (PPPOE_CIRCUIT_UDF_ONLY_E == valType)
{
tempLen = strlen((const char *)portCfg.udfValue);
memcpy(tempStr, portCfg.udfValue, tempLen);
idVal[len++] = 0x01;
idVal[len++] = 0;
memcpy(idVal + len, tempStr, tempLen);
len = len + tempLen;
idVal[1] = (char)(len - 2);
}
else
{
if (PPPOE_CIRCUIT_IP_E == valType)
{
if (ERR_NO_ERROR == libNetIfGetNetIfIndexFromPortAndVlanId(up, vlanid, (int *)&ifIndex))
{
DBG("get ip by ipc\n");
APPL_IF_ERR_RET(libNetIfIpv4PrimaryIpGet(LIB_NETIF_GETMODE_TPSTATE, ifIndex, &ifAddr));
// ifAddr.addr.v4.ip.s_addr = htonl(ifAddr.addr.v4.ip.s_addr);拿到的是网络字节序,不要再转成网络字节序
}
else
{
DBG("get ip by default\n");
ifAddr.addr.v4.ip.s_addr = htonl(0xc0a80001);
// 拿到的是网络字节序,ip设为默认192.168.0.1,此处由主机字节序转成网络字节序
}
DBG("ip:%x\n", ifAddr.addr.v4.ip.s_addr);
IpInt2Str(ifAddr.addr.v4.ip.s_addr, tempStr);
tempLen = strlen(tempStr);
DBG("tmpStr: %s, tempLen: %d\n", tempStr, tempLen);
}
else if (PPPOE_CIRCUIT_MAC_E == valType)
{
appGetMacAddress(mac);
ether2strClnDlm(tempStr, mac, 1);
DBG("mac:%s\n", tempStr);
tempLen = MAC_ADDRESS_LENGTH - 1;
}
else if (PPPOE_CIRCUIT_UDF_E == valType)
{
tempLen = strlen((const char *)portCfg.udfValue + 1);
memcpy(tempStr, portCfg.udfValue, tempLen);
}
else
{
return ERR_BAD_PARAM;
}
idVal[len++] = 0x01;
len = 2;
memcpy(idVal + len, macStr, MAC_ADDRESS_LENGTH - 1);
len = len + MAC_ADDRESS_LENGTH - 1;
idVal[len++] = ':';
idVal[len++] = ':';
memcpy(idVal + len, tempStr, tempLen);
len = len + tempLen;
idVal[len++] = ':';
idVal[len++] = ':';
sprintf((char *)portStr, "%d", nport);
if (nport < 10 && nport > 0)
{
idVal[len++] = portStr[0];
}
else if (nport >= 10 && nport < 100)
{
idVal[len++] = portStr[0];
idVal[len++] = portStr[1];
}
idVal[1] = (char)(len - 2); // circuit ID head
}
}
if (idType & 0x2) // 0x2 is 10, it means creat remote ID
{
if (portCfg.state & 0x2) // 0x2 is 10, it means remote ID Enable
{
idVal[len++] = 0x02;
tempPosition = len;
idVal[len++] = 0;
tempLen = strlen((const char *)portCfg.remoteId);
if (tempLen)
{
memcpy(tempStr, portCfg.remoteId, tempLen);
memcpy(idVal + len, tempStr, tempLen);
len = len + tempLen;
idVal[tempPosition] += tempLen; // length of remote ID
}
else
{
memcpy(idVal + len, macStr, MAC_ADDRESS_LENGTH - 1);
len = len + MAC_ADDRESS_LENGTH - 1;
idVal[tempPosition] += MAC_ADDRESS_LENGTH - 1; // length of remote ID
}
DBG("tempPosition:%x\n", tempPosition);
}
else
{
idVal[len++] = 0x02;
idVal[len++] = 0x00;
// idVal[1] = (char)(len - 4);//circuit ID head and 02 ID head
}
// idVal[1] = (char)(len - 2);//remote ID head
}
*length = len;
return ERR_NO_ERROR;
}
STATUS srvcPppoeCTagCreat(UINT32 tagState, int nport, UINT8 *srcMac, PPPOE_TAG *pppoeTag, UINT32 vlanid)
{
UINT8 idVal[TAG_LEN] = {};
UINT32 len = 0;
UINT32 *pVendorId = NULL;
if (NULL == srcMac || NULL == pppoeTag)
{
return ERR_BAD_PARAM;
}
if (tagState < 0x4) // no circuit ID
{
pppoeTag->tagType = htons(0x0105);
APPL_IF_ERR_RET(pppoeIdCreat(idVal, tagState, nport, srcMac, vlanid, &len));
pppoeTag->tagLen = htons((UINT16)len);
memcpy(pppoeTag->tagValue, idVal, len);
}
else if (tagState & 0x4) // it means no tag;tagState should be 0x7
{
pppoeTag->tagType = htons(0x0105);
APPL_IF_ERR_RET(pppoeIdCreat(idVal, 0x3, nport, srcMac, vlanid, &len));
pppoeTag->tagLen = htons((UINT16)(len + 4)); // add length of VENDOR_ID
pVendorId = (UINT32 *)pppoeTag->tagValue;
*pVendorId = htonl(VENDOR_ID_ADSL_FORUM);
memcpy(pppoeTag->tagValue + 4, idVal, len);
}
else
{
return ERR_BAD_PARAM;
}
return ERR_NO_ERROR;
}
STATUS srvcPppoeIDDel(FEP_PACKET_SEND_T *pkt, UINT32 *len)
{
// srvcPrintMsg(pkt);
UINT8 *pVal = NULL;
INT16 pLen = 0;
int tagFlag = 1;
INT16 tagLen = 0;
UINT16 tLen = 0;
PPPOE_PKT *pppoePkt = (PPPOE_PKT *)(pkt->buffer);
if ((PPPOE_PADI == pppoePkt->code && ntohs(pppoePkt->payloadLen) >= 1400) ||
(PPPOE_PADR == pppoePkt->code && ntohs(pppoePkt->payloadLen) >= 1414))
{
return ERR_NO_ERROR;
}
pVal = pppoePkt->payloadValue;
pLen = ntohs(pppoePkt->payloadLen);
while (pLen > 3 && tagFlag != 0)
{
tagLen = 0;
if (pppoePktTagExist(pVal))
{
tagLen = ((0 + *(pVal + 2)) << 8) + *(pVal + 3);
}
else
{
*len = pkt->len;
return ERR_NO_ERROR;
}
if ((*pVal != 0x01) || (*(pVal + 1) != 0x05))
{
pLen = pLen - tagLen - TAG_HEAD_LEN;
pVal = pVal + tagLen + TAG_HEAD_LEN;
}
else
{
tagFlag = 0;
}
}
if (tagFlag == 0)
{
/* 找到Vendor-Specific */
tagLen = ((0 + *(pVal + 2)) << 8) + *(pVal + 3);
if (pLen > tagLen)
{
memcpy(pVal, (pVal + tagLen + TAG_HEAD_LEN), (pLen - tagLen - TAG_HEAD_LEN));
tLen = ntohs(pppoePkt->payloadLen) - tagLen - TAG_HEAD_LEN;
pppoePkt->payloadLen = htons(tLen);
*len = ntohs(pppoePkt->payloadLen) + ETHER_HEAD_LEN;
}
else
{
return ERR_BAD_PARAM;
}
}
else
{
*len = pkt->len;
}
// srvcPrintMsg(pkt);
return ERR_NO_ERROR;
}
STATUS srvcPppoeIDAdd(FEP_PACKET_SEND_T *pkt, UINT32 *len, int nPort)
{
// srvcPrintMsg(pkt);
UINT8 *pVal = NULL, *vVal = NULL, *pTemp = NULL;
INT16 pLen = 0;
INT16 tempLen = 0;
UINT32 tagFlag = 0;
UINT32 vFlag = 0x3;
INT16 tagLen = 0;
UINT8 vLen = 0;
UINT8 vType = 0;
UINT16 tLen = 0;
PPPOE_TAG pppoeTag = {};
UINT32 vlanid = pkt->extraArg->commonArg.vid;
PPPOE_PKT *pppoePkt = (PPPOE_PKT *)(pkt->buffer);
// DBG("payloadLen:%d\n",pppoePkt->payloadLen);
if ((PPPOE_PADI == pppoePkt->code && ntohs(pppoePkt->payloadLen) >= 1400) ||
(PPPOE_PADR == pppoePkt->code && ntohs(pppoePkt->payloadLen) >= 1414))
{
return ERR_NO_ERROR;
}
/* 内容及长度 */
pVal = pppoePkt->payloadValue;
pLen = ntohs(pppoePkt->payloadLen);
// DBG("pLen:%d\n",pLen);
while (pLen > 0 && PPPOE_NO_0X0105TAG == tagFlag)
{
if (!pppoePktTagExist(pVal))
{
break;
}
/* tag type is 0x0105;end_of_list tag type is 0x0000 */
if (((*pVal != 0x01) || (*(pVal + 1) != 0x05)) && ((*pVal != 0x00) || (*(pVal + 1) != 0x00)))
{
tagLen = ((0 + *(pVal + 2)) << 8) + *(pVal + 3); /* check 添加类型转换 */
/* 指针后移,长度减少 */
pLen = pLen - tagLen - TAG_HEAD_LEN;
pVal = pVal + tagLen + TAG_HEAD_LEN;
}
else if ((*pVal == 0x00) && (*(pVal + 1) == 0x00))
{
/* tag type:END_OF_LIST */
tagLen = ((0 + *(pVal + 2)) << 8) + *(pVal + 3);
tagFlag = PPPOE_TAG_END_OF_LIST;
}
else
{
/* 找到tag 0x0105 */
tagLen = ((0 + *(pVal + 2)) << 8) + *(pVal + 3);
tagFlag = PPPOE_FIND_0X0105TAG;
}
}
// DBG("tagtype:%d",tagFlag);
if (PPPOE_FIND_0X0105TAG == tagFlag)
{
/* 找到Vendor-Specific */
vVal = pVal + TAG_HEAD_LEN + 4;
vType = *vVal;
vLen = *(vVal + 1);
tagLen = tagLen - 4;
pTemp = pVal;
while (tagLen >= 0 && vFlag != 0x0)
{
vType = *vVal;
if (vType != 0x1 && vType != 0x2)
{
vLen = *(vVal + 1);
tagLen = tagLen - vLen - 2;
vVal = vVal + vLen + 2;
// DBG("tagLen:%d, vLen:%d,vVal:%d",tagLen,vLen,*vVal);
}
else
{
if (0x1 == vType)
{
vFlag = vFlag & 0x2;
}
else
{
vFlag = vFlag & 0x1;
}
if (vFlag != 0x0) /* if vFlag != 0x0, it means that we have not found both of id */
{
vLen = *(vVal + 1);
tagLen = tagLen - vLen - 2;
vVal = vVal + vLen + 2;
// DBG("tagLen:%d, vLen:%d,vVal:%d",tagLen,vLen,*vVal);
}
}
}
if (vFlag == 0x0)
{
/* 存在circuit-ID & remote ID */
*len = pkt->len;
return ERR_NO_ERROR;
}
else
{
/* 存在tag,但没有circuit-ID,在该tag下增加circuit-ID */
APPL_IF_ERR_RET(srvcPppoeCTagCreat(vFlag, nPort, pppoePkt->srcMac, &pppoeTag, vlanid));
tLen = ntohs(pppoeTag.tagLen);
pppoePkt->payloadLen = ntohs(pppoePkt->payloadLen) + tLen; /* 总长度增加 */
if (pppoePkt->payloadLen > PAYLOAD_LEN_MAX)
{
return ERR_BAD_PARAM;
}
else
{
pppoePkt->payloadLen = htons(pppoePkt->payloadLen); /* 总长度增加 */
tempLen = 0;
tempLen = ((tempLen + *(pTemp + 2)) << 8) + *(pTemp + 3);
/* 复制vendor specific tag后的内容 */
memcpy(pVal + TAG_HEAD_LEN + tempLen + tLen, pVal + TAG_HEAD_LEN + tempLen, pLen - TAG_HEAD_LEN - tempLen);
memcpy(pVal + TAG_HEAD_LEN + tempLen, pppoeTag.tagValue, tLen);
tempLen = tempLen + tLen; /* tag长度增加 */
*(pTemp + 2) = (tempLen >> 8) & 0x00ff;
*(pTemp + 3) = tempLen & 0x00ff;
/* 复制circuit ID到packet */
*len = ntohs(pppoePkt->payloadLen) + ETHER_HEAD_LEN;
}
}
}
else if (PPPOE_TAG_END_OF_LIST == tagFlag)
{
/* no tag 0x0105,find end of list, we should add tag 0x0105 before end of list */
APPL_IF_ERR_RET(srvcPppoeCTagCreat(0x7, nPort, pppoePkt->srcMac, &pppoeTag, vlanid));
tLen = ntohs(pppoeTag.tagLen);
pppoePkt->payloadLen = tLen + TAG_HEAD_LEN + ntohs(pppoePkt->payloadLen); /* 总长度增加 */
if (pppoePkt->payloadLen > PAYLOAD_LEN_MAX)
{
return ERR_BAD_PARAM;
}
else
{
*len = pppoePkt->payloadLen + ETHER_HEAD_LEN; /* packet length */
pppoePkt->payloadLen = htons(pppoePkt->payloadLen); /* 转换为网络字节序 */
/* 复制end of : list tag后的内容 */
memcpy(pVal + 4 + tLen, pVal, pLen);
memcpy(pVal, (UINT8 *)(&pppoeTag), 4); // Head of Tag
memcpy(pVal + 4, pppoeTag.tagValue, tLen); // tag value
}
// DBG("tlen: %d, pkt len:%d", tLen, *len);
// DBG("tagtype:endoflist");
}
else
{
/* 不存在tag */
APPL_IF_ERR_RET(srvcPppoeCTagCreat(0x7, nPort, pppoePkt->srcMac, &pppoeTag, vlanid));
/* 在末尾添加tag */
pVal = pppoePkt->payloadValue;
pLen = ntohs(pppoePkt->payloadLen);
// DBG("oldpayloadLen:%x,",pLen);
pVal = pVal + pLen;
tLen = ntohs(pppoeTag.tagLen);
pppoePkt->payloadLen = tLen + TAG_HEAD_LEN + ntohs(pppoePkt->payloadLen); // 总长度增加
if (pppoePkt->payloadLen > PAYLOAD_LEN_MAX)
{
return ERR_BAD_PARAM;
}
pppoePkt->payloadLen = htons(pppoePkt->payloadLen);
memcpy(pVal, (UINT8 *)(&pppoeTag), 4); // Head of Tag
memcpy(pVal + 4, pppoeTag.tagValue, tLen); // tag value
*len = ntohs(pppoePkt->payloadLen) + ETHER_HEAD_LEN;
}
return ERR_NO_ERROR;
}
/******************************************************************************
*\fn STATUS srvcPppoePacketCallBack(FEP_PACKET_SEND_T *pkt)
*\brief
*\details
*
*\param[in] packet struct of packet
*
*\return
*\retval ERR_NO_ERROR OK
*\retval others ERROR
*
*\note
******************************************************************************/
STATUS srvcPppoePacketCallBack(FEP_PACKET_SEND_T *pkt)
{
// srvcPrintMsg(pkt);
FEP_PACKET_SEND_T fepPacket = {};
int upIdx = 0;
PPPOE_PKT pppoePacket = {};
PPPOE_CIRCUIT_PORT_CFG_T portCfg = {};
user_port up = {};
if (NULL == pkt || NULL == pkt->buffer)
{
return ERR_BAD_PARAM;
}
memset(&pppoePacket, 0, sizeof(PPPOE_PKT));
if (pkt->len < sizeof(PPPOE_PKT))
{
memcpy(&pppoePacket, pkt->buffer, pkt->len);
}
else
{
return ERR_BAD_PARAM;
}
memset(&fepPacket, 0, sizeof(FEP_PACKET_SEND_T));
memcpy(&fepPacket, pkt, sizeof(FEP_PACKET_SEND_T));
fepPacket.buffer = (char *)&pppoePacket;
// srvcPrintMsg(&fepPacket);
UP_ITER_LIST(&fepPacket.extraArg->commonArg.uportList, upIdx, up)
{
break;
}
if (!UP_IS_VALID(up))
{
return FEP_RX_OWNED;
}
UP_TO_IDX(up, upIdx);
dataPppoePortCfgGet(upIdx, &portCfg);
if (portCfg.state == DISABLE_PPPOE_CIRCUIT)
{
fepPacket.extraArg->commonArg.flags |= FEP_TX_PASS_THROUGHT;
goto PKT_SEND;
}
switch (pppoePacket.code)
{
case PPPOE_PADI:
APPL_IF_ERR_RET(srvcPppoeIDAdd(&fepPacket, &(fepPacket.len), upIdx));
fepPacket.extraArg->commonArg.flags |= FEP_TX_BROADCAST;
break;
case PPPOE_PADO:
APPL_IF_ERR_RET(srvcPppoeIDDel(&fepPacket, &(fepPacket.len)));
fepPacket.extraArg->commonArg.flags |= FEP_TX_PASS_THROUGHT; // 若有fdb地址表FEP_TX_PASS_THROUGHT,找不到fdb地址表自动广播,无需添加FEP_TX_BROADCAST
break;
case PPPOE_PADR:
APPL_IF_ERR_RET(srvcPppoeIDAdd(&fepPacket, &(fepPacket.len), upIdx));
fepPacket.extraArg->commonArg.flags |= FEP_TX_PASS_THROUGHT;
break;
case PPPOE_PADS:
APPL_IF_ERR_RET(srvcPppoeIDDel(&fepPacket, &(fepPacket.len)));
fepPacket.extraArg->commonArg.flags |= FEP_TX_PASS_THROUGHT;
break;
default:
fepPacket.extraArg->commonArg.flags |= FEP_TX_PASS_THROUGHT;
break;
}
PKT_SEND:
fepPacket.extraArg->commonArg.flags |= FEP_TX_CRC_APPEND;
// srvcPrintMsg(&fepPacket);
PFM_IF_FAIL_RET(fepPacketSend(handlePppoe, &fepPacket));
return ERR_NO_ERROR;
}
STATUS pppoeFepPacketRuleReg()
{
FEP_PACKET_CREATE_T createParam = {};
FEP_PACKET_FILTER_T fillter = {};
FEP_PACKET_RULE_DATA_T ruleData1 = {};
FEP_PACKET_RULE_DATA_T ruleData2 = {};
UINT8 value[2] = {0x88, 0x63};
FEP_PACKET_ADDR_T addr = {};
/* 创建fepPacket handle */
memset(&createParam, 0, sizeof(FEP_PACKET_CREATE_T));
createParam.domain = AF_PACKET;
createParam.type = SOCK_RAW;
createParam.protocol = htons(ETH_P_ALL);
createParam.filterFlag = TRUE;
memset(&addr, 0, sizeof(addr));
addr.family = AF_PACKET;
addr.info.eth.sllProtocol = htons(ETH_P_ALL);
addr.info.eth.sllIfindex = if_nametoindex("tp-eth");
createParam.addr = &addr;
memset(&fillter, 0, sizeof(FEP_PACKET_FILTER_T));
fillter.ruleListType = RX_LIST_PRIORITY_4;
fillter.priority = FEP_PACKET_DEFAULT_PRI;
fillter.modName = "pppoeCircuitId";
fillter.ruleNodeName = PPPOE_PKT_NODE;
fillter.own = FEP_RX_NOT_OWNED;
fillter.nodeNum = 2;
fillter.node[0].nodeType = PACKET_FILTER_MATCH;
fillter.node[0].isUnReg = FALSE;
fillter.node[0].filterType = FEP_PACKET_MATCH_NETWORK;
fillter.node[0].filterRule = FEP_PACKET_MATCH;
fillter.node[0].pos = FEP_PACKET_NODE_POS_TAIL;
fillter.node[0].level = SOL_SOCKET;
fillter.node[0].optName = SO_ATTACH_FILTER;
memset(&ruleData1, 0, sizeof(FEP_PACKET_RULE_DATA_T));
ruleData1.value = value;
ruleData1.len = 2;
fillter.node[0].rule = &ruleData1;
memset(&ruleData2, 0, sizeof(FEP_PACKET_RULE_DATA_T));
fillter.node[1].nodeType = PACKET_FILTER_ACTION;
fillter.node[1].filterType = FEP_PACKET_ACTION_SEND_TO_PROC;
fillter.node[1].pos = FEP_PACKET_NODE_POS_TAIL;
fillter.node[1].rule = &ruleData2;
createParam.fillter = &fillter;
handlePppoe = fepPacketCreate(&createParam);
APPL_ENSURE_RET(handlePppoe != NULL);
return ERR_NO_ERROR;
}
STATUS pppoeFepPacketInit()
{
FEP_PACKET_INIT_T fepPKtParam = {};
fepPKtParam.channelCfgPath = FEP_PACKET_CHANNEL_CFG_PATH;
fepPKtParam.maxBuffSize = 2048;
fepPKtParam.maxSocketNum = 10;
PFM_IF_FAIL_RET_VAL(fepPacketInit(&fepPKtParam), ERR_INIT);
return ERR_NO_ERROR;
}
STATUS srvcPppoeFepPacketInit()
{
APPL_IF_ERR_RET(pppoeFepPacketInit()); // fepPacket初始化
APPL_IF_ERR_RET(pppoeFepPacketRuleReg()); // 创建收发包规则
return ERR_NO_ERROR;
}
STATUS pppoeFepPacketRuleUnReg()
{
fepPacketDestroy(handlePppoe); // 删除收发包规则
return ERR_NO_ERROR;
}
STATUS pppoeFepPacketDeInit()
{
APPL_IF_ERR_RET(fepPacketRecvRemove(handlePppoe)); // 关闭收包
APPL_IF_ERR_RET(pppoeFepPacketRuleUnReg());
fepPacketDeInit();
return ERR_NO_ERROR;
}
STATUS srvcPppoeFepPacketDeinit()
{
APPL_IF_ERR_RET(pppoeFepPacketDeInit());
return ERR_NO_ERROR;
}
此代码主要对报文进行了哪些操作,若我想给报文添加时间戳,是否能够参考