关于 UnixDomaiSocket 中 send(; ; ; ) 的第二个参数使用 char *str 的可行性验证

本文通过一个简单的Unix套接字通信示例验证了send函数的第二个参数可以使用char*类型的指针。服务端与客户端程序成功实现了消息传递。

    今天要写的内容是来实验 send( , ,) 中的第二个参数是否可以使用 char *str 指针。

    结论是:可以!

    服务端的代码如下:

/* 2012-06-07 - 代码是在 http://beej.us/guide/bgipc/output/html/multipage/unixsock.html 基础上修改的。原始的代码下载
 * echos.c -- the echo server for echoc.c; demonstrates unix sockets
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "/home/tian/mysocket"

int main(void)
{
	int s, s2, t, len;
	struct sockaddr_un local, remote;
	char str[100];

	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
		perror("socket");
		exit(1);
	}

	local.sun_family = AF_UNIX;
	strcpy(local.sun_path, SOCK_PATH);
	unlink(local.sun_path);
	len = strlen(local.sun_path) + sizeof(local.sun_family);
	if (bind(s, (struct sockaddr *)&local, len) == -1) {
		perror("bind");
		exit(1);
	}

	if (listen(s, 5) == -1) {
		perror("listen");
		exit(1);
	}

	for(;;) 
	{
		int done, n;
		printf("Waiting for a connection...\n");
		t = sizeof(remote);
		if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
			perror("accept");
			exit(1);
		}

		printf("Connected.\n");
		
		do 
		{
			memset(str, 0, sizeof(str));
			n = recv(s2, str, 5, 0);
			if (n < 0) 
			{
				perror("recv");
				break;
			}
			else if (n == 0)
			{
				break;
			}
			
			//
			printf("echo> %s\n", str);
			//
		} while (1);

		close(s2);
	}
	return 0;
}

    服务端执行结果截图:


    客户端代码如下:

/* 2012-06-07 - 代码是在 http://beej.us/guide/bgipc/output/html/multipage/unixsock.html 基础上修改的。原始的代码下载
** echoc.c -- the echo client for echos.c; demonstrates unix sockets
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "/home/tian/mysocket"

int main(void)
{
    int s, t, len;
    struct sockaddr_un remote;

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    printf("Trying to connect...\n");

    remote.sun_family = AF_UNIX;
    strcpy(remote.sun_path, SOCK_PATH);
    len = strlen(remote.sun_path) + sizeof(remote.sun_family);
    if (connect(s, (struct sockaddr *)&remote, len) == -1) {
        perror("connect");
        exit(1);
    }

    printf("Connected.\n");

 
    int num = 5;
    char *str = (char*)calloc(5, sizeof(char));  
  
    while(1)
    {
         sprintf(str, "%d", num); //将 num 以10进制格式化到 str
	//
	printf("strlen---%d\n", strlen(str)); // 打印 str 的长度
	//
	if (send(s, str, strlen(str), 0) == -1)
    	{
    	    perror("send");
    	    exit(1);
    	}
    	printf("num---%d\n", num); // 打印 num,以此判断 while() 循环是否正确执行
    	num--;
    	if(num == 0) break;
    }
    if (str != NULL)
    {
        str = NULL;
        free(str);	 // 释放 str 占用的内存空间
    }
    close(s);

    return 0;
}

    客户端执行结果截图:


     根据服务端与客户端执行结果,可以判断出:程序执行正常。

/*!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; } 此代码主要对报文进行了哪些操作,若我想给报文添加时间戳,是否能够参考
10-24
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值