arp.c

来自「ARP协议,含ARP」· C语言 代码 · 共 390 行

C
390
字号
#include "arp.h"
#include "typedef.h"
#include "tick.h"
#include "string.h"
#include "stdio.h"
#include "mem.h"
#include "eth.h"
#include "cfg.h"
#include "string.h"

#define ARP_ITEM_NUM      3

#define ARP_HARD_TYPE     0x0100    //ARP包硬件类型 以太网0x0100
#define ARP_PROT_TYPE     0x0008     //ARP协议类型
#define ARP_OP_REQ         0x0100
#define ARP_OP_RES         0x0200

#define ARP_NULL         0
#define ARP_WAIT         1
#define ARP_WORK         4

#define ARP_WORK_OUT       7200
#define ARP_WAIT_OUT        60
#define ARP_QEQUEST_COUNT   10
struct _arp_item arp_items[ARP_ITEM_NUM];

void arp_recv_message(uc * msg)
{

    struct _eth_arp *p;
	p=(struct _eth_arp *)msg;
	
	if(ARP_OP_REQ==p->op)
    {
        //请求处理
		

       //ARP类型为响应类型
        p->op=ARP_OP_RES;

        //以太网头部填充
        cfg_get_mac_addr(p->src_mac);
        memcpy(p->dst_mac,p->src_mac,MAC_ADDR_LEN);

        //将接收到的ARP包的源IP、MAC赋给要发送的ARP Response包的目的IP、MAC
        memcpy(p->dst_ip_addr,p->src_ip_addr,IP_ADDR_LEN);
        memcpy(p->dst_mac_addr,p->src_mac_addr,MAC_ADDR_LEN);

        //填充以太网的源IP和源MAC地址
        cfg_get_mac_addr(p->src_mac_addr);
        cfg_get_src_addr(p->src_ip_addr);

        arp_send_response(p);
    }
    if(ARP_OP_RES==p->op)
    {
        //响应处理
        uc pid;
        struct _arp_item *p_temp;
        if(arp_find_ip(p->src_ip_addr,&pid))
        {
         p_temp=&(arp_items[pid]);
         if(ARP_WAIT==p_temp->state)
         {
             p_temp->state=ARP_WORK;
             p_temp->timer=ARP_WORK_OUT;
			 memcpy(p_temp->mac_addr,p->src_mac,MAC_ADDR_LEN);
         }
         else{}
        }   

    }

}


void arp_send_response(struct _eth_arp * p)
{

    struct _mem_block *pm;
    struct _eth_arp *p_arp;
    if(NULL==(pm=(struct _mem_block *) alloc_mb()))
    {
       // printf("ARP_request处内存块分配失败");
        return;
    }

    p_arp=(struct _eth_arp *)(pm->content);
    //memcpy(p_arp->dst_mac,p->dst_mac,MAC_ADDR_LEN);
	cfg_get_mac_addr(p_arp->dst_mac);
	//memset(p_arp->dst_mac,0xFF,MAC_ADDR_LEN);
    memcpy(p_arp->src_mac,p->src_mac,MAC_ADDR_LEN);
    memcpy(p_arp->dst_mac_addr,p->dst_mac_addr,MAC_ADDR_LEN);
    memcpy(p_arp->src_mac_addr,p->src_mac_addr,MAC_ADDR_LEN);

    memcpy(p_arp->dst_ip_addr,p->dst_ip_addr,IP_ADDR_LEN);
    memcpy(p_arp->src_ip_addr,p->src_ip_addr,IP_ADDR_LEN);

    p_arp->frame_type=ETH_FRAME_ARP;
    
    //填充ARP头部
    p_arp->hard_type=ARP_HARD_TYPE;
    p_arp->prot_type=ARP_PROT_TYPE;
    p_arp->hard_addr_len=MAC_ADDR_LEN;
    p_arp->prot_addr_len=IP_ADDR_LEN;
    p_arp->op=ARP_OP_RES;

    pm->len=sizeof(struct _eth_arp);

    eth_send_msg(pm);	
    free_msg(pm);
}

void arp_send_request(uc * ip_addr,uc * src_addr)
{
    struct _mem_block *pm;
    struct _eth_arp *p;

    if(NULL==(pm=(struct _mem_block *)alloc_mb()))
    {
       // printf("ARP_request处内存块分配失败");
        return;
    }
    p=(struct _eth_arp *)(pm->content);
    
    //填充以太网头部
    memset(p->dst_mac,0xFF,MAC_ADDR_LEN);//ARP请求目的MAC地址为广播
    cfg_get_mac_addr(p->src_mac);
    p->frame_type=ETH_FRAME_ARP;
    
    //填充ARP头部
    p->hard_type=ARP_HARD_TYPE;
    p->prot_type=ARP_PROT_TYPE;
    p->hard_addr_len=MAC_ADDR_LEN;
    p->prot_addr_len=IP_ADDR_LEN;
    p->op=ARP_OP_REQ;
    cfg_get_mac_addr(p->src_mac_addr);
	memset(p->dst_mac_addr,0,MAC_ADDR_LEN);
    //memcpy(p->src_ip_addr,src_addr,
    //cfg_get_src_addr(p->src_ip_addr);
    memcpy(p->src_ip_addr,src_addr,IP_ADDR_LEN);
    memcpy(p->dst_ip_addr,ip_addr,IP_ADDR_LEN);
    
    pm->len=sizeof(struct _eth_arp);
    
    eth_send_msg(pm);
    free_msg(pm);

}


void arp_task(void)
{
    struct _arp_item *p;
    uc i;

 //   printf("这是ARP任务!\n");
    //print_arp_items();
    for(i=0;i<ARP_ITEM_NUM;i++)
    {
       p=&(arp_items[i]);
       switch(p->state)
       {
		case ARP_WAIT:
           if(0==p->timer)
           {
               //状态迁移到初始态
               p->state=ARP_NULL;
                         
           }
           else
           {              
               if(0==p->count)
               {
                   p->count=10;
                   uc  src_ip_temp[4];
                   uc  dst_ip_temp[4];
                   cfg_get_src_addr(src_ip_temp);
                   memcpy(dst_ip_temp,p->ip_addr,IP_ADDR_LEN);
                   arp_send_request(src_ip_temp,dst_ip_temp);
               }
               else
               {
                   p->count--;
               }
               p->timer--;            
           }
		case ARP_WORK:
           if(0==p->timer)
           {
               p->state=ARP_NULL;
               
           }
           else
           {
               p->timer--;
           }
		case ARP_NULL:
		default:;      
       }                    
    }
}


void arp_tick(void)
{ 
    static uc cnt=0;

    cnt++;
    if(cnt>=50)
    {
        cnt=0;
        arp_task();
    }
 
}

bool arp_find_ip(uc * ip_addr,uc *pidx)
{
    struct _arp_item *p;
    for(uc i=0;i<ARP_ITEM_NUM;i++)
    {
        p=&(arp_items[i]);
        if(ARP_NULL==p->state)
        {
            continue;
        }
        if(cfg_same_ip(ip_addr,p->ip_addr))
        {
            *pidx=i;
            return true;
        }
    }
    return false;
}
us arp_item_age(struct _arp_item *p)
{
	us age;
	
	switch ( p->state )
	{
		case ARP_WAIT:
			age=(ARP_WAIT_OUT-p->timer);
			break;
		case ARP_WORK:
			age=(ARP_WORK_OUT-p->timer)+ARP_WAIT_OUT;
			break;
		case ARP_NULL:
		default:
		age=0x7FFF;
	}
	return age;
}

uc arp_find_empty_item(void)
{
	struct _arp_item *p;
	us max_age,age;
	uc i,sel_i;
	
	max_age=0;
	sel_i=0;
	
	for(i=0;i<ARP_ITEM_NUM;i++)
	{
		p=&(arp_items[i]);
		if(ARP_NULL==p->state)
		{
		 sel_i=i;
		 break;
		}
		
		age=arp_item_age(p);
		if(age>max_age)
		{
			max_age=age;
			sel_i=i;
		}
	}
	
	memset(&(arp_items[sel_i]),0,sizeof(struct _arp_item));
	return sel_i;
}

void arp_put_ip(uc index,uc * des_ip_addr)
{	
	struct _arp_item *p;
	p=&(arp_items[index]);
	memcpy(p->ip_addr,des_ip_addr,MAC_ADDR_LEN);
	p->state=ARP_WAIT;
	p->timer=ARP_WAIT_OUT;
	p->count=ARP_QEQUEST_COUNT;
}

void init_arp_items(void)
{
    uc ip[4];
    uc mac[6];
    ip[0]=192;
    ip[1]=168;
    ip[2]=2;
    ip[3]=1;

    mac[0]=0x11;
    mac[1]=0x22;
    mac[2]=0x33;
    mac[3]=0x44;
    mac[4]=0x55;
    mac[5]=0x66;
    memcpy(arp_items[0].ip_addr,ip,4);
    memcpy(arp_items[0].mac_addr,mac,6);
    arp_items[0].state=ARP_NULL;
    arp_items[0].timer=0;

    memcpy(arp_items[1].ip_addr,ip,4);
    memcpy(arp_items[1].mac_addr,mac,6);
    arp_items[1].state=ARP_WORK;
    arp_items[1].timer=7200;

    memcpy(arp_items[2].ip_addr,ip,4);
    memcpy(arp_items[2].mac_addr,mac,6);
    arp_items[2].state=ARP_WAIT;
    arp_items[2].timer=60;

}
void init_arp(void)
{
    memset(arp_items,0,sizeof(arp_items));
  //  init_arp_items();
    enroll_tick(arp_tick);

}

void print_arp_items(void)
{

    struct _arp_item *p;
    uc i=0;
	put_char ('\r');
	put_char ('\n');
	put_char('a');
	put_char('r');
	put_char('p');
	put_char('.');
	for(i=0;i<ARP_ITEM_NUM;i++)
	{
		p=&(arp_items[i]);
		put_char ('\r');
		put_char ('\n');
		put_hex(i+1);
		put_char('.');
		put_char('i');
		put_char('p');
		put_char('-');
		put_char('>');
		put_hex4(p->ip_addr);
		put_char ('\r');
		put_char ('\n');
		put_char('m');
		put_char('a');
		put_char('c');
		put_char('-');
		put_char('>');
		put_hex_6(p->mac_addr);
		put_char ('\r');
		put_char ('\n');
		put_char('s');
		put_char('t');
		put_char('a');
		put_char('t');
		put_char('e');
		put_char('-');
		put_char('>');
		put_hex(p->state);
		put_char ('\r');
		put_char ('\n');
		put_char('t');
		put_char('i');
		put_char('m');
		put_char('e');
		put_char('r');
		put_char('-');
		put_char('>');
		put_hex_2(p->timer);
	}


}

   

⌨️ 快捷键说明

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