EtherLib/prefab/conn_blocks/ipv4_connblock.c
Wiesner András ab8d45932f Timestamping and bunch of bugfix and optimization
- Timestamping management added
- Errors due to reading uninitialized data in ARP fixed
- EthInterface reworked, incoming packet notification and payload readout separated (through which fixing concurrent access problems)
- RX and TX offloads added
- Capability to add a packet sieve layer without prior registration of specific packet class added (this makes it possible to register arbitrary EtherType connection blocks, for example)
2023-04-27 09:38:26 +02:00

71 lines
2.7 KiB
C

//
// Created by epagris on 2022.11.07..
//
#include "ipv4_connblock.h"
#include "../../utils.h"
#include "../../global_state.h"
static bool filtIPv4(const PcktSieveFilterCondition *filtCond, const PcktProps *contProps, const PcktProps *ownProps, EthInterface * intf) {
EthernetProps *etherProps = (EthernetProps *) contProps;
IPv4Props *ipProps = (IPv4Props *) ownProps;
// check header
bool headerOK = (etherProps->length_type == ETH_IPv4_PACKET_CLASS) && ((IP_ADDR_FROM_FILTCOND(filtCond) == ipProps->DestIPAddr) ||
((IP_ADDR_FROM_FILTCOND(filtCond) == IPv4_IF_ADDR) && (ipProps->DestIPAddr == intf->ip) && (intf->ip != 0)));
return headerOK;
}
ConnBlock ipv4_new_connblock(EthInterface *intf, ip4_addr ipAddr, SieveCallBackFn cbFn) {
ConnBlock connb;
connb_init_defaults(&connb);
PcktSieveFilterCondition filtCond;
packfiltcond_zero(&filtCond);
IP_ADDR_TO_FILTCOND(&filtCond, ipAddr);
PcktSieveLayerTag tag;
tag.u = 0;
bool matchAny = ipAddr == IPv4_ANY_ADDR;
connb.sieveLayer = packsieve_new_layer(&intf->sieve.layer0, &filtCond, matchAny, filtIPv4, cbFn, tag, ETH_IPv4_PACKET_CLASS);
ASSERT_NULL(connb.sieveLayer);
connb.sieve = &intf->sieve;
connb.sieveLayer->connBReportFn = ipv4_print_report;
return connb;
}
void ipv4_print_report(const ConnBlock* connBlock) {
const PcktSieveLayer * sl = connBlock->sieveLayer;
ip4_addr ipAddr = IP_ADDR_FROM_FILTCOND(&sl->filtCond);
if (!sl->matchAny) {
if (ipAddr == IPv4_IF_ADDR) {
ipAddr = connBlock->sieve->intf->ip;
}
INFO("IP: %u.%u.%u.%u", (ipAddr & 0xFF), ((ipAddr >> 8) & 0xFF),
((ipAddr >> 16) & 0xFF), ((ipAddr >> 24) & 0xFF));
} else {
INFO("IP: ANY");
}
}
bool ipv4_in_range(ip4_addr a, ip4_addr l, ip4_addr u) {
l = ntohl(l); // this way IP addresses are mathematically sortable (by changing byte order)
u = ntohl(u);
a = ntohl(a);
return (l <= a) && (a <= u);
}
bool ipv4_is_multicast_address(ip4_addr addr) {
return ipv4_in_range(addr, IPv4(224, 0, 0, 0), IPv4(224, 0, 255, 255)) ||
ipv4_in_range(addr, IPv4(224, 1, 0, 0), IPv4(224, 1, 255, 255)) ||
ipv4_in_range(addr, IPv4(224, 3, 0, 0), IPv4(224, 4, 255, 255)) ||
ipv4_in_range(addr, IPv4(225, 0, 0, 0), IPv4(239, 255, 255, 255));
// ipv4_in_range(addr, IPv4(225, 0, 0, 0), IPv4(231, 255, 255, 255)) ||
// ipv4_in_range(addr, IPv4(232, 0, 0, 0), IPv4(232, 255, 255, 255)) ||
// ipv4_in_range(addr, IPv4(233, 0, 0, 0), IPv4(233, 251, 255, 255)) ||
// ipv4_in_range(addr, IPv4(233, 252, 0, 0), IPv4(233, 255, 255, 255)) ||
// ipv4_in_range(addr, IPv4(234, 252, 0, 0), IPv4(239, 255, 255, 255)) ||
}