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

📄 arp.c

📁 LPC2292 bios测试程序 说明:YL_LPC229X_BIOS_Data的目录说明
💻 C
字号:
#include "../../inc/config.h"
#include "skbuff.h"
#include "eth.h"
#include "arp.h"
#include "utils.h"

#ifdef	TFTP_DOWNLOAD_SUPPORT

#define ARP_CACHE_SIZE   16

typedef struct arp_entry
{
	unsigned char ar_ha[ETH_ALEN];
	unsigned long ar_ip;
} arp_entry;

static arp_entry arp_entrys;
static arp_entry arp_cache[ARP_CACHE_SIZE];
static int arp_chche_cur = 0;

int arp_init( void )
{
	memset( &arp_entrys , 0 , sizeof( arp_entry ) );
	memset( arp_cache , 0 , sizeof( arp_entry ) * ARP_CACHE_SIZE );

	return 0;
}

int arp_add_entry( unsigned char* ha , unsigned long ip )
{
	memcpy( arp_entrys.ar_ha , ha , ETH_ALEN );
	arp_entrys.ar_ip = htonl( ip );

	return 0;
}

int arp_add_cache( unsigned char* ha , unsigned long ip )
{
	int i;

	for ( i = 0; i < ARP_CACHE_SIZE; i++ )
	{
		if ( ip == arp_cache[i].ar_ip )
			break;
	}

	if ( i == ARP_CACHE_SIZE )
	{
		i = arp_chche_cur;
		//		arp_chche_cur = (arp_chche_cur + 1) % ARP_CACHE_SIZE;
		arp_chche_cur++;
		if ( arp_chche_cur >= ARP_CACHE_SIZE )
			arp_chche_cur = 0;
	}

	memcpy( arp_cache[i].ar_ha , ha , ETH_ALEN );
	arp_cache[i].ar_ip = ip;

	return 0;
}

int arp_send_req( unsigned long ip )
{
	struct sk_buff* skb;
	struct arphdr* arp_req;	
	unsigned char broadcast[ETH_ALEN] =
	{
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
	};	

	skb = alloc_skb( ETH_HLEN + sizeof( struct arphdr ) );
	eth_skb_reserve( skb );
	arp_req = ( struct arphdr * ) skb_put( skb , sizeof( struct arphdr ) );

	arp_req->ar_hrd = htons( ARPHRD_ETHER );
	arp_req->ar_pro = htons( ETH_P_IP );
	arp_req->ar_hln = 0x06;
	arp_req->ar_pln = 0x04;
	arp_req->ar_op = htons( ARPOP_REQUEST );	
	memcpy( ( unsigned char * ) arp_req->ar_sha , arp_entrys.ar_ha , ETH_ALEN );
	arp_req->ar_sip = arp_entrys.ar_ip;	
	memset( ( unsigned char * ) arp_req->ar_tha , 0x00 , ETH_ALEN );
	arp_req->ar_tip = htonl( ip );

	eth_send( skb , broadcast , ETH_P_ARP );

	return 0;
}

int arp_send_rsp( struct arphdr* arp_hdr )
{
	struct sk_buff* skb;
	struct arphdr* arp_rsp;	

	skb = alloc_skb( ETH_HLEN + sizeof( struct arphdr ) );
	eth_skb_reserve( skb );
	arp_rsp = ( struct arphdr * ) skb_put( skb , sizeof( struct arphdr ) );

	arp_rsp->ar_hrd = htons( ARPHRD_ETHER );
	arp_rsp->ar_pro = htons( ETH_P_IP );
	arp_rsp->ar_hln = 0x06;
	arp_rsp->ar_pln = 0x04;
	arp_rsp->ar_op = htons( ARPOP_REPLY );
	memcpy( ( unsigned char * ) arp_rsp->ar_sha , arp_entrys.ar_ha , ETH_ALEN );
	arp_rsp->ar_sip = arp_hdr->ar_tip;
	memcpy( ( unsigned char * ) arp_rsp->ar_tha ,
		( unsigned char * ) arp_hdr->ar_sha , ETH_ALEN );
	arp_rsp->ar_tip = arp_hdr->ar_sip;

	eth_send( skb , arp_hdr->ar_sha , ETH_P_ARP );

	return 0;
}

int arp_get_eth_addr( unsigned long ip , unsigned char* ha )
{
	int i;

	for ( i = 0; i < ARP_CACHE_SIZE; i++ )
	{
		if ( htonl( ip ) == arp_cache[i].ar_ip )
		{
			memcpy( ha , arp_cache[i].ar_ha , ETH_ALEN );
			break;
		}
	}

	if ( i == ARP_CACHE_SIZE )
	{
		arp_send_req( ip );
		return -1;
	}

	return 0;
}

int arp_rcv_packet( struct sk_buff* skb )
{
	struct arphdr* arp_hdr = ( struct arphdr* ) ( skb->data );

	if ( arp_hdr->ar_tip != arp_entrys.ar_ip )
		return 0;

	if ( arp_hdr->ar_op == htons( ARPOP_REQUEST ) )
		arp_send_rsp( arp_hdr );
	arp_add_cache( arp_hdr->ar_sha , arp_hdr->ar_sip );

	return 0;
}

#endif

⌨️ 快捷键说明

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