arp function finished

This commit is contained in:
2025-11-20 13:29:05 +08:00
parent d1fb91111e
commit e909592496
4 changed files with 63 additions and 17 deletions

View File

@@ -8,21 +8,6 @@
static const uint8_t net_broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
typedef enum _xarp_state_t {
XARP_ENTRY_STATE_FREE,
XARP_ENTRY_STATE_RESOLVED,
XARP_ENTRY_STATE_PENDING,
} xarp_state_t;
typedef struct _xarp_entry_t {
uint8_t ip_addr[4];
uint8_t mac_addr[XNET_MAC_ADDR_SIZE];
xarp_state_t state;
int tmo;
int retry;
xnet_packet_t *packet;
} xarp_entry_t;
static xarp_entry_t arp_table[XARP_CACHE_SIZE];
#define swap_order16(v) ((((v) & 0xFF) << 8) | (((v) >> 8) & 0xFF))
@@ -31,6 +16,8 @@ void xarp_init(void) {
for (int i = 0; i < XARP_CACHE_SIZE; i++) {
arp_table[i].state = XARP_ENTRY_STATE_FREE;
arp_table[i].packet = (xnet_packet_t *)0;
arp_table[i].tmo = 0;
arp_table[i].retry_count = 0;
}
}
@@ -58,6 +45,8 @@ static void update_entry(const uint8_t *ip_addr, const uint8_t *mac_addr, int fo
memcpy(entry->ip_addr, ip_addr, 4);
memcpy(entry->mac_addr, mac_addr, XNET_MAC_ADDR_SIZE);
entry->state = XARP_ENTRY_STATE_RESOLVED;
entry->tmo = 0; // Reset timeout
entry->retry_count = 0; // Reset retry count
if (entry->packet) {
ethernet_out_to(XNET_PROTOCOL_IP, mac_addr, entry->packet);
@@ -136,6 +125,9 @@ const uint8_t *xarp_resolve(xnet_packet_t *packet, const uint8_t *ip_addr) {
if (entry->state == XARP_ENTRY_STATE_RESOLVED) {
return entry->mac_addr;
} else if (entry->state == XARP_ENTRY_STATE_PENDING) {
// A packet is already pending for this IP, so store this new packet as well
// Or replace the old one if only one packet can be queued.
// For now, let's assume only one packet can be queued per pending ARP entry.
if (entry->packet) {
xnet_free_packet(entry->packet);
}
@@ -148,9 +140,12 @@ const uint8_t *xarp_resolve(xnet_packet_t *packet, const uint8_t *ip_addr) {
entry->state = XARP_ENTRY_STATE_PENDING;
memcpy(entry->ip_addr, ip_addr, 4);
entry->packet = packet;
entry->tmo = XARP_TIMEOUT_MS; // Initialize timeout
entry->retry_count = XARP_RETRY_COUNT; // Initialize retry count
send_arp_request(ip_addr);
} else {
// ARP table full, free the packet
xnet_free_packet(packet);
}
}
@@ -161,3 +156,32 @@ 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) {
update_entry(ip_addr, mac_addr, 1);
}
/**
* @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.
*/
void xarp_poll(void) {
for (int i = 0; i < XARP_CACHE_SIZE; i++) {
xarp_entry_t *entry = &arp_table[i];
if (entry->state == XARP_ENTRY_STATE_PENDING) {
entry->tmo -= XNET_POLL_CYCLE_MS; // Assuming XNET_POLL_CYCLE_MS is defined elsewhere as the poll interval
if (entry->tmo <= 0) {
if (entry->retry_count > 0) {
entry->retry_count--;
entry->tmo = XARP_TIMEOUT_MS; // Reset timeout for retransmission
send_arp_request(entry->ip_addr);
} else {
// No more retries, give up and free the packet
if (entry->packet) {
xnet_free_packet(entry->packet);
entry->packet = (xnet_packet_t *)0;
}
entry->state = XARP_ENTRY_STATE_FREE;
}
}
}
}
}

View File

@@ -3,6 +3,25 @@
#include "xnet_tiny.h"
// ARP configuration
#define XARP_RETRY_COUNT 3 // Number of ARP retransmissions
#define XARP_TIMEOUT_MS 1000 // ARP timeout in milliseconds (1 second)
typedef enum _xarp_state_t {
XARP_ENTRY_STATE_FREE,
XARP_ENTRY_STATE_RESOLVED,
XARP_ENTRY_STATE_PENDING,
} xarp_state_t;
typedef struct _xarp_entry_t {
uint8_t ip_addr[4];
uint8_t mac_addr[XNET_MAC_ADDR_SIZE];
xarp_state_t state;
uint32_t tmo; // Timeout counter for pending entries
uint32_t retry_count; // Remaining retry attempts for pending entries
xnet_packet_t *packet; // Packet awaiting resolution
} xarp_entry_t;
#define XARP_HW_ETHER 1 // 硬件类型:以太网
#define XARP_PROTOCOL_IP 0x0800 // 协议类型:IP
@@ -32,5 +51,6 @@ void xarp_init(void);
void xarp_in(xnet_packet_t *packet);
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
#endif // XARP_H

View File

@@ -169,4 +169,5 @@ void xnet_init (void) {
*/
void xnet_poll(void) {
ethernet_poll();
xarp_poll(); // Call ARP poll to handle timeouts and retransmissions
}

View File

@@ -1,16 +1,17 @@
#ifndef XNET_TINY_H
#ifndef XNET_TINY_H
#define XNET_TINY_H
#include <stdint.h>
#define XNET_CFG_PACKET_MAX_SIZE 1516 // 收发数据包的最大大小
#define XNET_POLL_CYCLE_MS 100 // Polling cycle in milliseconds, used by ARP and other modules
#pragma pack(1)
#define XNET_MAC_ADDR_SIZE 6 // MAC地址长度
/**
* 以太网数据帧格式RFC894
* 以太网数据帧格式:RFC894
*/
typedef struct _xether_hdr_t {
uint8_t dest[XNET_MAC_ADDR_SIZE]; // 目标mac地址