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

📄 udp.c

📁 RTL8019以太网开发板资料
💻 C
📖 第 1 页 / 共 4 页
字号:
            {                                  // 计算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 + -