📄 udp.c
字号:
{ // 计算ICMP校验和
pIcmpHead->usCheckSum = CheckSum((UWORK16 *)&gstaRevEthernet.ucaPacket[20],usTotalLen);
gstIphead.usSegOffset = 0;
gstIphead.usTotalLen = 20 + usTotalLen;
memcpy(&NetSend_buf[20],&gstaRevEthernet.ucaPacket[20],usTotalLen); // 拷贝数据到发送缓冲
IpSend();
}
else
{ // 计算ICMP校验和
pIcmpHead->usCheckSum = CheckSum((UWORK16 *)&gucaSegTemp[20],usTotalLen);
ucNum = (UWORK8)(usTotalLen / 1480);
usRes = usTotalLen % 1480;
gstIphead.usTotalLen = 20 + 1480;
for(usLoop = 0; usLoop < ucNum; usLoop++)
{
if((0 == usRes) && (ucNum == (usLoop + 1))) // 数据为1480的整数倍且是最后一帧数据
{
gstIphead.usSegOffset = usLoop * (1480 / 8);
}
else
{
gstIphead.usSegOffset = 0x2000 + usLoop * (1480 / 8); // 不是最后一帧数据,需要将IP的more fragment位置1,所以要加上"0x2000"
}
memcpy(&NetSend_buf[20],&gucaSegTemp[usLoop * 1480 + 20],1480); // 拷贝数据到发送缓冲
IpSend();
}
if(0 != usRes)
{
gstIphead.usTotalLen = 20 + usRes;
gstIphead.usSegOffset = usLoop * (1480 / 8);
memcpy(&NetSend_buf[20],&gucaSegTemp[usLoop * 1480 + 20],usRes); // 拷贝数据到发送缓冲
IpSend();
}
}
break;
default:
break;
}
}
/*********************************************************************
函数名: void UdpReceive(void)
功能: Udp处理,因为是接收一帧处理一帧,不用返回成功失败
输入: none
输出: 处理Udp报文
返回: None
日期: 2004/12/27
*********************************************************************/
void UdpReceive(void)
{
ST_UDP_HEAD_FORMAT *pUdpHead;
ST_IP_HEAD_FORMAT *pIpHead;
UWORK8 *pucUDPData;
UWORK16 usCheckSum,usCheckSumBak;
UWORK8 ucTTLBak;
if(FALSE == gbHaveFragment)
{ // 没有分片的数据
pUdpHead = (ST_UDP_HEAD_FORMAT *)&gstaRevEthernet.ucaPacket[20]; // 指向udP头
pIpHead = (ST_IP_HEAD_FORMAT *)&gstaRevEthernet.ucaPacket[0]; // 指向IP头
}
else
{ // 分片的数据
pUdpHead = (ST_UDP_HEAD_FORMAT *)&gucaSegTemp[20]; // 指向udP头
pIpHead = (ST_IP_HEAD_FORMAT *)&gucaSegTemp[0]; // 指向IP头
}
// 检验端口号,本地端口号,DHCP端口号,配置端口号
if((pUdpHead->usDesPort != NetParameter.Port_Local) && (CONFIG_PORT != pUdpHead->usDesPort))
{
//IcmpSend(ICMP_PORT_UNREACHABLE,PORT_UNREACHABLE); // 发送端口不可达报文
//gstUDPStatistics.ulUDPPortError++; // 端口号错误统计
return;
}
if(pIpHead->usTotalLen < pUdpHead->usTotalLen) // 属于恶意攻击
{
return;
}
// 发送端没有进行UDP校验和计算,直接送入串口缓冲
if((0 == pUdpHead->usCheckSum) && (CONFIG_PORT != pUdpHead->usDesPort))
{
// 初始化数据指针
if(FALSE == gbHaveFragment) // 没有分片的数据
{
pucUDPData = &gstaRevEthernet.ucaPacket[28];
}
else
{
pucUDPData = &gucaSegTemp[28]; // 分片的数据
}
SerialSendbuf(pucUDPData,pUdpHead->usTotalLen - 8);
gstUDPStatistics.ulUDPReceiveDataNum += (pUdpHead->usTotalLen - 8); // 统计UDP接收的数据个数
}
else
{ // 备份数据,以便发远端抑制报文
ucTTLBak = pIpHead->ucTTL;
usCheckSumBak = pIpHead->usCheckSum;
// 组装UDP伪头
pIpHead->ucTTL = 0;
pIpHead->usCheckSum = pUdpHead->usTotalLen;
// 计算校验和
if(FALSE == gbHaveFragment)
{
usCheckSum = CheckSum((UWORK16 *)&gstaRevEthernet.ucaPacket[8],pUdpHead->usTotalLen + 12); // 12个字节的伪头
}
else
{
usCheckSum = CheckSum((UWORK16 *)&gucaSegTemp[8],pUdpHead->usTotalLen + 12); // 12个字节的伪头
}
if(0x0000 == usCheckSum)
{
pIpHead->ucTTL = ucTTLBak; // 可能会发抑制报文
pIpHead->usCheckSum = usCheckSumBak;
if(NetParameter.Port_Local == pUdpHead->usDesPort)
{ // 初始化数据指针
if(FALSE == gbHaveFragment) // 没有分片的数据
{
pucUDPData = &gstaRevEthernet.ucaPacket[28];
}
else
{
pucUDPData = &gucaSegTemp[28]; // 分片的数据
}
SerialSendbuf(pucUDPData,pUdpHead->usTotalLen - 8);
gstUDPStatistics.ulUDPReceiveDataNum += (pUdpHead->usTotalLen - 8); // 统计UDP接收的数据个数
}
else if(CONFIG_PORT == pUdpHead->usDesPort)
{
ConfigParameter(); // 配置参数
}
}
else
{
gstUDPStatistics.ulUDPCheckSumError++; // 统计校验错误次数
}
}
}
/*********************************************************************
函数名: void UdpSend(UWORK8 *pucAddr,UWORK8 ucLen)
功能: Udp发送函数
输入: 串口有完整数据帧到来
输出: 发送Udp报文
返回: None
日期: 2007/01/30
*********************************************************************/
void UdpSend(UWORK8 *pucAddr,UWORK16 usLen)
{
UWORK16 usSendLen;
ST_UDP_HEAD_FORMAT *pUdpHead;
usSendLen = usLen;
// UDP头
pUdpHead = (ST_UDP_HEAD_FORMAT *)&NetSend_buf[20];
pUdpHead->usSourcePort = NetParameter.Port_Local;
pUdpHead->usTotalLen = 8 + usSendLen;
// UDP数据
memcpy(&NetSend_buf[UDP_DATA_START],pucAddr,usSendLen);
// UDP头
pUdpHead = (ST_UDP_HEAD_FORMAT *)&NetSend_buf[20];
pUdpHead->usSourcePort = NetParameter.Port_Local;
pUdpHead->usTotalLen = 8 + usSendLen;
gstIphead.usTotalLen = UDP_DATA_START + usSendLen; // 28 = 20个字节IP头 + 8个字节UDP头
memcpy(&gstIphead.ucSourceIP[0],&IPAddress_buf[0],IP_LEN); // 源IP
// IP头
gstIphead.usID = ++LocalIpID;
gstIphead.usSegOffset = 0;
memcpy(&gstIphead.ucDestIP[0],&ArpCache_Buf[0].ucaIP[0],IP_LEN); // 目的IP
// UDP伪头
gstIphead.ucTTL = 0;
gstIphead.ucprotocol = UDP;
gstIphead.usCheckSum = 8 + usSendLen; // 8个字节UDP头
memcpy(&NetSend_buf[0],&gstIphead,20);
pUdpHead->usDesPort = ArpCache_Buf[0].usRemotePort;
pUdpHead->usCheckSum = 0;
pUdpHead->usCheckSum = CheckSum((UWORK16 *)&NetSend_buf[8],usSendLen + 20); // 20 = 12个字节伪头 + 8个字节UDP头
gstIphead.ucTTL = 0x80; //校验和计算完毕,重赋TTL值
memcpy(&MAC_Remote_buf[0],&ArpCache_Buf[0].ucaMAC[0],MAC_LEN); // 远程MAC */
IpSend();
gstUDPStatistics.ulUDPSendDataNum += usSendLen; // UDP发送数据个数统计
}
/*********************************************************************
函数名: void ConfigParameter(void)
功能: 配置参数
输入: 配置软件发送来的请求包
输出: 根据命令输出数据
返回: None
日期: 2007/01/20
*********************************************************************/
void ConfigParameter(void)
{
if(0 == memcmp(&gstaRevEthernet.ucaPacket[UDP_DATA_START],&NetParameter.SeupHead_buf[0],32)) //判断前导信号和标志信号
{
memcpy(&NetSend_buf[UDP_DATA_START],&NetParameter.SeupHead_buf[0],32); //前导和标志信号
NetSend_buf[SAVE_OK] = 0; // 初始化保存成功
switch(gstaRevEthernet.ucaPacket[COMMAND_START_ADDR]) //命令字节
{
case BROADCAST_SEARCH: // 广播搜索
NetSend_buf[COMMAND_START_ADDR] = REPLY_BROADCAST; // 回应广播信号
memcpy(&NetSend_buf[EQUNAME_LEN],&NetParameter.Name_len, 27); // 名字,MAC,IP
DelayMs((TL0 & 0x07)); // 随机延时,防止同时回应
UDPConfigSend(END_PARA);
break;
case CONFIG_REQUEST:
//******************** 网口参数 **********************
NetSend_buf[COMMAND_START_ADDR] = REPLY_CONFIG; // 配置请求回应
memcpy(&NetSend_buf[EQUNAME_LEN],&NetParameter.Name_len,108);
//********************* 统计数据 *************************
ShowStatistic();
UDPConfigSend(END_PARA);
break;
case SAVE_NET_CONFIG: // 保存配置
NetSend_buf[COMMAND_START_ADDR] = REPLY_SAVE_NETCONFIG;
if(0 != memcmp(&NetParameter.Name_len,&gstaRevEthernet.ucaPacket[EQUNAME_LEN],(sizeof(Setup_Parameter) - 42))) //比较接收的数据与本机的参数是否相等。
{
// 将参数保存进FLASH
memcpy(&NetParameter.Name_len, &gstaRevEthernet.ucaPacket[EQUNAME_LEN], (sizeof(Setup_Parameter) - 42));
FlashWriteData(NetParameter_Addr, &NetParameter.startFlag, sizeof(Setup_Parameter)); //保存参数
FlashWriteData(NetParameter_BakAddr, &NetParameter.startFlag, sizeof(Setup_Parameter)); //保存到备份参数
if(0 != memcmp(&NetParameter.MAC_Local_buf[0],&gstaRevEthernet.ucaPacket[MAC_ADDR],MAC_LEN)) //比较MAC
{
UDPConfigSend(END_PARA); // 改变了MAC,需要重新初始化以太网芯片
DelayMs(10); // 等待网络发送完
InitPara();
InitSerial();
if(OK == RTL8019asInit()) //初始化以太网芯片
{
ResetSystem();
}
}
else
{
UDPConfigSend(END_PARA);
InitPara();
InitSerial();
}
IPConflitTestFlag = TRUE;
}
else
{
UDPConfigSend(END_PARA);
}
break;
case REFLESH_STATISTIC: // 刷新统计信息
ShowStatistic();
NetSend_buf[COMMAND_START_ADDR] = REPLY_FLESH;
UDPConfigSend(END_PARA);
break;
case CLEAR_STATISTIC: // 清零统计信息请求
memset(&gstUDPStatistics,0,sizeof(gstUDPStatistics));
memset(&gstUARTStatistics,0,sizeof(gstUARTStatistics));
NetSend_buf[COMMAND_START_ADDR] = REPLY_CLEAR_STATISTIC;
UDPConfigSend(END_PARA);
break;
case RESET_SYSTEM: //复位系统
ResetSystem();
break;
default:
break;
}
}
}
/*********************************************************************
函数名: void UDPConfigSend(UWORK16 usUdpDataLen)
功能: Udp发送配置函数
输入: 发送数据的长度
输出: 发送Udp报文
返回: None
日期: 2005/06/28
*********************************************************************/
void UDPConfigSend(UWORK16 usUdpDataLen)
{
xdata ST_UDP_HEAD_FORMAT *pUdpHead;
//IP头
gstIphead.usTotalLen = UDP_DATA_START + usUdpDataLen; //28 = 20个字节IP头 + 8个字节UDP头
gstIphead.usID = ++LocalIpID;
gstIphead.usSegOffset = 0;
memcpy(&gstIphead.ucSourceIP[0],&IPAddress_buf[0],IP_LEN); // 源IP
memcpy(&gstIphead.ucDestIP[0],&gstaRevEthernet.ucaPacket[12],IP_LEN); // 目的IP
// UDP伪头
gstIphead.ucTTL = 0;
gstIphead.ucprotocol = UDP;
gstIphead.usCheckSum = 8 + usUdpDataLen; // 8个字节UDP头
memcpy(&NetSend_buf[0],&gstIphead,20);
//UDP头
pUdpHead = (ST_UDP_HEAD_FORMAT *)&NetSend_buf[20];
pUdpHead->usSourcePort = CONFIG_PORT;
pUdpHead->usDesPort = CONFIG_PORT;
pUdpHead->usTotalLen = 8 + usUdpDataLen;
//UDP校验
pUdpHead->usCheckSum = 0;
pUdpHead->usCheckSum = CheckSum((UWORK16 *)&NetSend_buf[8],usUdpDataLen + 20); // 20 = 12个字节伪头 + 8个字节UDP头
gstIphead.ucTTL = 0x80; // 校验和计算完毕,重赋TTL值
memcpy(&MAC_Remote_buf[0],&gstaRevEthernet.ucaSourceNodID[0],MAC_LEN); // 目的MAC
IpSend();
}
/*********************************************************************
函数名: void ShowStatistic(void)
功能: 显示统计信息
输入: 配置软件发送统计请求
输出: 将统计信息发送出去
返回: None
日期: 2005/07/05
*********************************************************************/
void ShowStatistic(void)
{
memcpy(&NetSend_buf[RUN_DAYS],(UWORK8 *)&gusDate,2); //运行天数
NetSend_buf[RUN_HOURS] = gucHour; //运行小时数
NetSend_buf[RUN_MINUTES] = gucMinute; //运行分钟数
NetSend_buf[RUN_SECONDS] = gucSecond; //运行秒数
memcpy(&NetSend_buf[UDP_RCV_BYTES],(UWORK8 *)&gstUDPStatistics.ulUDPReceiveDataNum,4); //UDP接收字节数
memcpy(&NetSend_buf[UDP_SEND_BYTES],(UWORK8 *)&gstUDPStatistics.ulUDPSendDataNum,4); //UDP发送字节数
memcpy(&NetSend_buf[UART_RCV_BYTES],(UWORK8 *)&gstUARTStatistics.ulUARTReceiveDataNum,4); //串口接收字节数
memcpy(&NetSend_buf[UART_SEND_BYTES],(UWORK8 *)&gstUARTStatistics.ulUARTSendDataNum,4); //串口发送字节数
memcpy(&NetSend_buf[UART_RCV_SOFT_OVERFLOW],(UWORK8 *)&gstUARTStatistics.ulUARTRcvLackQueNum,4); //串口接收软件溢出
memcpy(&NetSend_buf[UART_SEND_SOFT_OVERFLOW],(UWORK8 *)&gstUARTStatistics.ulUARTSendLackQueNum,4); //串口发送软件溢出
memcpy(&NetSend_buf[HARD_SOFT_EIDTION],&NetParameter.VerCode_buf[0],VER_NUM); //软硬件版本号
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -