ARP learning works; ARP connblock basics

This commit is contained in:
Wiesner András 2022-12-15 08:37:53 +01:00
parent 905b455bb3
commit 3efcde1c4b
7 changed files with 130 additions and 3 deletions

View File

@ -5,6 +5,7 @@
#include <memory.h> #include <memory.h>
#include "arp_cache.h" #include "arp_cache.h"
#include "dynmem.h" #include "dynmem.h"
#include "utils.h"
ArpCache *arpc_new(uint16_t size) { ArpCache *arpc_new(uint16_t size) {
ArpCache * arcp = (ArpCache *) dynmem_alloc(2 * sizeof(uint16_t) + size * sizeof(ArpEntry)); ArpCache * arcp = (ArpCache *) dynmem_alloc(2 * sizeof(uint16_t) + size * sizeof(ArpEntry));
@ -40,3 +41,12 @@ const ArpEntry *arpc_get(ArpCache *arpc, ip4_addr ip) {
return NULL; return NULL;
} }
void arpc_dump(ArpCache *arpc) {
for (uint16_t i = 0; i < arpc->fill; i++) {
ArpEntry * entry = arpc->entries + i;
PRINT_IPv4(entry->ip);
MSG(" -> %02x:%02x:%02x:%02x:%02x:%02x\n", entry->eth[0], entry->eth[1], entry->eth[2], entry->eth[3], entry->eth[4], entry->eth[5]);
}
MSG("\n");
}

View File

@ -4,6 +4,8 @@
#include "prefab/packet_parsers/ethernet_frame.h" #include "prefab/packet_parsers/ethernet_frame.h"
#include "prefab/packet_parsers/ipv4_types.h" #include "prefab/packet_parsers/ipv4_types.h"
#define ETH_ARP_PACKET_CLASS (0x0806)
/** /**
* ARP cache entry record. * ARP cache entry record.
*/ */
@ -48,4 +50,10 @@ const ArpEntry *arpc_get(ArpCache *arpc, ip4_addr ip);
*/ */
void arpc_free(ArpCache * aprc); void arpc_free(ArpCache * aprc);
/**
* Dump ARP cache contents.
* @param arpc
*/
void arpc_dump(ArpCache * arpc);
#endif //ETHERLIB_TEST_ARP_CACHE_H #endif //ETHERLIB_TEST_ARP_CACHE_H

View File

@ -4,6 +4,7 @@
#include "prefab/prefab.h" #include "prefab/prefab.h"
#include "packet_sieve.h" #include "packet_sieve.h"
#include "prefab/packet_parsers/arp_packet.h"
EthState gEthState; EthState gEthState;
@ -29,6 +30,13 @@ static void register_packet_parsers() {
cdesc.procFun = parse_udp; cdesc.procFun = parse_udp;
cdesc.propertySize = sizeof(UdpProps); cdesc.propertySize = sizeof(UdpProps);
packreg_add_class(E.pcktReg, &cdesc); packreg_add_class(E.pcktReg, &cdesc);
// ARP packet parser
cdesc.class = ETH_ARP_PACKET_CLASS;
cdesc.containerClass = 0;
cdesc.procFun = parse_arp;
cdesc.propertySize = sizeof(ArpProps);
packreg_add_class(E.pcktReg, &cdesc);
} }
void ethlib_init() { void ethlib_init() {

View File

@ -0,0 +1,32 @@
#include "arp_connblock.h"
#include <stddef.h>
#include "../packet_parsers/packet_parsers.h"
#include "../../utils.h"
#include "../../dynmem.h"
#include "../packet_parsers/arp_packet.h"
static bool filtArp(const PcktSieveFilterCondition * filtCond, const PcktProps * contProps, const PcktProps * ownProps) {
EthernetProps * ethProps = (EthernetProps *) contProps;
ArpProps * arpProps = (ArpProps *) ownProps;
return ethProps->length_type == ETH_ARP_PACKET_CLASS;
}
ConnBlock arp_new_connblock(EthInterface * intf) {
ConnBlock arpConnB; // create ARP connblock
PcktSieveFilterCondition filtCond;
packfiltcond_zero(&filtCond);
PcktSieveLayerTag tag;
tag.u = 0;
arpConnB.sieveLayer = packsieve_new_layer(&intf->sieve.layer0, &filtCond, false, filtArp, NULL, tag, ETH_ARP_PACKET_CLASS);
ASSERT_NULL(arpConnB.sieveLayer);
arpConnB.intf = intf;
SNPRINTF(arpConnB.sieveLayer->infoTag, PCKT_SIEVE_INFOTAG_LEN, "ARP");
return arpConnB;
}

View File

@ -0,0 +1,15 @@
#ifndef ETHERLIB_TEST_ARP_CONNBLOCK_H
#define ETHERLIB_TEST_ARP_CONNBLOCK_H
#endif //ETHERLIB_TEST_ARP_CONNBLOCK_H
#include <stdint.h>
#include "../../connection_block.h"
#include "../../eth_interface.h"
/**
* Create new ARP connection block.
* @param intf associated Ethernet interface
* @return ARP connection block
*/
ConnBlock arp_new_connblock(EthInterface * intf);

View File

@ -6,7 +6,52 @@
#include "../../packet_registry.h" #include "../../packet_registry.h"
#include "ethernet_frame.h" #include "ethernet_frame.h"
#include "../../utils.h" #include "../../utils.h"
#include "../../eth_interface.h"
int parse_arp_packet(const uint8_t *hdr, uint32_t size, PcktProps * props) { static EthernetAddress emptyEthAddr = { 0x00 };
static void arp_fetch_mapping(const ArpProps * arpProps, ArpCache * arpc) {
ArpEntry entry;
if ((memcmp(arpProps->SHA, emptyEthAddr, ETH_HW_ADDR_LEN)) && (arpProps->SPA != 0)) {
memcpy(entry.eth, arpProps->SHA, ETH_HW_ADDR_LEN);
entry.ip = arpProps->SPA;
arpc_learn(arpc, &entry);
}
if ((memcmp(arpProps->THA, emptyEthAddr, ETH_HW_ADDR_LEN)) && (arpProps->TPA != 0)) {
memcpy(entry.eth, arpProps->THA, ETH_HW_ADDR_LEN);
entry.ip = arpProps->TPA;
arpc_learn(arpc, &entry);
}
}
int parse_arp(const uint8_t *hdr, uint32_t size, PcktHeaderElement *pcktHdrLe, struct EthInterface_ *intf) {
// parse ARP packet
ArpProps *arpProps = HEADER_FETCH_PROPS(ArpProps, pcktHdrLe);
FETCH_WORD_H2N_ADVANCE(&arpProps->HTYPE, hdr); // hardware type
FETCH_WORD_H2N_ADVANCE(&arpProps->PTYPE, hdr); // protocol type
FETCH_BYTE_ADVANCE(&arpProps->HLEN, hdr); // hardware address size
FETCH_BYTE_ADVANCE(&arpProps->PLEN, hdr); // protocol address size
FETCH_WORD_H2N_ADVANCE(&arpProps->OPER, hdr); // operation code
FETCH_ADVANCE(&arpProps->SHA, hdr, ETH_HW_ADDR_LEN); // sender HW address
FETCH_ADVANCE(&arpProps->SPA, hdr, sizeof(ip4_addr)); // sender protocol address
FETCH_ADVANCE(&arpProps->THA, hdr, ETH_HW_ADDR_LEN); // target HW address
FETCH_ADVANCE(&arpProps->TPA, hdr, sizeof(ip4_addr)); // target protocol address
// learn new mapping
arp_fetch_mapping(arpProps, intf->arpc);
return 0; return 0;
} }
void insert_arp_header(uint8_t *hdr, const PcktHeaderElement *headers) {
ArpProps *arpProps = HEADER_FETCH_PROPS(ArpProps, headers);
FILL_WORD_H2N_ADVANCE(hdr, arpProps->HTYPE); // hardware type
FILL_WORD_H2N_ADVANCE(hdr, arpProps->PTYPE); // protocol type
FILL_BYTE_ADVANCE(hdr, &arpProps->HLEN); // hardware address size
FILL_BYTE_ADVANCE(hdr, &arpProps->PLEN); // protocol address size
FILL_WORD_H2N_ADVANCE(hdr, arpProps->OPER); // operation code
FILL_ADVANCE(hdr, &arpProps->SHA, ETH_HW_ADDR_LEN); // sender HW address
FILL_ADVANCE(hdr, &arpProps->SPA, sizeof(ip4_addr)); // sender protocol address
FILL_ADVANCE(hdr, &arpProps->THA, ETH_HW_ADDR_LEN); // target HW address
FILL_ADVANCE(hdr, &arpProps->TPA, sizeof(ip4_addr)); // target protocol address
}

View File

@ -6,6 +6,10 @@
#define ETHERLIB_TEST_ARP_PACKET_H #define ETHERLIB_TEST_ARP_PACKET_H
#include <stdint.h> #include <stdint.h>
#include "ipv4_types.h"
#include "../../packet_registry.h"
#include "../../packet_sieve.h"
#define ETH_ARP_PACKET_CLASS (0x0806) #define ETH_ARP_PACKET_CLASS (0x0806)
@ -30,7 +34,12 @@ typedef struct {
uint8_t HLEN; ///< Hardware address length uint8_t HLEN; ///< Hardware address length
uint8_t PLEN; ///< Protocol address length uint8_t PLEN; ///< Protocol address length
uint16_t OPER; ///< Operation uint16_t OPER; ///< Operation
uint16_t addr[]; ///< Array of addresses (SHA, SPA, THA, TPA) uint8_t SHA[6]; ///< Array of addresses (SHA, SPA, THA, TPA)
ip4_addr SPA;
uint8_t THA[6];
ip4_addr TPA;
} ArpProps; } ArpProps;
int parse_arp(const uint8_t *hdr, uint32_t size, PcktHeaderElement *pcktHdrLe, struct EthInterface_ *intf);
#endif //ETHERLIB_TEST_ARP_PACKET_H #endif //ETHERLIB_TEST_ARP_PACKET_H