From c6e3500aa7dc9896c2fbfd95eb47115c3e5e0b42 Mon Sep 17 00:00:00 2001 From: lh <3191213465@qq.com> Date: Thu, 9 Jul 2026 11:05:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8ioctl=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E5=92=8C=E5=9B=9E=E8=AF=BBIP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TSCP/src/MSCP/CFM/CFM_Net.c | 29 ++-- TSCP/src/MSCP/CM/CM_IP.c | 268 ++++++++++++++++++++++++++++++++++++ TSCP/src/MSCP/CM/CM_IP.h | 55 ++++++++ 3 files changed, 337 insertions(+), 15 deletions(-) create mode 100644 TSCP/src/MSCP/CM/CM_IP.c create mode 100644 TSCP/src/MSCP/CM/CM_IP.h diff --git a/TSCP/src/MSCP/CFM/CFM_Net.c b/TSCP/src/MSCP/CFM/CFM_Net.c index fb5a6d5..13be76b 100644 --- a/TSCP/src/MSCP/CFM/CFM_Net.c +++ b/TSCP/src/MSCP/CFM/CFM_Net.c @@ -37,8 +37,14 @@ #include "PFM_RemoteUpdate.h" #include "MSCP_Define.h" #include "CFM_Raw.h" +#include "CM_IP.h" #include +/** @brief 网卡名 */ +#define CFM_IP_INTERFACE_2oo2 "fec0" +#define CFM_IP_INTERFACE_2x2 "fec1" +#define CFM_IP_INTERFACE_MAINTAIN "wm0" + #define CFM_2oo2_MSG_NUM_MAX (200u) #define CFM_2X2_MSG_NUM_MAX (200u) #define CFM_OUTNET_MSG_NUM_MAX (5000u) @@ -2877,24 +2883,17 @@ void CFM_Net_Init(void) void CFM_NetworkCard_Init(void) { /*- 变量初始化 */ - CM_CHAR str[1024] = {0}; + ENUM_CM_RETURN ret = ENUM_CM_FALSE; + /*- 配置2取网卡ip */ - (void)memset(str, 0, sizeof(str)); - (void)sprintf(str, "ifconfig %s %s", "fec0", g_PFM_Cfg.Local_Cfg.IP_2oo2); - (void)printf("%s\n", str); - (void)system(str); - + ret = CM_IP_TrySetIpAddrRetry(CFM_IP_INTERFACE_2oo2, g_PFM_Cfg.Local_Cfg.IP_2oo2, 3); + CM_NM_ASSERT(ENUM_CM_TRUE == ret, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_42, TSCP_DARK_ASSERT_1); /*- 配置通用网卡ip */ - (void)memset(str, 0, sizeof(str)); - (void)sprintf(str, "ifconfig %s %s", "fec1", g_PFM_Cfg.Local_Cfg.IP_Com); - (void)printf("%s\n", str); - (void)system(str); - + ret = CM_IP_TrySetIpAddrRetry(CFM_IP_INTERFACE_2x2, g_PFM_Cfg.Local_Cfg.IP_Com, 3); + CM_NM_ASSERT(ENUM_CM_TRUE == ret, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_42, TSCP_DARK_ASSERT_2); /*- 配置维护网卡ip */ - (void)memset(str, 0, sizeof(str)); - (void)sprintf(str, "ifconfig %s %s", "wm0", g_PFM_Cfg.Local_Cfg.IP_Maintain); - (void)printf("%s\n", str); - (void)system(str); + ret = CM_IP_TrySetIpAddrRetry(CFM_IP_INTERFACE_MAINTAIN, g_PFM_Cfg.Local_Cfg.IP_Maintain, 3); + CM_NM_ASSERT(ENUM_CM_TRUE == ret, NET_MODE, DARK_FAULT_CODE_FUN_ORDER_42, TSCP_DARK_ASSERT_3); } /** * @brief UDP接收线程 diff --git a/TSCP/src/MSCP/CM/CM_IP.c b/TSCP/src/MSCP/CM/CM_IP.c new file mode 100644 index 0000000..5d27411 --- /dev/null +++ b/TSCP/src/MSCP/CM/CM_IP.c @@ -0,0 +1,268 @@ +#include "CM_IP.h" +#include "CM_Memory.h" + +#include +#include +#include +#include +#include +#include +#include + +/** +* @brief 设置网卡IPv4地址 +* @param[in] pNetCardName 网卡名 +* @param[in] pIpAddr IPv4点分十进制字符串 +* @return 设置结果 +*/ +ENUM_CM_RETURN CM_IP_SetIpAddr(IN const CM_CHAR *pNetCardName, IN const CM_CHAR *pIpAddr) +{ + ENUM_CM_RETURN rt = ENUM_CM_FALSE; + ENUM_CM_RETURN retMem = ENUM_CM_FALSE; + CM_INT32 sock = -1; + CM_INT32 ret = 0; + struct ifreq ifReq; + struct sockaddr_in *pSockAddr = NULL; + + if (NULL == pNetCardName) + { + printf("CM_IP_SetIpAddr netcard name is NULL.\n"); + } + else if (strlen(pNetCardName) >= IFNAMSIZ) + { + printf("CM_IP_SetIpAddr netcard name is too long: %s.\n", pNetCardName); + } + else if (NULL == pIpAddr) + { + printf("CM_IP_SetIpAddr ipAddr is NULL.\n"); + } + else + { + retMem = CM_Memset((void*)&ifReq, (CM_UINT8)0U, (CM_SIZE_T)sizeof(struct ifreq), (CM_SIZE_T)sizeof(struct ifreq)); + if (ENUM_CM_TRUE != retMem) + { + printf("CM_IP_SetIpAddr memset ifreq failed.\n"); + } + else + { + (void)strncpy(ifReq.ifr_name, pNetCardName, IFNAMSIZ - 1); + pSockAddr = (struct sockaddr_in*)&ifReq.ifr_addr; +#ifdef QNX + pSockAddr->sin_len = sizeof(struct sockaddr_in); +#endif + pSockAddr->sin_family = AF_INET; + + ret = (CM_INT32)inet_pton(AF_INET, pIpAddr, &pSockAddr->sin_addr); + if (1 != ret) + { + if (0 == ret) + { + printf("CM_IP_SetIpAddr invalid ip address: %s.\n", pIpAddr); + } + else + { + perror("CM_IP_SetIpAddr inet_pton"); + } + } + else + { + sock = (CM_INT32)socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) + { + perror("CM_IP_SetIpAddr socket"); + } + else + { + /*- 通过临时UDP socket设置指定网卡IP */ + ret = (CM_INT32)ioctl(sock, SIOCSIFADDR, &ifReq); + if (0 != ret) + { + perror("CM_IP_SetIpAddr ioctl SIOCSIFADDR"); + } + else + { + rt = ENUM_CM_TRUE; + } + + (void)close(sock); + } + } + } + } + + return rt; +} + +/** +* @brief 尝试设置网卡IPv4地址并读回校验 +* @param[in] pNetCardName 网卡名 +* @param[in] pIpAddr IPv4点分十进制字符串 +* @return 设置和校验结果 +*/ +ENUM_CM_RETURN CM_IP_TrySetIpAddr(IN const CM_CHAR *pNetCardName, IN const CM_CHAR *pIpAddr) +{ + ENUM_CM_RETURN rt = ENUM_CM_FALSE; + ENUM_CM_RETURN setRt = ENUM_CM_FALSE; + ENUM_CM_RETURN getRt = ENUM_CM_FALSE; + CM_CHAR ipAddrRead[CM_IP_ADDR_STR_LEN] = { 0 }; + + setRt = CM_IP_SetIpAddr(pNetCardName, pIpAddr); + if (ENUM_CM_TRUE != setRt) + { + printf("CM_IP_TrySetIpAddr set ip failed.\n"); + } + else + { + getRt = CM_IP_GetIpAddr(pNetCardName, ipAddrRead, (CM_UINT32)sizeof(ipAddrRead)); + if (ENUM_CM_TRUE != getRt) + { + printf("CM_IP_TrySetIpAddr get ip failed.\n"); + } + else if (0 != strcmp(ipAddrRead, pIpAddr)) + { + printf("CM_IP_TrySetIpAddr ip mismatch, set:%s, read:%s.\n", pIpAddr, ipAddrRead); + } + else + { + rt = ENUM_CM_TRUE; + } + } + + return rt; +} + +/** +* @brief 尝试设置网卡IPv4地址,失败时重复尝试 +* @param[in] pNetCardName 网卡名 +* @param[in] pIpAddr IPv4点分十进制字符串 +* @param[in] retryTimes 失败后的重试次数,总尝试次数为retryTimes + 1 +* @return 设置和校验结果 +*/ +ENUM_CM_RETURN CM_IP_TrySetIpAddrRetry(IN const CM_CHAR *pNetCardName, IN const CM_CHAR *pIpAddr, IN CM_UINT32 retryTimes) +{ + ENUM_CM_RETURN rt = ENUM_CM_FALSE; + CM_UINT32 tryIndex = 0u; + + while (CM_TRUE) + { + if (0u != tryIndex) + { + printf("CM_IP_TrySetIpAddrRetry retry %u.\n", tryIndex); + } + else + { + /* No action. */ + } + + rt = CM_IP_TrySetIpAddr(pNetCardName, pIpAddr); + if (ENUM_CM_TRUE == rt) + { + break; + } + else if (tryIndex >= retryTimes) + { + break; + } + else + { + tryIndex++; + } + } + + if (ENUM_CM_TRUE == rt) + { + printf("IP Set Success, Interface:%s, IP:%s, retryTimes:%u.\n", pNetCardName, pIpAddr, tryIndex); + } + else + { + printf("IP Set Failed, Interface:%s, IP:%s, retryTimes:%u.\n", pNetCardName, pIpAddr, tryIndex); + } + + return rt; +} + +/** +* @brief 读取网卡IPv4地址 +* @param[in] pNetCardName 网卡名 +* @param[out] pIpAddr IPv4点分十进制字符串输出缓存 +* @param[in] ipAddrLen pIpAddr缓存长度 +* @return 读取结果 +*/ +ENUM_CM_RETURN CM_IP_GetIpAddr(IN const CM_CHAR *pNetCardName, OUT CM_CHAR *pIpAddr, IN CM_UINT32 ipAddrLen) +{ + ENUM_CM_RETURN rt = ENUM_CM_FALSE; + ENUM_CM_RETURN retMem = ENUM_CM_FALSE; + CM_INT32 sock = -1; + CM_INT32 ret = 0; + struct ifreq ifReq; + struct sockaddr_in *pSockAddr = NULL; + const CM_CHAR *pRetIpAddr = NULL; + + if (NULL == pNetCardName) + { + printf("CM_IP_GetIpAddr netcard name is NULL.\n"); + } + else if (strlen(pNetCardName) >= IFNAMSIZ) + { + printf("CM_IP_GetIpAddr netcard name is too long: %s.\n", pNetCardName); + } + else if (NULL == pIpAddr) + { + printf("CM_IP_GetIpAddr ipAddr is NULL.\n"); + } + else if (CM_IP_ADDR_STR_LEN > ipAddrLen) + { + printf("CM_IP_GetIpAddr ipAddr buffer is too small.\n"); + } + else + { + pIpAddr[0] = '\0'; + retMem = CM_Memset((void*)&ifReq, (CM_UINT8)0U, (CM_SIZE_T)sizeof(struct ifreq), (CM_SIZE_T)sizeof(struct ifreq)); + if (ENUM_CM_TRUE != retMem) + { + printf("CM_IP_GetIpAddr memset ifreq failed.\n"); + } + else + { + (void)strncpy(ifReq.ifr_name, pNetCardName, IFNAMSIZ - 1); + pSockAddr = (struct sockaddr_in*)&ifReq.ifr_addr; +#ifdef QNX + pSockAddr->sin_len = sizeof(struct sockaddr_in); +#endif + pSockAddr->sin_family = AF_INET; + + sock = (CM_INT32)socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) + { + perror("CM_IP_GetIpAddr socket"); + } + else + { + /*- 通过临时UDP socket读取指定网卡IP */ + ret = (CM_INT32)ioctl(sock, SIOCGIFADDR, &ifReq); + if (0 != ret) + { + perror("CM_IP_GetIpAddr ioctl SIOCGIFADDR"); + } + else + { + /*- 将二进制地址转换为点分十进制IP字符串 */ + pSockAddr = (struct sockaddr_in*)&ifReq.ifr_addr; + pRetIpAddr = (const CM_CHAR*)inet_ntop(AF_INET, &pSockAddr->sin_addr, pIpAddr, ipAddrLen); + if (NULL == pRetIpAddr) + { + perror("CM_IP_GetIpAddr inet_ntop"); + } + else + { + rt = ENUM_CM_TRUE; + } + } + + (void)close(sock); + } + } + } + + return rt; +} diff --git a/TSCP/src/MSCP/CM/CM_IP.h b/TSCP/src/MSCP/CM/CM_IP.h new file mode 100644 index 0000000..dfe768c --- /dev/null +++ b/TSCP/src/MSCP/CM/CM_IP.h @@ -0,0 +1,55 @@ +/** +* @file CM_IP.h +* @brief 获取网卡IP地址 +*/ +#ifndef CM_IP_H_ +#define CM_IP_H_ + +#include "CM_Types.h" + +/** @brief IPv4点分十进制字符串长度,包含字符串结束符 */ +#define CM_IP_ADDR_STR_LEN (16u) + +/** +* @brief 设置网卡IPv4地址 +* @param[in] pNetCardName 网卡名,可使用CM_IP_NETCARD_FEC0等宏 +* @param[in] pIpAddr IPv4点分十进制字符串,例如"192.168.1.10" +* @return 设置结果 +* - ENUM_CM_TRUE 成功 +* - ENUM_CM_FALSE 失败 +*/ +ENUM_CM_RETURN CM_IP_SetIpAddr(IN const CM_CHAR *pNetCardName, IN const CM_CHAR *pIpAddr); + +/** +* @brief 尝试设置网卡IPv4地址并读回校验 +* @param[in] pNetCardName 网卡名,可使用CM_IP_NETCARD_FEC0等宏 +* @param[in] pIpAddr IPv4点分十进制字符串,例如"192.168.1.10" +* @return 设置和校验结果 +* - ENUM_CM_TRUE 设置成功且读回一致 +* - ENUM_CM_FALSE 设置失败或读回不一致 +*/ +ENUM_CM_RETURN CM_IP_TrySetIpAddr(IN const CM_CHAR *pNetCardName, IN const CM_CHAR *pIpAddr); + +/** +* @brief 尝试设置网卡IPv4地址,失败时重复尝试 +* @param[in] pNetCardName 网卡名,可使用CM_IP_NETCARD_FEC0等宏 +* @param[in] pIpAddr IPv4点分十进制字符串,例如"192.168.1.10" +* @param[in] retryTimes 失败后的重试次数,总尝试次数为retryTimes + 1 +* @return 设置和校验结果 +* - ENUM_CM_TRUE 设置成功且读回一致 +* - ENUM_CM_FALSE 全部尝试失败或读回不一致 +*/ +ENUM_CM_RETURN CM_IP_TrySetIpAddrRetry(IN const CM_CHAR *pNetCardName, IN const CM_CHAR *pIpAddr, IN CM_UINT32 retryTimes); + +/** +* @brief 读取网卡IPv4地址 +* @param[in] pNetCardName 网卡名,可使用CM_IP_NETCARD_FEC0等宏 +* @param[out] pIpAddr IPv4点分十进制字符串输出缓存 +* @param[in] ipAddrLen pIpAddr缓存长度,至少为CM_IP_ADDR_STR_LEN +* @return 读取结果 +* - ENUM_CM_TRUE 成功 +* - ENUM_CM_FALSE 失败 +*/ +ENUM_CM_RETURN CM_IP_GetIpAddr(IN const CM_CHAR *pNetCardName, OUT CM_CHAR *pIpAddr, IN CM_UINT32 ipAddrLen); + +#endif