arp function finished
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -169,4 +169,5 @@ void xnet_init (void) {
|
||||
*/
|
||||
void xnet_poll(void) {
|
||||
ethernet_poll();
|
||||
xarp_poll(); // Call ARP poll to handle timeouts and retransmissions
|
||||
}
|
||||
|
||||
@@ -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地址
|
||||
|
||||
Reference in New Issue
Block a user