Files
microtcp/src/arp.h
T
2023-10-31 16:09:51 +01:00

125 lines
3.8 KiB
C

#include <assert.h>
#include <stdint.h>
#include <stddef.h>
#include "defs.h"
#define ARP_MAX_PENDING_REQUESTS 32
#define ARP_TRANSLATION_TABLE_SIZE 128
typedef enum {
ARP_RESOLUTION_OK,
ARP_RESOLUTION_FAILED,
ARP_RESOLUTION_TIMEOUT,
} arp_resolution_status_t;
typedef struct arp_translation_table_entry_t arp_translation_table_entry_t;
struct arp_translation_table_entry_t {
arp_translation_table_entry_t *prev;
arp_translation_table_entry_t *next;
mac_address_t mac;
ip_address_t ip;
uint64_t timeout;
};
typedef struct {
uint64_t time;
arp_translation_table_entry_t *used_list_head;
arp_translation_table_entry_t *used_list_tail;
arp_translation_table_entry_t *free_list;
arp_translation_table_entry_t entries[ARP_TRANSLATION_TABLE_SIZE];
} arp_translation_table_t;
typedef struct arp_pending_request_t arp_pending_request_t;
struct arp_pending_request_t {
arp_pending_request_t *prev;
arp_pending_request_t *next;
ip_address_t ip;
uint64_t timeout;
void *callback_data;
void (*callback)(void*, arp_resolution_status_t status, mac_address_t);
};
typedef enum {
ARP_HARDWARE_ETHERNET = 1,
} arp_hardware_type;
typedef enum {
ARP_PROTOCOL_IP = 0x800,
} arp_protocol_type;
typedef enum {
ARP_OPERATION_REQUEST = 1,
ARP_OPERATION_REPLY = 2,
} arp_operation_t;
typedef struct __attribute__((__packed__)) {
uint16_t hardware_type;
uint16_t protocol_type;
uint8_t hardware_len;
uint8_t protocol_len;
uint16_t operation_type;
mac_address_t sender_hardware_address;
ip_address_t sender_protocol_address;
mac_address_t target_hardware_address;
ip_address_t target_protocol_address;
} arp_packet_t;
static_assert(offsetof(arp_packet_t, hardware_type) == 0);
static_assert(offsetof(arp_packet_t, protocol_type) == 2);
static_assert(offsetof(arp_packet_t, hardware_len) == 4);
static_assert(offsetof(arp_packet_t, protocol_len) == 5);
static_assert(offsetof(arp_packet_t, operation_type) == 6);
static_assert(offsetof(arp_packet_t, sender_hardware_address) == 8);
static_assert(offsetof(arp_packet_t, sender_protocol_address) == 14);
static_assert(offsetof(arp_packet_t, target_hardware_address) == 18);
static_assert(offsetof(arp_packet_t, target_protocol_address) == 24);
static_assert(sizeof(arp_packet_t) == 28);
typedef struct {
uint64_t time;
uint64_t cache_timeout;
uint64_t request_timeout;
arp_packet_t *output;
void *send_data;
void (*send)(void *send_data, mac_address_t dest_mac);
ip_address_t self_ip;
mac_address_t self_mac;
arp_translation_table_t table;
arp_pending_request_t *pending_request_free_list;
arp_pending_request_t *pending_request_used_list;
arp_pending_request_t *pending_request_used_tail;
arp_pending_request_t pending_request_pool[ARP_MAX_PENDING_REQUESTS];
} arp_state_t;
typedef enum {
ARP_PROCESS_RESULT_HWARENOTSUPP,
ARP_PROCESS_RESULT_PROTONOTSUPP,
ARP_PROCESS_RESULT_INVALID,
ARP_PROCESS_RESULT_OK,
} arp_process_result_t;
void arp_init(arp_state_t *state,
ip_address_t ip,
mac_address_t mac,
void *send_data,
void (*send)(void*, mac_address_t));
void arp_free(arp_state_t *state);
arp_process_result_t
arp_process_packet(arp_state_t *state,
const void *packet,
size_t len);
void arp_resolve_mac(arp_state_t *state,
ip_address_t ip,
void *userp,
void (*callback)(void*, arp_resolution_status_t, mac_address_t));
void arp_ms_passed(arp_state_t *state, size_t ms);
void arp_change_output_buffer(arp_state_t *state, void *ptr, size_t max);