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

📄 arp.c

📁 在ucos_ii基础上加上网络功能
💻 C
字号:
/* 
 * $Id: arp.c,v 1.4 2002/02/07 01:08:53 linfusheng Exp $
 */
#include "includes.h"
#include "ether.h"
#include "nic.h"



#define ARP_DEBUG
int debug = 1;

/* Cache stuff */
#define ARP_NUM 8			/* need at most 3 arp entries */

#define bcopy(x,y,l)	memcpy(y,x,l)
#define bzero(x,l)	memset(x,0,l)
#define bcmp(x,y,l)	memcmp(x,y,l)
#define MACPY(s,d)	bcopy(s,d,ETH_ALEN)

struct arp_list {
	struct in_addr	addr;
	unsigned char	ea[6];
} arp_list[ARP_NUM] = {
	/* XXX - net order `INADDR_BROADCAST' must be a constant */
	{ {0xffffffff}, BA }
};
int arp_num = 1;


void arp_reply(struct nbuf *nbuf);

/* Broadcast an ARP packet, asking who has addr on interface d */
unsigned char *
arpwhohas(struct nic *d, struct in_addr addr)
{
	int i;
	struct ether_arp *ah;
	struct arp_list *al;
	struct {
		struct ethhdr eh;
		struct {
			struct ether_arp arp;
			unsigned char pad[18]; 	/* 60 - sizeof(...) */
		} data;
	} wbuf;
	struct {
		struct ethhdr eh;
		struct {
			struct ether_arp arp;
			unsigned char pad[24]; 	/* extra space */
		} data;
	} rbuf;

	/* Try for cached answer first */
	for (i = 0, al = arp_list; i < arp_num; ++i, ++al)
		if (addr.s_addr == al->addr.s_addr)
			return (al->ea);

	/* Don't overflow cache */
	if (arp_num > ARP_NUM - 1) {
		arp_num = 1;	/* recycle */
		debug_print("arpwhohas: overflowed arp_list!\r\n");
	}

#ifdef ARP_DEBUG
 	if (debug)
 	    debug_print("arpwhohas: send request for %08x\r\n", addr.s_addr);
#endif

	bzero((char*)&wbuf.data, sizeof(wbuf.data));
	ah = &wbuf.data.arp;
	ah->arp_hrd = htons(ARPHRD_ETHER);
	ah->arp_pro = htons(ETHERTYPE_IP);
	ah->arp_hln = sizeof(ah->arp_sha); /* hardware address length */
	ah->arp_pln = sizeof(ah->arp_spa); /* protocol address length */
	ah->arp_op = htons(ARPOP_REQUEST);
	MACPY(d->node_addr, ah->arp_sha);
	bcopy(&d->ip_addr, ah->arp_spa, sizeof(ah->arp_spa));
	/* Leave zeros in arp_tha */
	bcopy(&addr, ah->arp_tpa, sizeof(ah->arp_tpa));

	/* Store ip address in cache (incomplete entry). */
	al->addr = addr;



	/* send packet */


	/* Store ethernet address in cache */
	ah = &rbuf.data.arp;

	MACPY(ah->arp_sha, al->ea);
	++arp_num;

	return (al->ea);
}


static int
arpsend(struct nbuf *nbuf,unsigned char *dest_hw,unsigned short ptype)
{
	struct ethhdr *eh = nbuf->lh.ethernet;
	struct nic *d = nbuf->nic;

	nbuf->data -= ETH_HLEN;
	nbuf->len += ETH_HLEN;

	MACPY(d->node_addr, eh->ether_shost);		/* by byte */
	MACPY(dest_hw, eh->ether_dhost);			/* by byte */
	eh->ether_type = htons(ptype);

	
	if(d->transmit)
		return d->transmit(d, nbuf->data,nbuf->len);
	return 0;
}



/*
 * Returns 0 if this is the packet we're waiting for
 * else -1 (and errno == 0)
 */
int
arprecv(struct nbuf *nbuf)

{
	int n = nbuf->len;
	struct ether_arp *ah = nbuf->nh.arph;


	errno = 0;	/* XXX */
	if (n < 0 || n < sizeof(struct ether_arp)) {
		return (-1);
	}


	/* Ethernet address now checked in readether() */

	if (ah->arp_hrd != htons(ARPHRD_ETHER) ||
	    ah->arp_pro != htons(ETHERTYPE_IP) ||
	    ah->arp_hln != sizeof(ah->arp_sha) ||
	    ah->arp_pln != sizeof(ah->arp_spa) )
	{
		return (-1);
	}

	if (ah->arp_op == htons(ARPOP_REQUEST)) {
		arp_reply(nbuf);
		return (-1);
	}

	if (ah->arp_op != htons(ARPOP_REPLY)) {
		return (-1);
	}

	/* Is the reply from the source we want? */
	if (bcmp(&arp_list[arp_num].addr,
			 ah->arp_spa, sizeof(ah->arp_spa)))
	{
		return (-1);
	}

	/* We don't care who the reply was sent to. */

	/* We have our answer. */

	return (0);
}



/*
 * Convert an ARP request into a reply and send it.
 * Notes:  Re-uses buffer.  Pad to length = 46.
 */
void
arp_reply(struct nbuf *nbuf)
{
	struct ether_arp *arp = nbuf->nh.arph;
	struct nic *d = nbuf->nic;

	/* If we are not the target, ignore the request. */
	if (bcmp(arp->arp_tpa, &d->ip_addr, sizeof(arp->arp_tpa))) {
		return;
	}

	arp->arp_op = htons(ARPOP_REPLY);
	/* source becomes target */
	bcopy(arp->arp_sha, arp->arp_tha, sizeof(arp->arp_tha));
	bcopy(arp->arp_spa, arp->arp_tpa, sizeof(arp->arp_tpa));
	/* here becomes source */
	bcopy(d->node_addr,  arp->arp_sha, sizeof(arp->arp_sha));
	bcopy(&d->ip_addr, arp->arp_spa, sizeof(arp->arp_spa));

	/*
	 * No need to get fancy here.  If the send fails, the
	 * requestor will just ask again.
	*/
	(void) arpsend(nbuf,arp->arp_tha, ETHERTYPE_ARP);
}

/* 
 * $Log: arp.c,v $
 * Revision 1.4  2002/02/07 01:08:53  linfusheng
 * update
 *
 * Revision 1.3  2002/01/28 01:13:52  linfusheng
 * update
 *
 * Revision 1.2  2002/01/28 00:58:45  linfusheng
 * update
 *
 */

⌨️ 快捷键说明

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