- 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)
71 lines
2.7 KiB
C
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)) ||
|
|
} |