⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp.c

📁 RTL8019以太网开发板资料
💻 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 + -