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

📄 ethernet.c

📁 基于S3C2410和SM501的彩屏控制器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#define __ETHERNET
#include "ethernet.h"
#undef __ETHERNET


//********************** Global Variable **********************
volatile uchar *udppack = 0;	// 接收的udp包的IP指针
volatile uchar	PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
ushort ourport[10] = {10000,20000,30000,40000,50000,60000,808,300,800,801};

IPaddr_t	NetOurIP;				/* Our IP addr (0 = unknown) */
IPaddr_t	NetOurSubnetMask=0;		/* Our subnet mask (0=unknown) */
IPaddr_t	NetOurGatewayIP=0;		/* Our gateways IP address */
IPaddr_t	NetServerIP;			/* Server IP addr (0 = unknown) */
IPaddr_t	NetArpWaitPacketIP;
IPaddr_t	NetArpWaitReplyIP;

static 	rxhand_f *packetHandler;	/* Current RX packet handler */
int		NetArpWaitTxPacketSize;
uchar	NetOurEther[6];				/* Our ethernet address	*/
uchar	NetServerEther[6];		/* Boot server enet address	*/
volatile uchar * NetRxPkt;		/* Current receive packet */
int		NetRxPktLen;	/* Current rx packet length	*/

uchar 	NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
uchar	NetBcastAddr[6] =	/* Ethernet bcast address */
			{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
uchar	NetEtherNullAddr[6] = { 0, 0, 0, 0, 0, 0 };
int		NetArpWaitTry;
ulong	NetArpWaitTimerStart;
ulong 	NetIPID;		/* IP packet ID	*/
int		NetState;		/* Network loop state */

static thand_f *timeHandler;			/* Current timeout handler */
static ulong	timeStart;				/* Time base value */
static ulong	timeDelta;				/* Current timeout value */
uchar	       *NetArpWaitPacketMAC;	/* MAC address of waiting packet's destination */
uchar          *NetArpWaitTxPacket;		/* THE transmit packet */

//*************************************************************



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 判断是否16进制字符.
//
// [参数表]
//	s: 待判断的字符.
//
// 返回: 0-FALSE; 1-TRUE.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
uchar IsXDigital (uchar s)
{
	if(( s >= '0' && s <= '9') ||
	  (s >= 'A' && s <= 'F') ||
	  (s >= 'a' && s <= 'f'))
		return 1;
	else
		return 0;
}//IsXDigital()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 判断是否十进制字符.
//
// [参数表]
//	s: 待判断的字符.
//
// 返回: 0-FALSE; 1-TRUE.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
uchar IsDigital (uchar s)
{
	if( s >= '0' && s <= '9' )
		return 1;
	else
		return 0;
}//IsDigital()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 判断是否字符a~f.
//
// [参数表]
//	s: 待判断的字符.
//
// 返回: 0-FALSE; 1-TRUE.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 判断是否是16进制字符中的'a'-'f' **************************
uchar IsLowerStr (uchar s)
{
	if( s >= 'a' && s <= 'f' )
		return 1;
	else
		return 0;
}//IsLowerStr()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 将小写字符转换为大写字符.
//
// [参数表]
//	s: 待转换的字符.
//
// 返回: 转换后的字符.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
uchar LowerToUp(uchar s)
{
	return s-32;
}//LowerToUp()



ulong simple_strtoul (const char *cp, char **endp, uint base)
{
	unsigned long result = 0,value;
	
	if (*cp == '0') 
	{
		cp++;
		if ((*cp == 'x') && IsXDigital(cp[1])) 
		{
			base = 16;
			cp++;
		}
		if (!base) 
		{
			base = 8;
		}
	}
	if (!base) 
	{
		base = 10;
	}

	while (IsXDigital(*cp) && (value = IsDigital(*cp) ? *cp-'0' : (IsLowerStr(*cp)
	    ? LowerToUp(*cp) : *cp)-'A'+10) < base) 
	{
		result = result*base + value;
		cp++;

	}
	if (endp)
		*endp = (char *)cp;
	return result;
}//simple_strtoul()



void NetSetHandler(rxhand_f * f)
{
	packetHandler = f;
}//NetSetHandler()



static startAgainTimeout(void)
{
	NetState = NETLOOP_RESTART;
	return NetState;
}//startAgainTimeout()



static IPaddr_t NetReadIP (void *from)
{
	IPaddr_t ip;
	memcpy((void*)&ip, from, sizeof(ip));
	return ip;
}//NetReadIP()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 复制IP.
// 描述: Copy IP.
//
// [参数表]
//	to: 目的地址.
//	from: 源地址.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NetCopyIP (void *to, void *from)
{
	memcpy(to, from, sizeof(IPaddr_t));
}//NetCopyIP()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 将IP转换为字符串.
// 描述: Convert an IP address to a string.
//
// [参数表]
//	x: IP.
//	s: 存储字符串的数组.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ip_to_string (IPaddr_t x, char *s)
{
 	 x = ntohl(x);
    sprintf (s,"%d.%d.%d.%d",
	(int)((x >> 24) & 0xff),
	(int)((x >> 16) & 0xff),
	(int)((x >>  8) & 0xff),
	(int)((x >>  0) & 0xff)
    );
}//ip_to_string()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网络校验和检查.
// 描述: 
//
// [参数表]
//	ptr: 数据指针.
//	len: 数据包长度.
//
// 返回: 校验和结果.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ushort NetCksum (uchar * ptr, int len)
{
	ulong	xsum;

	xsum = 0;
	while (len-- > 0)
		xsum += *((ushort *)ptr)++;
	xsum = (xsum & 0xffff) + (xsum >> 16);
	xsum = (xsum & 0xffff) + (xsum >> 16);

	return (xsum & 0xffff);
}//NetCksum()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网络校验和检查是否成功.
//
// [参数表]
//	ptr: 数据指针.
//	len: 数据包长度.
//
// 返回: 0-FALSE; 1-TRUE.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int NetCksumOk (uchar * ptr, int len)
{
	return !((NetCksum(ptr, len) + 1) & 0xfffe);
}//NetCksumOk()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网络数据包接收.
// 描述:  UDP包接收.
//
// [参数表]
//	udpdata: 数据指针.
//	srcipaddr: 源IP地址.
//	srcport: 源端口号.
//	
// 返回: 数据长度.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ushort NetRxPack (uchar *udpdata, char *srcipaddr,ushort *srcport)
{
	int i;	
	IP_t *ip ;
	Ethernet_t *et;
	IP_t *netarpip;
	ushort udplen;

	NetTRPackInit();	// 分配接收、发送缓冲区
			
	( uchar *) udppack = NULL;
	eth_rx();
	
	if( !udppack )	// 若UDP包的IP地址为0, 则返回
		return 0;
		
	ip = (IP_t *)udppack;

	for( i=0; i<10; i++ )
	{
		// 判定udp端口在不在我的端口范围
		if( ntohs(ip->udp_dst)==ourport[i] )
			break;
	}
		
	if( i==10 ) 
	{	
		// 判定udp端口不相等
		return 0;
	}

	// 读出发送端IP地址
	ip_to_string(NetReadIP(&ip->ip_src), srcipaddr);

	// 存贮ip地址和对应的MAC地址
	et = (Ethernet_t *)((ulong)ip-ETHER_HDR_SIZE);
	
	// 保存收包IP地址
	memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest,(char *)et->et_src,6);
	
	netarpip = (IP_t *)(NetArpWaitTxPacket+ETHER_HDR_SIZE);
	NetCopyIP(&netarpip->ip_dst,&ip->ip_src);	   // 保存收包MAC地址

	// 读出源端口
	*srcport = ntohs(ip->udp_dst);
	
	// 读出udp数据长度
	udplen = ntohs(ip->udp_len) - 8;
	
	// 读出udp数据
	memcpy (udpdata,(uchar *)ip + IP_HDR_SIZE, udplen);

	return (udplen);  	
}//NetRxPack()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 设置网络参数.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NetSetEther (volatile uchar * xet, uchar * addr, uint prot)
{
	Ethernet_t *et = (Ethernet_t *)xet;

	memcpy (et->et_dest, addr, 6);
	memcpy (et->et_src, NetOurEther, 6);
	et->et_protlen = htons(prot);
}//NetSetEther()


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 设置网络参数.
//
// [参数表]
//	x: IP.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void print_IPaddr (IPaddr_t x)
{
    char tmp[16];

    ip_to_string(x, tmp);
}//print_IPaddr()



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 函数: 网络接收数据包处理.
//
// [参数表]
//	ptr: 数据指针.
//	len: 数据包长度.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NetReceiveProcess (volatile uchar * pkt, int len)
{
	Ethernet_t 	*et;
	IP_t 		*ip;
	ARP_t 		*arp;
	IPaddr_t 	tmp;
	int	x;
	
	NetRxPkt = pkt;
	NetRxPktLen = len;
	et = (Ethernet_t *)pkt;
	x = ntohs(et->et_protlen);

	if( x<1514 )
	{
	/*
	 *	Got a 802 packet.  Check the other protocol field.
	 */
		x = ntohs(et->et_prot);
		ip = (IP_t *)(pkt + E802_HDR_SIZE);
		len -= E802_HDR_SIZE;
	}
	else
	{
		ip = (IP_t *)(pkt + ETHER_HDR_SIZE);
		len -= ETHER_HDR_SIZE;
	}

	switch (x)		// 根据协议选择处理
	{
		case PROT_ARP:
			/*
			 * We have to deal with two types of ARP packets:
			 * - REQUEST packets will be answered by sending  our
			 *   IP address - if we know it.
			 * - REPLY packates are expected only after we asked
			 *   for the TFTP server's or the gateway's ethernet
			 *   address; so if we receive such a packet, we set
			 *   the server ethernet address
			 */

			arp = (ARP_t *)ip;	
				
			if (NetReadIP(&arp->ar_data[16]) != NetOurIP) {
				return;
			}
			if (len < ARP_HDR_SIZE) {
				return;
			}
			if (ntohs(arp->ar_hrd) != ARP_ETHER) {
				return;
			}
			if (ntohs(arp->ar_pro) != PROT_IP) {
				return;
			}
			if (arp->ar_hln != 6) {
				return;
			}
			if (arp->ar_pln != 4) {
				return;
			}

			if (NetOurIP == 0) {
				return;
			}

			switch (ntohs(arp->ar_op)) 
			{
				case ARPOP_REQUEST:		/* reply with our IP address	*/
					NetSetEther((uchar *)et, et->et_src, PROT_ARP);
					arp->ar_op = htons(ARPOP_REPLY);
					memcpy   (&arp->ar_data[10], &arp->ar_data[0], 6);
					NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]);
					memcpy   (&arp->ar_data[ 0], NetOurEther, 6);
					NetCopyIP(&arp->ar_data[ 6], &NetOurIP);
					(void) eth_send((uchar *)et, ((uchar *)arp-pkt) + ARP_HDR_SIZE);
					return;

				case ARPOP_REPLY:		/* arp reply */
					/* are we waiting for a reply */
					if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC)
						break;
					tmp = NetReadIP(&arp->ar_data[6]);

					/* matched waiting packet's address */
					if (tmp == NetArpWaitReplyIP) 
					{
					/* save address for later use */
					memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6);

					/* modify header, and transmit it */
					memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6);
					(void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize);
					/* no arp request pending now */
					NetArpWaitPacketIP = 0;
					NetArpWaitTxPacketSize = 0;
					NetArpWaitPacketMAC = NULL;

					}
					return;
				default:
					return;
		}

		case PROT_RARP:

			arp = (ARP_t *)ip;
			if (len < ARP_HDR_SIZE) 
			{
				//printf("bad length %d < %d\n", len, ARP_HDR_SIZE);
				return;
			}

			if ((ntohs(arp->ar_op) != RARPOP_REPLY) ||

⌨️ 快捷键说明

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