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 <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");
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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() {
|
||||||
|
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 "../../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
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user