blob: be5c1d305ae1c3d0d517d133e000d281e3da7a4f [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Concrete implementations of `FilterBuilder` required by the parser.
#ifndef SRC_CONNECTIVITY_NETWORK_NETDUMP_FILTER_BUILDER_IMPL_H_
#define SRC_CONNECTIVITY_NETWORK_NETDUMP_FILTER_BUILDER_IMPL_H_
#include "filter.h"
#include "parser.h"
namespace netdump::parser {
// The reference implementation for constructing filter tree nodes.
// `FilterTreeBuilder` takes parameters in host byte order, and converts them in network byte order
// for the filter node constructors.
class FilterTreeBuilder : public FilterBuilder<FilterPtr> {
public:
explicit FilterTreeBuilder(const Tokenizer& tokenizer) : FilterBuilder<FilterPtr>(tokenizer) {}
inline FilterPtr frame_length(uint16_t length, TokenPtr comparator) override {
return FilterPtr(new FrameLengthFilter(htons(length), comparator->get_tag<LengthComparator>()));
}
inline FilterPtr ethertype(uint16_t type) override {
return FilterPtr(new EthFilter(htons(type)));
}
inline FilterPtr mac(std::array<uint8_t, ETH_ALEN> address, TokenPtr addr_type) override {
std::reverse(address.begin(), address.end()); // Constructor expects network byte order.
return FilterPtr(new EthFilter(address, addr_type->get_tag<AddressFieldType>()));
}
inline FilterPtr ip_version(uint8_t version) override { return FilterPtr(new IpFilter(version)); }
inline FilterPtr ip_pkt_length(uint8_t version, uint16_t length, TokenPtr comparator) override {
return FilterPtr(new IpFilter(version, htons(length), comparator->get_tag<LengthComparator>()));
}
inline FilterPtr ip_protocol(uint8_t version, uint8_t protocol) override {
return FilterPtr(new IpFilter(version, protocol));
}
inline FilterPtr ipv4_address(uint32_t address, TokenPtr type) override {
return FilterPtr(new IpFilter(htonl(address), type->get_tag<AddressFieldType>()));
}
inline FilterPtr ipv6_address(std::array<uint8_t, IP6_ADDR_LEN> address,
TokenPtr addr_type) override {
std::reverse(address.begin(), address.end()); // Constructor expects network byte order.
return FilterPtr(new IpFilter(address, addr_type->get_tag<AddressFieldType>()));
}
FilterPtr ports(std::vector<PortRange> ranges, TokenPtr port_type) override {
for (auto range_it = ranges.begin(); range_it < ranges.end(); ++range_it) {
range_it->first = htons(range_it->first);
range_it->second = htons(range_it->second);
}
if (port_type == tkz.SRC) {
return FilterPtr(new PortFilter(std::move(ranges), SRC_PORT));
}
if (port_type == tkz.DST) {
return FilterPtr(new PortFilter(std::move(ranges), DST_PORT));
}
if (port_type == tkz.PORT) {
return FilterPtr(new PortFilter(std::move(ranges), EITHER_PORT));
}
ZX_DEBUG_ASSERT_MSG(port_type->one_of(tkz.SRC, tkz.DST, tkz.PORT),
"Invalid port type token: %s", port_type->get_term().c_str());
return nullptr;
}
inline FilterPtr negation(FilterPtr filter) override {
return FilterPtr(new NegFilter(std::move(filter)));
}
inline FilterPtr conjunction(FilterPtr left, FilterPtr right) override {
return FilterPtr(new ConjFilter(std::move(left), std::move(right)));
}
inline FilterPtr disjunction(FilterPtr left, FilterPtr right) override {
return FilterPtr(new DisjFilter(std::move(left), std::move(right)));
}
};
} // namespace netdump::parser
#endif // SRC_CONNECTIVITY_NETWORK_NETDUMP_FILTER_BUILDER_IMPL_H_