arplab finished again
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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请求包
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user