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

📄 arp.c

📁 包括EPA协议栈
💻 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 + -