📄 zarp.c
字号:
#include "./include/zarp.h"#include "./include/zeth.h"#define ARP_LIVING_TIME 100 /*100 seconds*/#define ARP_ITEM_NUM 20STRUCT_BEGINtypedef struct _arp_header{ ethaddr_t dest_hwaddr; ethaddr_t src_hwaddr; u16_t eth_type; u16_t hwtype; u16_t proto; u16_t _hwlen_protolen; u16_t opcode; ethaddr_t shwaddr; ipaddr_t sipaddr; ethaddr_t dhwaddr; ipaddr_t dipaddr;}arp_header_t;STRUCT_ENDtypedef struct _arp_item{ ethaddr_t hwaddr; ipaddr_t ipaddr; u16_t ctime;}arp_item_t;static arp_item_t arp_table[ARP_ITEM_NUM];#define NTOHS#define HTONS#define ARPH_HWLEN(hdr) (NTOHS((hdr)->_hwlen_protolen) >> 8)#define ARPH_PROTOLEN(hdr) (NTOHS((hdr)->_hwlen_protolen) & 0xff)#define ARPH_HWLEN_SET(hdr, len) (hdr)->_hwlen_protolen = HTONS(ARPH_PROTOLEN(hdr) | ((len) << 8))#define ARPH_PROTOLEN_SET(hdr, len) (hdr)->_hwlen_protolen = HTONS((len) | (ARPH_HWLEN(hdr) << 8))void add_arp_item(ipaddr_t *ipaddr, ethaddr_t *hwaddr){ u8_t i,j,olditem = 0; u16_t oldtime = 0xffff; /*MAX VALUE*/ for ( i = 0; i < ARP_ITEM_NUM; i++) { if ( arp_table[i].ipaddr == *ipaddr) { for (j = 0; j < 6; j++) arp_table[i].hwaddr.addr[j] = hwaddr->addr[j]; arp_table[i].ctime = sys_get_time() / 100; return; } if ( arp_table[i].ctime < oldtime) { oldtime = arp_table[i].ctime; olditem = i; } } for (j = 0; j < 6; j++) arp_table[olditem].hwaddr.addr[j] = hwaddr->addr[j]; arp_table[olditem].ipaddr = *ipaddr; arp_table[olditem].ctime = sys_get_time() / 100; return;}void arp_init(void){ u8_t i; for ( i = 0; i < ARP_ITEM_NUM; i++) { arp_table[i].ipaddr = IPADDRANY; arp_table[i].ctime = 0; } }zbuffer_t * arp_arp_input(znetif_t *pnetif, zbuffer_t *pbuffer){ arp_header_t *pheader; u8_t i; if ( pbuffer->tot_len < sizeof( arp_header_t ) ) { return NULL; } pheader =(arp_header_t *) pbuffer->pdata; switch ( pheader->opcode ) { case ARP_REQUEST: { if ( pheader->dipaddr == pnetif->ipaddr ) { pheader->opcode = ARP_REPLY; pheader->dipaddr = pheader->sipaddr; pheader->sipaddr = pnetif->ipaddr; for (i = 0; i < 6; i++) { pheader->dhwaddr.addr[i] = pheader->shwaddr.addr[i]; pheader->shwaddr.addr[i] = pnetif->hwaddr.addr[i]; pheader->dest_hwaddr.addr[i] = pheader->dhwaddr.addr[i]; pheader->src_hwaddr.addr[i] = pnetif->hwaddr.addr[i]; } pheader->hwtype = htons(HWTYPE_ETHERNET); ARPH_HWLEN_SET(pheader, 6); pheader->proto = ETHTYPE_IP; ARPH_PROTOLEN_SET(pheader, sizeof( ipaddr_t)); pheader->eth_type = htons(ETHTYPE_ARP); return pbuffer; } break; } case ARP_REPLY: { if (pheader->dipaddr == pnetif->ipaddr) { add_arp_item(&pheader->sipaddr, &pheader->shwaddr); return NULL; } break; } default: break; } return NULL;}u8_t arp_lookup(ethaddr_t *hwaddr, ipaddr_t *ipaddr){ u8_t i, j; u16_t ctime; sys_enter_critical(); for ( i = 0; i < ARP_ITEM_NUM; i++) { if ( arp_table[i].ipaddr == *ipaddr) { ctime = sys_get_time() / 100; if ( (ctime - arp_table[i].ctime ) >ARP_LIVING_TIME) { arp_table[i].ipaddr = IPADDRANY; /*this must be refresh*/ return -1; } for ( j = 0; j < 6; j++) hwaddr->addr[j] = arp_table[i].hwaddr.addr[j]; sys_exit_critical(); return 0; } } sys_exit_critical(); return -1;}u8_t arp_query(ethaddr_t *hwaddr, ipaddr_t *ipaddr){ zbuffer_t *pbuffer; arp_header_t *parpheader; u8_t i; pbuffer = zbuffer_new(sizeof(arp_header_t)); if ( pbuffer == NULL) return -1; parpheader = (arp_header_t *)pbuffer->pdata; for(i = 0; i < 6; ++i) { parpheader->dhwaddr.addr[i] = 0x00; parpheader->shwaddr.addr[i] = default_netif.hwaddr.addr[i]; } for(i = 0; i < 6; ++i) { parpheader->dest_hwaddr.addr[i] = 0xff; parpheader->src_hwaddr.addr[i] = default_netif.hwaddr.addr[i]; } parpheader->eth_type = ETHTYPE_ARP; parpheader->dipaddr = *ipaddr; parpheader->sipaddr = default_netif.ipaddr; parpheader->hwtype = HWTYPE_ETHERNET; ARPH_HWLEN_SET(parpheader, 6); parpheader->proto = ETHTYPE_IP; parpheader->opcode = ARP_REQUEST; ARPH_PROTOLEN_SET(parpheader, sizeof(ipaddr_t) ); i = 0; while( i < 5) { default_netif.netif_tx(&default_netif, pbuffer); sys_delay(20); i++; if ( arp_lookup(hwaddr, ipaddr) == 0 ) { zbuffer_delete(pbuffer); return 0; } } zbuffer_delete(pbuffer); return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -