EtherLib/prefab/conn_blocks/arp_connblock.c
Wiesner András ac5fc9c529 -IP reassembler added
-PcktSieve special return functionality added
-ARP multicast learning bug fixed
-include guards have been refactored
-Doxygen style tweaked
2023-02-04 11:04:26 +01:00

86 lines
2.6 KiB
C

#include "arp_connblock.h"
#include <stddef.h>
#include "../../utils.h"
#include "../../dynmem.h"
static bool filtArp(const PcktSieveFilterCondition * filtCond, const PcktProps * contProps, const PcktProps * ownProps, EthInterface * intf) {
EthernetProps * ethProps = (EthernetProps *) contProps;
ArpProps * arpProps = (ArpProps *) ownProps;
return ethProps->length_type == ETH_ARP_PACKET_CLASS;
}
ConnBlock arp_new_connblock(EthInterface * intf, SieveCallBackFn cb) {
ConnBlock arpConnB; // create ARP connblock
PcktSieveFilterCondition filtCond;
packfiltcond_zero(&filtCond);
PcktSieveLayerTag tag;
tag.p = intf;
arpConnB.sieveLayer = packsieve_new_layer(&intf->sieve.layer0, &filtCond, false, filtArp, cb, tag, ETH_ARP_PACKET_CLASS);
ASSERT_NULL(arpConnB.sieveLayer);
arpConnB.sieve = &intf->sieve;
arpConnB.sieveLayer->connBReportFn = arp_print_report;
return arpConnB;
}
void arp_send(const ConnBlock * connBlock, const ArpProps * props) {
// allocate header chain
PcktHeaderElement * arpHeader = ALLOC_HEADER_ELEMENT(ArpProps);
PcktHeaderElement * ethHeader = ALLOC_HEADER_ELEMENT(EthernetProps);
arpHeader->next = NULL;
arpHeader->prev = ethHeader;
ethHeader->next = arpHeader;
ethHeader->prev = NULL;
// fetch props
ArpProps * arpProps = HEADER_FETCH_PROPS(ArpProps, arpHeader);
EthernetProps * ethProps = HEADER_FETCH_PROPS(EthernetProps, ethHeader);
// ARP
*arpProps = *props;
// Ethernet
ethProps->length_type = ETH_ARP_PACKET_CLASS;
memset(ethProps->destAddr, 0xFF, ETH_HW_ADDR_LEN); // broadcast destination
memcpy(ethProps->sourceAddr, connBlock->sieve->intf->mac, ETH_HW_ADDR_LEN); // source
// allocate transmit buffer
uint32_t txHeaderSize = ETH_ETHERNET_HEADER_SIZE + ETH_ARP_HEADER_SIZE;
uint32_t txBufSize = MAX(txHeaderSize + 4, 60);
uint8_t * txBuf = dynmem_alloc(txBufSize);
// insert Ethernet header
insert_ethernet_header(txBuf, ethHeader);
// insert ARP header
insert_arp_header(txBuf + ETH_ETHERNET_HEADER_SIZE, arpHeader);
// release headers
dynmem_free(arpHeader);
dynmem_free(ethHeader);
// append CRC at the end
uint32_t crc = crc32(txBuf, txBufSize - 4);
memcpy(txBuf + txBufSize - 4, &crc, 4);
// send packet
RawPckt rpckt;
rpckt.size = txBufSize;
rpckt.payload = txBuf;
rpckt.time_s = 0;
rpckt.time_ns = 0;
ethinf_transmit(connBlock->sieve->intf, &rpckt);
// release transmit buffer
dynmem_free(txBuf);
}
void arp_print_report(const ConnBlock *connBlock) {
INFO("ARP");
}