arplab finished again
This commit is contained in:
@ -1,5 +1,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "xnet_tiny.h"
|
#include "xnet_tiny.h"
|
||||||
|
#include "xarp.h"
|
||||||
|
|
||||||
int main (void) {
|
int main (void) {
|
||||||
printf("xnet running\n");
|
printf("xnet running\n");
|
||||||
@ -11,9 +13,25 @@ int main (void) {
|
|||||||
// printf("=== xnet initialized, entering main loop ===\n");
|
// printf("=== xnet initialized, entering main loop ===\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
|
const uint8_t target_ip[] = {172, 17, 0, 2};
|
||||||
|
int arp_timer = 0;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
xnet_poll();
|
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;
|
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));
|
xnet_packet_t *tx_packet = xnet_alloc_for_send(sizeof(xarp_packet_t));
|
||||||
if (tx_packet) {
|
if (tx_packet) {
|
||||||
xarp_packet_t *arp_request = (xarp_packet_t *)tx_packet->data;
|
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.
|
* @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.
|
* 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) {
|
void xarp_poll(void) {
|
||||||
for (int i = 0; i < XARP_CACHE_SIZE; i++) {
|
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
|
// Refresh the entry by sending a new ARP request
|
||||||
entry->tmo = XARP_STABLE_TMO_MS;
|
entry->tmo = XARP_STABLE_TMO_MS;
|
||||||
// send_arp_request(entry->ip_addr);
|
// 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_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_poll(void); // Declaration for the new periodic poll function
|
||||||
void xarp_send_gratuitous(void);
|
void xarp_send_gratuitous(void);
|
||||||
|
void send_arp_request(const uint8_t *ip_addr);
|
||||||
|
|
||||||
#endif // XARP_H
|
#endif // XARP_H
|
||||||
|
|||||||
Reference in New Issue
Block a user