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

📄 ip.c

📁 S3C2440驱动DM9000A的裸机程序
💻 C
字号:
#include "MyLib.h"

//用到gMyIP[4],gIP_ident
extern struct _CONN conn[MAX_CONN+1];//tcpdata.c

U32 Calc_checksum(U8 *buf, U32 len)		// 计算16位校验和
{
	U32 i,sum=0;
	for(i=0; i<len; i++){
		if(i&0x01)	// 低位
			sum+=buf[i];
		else			// 高位
			sum+=(buf[i]*256);
	}
	while(sum>0xFFFF)
		sum=sum/0x10000+sum%0x10000;
	sum=0xFFFF-sum;
	return sum;
}
//ipaddr=目标地址,proro_id=协议类型
void IP_send(U8 *buf, U8 *ipaddr, U8 proto_id, U32 len)//len是上一级的长度
{
	U8 *hwaddr;
	U32 sum;
	buf[0x0E]=0x45;							// IPv4 with 20 byte header
    buf[0x0F]=0;								// Type_of_service
    buf[0x10]=(len+20)/256;  buf[0x11]=(len+20)%256;	// Total_length
	buf[0x12]=gIP_ident/256;  buf[0x13]=gIP_ident%256;  gIP_ident++;
	buf[0x14]=buf[0x15]=0;					// Fragment_info=0(not fragmented)
	buf[0x16]=0x80;							// Time to live
	buf[0x17]=proto_id;						// Protocol id
	buf[0x18]=buf[0x19]=0;					// Header checksum
	MyMemcpy(buf+0x1A, gMyIP, 4);			// Source IP
	MyMemcpy(buf+0x1E, ipaddr, 4);		// Dest IP
	sum=Calc_checksum(buf+14, 20);
	buf[0x18]=sum/256;  buf[0x19]=sum%256;
	hwaddr=Arp_resolve(ipaddr);//查找目标网卡物理地址
	if(hwaddr==NULL)							// 无效IP地址
		return;
	MyMemcpy(buf, hwaddr, 6);				// 目的网卡MAC地址
	MyMemcpy(buf+6, gMyPhy, 6);			// 发送网卡MAC地址
	buf[0x0C]=0x08;  buf[0x0D]=0x00;		// IP_Packet
	DM9000_SendBuf(buf, len+34);
}

void IP_receive(U8 *buf, U32 len)
{
	U16 dat;
	U16 header_len, payload_len;
	if(MyMemcmp(buf+0x1E, gMyIP, 4))		// 判断是否为本机IP
		return;
	header_len=(buf[0x0E]&0x0F)*4;		// header_len=20
	payload_len=buf[0x10]*256+buf[0x11]-header_len;
	if(Calc_checksum(buf+14, header_len))// 检查IP校验和
		return;
	if((buf[0x0E]&0xF0)!=0x40)				// 检查IP版本号(IPV4)
		return;
	dat=buf[0x14]+buf[0x15]*0x100;
	if((dat&0xFF3F)!=0)	// 检查分段(本系统不支持分段)
		return; 
	if(header_len>20){
		MyMemcpy(buf+34, buf+14+header_len, payload_len);
		header_len=20;  buf[0x0E]=0x45;
		buf[0x10]=(payload_len+20)/256;  buf[0x11]=(payload_len+20)%256;
	}
	Arp_update(buf+0x1A, buf+0x06);		// 确保IP对应的网卡物理地址在Cache中
	switch(buf[0x17]){						// IP协议处理
	case ICMP_TYPE:							// ICMP协议(Ping)
		ICMP_receive(buf, payload_len);//payload是该包的长度,从buf+34开始
		break;
	case UDP_TYPE:								// UDP协议
		UDP_receive(buf, payload_len);	// UDP数据从第34字节开始,包括8个字节UDP包头
		break;
	case TCP_TYPE:								// TCP协议
		//TCP_receive(buf, payload_len);	// 真正数据从第34字节开始(14字节以太网头+20字节IP头)
		break;
	}
}

/*void http_send(U8 *buf, U32 len, U32 nr)
{
	U32 tmp,sum;
	buf[34]=HTTP_PORT/256;  buf[35]=HTTP_PORT%256;	// TCP->source_port
	MyMemcpy(buf+36, conn[nr].port, 4);					// TCP->dest_port
	MyMemcpy(buf+38, conn[nr].my_sequence, 4);		// TCP->sequence
	MyMemcpy(buf+42, conn[nr].his_sequence, 4);		// TCP->ack_number
	tmp=0x5000 | TCP_ACK;
	buf[46]=tmp/256;  buf[47]=tmp%256;					// TCP->flags
	buf[48]=1460/256;  buf[49]=1460%256;				// tcp->window
	buf[50]=buf[51]=0;										// tcp->checksum
	buf[52]=buf[53]=0;										// tcp->urgent_ptr
	MyMemcpy(buf+30, conn[nr].ipaddr, 4);				// ip->dest_ipaddr
	MyMemcpy(buf+26, gMyIP, 4);							// ip->source_ipaddr
	sum=0xFFFF-Calc_checksum(buf+26, 8+len);
	sum+=(len+6);
	sum=(sum&0xFFFF)+(sum>>16);
	sum=0xFFFF-sum;
	buf[50]=sum/256;  buf[51]=sum%256;					// tcp->checksum
	IP_send(buf, conn[nr].ipaddr, TCP_TYPE, len);
}
*/

⌨️ 快捷键说明

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