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

📄 icmp.c

📁 用AVR单片机和RTL8019实现TCP/IP协议.支持ARP,PING,UDP,TCP,HTML网页显示等功能.
💻 C
字号:
//**********************************
//*版本: Test 1.0
//*作者: XUGUOHONG
//*E-MAIL: KK20Y@YAHOO.COM.CN
//*WEBSITE:microdesign.000webhost.com
//**********************************

#include <icmp.h>
#include <ip.h>
#include <rtl8019as.h>
//**********************************
//*  系统 MAC地址设定(根据需要修正)
//**********************************
extern unsigned char SYSMAC[6];
//**********************************
//*  系统 IP地址设定(根据需要修正)
//**********************************
extern unsigned char SYSIP[4];

void icmp(void);
void ping_reply(void);
unsigned int icmp_cal_csum(void);

//**********************************
//*  ICMP处理
//*根据条件判断是哪种ICMP
//*目前只支持PING
//**********************************
void icmp(void)
{
 unsigned char temp;
 temp=read_62256(ICMP_TYP);
 if( temp==0X08)
    ping_reply();
}

void ping_reply(void)
{
 unsigned char temp0;
 unsigned char temp1;
 unsigned int temp2;
 //对IP数据头进行处理,在已收到数据基础上修改
 temp2=read_62256(IP_ID_ADD);                   // 1. IP头数据中IP标识区数据加1
 temp1=read_62256(IP_ID_ADD+1);
 temp2=(temp2<<8)+temp1;
 temp2++;
 write_62256(IP_ID_ADD+1,temp2);
 write_62256(IP_ID_ADD,temp2>>8);
 
 write_62256(IP_HDR_CSUM,0x00);                // 2. IP头CHECKSUM部分至0x0000
 write_62256(IP_HDR_CSUM+1,0x00);
 
 for(temp0=0;temp0<4;temp0++)                  // 3. 设置目标IP地址
 {
  temp1=read_62256(IP_SRC_IP0+temp0);
  write_62256(IP_DES_IP0+temp0,temp1);
 }
 
 for(temp0=0;temp0<4;temp0++)
   write_62256(IP_SRC_IP0+temp0,SYSIP[temp0]); // 4. 设置本机IP地址
   
 temp2=ip_cal_csum();                          // 5. IP头chechsum计算
 write_62256(IP_HDR_CSUM+1,temp2);              
 write_62256(IP_HDR_CSUM,temp2>>8);
 
 //对ICMP数据头进行处理,在已收到数据基础上修改
 write_62256(ICMP_TYP,0X00);                   // 1. ICMPTYPE改为0X00
 write_62256(ICMP_CSUM,0X00);                  // 2. Icmp chechsum计算 
 write_62256(ICMP_CSUM+1,0X00); 
 temp2=icmp_cal_csum();                        //    调用CHECHSUM函数计算
 write_62256(ICMP_CSUM+1,temp2);              
 write_62256(ICMP_CSUM,temp2>>8);
 
 //修改ETHERNET数据包目标和源MAC地址
 for(temp0=0;temp0<6;temp0++)                  // 3. 设置目标MAC地址
 {
  temp1=read_62256(SRCMAC0+temp0);
  write_62256(DESMAC0+temp0,temp1);
 }
 for(temp0=0;temp0<6;temp0++)                  // 4. 设置本机MAC地址
  write_62256(SRCMAC0+temp0,SYSMAC[temp0]);   
 
 // 发送数据包
 temp2=read_62256(IP_TOL_LEN);                 // 5. 计算数据包长度
 temp1=read_62256(IP_TOL_LEN+1);
 temp2=(temp2<<8)+temp1+0X0E;                               
 sendpacket(temp2);                            //  发送数据    
}

//************************************
//      ICMP数据包CHECKSUM
//************************************
unsigned int icmp_cal_csum(void)
{
 unsigned char temp1;
 unsigned int temp2;
 unsigned long datah=0x00000000;
 unsigned int data=0x0000;
 temp2=read_62256(IP_TOL_LEN);                  // 1. 计算数据包长度
 temp1=read_62256(IP_TOL_LEN+1);
 temp2=(temp2<<8)+temp1-20;
 
  if((temp2&0x0001)==0x0001)                        //  奇数个数据处理
 {
	write_62256(temp2+ICMP_TYP,0x00);
 }
 
 for(temp1=0;temp1<temp2;temp1=temp1+2)
 {
  data=read_62256(ICMP_TYP +temp1);            // 高位数值xxxxabcd
  datah= datah+(data<<8);                      // 形成数值xxxxabcdxxxx
  datah=datah+read_62256(ICMP_TYP +1+temp1);   // 形成数值xxxxabcdefgh
 }
  data=datah+(datah>>16);
  
  data=0xFFFF-data;
  return data;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -