EtherLib/prefab/conn_blocks/icmp_connblock.c
Wiesner András 8676a392e5 - TCP basic implementation added
- TCPWindow added
- Checksum bug fixed (again)
- CBD introduced
- ConnBlock modified
- PackSieve report funtionality modified to decrease memory consumption
2023-01-30 11:04:46 +01:00

83 lines
2.8 KiB
C

#include "icmp_connblock.h"
#include <stddef.h>
#include "../packet_parsers/packet_parsers.h"
#include "../../utils.h"
#include "../../dynmem.h"
#include "../../pckt_assembler.h"
#include "../../eth_interface.h"
#include "../packet_parsers/icmp_packet.h"
#include "ipv4_connblock.h"
static bool filtIcmp(const PcktSieveFilterCondition * filtCond, const PcktProps * contProps, const PcktProps * ownProps, EthInterface * intf) {
IPv4Props * ipProps = (IPv4Props *) contProps;
IcmpProps * icmpProps = (IcmpProps *) ownProps;
return ipProps->Protocol == ETH_ICMP_PACKET_CLASS;
}
static int icmp_recv_cb(const Pckt * pckt, PcktSieveLayerTag tag) {
IcmpProps * icmpProps = HEADER_FETCH_PROPS(IcmpProps, pckt->header);
EthInterface * intf = (EthInterface *) tag.p; // icmp_new_connblock() puts pointer to intf into tag field
switch (icmpProps->type) {
case ICMP_MT_ECHO_REQUEST: {
icmpProps->type = ICMP_MT_ECHO_REPLY; // replace request with reply
icmpProps->hdrInsFn = insert_icmp_header;
// swap source an destination IP addresses
IPv4Props * iPv4Props = HEADER_FETCH_PROPS(IPv4Props, pckt->header->prev);
ip4_addr tmpIp = iPv4Props->SourceIPAddr;
iPv4Props->SourceIPAddr = iPv4Props->DestIPAddr;
iPv4Props->DestIPAddr = tmpIp;
iPv4Props->hdrInsFn = insert_ipv4_header;
// swap Ethernet fields
EthernetAddress tmpEth;
EthernetProps * ethProps = HEADER_FETCH_PROPS(EthernetProps, pckt->header->prev->prev);
HWACPY(tmpEth, ethProps->sourceAddr);
HWACPY(ethProps->sourceAddr, ethProps->destAddr);
HWACPY(ethProps->destAddr, tmpEth);
ethProps->hdrInsFn = insert_ethernet_header;
// payload is the same...
// assemble packet
RawPckt raw;
pckt_assemble(&raw, pckt);
// release headers
pckthdr_chain_free(pckt->header);
ethinf_transmit(intf, &raw);
}
break;
default:
break;
}
return 0;
}
ConnBlock icmp_new_connblock(EthInterface * intf) {
ConnBlock icmpConnB;
ConnBlock ipConnB = ipv4_new_connblock(intf, IPv4_IF_ADDR, NULL); // create new IPv4 connection block
PcktSieveFilterCondition filtCond;
packfiltcond_zero(&filtCond);
PcktSieveLayerTag tag;
tag.p = intf; // Ethernet-interface passed in 'tag.p'
icmpConnB.sieveLayer = packsieve_new_layer(ipConnB.sieveLayer, &filtCond, false, filtIcmp, icmp_recv_cb, tag, ETH_ICMP_PACKET_CLASS);
ASSERT_NULL(icmpConnB.sieveLayer);
icmpConnB.sieve = &intf->sieve;
icmpConnB.sieveLayer->connBReportFn = icmp_print_report;
return icmpConnB;
}
void icmp_print_report(const ConnBlock *connBlock) {
INFO("ICMP (ping)");
}