ARP learning works; ARP connblock basics
This commit is contained in:
parent
905b455bb3
commit
3efcde1c4b
10
arp_cache.c
10
arp_cache.c
@ -5,6 +5,7 @@
|
||||
#include <memory.h>
|
||||
#include "arp_cache.h"
|
||||
#include "dynmem.h"
|
||||
#include "utils.h"
|
||||
|
||||
ArpCache *arpc_new(uint16_t size) {
|
||||
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;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "prefab/packet_parsers/ethernet_frame.h"
|
||||
#include "prefab/packet_parsers/ipv4_types.h"
|
||||
|
||||
#define ETH_ARP_PACKET_CLASS (0x0806)
|
||||
|
||||
/**
|
||||
* ARP cache entry record.
|
||||
*/
|
||||
@ -48,4 +50,10 @@ const ArpEntry *arpc_get(ArpCache *arpc, ip4_addr ip);
|
||||
*/
|
||||
void arpc_free(ArpCache * aprc);
|
||||
|
||||
/**
|
||||
* Dump ARP cache contents.
|
||||
* @param arpc
|
||||
*/
|
||||
void arpc_dump(ArpCache * arpc);
|
||||
|
||||
#endif //ETHERLIB_TEST_ARP_CACHE_H
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "prefab/prefab.h"
|
||||
#include "packet_sieve.h"
|
||||
#include "prefab/packet_parsers/arp_packet.h"
|
||||
|
||||
EthState gEthState;
|
||||
|
||||
@ -29,6 +30,13 @@ static void register_packet_parsers() {
|
||||
cdesc.procFun = parse_udp;
|
||||
cdesc.propertySize = sizeof(UdpProps);
|
||||
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() {
|
||||
|
32
prefab/conn_blocks/arp_connblock.c
Normal file
32
prefab/conn_blocks/arp_connblock.c
Normal 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;
|
||||
}
|
15
prefab/conn_blocks/arp_connblock.h
Normal file
15
prefab/conn_blocks/arp_connblock.h
Normal 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);
|
@ -6,7 +6,52 @@
|
||||
#include "../../packet_registry.h"
|
||||
#include "ethernet_frame.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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -6,6 +6,10 @@
|
||||
#define ETHERLIB_TEST_ARP_PACKET_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "ipv4_types.h"
|
||||
|
||||
#include "../../packet_registry.h"
|
||||
#include "../../packet_sieve.h"
|
||||
|
||||
#define ETH_ARP_PACKET_CLASS (0x0806)
|
||||
|
||||
@ -30,7 +34,12 @@ typedef struct {
|
||||
uint8_t HLEN; ///< Hardware address length
|
||||
uint8_t PLEN; ///< Protocol address length
|
||||
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;
|
||||
|
||||
int parse_arp(const uint8_t *hdr, uint32_t size, PcktHeaderElement *pcktHdrLe, struct EthInterface_ *intf);
|
||||
|
||||
#endif //ETHERLIB_TEST_ARP_PACKET_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user