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:
145
src/arp.h
Normal file
145
src/arp.h
Normal 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 */
|
||||
Reference in New Issue
Block a user