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 };
|
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];
|
static xarp_entry_t arp_table[XARP_CACHE_SIZE];
|
||||||
|
|
||||||
#define swap_order16(v) ((((v) & 0xFF) << 8) | (((v) >> 8) & 0xFF))
|
#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++) {
|
for (int i = 0; i < XARP_CACHE_SIZE; i++) {
|
||||||
arp_table[i].state = XARP_ENTRY_STATE_FREE;
|
arp_table[i].state = XARP_ENTRY_STATE_FREE;
|
||||||
arp_table[i].packet = (xnet_packet_t *)0;
|
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->ip_addr, ip_addr, 4);
|
||||||
memcpy(entry->mac_addr, mac_addr, XNET_MAC_ADDR_SIZE);
|
memcpy(entry->mac_addr, mac_addr, XNET_MAC_ADDR_SIZE);
|
||||||
entry->state = XARP_ENTRY_STATE_RESOLVED;
|
entry->state = XARP_ENTRY_STATE_RESOLVED;
|
||||||
|
entry->tmo = 0; // Reset timeout
|
||||||
|
entry->retry_count = 0; // Reset retry count
|
||||||
|
|
||||||
if (entry->packet) {
|
if (entry->packet) {
|
||||||
ethernet_out_to(XNET_PROTOCOL_IP, mac_addr, 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) {
|
if (entry->state == XARP_ENTRY_STATE_RESOLVED) {
|
||||||
return entry->mac_addr;
|
return entry->mac_addr;
|
||||||
} else if (entry->state == XARP_ENTRY_STATE_PENDING) {
|
} 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) {
|
if (entry->packet) {
|
||||||
xnet_free_packet(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;
|
entry->state = XARP_ENTRY_STATE_PENDING;
|
||||||
memcpy(entry->ip_addr, ip_addr, 4);
|
memcpy(entry->ip_addr, ip_addr, 4);
|
||||||
entry->packet = packet;
|
entry->packet = packet;
|
||||||
|
entry->tmo = XARP_TIMEOUT_MS; // Initialize timeout
|
||||||
|
entry->retry_count = XARP_RETRY_COUNT; // Initialize retry count
|
||||||
|
|
||||||
send_arp_request(ip_addr);
|
send_arp_request(ip_addr);
|
||||||
} else {
|
} else {
|
||||||
|
// ARP table full, free the packet
|
||||||
xnet_free_packet(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) {
|
void xarp_update_from_ip(const uint8_t *ip_addr, const uint8_t *mac_addr) {
|
||||||
update_entry(ip_addr, mac_addr, 1);
|
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"
|
#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_HW_ETHER 1 // 硬件类型:以太网
|
||||||
#define XARP_PROTOCOL_IP 0x0800 // 协议类型:IP
|
#define XARP_PROTOCOL_IP 0x0800 // 协议类型:IP
|
||||||
|
|
||||||
@@ -32,5 +51,6 @@ void xarp_init(void);
|
|||||||
void xarp_in(xnet_packet_t *packet);
|
void xarp_in(xnet_packet_t *packet);
|
||||||
const uint8_t *xarp_resolve(xnet_packet_t *packet, const uint8_t *ip_addr);
|
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
|
||||||
|
|
||||||
#endif // XARP_H
|
#endif // XARP_H
|
||||||
|
|||||||
@@ -169,4 +169,5 @@ void xnet_init (void) {
|
|||||||
*/
|
*/
|
||||||
void xnet_poll(void) {
|
void xnet_poll(void) {
|
||||||
ethernet_poll();
|
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
|
#define XNET_TINY_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define XNET_CFG_PACKET_MAX_SIZE 1516 // 收发数据包的最大大小
|
#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)
|
#pragma pack(1)
|
||||||
|
|
||||||
#define XNET_MAC_ADDR_SIZE 6 // MAC地址长度
|
#define XNET_MAC_ADDR_SIZE 6 // MAC地址长度
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 以太网数据帧格式:RFC894
|
* 以太网数据帧格式:RFC894
|
||||||
*/
|
*/
|
||||||
typedef struct _xether_hdr_t {
|
typedef struct _xether_hdr_t {
|
||||||
uint8_t dest[XNET_MAC_ADDR_SIZE]; // 目标mac地址
|
uint8_t dest[XNET_MAC_ADDR_SIZE]; // 目标mac地址
|
||||||
|
|||||||
Reference in New Issue
Block a user