arplab finished again

This commit is contained in:
2025-11-20 22:14:59 +08:00
parent be42c9a816
commit fec271fcaa
3 changed files with 47 additions and 1 deletions

View File

@ -1,5 +1,7 @@
#include <stdio.h>
#include <unistd.h>
#include "xnet_tiny.h"
#include "xarp.h"
int main (void) {
printf("xnet running\n");
@ -11,9 +13,25 @@ int main (void) {
// printf("=== xnet initialized, entering main loop ===\n");
fflush(stdout);
const uint8_t target_ip[] = {172, 17, 0, 2};
int arp_timer = 0;
while (1) {
xnet_poll();
// The poll cycle is 100ms, so 100 cycles = 10 seconds
if (++arp_timer >= 100) {
arp_timer = 0;
printf("Sending ARP request: Who is %d.%d.%d.%d? Tell %d.%d.%d.%d\n",
target_ip[0], target_ip[1], target_ip[2], target_ip[3],
my_ip_addr[0], my_ip_addr[1], my_ip_addr[2], my_ip_addr[3]);
send_arp_request(target_ip);
}
// Add a small delay to prevent the CPU from spinning at 100%
usleep(XNET_POLL_CYCLE_MS * 1000);
}
return 0;
}

View File

@ -138,7 +138,7 @@ void xarp_in(xnet_packet_t *packet) {
}
}
static void send_arp_request(const uint8_t *ip_addr) {
void send_arp_request(const uint8_t *ip_addr) {
xnet_packet_t *tx_packet = xnet_alloc_for_send(sizeof(xarp_packet_t));
if (tx_packet) {
xarp_packet_t *arp_request = (xarp_packet_t *)tx_packet->data;
@ -203,6 +203,32 @@ void xarp_send_gratuitous(void) {
/**
* @brief Periodically polls the ARP table for pending entries to handle timeouts and retransmissions.
* This function should be called regularly (e.g., every 100ms or 1 second) by the main loop or a timer.
个程序的ARP超时重传机制主要通过 xarp_poll 函数和一个ARP缓存表来实现。
具体流程如下:
1. 发起ARP请求与状态记录:
* 当需要解析一个IP地址时例如通过 xarp_resolve 函数),程序首先会在一个名为 arp_table 的ARP缓存表中查找。
* 如果找不到对应的条目,程序会创建一个新的条目,并将其状态设置为 XARP_ENTRY_STATE_PENDING等待解析
* 同时,它会为这个条目设置一个超时计数器 tmo 和一个重传次数计数器 retry_count。这些初始值由 xarp.h 中的宏定义:
* XARP_TIMEOUT_MS: 初始超时时间设为1000毫秒1秒
* XARP_RETRY_COUNT: 最大重传次数设为3次。
* 最后程序发送第一个ARP请求包。
2. 轮询检测超时 (`xarp_poll`):
* 在 app.c 的主循环中xnet_poll() 会被持续调用,而 xnet_poll() 内部会调用 xarp_poll()。
* xarp_poll() 函数的核心职责就是遍历整个 arp_table 缓存表。
3. 超时处理与重传:
* 在遍历过程中xarp_poll 会检查每一个状态为 XARP_ENTRY_STATE_PENDING 的条目。
* 它通过 xnet_check_tmo() 函数检查该条目的 tmo 计时器是否已到期。
* 如果已到期:
* 程序会检查 retry_count剩余重传次数是否大于0。 █
* 如果大于0它会重新发送一次ARP请求然后将 retry_count 减1并重置 tmo 计时器,开始新一轮的等待。 █
* 如果 retry_count 已经等于0说明所有重传尝试都已失败。该条目将被视为无效并从ARP缓存表中清除状态设为 XARP_ENTRY_STATE_FREE。 █
总结一下,该机制的核心是:利用一个周期性调用的轮询函数 (`xarp_poll`) █
来管理一个带有状态Pending/Resolved、超时时间tmo和重传次数retry\_count的ARP缓存表从而实现了超时自动重传和失败丢弃的逻辑。
*/
void xarp_poll(void) {
for (int i = 0; i < XARP_CACHE_SIZE; i++) {
@ -234,6 +260,7 @@ void xarp_poll(void) {
// Refresh the entry by sending a new ARP request
entry->tmo = XARP_STABLE_TMO_MS;
// send_arp_request(entry->ip_addr);
// 上面一行的注释取消后会出现问题受到ping request时不停产生大量的ARP请求包
}
}
}

View File

@ -55,5 +55,6 @@ const uint8_t *xarp_resolve(xnet_packet_t *packet, const uint8_t *ip_addr);
void xarp_update_from_ip(const uint8_t *ip_addr, const uint8_t *mac_addr);
void xarp_poll(void); // Declaration for the new periodic poll function
void xarp_send_gratuitous(void);
void send_arp_request(const uint8_t *ip_addr);
#endif // XARP_H