Implement ARP subsystem and arp app (AI)

- Created src/arp.h: ARP packet struct, cache entry struct, operation codes,
  lookup/request/resolve/receive API, sysfs registration
- Created src/arp.c: ARP cache with 32 entries, request/reply handling,
  ARP response to incoming requests for our IP, sysfs /sys/arp/table
  with formatted IP/MAC/interface/state columns
- Created apps/arp/arp.c: reads and displays /sys/arp/table
- Kernel calls arp_init() at boot, registered sysfs 'arp' namespace
- Tested: clean boot, ARP initialized, arp app in CPIO
This commit is contained in:
AI
2026-02-24 07:31:45 +00:00
parent 1825448528
commit d7d7e8e58e
7 changed files with 571 additions and 7 deletions

145
src/arp.h Normal file
View File

@@ -0,0 +1,145 @@
/**
* @file arp.h
* @brief Address Resolution Protocol (ARP) subsystem.
*
* Implements ARP (RFC 826) for mapping IPv4 addresses to Ethernet
* MAC addresses. Maintains an ARP cache and handles ARP requests
* and replies.
*
* The ARP table is exposed via sysfs at /sys/arp for userspace tools.
*/
#ifndef ARP_H
#define ARP_H
#include <stdint.h>
/** Maximum number of ARP cache entries. */
#define ARP_TABLE_SIZE 32
/** ARP hardware type: Ethernet */
#define ARP_HW_ETHER 1
/** ARP operation codes */
#define ARP_OP_REQUEST 1
#define ARP_OP_REPLY 2
/** ARP cache entry states */
#define ARP_STATE_FREE 0 /**< Unused slot. */
#define ARP_STATE_INCOMPLETE 1 /**< Request sent, awaiting reply. */
#define ARP_STATE_RESOLVED 2 /**< MAC address known. */
/* ================================================================
* ARP packet (28 bytes for IPv4-over-Ethernet)
* ================================================================ */
/**
* ARP packet structure for IPv4 over Ethernet.
* All multi-byte fields are in network byte order.
*/
typedef struct __attribute__((packed)) arp_packet {
uint16_t hw_type; /**< Hardware type (1 = Ethernet). */
uint16_t proto_type; /**< Protocol type (0x0800 = IPv4). */
uint8_t hw_len; /**< Hardware address length (6). */
uint8_t proto_len; /**< Protocol address length (4). */
uint16_t operation; /**< Operation (1=request, 2=reply). */
uint8_t sender_mac[6]; /**< Sender hardware address. */
uint32_t sender_ip; /**< Sender protocol address. */
uint8_t target_mac[6]; /**< Target hardware address. */
uint32_t target_ip; /**< Target protocol address. */
} arp_packet_t;
/** ARP packet size. */
#define ARP_PACKET_SIZE 28
/* ================================================================
* ARP cache entry
* ================================================================ */
/**
* ARP cache entry.
*/
typedef struct arp_entry {
uint32_t ip_addr; /**< IPv4 address (host byte order). */
uint8_t mac[6]; /**< Resolved MAC address. */
uint8_t state; /**< ARP_STATE_*. */
uint8_t iface_idx; /**< Ethernet interface index. */
uint32_t timestamp; /**< Time when entry was created (tick count). */
} arp_entry_t;
/* ================================================================
* Public API
* ================================================================ */
/**
* Initialize the ARP subsystem.
* Registers sysfs namespace "arp".
*/
void arp_init(void);
/**
* Look up an IP address in the ARP cache.
*
* @param ip IPv4 address (host byte order).
* @param mac Output: 6-byte MAC address if found.
* @return 0 if found and resolved, -1 if not in cache or incomplete.
*/
int arp_lookup(uint32_t ip, uint8_t *mac);
/**
* Send an ARP request for the given IP address.
*
* @param iface_idx Ethernet interface to send on.
* @param target_ip IP address to resolve (host byte order).
* @return 0 on success, -1 on failure.
*/
int arp_request(uint32_t iface_idx, uint32_t target_ip);
/**
* Resolve an IP address to a MAC address.
*
* Checks the ARP cache first. If not found, sends an ARP request
* and returns -1 (caller should retry later).
*
* @param iface_idx Ethernet interface index.
* @param ip IPv4 address (host byte order).
* @param mac Output: 6-byte MAC address.
* @return 0 if resolved, -1 if pending.
*/
int arp_resolve(uint32_t iface_idx, uint32_t ip, uint8_t *mac);
/**
* Process an incoming ARP packet.
*
* Called by the Ethernet subsystem when an ARP frame is received.
*
* @param data Raw ARP packet.
* @param len Packet length.
* @param iface_idx Interface the packet arrived on.
*/
void arp_receive(const void *data, uint32_t len, uint32_t iface_idx);
/**
* Add a static ARP entry.
*
* @param ip IPv4 address (host byte order).
* @param mac 6-byte MAC address.
* @param iface_idx Ethernet interface index.
* @return 0 on success, -1 if table full.
*/
int arp_add_static(uint32_t ip, const uint8_t *mac, uint32_t iface_idx);
/**
* Get an ARP table entry by index (for enumeration).
*
* @param index 0-based index.
* @return Pointer to entry, or NULL if out of range.
*/
const arp_entry_t *arp_get_entry(uint32_t index);
/**
* Get the number of active ARP entries.
*/
uint32_t arp_get_count(void);
#endif /* ARP_H */