📄 arp.c
字号:
#include "tcpip.h"
#include <string.h>
#define ARP_PKT_LEN (42)
/*-----------------------------------------------------------------------------*
*- Function : ArpSeek -*
*- Parameter: ipaddr, Ip address -*
*- Return : 0, if specific entry is found -*
*- Brief : Seek the whole ARP table untill an entry is found with it's ip -*
*- address equal with the given one
*-----------------------------------------------------------------------------*/
uint8 ArpSeek(PSock psock, PNetIF pni) {
uint8 idx;
for(idx = 0; idx < ARP_ENTRY_AMOUNT; ++idx) {
if(pni->arptbl[idx].ip == psock->dst_ip) {
memcpy(psock->buff, pni->arptbl[idx].mac, 6);
return IP_NO_ERR;
}
}
return IP_MAC_NOT_FOUND;
}
uint8 AddrResolve(PSock psock, PNetIF pni) {
if((psock->dst_ip & (~pni->mask)) == (~pni->mask)) {
memset(psock->buff, 0xFF, 6);
memcpy(psock->buff + 6, pni->mac, 6);
return IP_NO_ERR;
}
if((psock->dst_ip & 0xF0000000) == 0xE0000000) {
psock->buff[0] = 0x01;
psock->buff[1] = 0x00;
psock->buff[2] = 0x5E;
psock->buff[3] = (uint8)(psock->dst_ip >> 16) & 0x7F;
psock->buff[4] = (uint8)(psock->dst_ip >> 8);
psock->buff[5] = (uint8)psock->dst_ip;
memcpy(psock->buff + 6, pni->mac, 6);
return IP_NO_ERR;
}
if((psock->dst_ip & pni->mask) == (pni->ip & pni->mask)) {
return (ArpSeek(psock, pni));
}
else {
psock->dst_ip = pni->gate;
return (ArpSeek(psock, pni));
}
}
/*-----------------------------------------------------------------------------*
*- Function : ArpInput -*
*- Parameter: phdr, Pointer of an ARPHeader struct variable -*
*- payload, First address of ARP data -*
*- Return : void -*
*- Brief : receive an ARP protocol packet -*
*-----------------------------------------------------------------------------*/
uint8 ArpInput(PSock psock) {
uint32 dstip, srcip;
uint16 operation;
n2h32(psock->payload + 14, &srcip);
n2h32(psock->payload + 24, &dstip);
n2h16(psock->payload + 6, &(operation));
switch(operation) {
case ARP_OP_QUERY:
if(dstip == psock->pni->ip) {
ArpAddEntry(srcip, psock->payload + 8, psock->pni);
ArpOutput(srcip, psock->payload + 8, ARP_OP_REPLY);
}
break;
case ARP_OP_REPLY:
ArpAddEntry(srcip, psock->payload + 8, psock->pni);
break;
}
PutSock(psock);
return (0);
}
/*-----------------------------------------------------------------------------*
*- Function : ArpOutput -*
*- Parameter: ipaddr, Ip address -*
*- Return : void -*
*- Brief : Query the mac address of given ip address -*
*-----------------------------------------------------------------------------*/
uint8 ArpOutput(uint32 ip, uint8 mac[], uint16 op) {
PSock psock;
psock = GetSock(PROTOCOL_ETHER, ARP_PKT_LEN, 0, ip, NISelect(ip));
h2n16(ARP_TYPE, psock->payload + 12);
h2n16(1, psock->payload + 14);
h2n16(0x0800, psock->payload + 16);
psock->payload[18] = 6;
psock->payload[19] = 4;
h2n16(op, psock->payload + 20);
memcpy(psock->payload + 6, psock->pni->mac, 6);
memcpy(psock->payload + 22, psock->pni->mac, 6);
h2n32(psock->pni->ip, psock->payload + 28);
h2n32(ip, psock->payload + 38);
if(ARP_OP_REPLY == op) {
memcpy(psock->payload, mac, 6);
memcpy(psock->payload + 32, mac, 6);
}
else {
memset(psock->payload, 0xFF, 6);
}
return (psock->pni->output(psock));
}
/*-----------------------------------------------------------------------------*
*- Function : ArpAddEntry -*
*- Parameter: ipaddr, Ip address -*
*- macaddr, MAC address -*
*- Return : void -*
*- Brief : Add an ARP entry to the end of ARP table, if the table is -*
*- already full, an oldest entry in it will be replaced -*
*-----------------------------------------------------------------------------*/
uint8 ArpAddEntry(uint32 ip, uint8 mac[], PNetIF pni) {
pni->arptbl[pni->arp_idx].ip = ip;
memcpy(pni->arptbl[pni->arp_idx].mac, mac, 6);
pni->arp_idx += 1;
pni->arp_idx &= (ARP_ENTRY_AMOUNT - 1);
return (pni->arp_idx);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -