#include "arp_connblock.h" #include #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, 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"); }