// // 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)) || }