📄 udp.c
字号:
/************************************************************************
FileName: Udp.c
Description: Udp protocol process
Date: 2007 09 21
************************************************************************/
#include "Main.h"
#include "EEPROM.h"
#include "tcp.h"
#include "ip.h"
#include "arp.h"
#include "RTL8019.h"
/************************************************************************/
bit EthernetBuf0DataFlag; // 以太网卡缓冲0已有数据
bit EthernetLinkFlag; // 以太网是否LINK上
bit EthernetNoDataFlag; // 以太网芯片中没有数据
UWORK16 RTL8019asRcvNum; // 在缓存中以太网包的个数,16K存满64页,每页256字节
xdata ST_RECEIVE_ETHERNET gstaRevEthernet; // 接收以太网包
xdata ST_ETHERNET_STATISTICS gstEthernetStatistics; // 以太网卡收发统计
xdata UWORK8 MAC_Remote_buf[ETHER_HEAD_LEN]; // 以太网头(目的MAC,源MAC,协议)
xdata UWORK8 NetSend_buf[NET_SEND_BUFF]; // 以太网发送缓冲
xdata UWORK8 gucaSegTemp[SEGMENT_DATA]; // 分片数据
/************************************************************************/
xdata UWORK16 LocalIpID; // 本地IP的ID号
xdata UWORK16 RevIpID; // 接收的ID号
bit gbMoreSegFlag; // 还有更多的分片标志
bit gbHaveFragment; // 有分片标志
/***********************************************************************/
xdata UWORK8 SetupIP_RcvSignal[32]; // 接收前导和标志信号
xdata UWORK8 SetupIP_SendSignal[32]; // 发送前导和标志信号
xdata ST_UDP_STATISTICS gstUDPStatistics; // UDP统计
/*********************************************************************
函数名: 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],&IPLocalAddress_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 = 0x20; //校验和计算完毕,重赋TTL值
memcpy(&MAC_Remote_buf[0],&ArpCache_Buf[0].ucaMAC[0],MAC_LEN); // 远程MAC */
IpSend();
gstUDPStatistics.ulUDPSendDataNum += usSendLen; // UDP发送数据个数统计
}
/*********************************************************************
函数名: 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],&IPLocalAddress_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 = 0x20; // 校验和计算完毕,重赋TTL值
memcpy(&MAC_Remote_buf[0],&gstaRevEthernet.ucaSourceNodID[0],MAC_LEN); // 目的MAC
IpSend();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -